Skip to content

Commit 37b8acd

Browse files
authored
Merge pull request #117 from TheThingsNetwork/fix/env
Fix update of flags from the environment
2 parents 6283d81 + 72d0a60 commit 37b8acd

File tree

11 files changed

+126
-97
lines changed

11 files changed

+126
-97
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
2020

2121
### Fixed
2222

23+
- Flags are always only loaded from the env. Now flags are loaded from env only if set.
24+
2325
## [v0.11.2] (2024-03-04)
2426

2527
### Fixed

pkg/source/chirpstack/config/config.go

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,35 +57,35 @@ func New() *Config {
5757

5858
config.flags.StringVar(&config.url,
5959
"api-url",
60-
"",
60+
os.Getenv("CHIRPSTACK_API_URL"),
6161
"ChirpStack API URL")
6262
config.flags.StringVar(&config.apiKey,
6363
"api-key",
6464
"",
6565
"ChirpStack API key")
6666
config.flags.StringVar(&config.caCertPath,
6767
"ca-cert-path",
68-
"",
68+
os.Getenv("CHIRPSTACK_CA_CERT_PATH"),
6969
"(optional) Path to the CA certificate file for ChirpStack API TLS connections")
7070
config.flags.BoolVar(&config.insecure,
7171
"insecure",
72-
false,
72+
os.Getenv("CHIRPSTACK_INSECURE") == "true",
7373
"Do not connect to ChirpStack over TLS")
7474
config.flags.BoolVar(&config.ExportVars,
7575
"export-vars",
76-
false,
76+
os.Getenv("EXPORT_VARS") == "true",
7777
"Export device variables from ChirpStack")
7878
config.flags.BoolVar(&config.ExportSession,
7979
"export-session",
80-
false,
80+
os.Getenv("EXPORT_SESSION") == "true",
8181
"Export device session keys from ChirpStack")
8282
config.flags.StringVar(&config.joinEUI,
8383
"join-eui",
84-
"",
84+
os.Getenv("JOIN_EUI"),
8585
"JoinEUI of exported devices")
8686
config.flags.StringVar(&config.FrequencyPlanID,
8787
"frequency-plan-id",
88-
"",
88+
os.Getenv("FREQUENCY_PLAN_ID"),
8989
"Frequency Plan ID of exported devices")
9090

9191
return config
@@ -94,26 +94,25 @@ func New() *Config {
9494
func (c *Config) Initialize(src source.Config) error {
9595
c.src = src
9696

97-
if c.apiKey = os.Getenv("CHIRPSTACK_API_KEY"); c.apiKey == "" {
97+
if apiKey := os.Getenv("CHIRPSTACK_API_KEY"); apiKey != "" && c.apiKey == "" {
98+
c.apiKey = apiKey
99+
}
100+
if c.apiKey == "" {
98101
return errNoAPIToken.New()
99102
}
100-
if c.url = os.Getenv("CHIRPSTACK_API_URL"); c.url == "" {
103+
if c.url == "" {
101104
return errNoAPIURL.New()
102105
}
103-
if c.FrequencyPlanID = os.Getenv("FREQUENCY_PLAN_ID"); c.FrequencyPlanID == "" {
106+
if c.FrequencyPlanID == "" {
104107
return errNoFrequencyPlan.New()
105108
}
106-
if c.joinEUI = os.Getenv("JOIN_EUI"); c.joinEUI == "" {
109+
if c.joinEUI == "" {
107110
return errNoJoinEUI.New()
108111
}
109112
c.JoinEUI = &types.EUI64{}
110113
if err := c.JoinEUI.UnmarshalText([]byte(c.joinEUI)); err != nil {
111114
return errInvalidJoinEUI.WithAttributes("join_eui", c.joinEUI)
112115
}
113-
c.caCertPath = os.Getenv("CHIRPSTACK_CA_CERT_PATH")
114-
c.insecure = os.Getenv("CHIRPSTACK_INSECURE") == "true"
115-
c.ExportSession = os.Getenv("EXPORT_SESSION") == "true"
116-
c.ExportVars = os.Getenv("EXPORT_VARS") == "true"
117116

118117
err := c.dialGRPC(
119118
grpc.FailOnNonTempDialError(true),

pkg/source/firefly/config.go

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -53,36 +53,36 @@ func NewConfig() *Config {
5353

5454
config.flags.StringVar(&config.Host,
5555
"host",
56-
"",
56+
os.Getenv("FIREFLY_HOST"),
5757
"Host of the Firefly API. Don't use the scheme (http/https). Port is optional")
5858
config.flags.StringVar(&config.CACertPath,
5959
"ca-cert-path",
60-
"",
60+
os.Getenv("FIREFLY_CA_CERT_PATH"),
6161
"(optional) Path to the CA certificate for the Firefly API")
6262
config.flags.StringVar(&config.APIKey,
6363
"api-key",
6464
"",
6565
"Key to access the Firefly API")
6666
config.flags.StringVar(&config.joinEUI,
6767
"join-eui",
68-
"",
68+
os.Getenv("JOIN_EUI"),
6969
"JoinEUI for the exported devices")
7070
config.flags.StringVar(&config.frequencyPlanID,
7171
"frequency-plan-id",
72-
"",
72+
os.Getenv("FREQUENCY_PLAN_ID"),
7373
"Frequency Plan ID for the exported devices")
7474
config.flags.StringVar(&config.macVersion,
7575
"mac-version",
76-
"",
76+
os.Getenv("MAC_VERSION"),
7777
`LoRaWAN MAC version for the exported devices.
7878
Supported options are 1.0.0, 1.0.1, 1.0.2a, 1.0.2b, 1.0.3, 1.1.0a, 1.1.0b`)
7979
config.flags.StringVar(&config.appID,
8080
"app-id",
81-
"",
81+
os.Getenv("APP_ID"),
8282
"Application ID for the exported devices")
8383
config.flags.BoolVar(&config.invalidateKeys,
8484
"invalidate-keys",
85-
false,
85+
os.Getenv("INVALIDATE_KEYS") == "true",
8686
`Invalidate the root and/or session keys of the devices on the Firefly server.
8787
This is necessary to prevent both networks from communicating with the same device.
8888
The last byte of the keys will be incremented by 0x01. This enables an easy rollback if necessary.
@@ -91,11 +91,11 @@ where the devices are exported but they are still valid on the firefly server
9191
`)
9292
config.flags.BoolVar(&config.UseHTTP,
9393
"use-http",
94-
false,
94+
os.Getenv("FIREFLY_USE_HTTP") == "true",
9595
"(optional) Use HTTP instead of HTTPS for the Firefly API. Only for testing")
9696
config.flags.BoolVar(&config.all,
9797
"all",
98-
false,
98+
os.Getenv("EXPORT_ALL") == "true",
9999
"Export all devices that the API key has access to. This is only used by the application command")
100100
return config
101101
}
@@ -104,34 +104,25 @@ where the devices are exported but they are still valid on the firefly server
104104
func (c *Config) Initialize(src source.Config) error {
105105
c.src = src
106106

107-
if c.appID = os.Getenv("APP_ID"); c.appID == "" {
107+
if apiKey := os.Getenv("FIREFLY_API_KEY"); apiKey != "" && c.APIKey == "" {
108+
c.APIKey = apiKey
109+
}
110+
if c.appID == "" {
108111
return errNoAppID.New()
109112
}
110-
if c.frequencyPlanID = os.Getenv("FREQUENCY_PLAN_ID"); c.frequencyPlanID == "" {
113+
if c.frequencyPlanID == "" {
111114
return errNoFrequencyPlanID.New()
112115
}
113-
if c.joinEUI = os.Getenv("JOIN_EUI"); c.joinEUI == "" {
116+
if c.joinEUI == "" {
114117
return errNoJoinEUI.New()
115118
}
116-
if invalidateKeys := os.Getenv("JOIN_EUI"); invalidateKeys == "true" {
117-
c.invalidateKeys = true
118-
}
119-
if all := os.Getenv("ALL"); all == "true" {
120-
c.all = true
121-
}
122-
123-
if c.Host = os.Getenv("FIREFLY_HOST"); c.Host == "" {
119+
if c.Host == "" {
124120
return errNoHost.New()
125121
}
126-
if c.APIKey = os.Getenv("FIREFLY_API_KEY"); c.APIKey == "" {
122+
if c.APIKey == "" {
127123
return errNoAPIKey.New()
128124
}
129-
c.CACertPath = os.Getenv("FIREFLY_CA_CERT_PATH")
130-
if useHTTP := os.Getenv("FIREFLY_USE_HTTP"); useHTTP == "true" {
131-
c.UseHTTP = true
132-
}
133125

134-
c.macVersion = os.Getenv("MAC_VERSION")
135126
switch c.macVersion {
136127
case "1.0.0":
137128
c.derivedMacVersion = ttnpb.MACVersion_MAC_V1_0

pkg/source/ttnv2/config.go

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,62 +35,62 @@ const (
3535
clientName = "ttn-lw-migrate"
3636
)
3737

38-
func New() (*Config, *pflag.FlagSet) {
39-
var (
40-
config = &Config{sdkConfig: ttnsdk.NewCommunityConfig(clientName)}
41-
flags = &pflag.FlagSet{}
42-
)
38+
func NewConfig() *Config {
39+
config := &Config{
40+
sdkConfig: ttnsdk.NewCommunityConfig(clientName),
41+
flags: &pflag.FlagSet{},
42+
}
4343

44-
flags.StringVar(&config.frequencyPlanID,
44+
config.flags.StringVar(&config.frequencyPlanID,
4545
"frequency-plan-id",
4646
os.Getenv("FREQUENCY_PLAN_ID"),
4747
"Frequency Plan ID of exported devices")
48-
flags.StringVar(&config.appID,
48+
config.flags.StringVar(&config.appID,
4949
"app-id",
5050
os.Getenv("TTNV2_APP_ID"),
5151
"TTN Application ID")
52-
flags.StringVar(&config.appAccessKey,
52+
config.flags.StringVar(&config.appAccessKey,
5353
"app-access-key",
54-
os.Getenv("TTNV2_APP_ACCESS_KEY"),
54+
"",
5555
"TTN Application Access Key (with 'devices' permissions")
56-
flags.StringVar(&config.caCert,
56+
config.flags.StringVar(&config.caCert,
5757
"ca-cert",
5858
os.Getenv("TTNV2_CA_CERT"),
5959
"(only for private networks)")
60-
flags.StringVar(&config.sdkConfig.HandlerAddress,
60+
config.flags.StringVar(&config.sdkConfig.HandlerAddress,
6161
"handler-address",
6262
os.Getenv("TTNV2_HANDLER_ADDRESS"),
6363
"(only for private networks) Address for the Handler")
64-
flags.StringVar(&config.sdkConfig.AccountServerAddress,
64+
config.flags.StringVar(&config.sdkConfig.AccountServerAddress,
6565
"account-server-address",
6666
os.Getenv("TTNV2_ACCOUNT_SERVER_ADDRESS"),
6767
"(only for private networks) Address for the Account Server")
68-
flags.StringVar(&config.sdkConfig.AccountServerClientID,
68+
config.flags.StringVar(&config.sdkConfig.AccountServerClientID,
6969
"account-server-client-id",
7070
os.Getenv("TTNV2_ACCOUNT_SERVER_CLIENT_ID"),
7171
"(only for private networks) Client ID for the Account Server")
72-
flags.StringVar(&config.sdkConfig.AccountServerClientSecret,
72+
config.flags.StringVar(&config.sdkConfig.AccountServerClientSecret,
7373
"account-server-client-secret",
74-
os.Getenv("TTNV2_ACCOUNT_SERVER_CLIENT_SECRET"),
74+
"",
7575
"(only for private networks) Client secret for the Account Server")
76-
flags.StringVar(&config.sdkConfig.DiscoveryServerAddress,
76+
config.flags.StringVar(&config.sdkConfig.DiscoveryServerAddress,
7777
"discovery-server-address",
7878
os.Getenv("TTNV2_DISCOVERY_SERVER_ADDRESS"),
7979
"(only for private networks) Address for the Discovery Server")
80-
flags.BoolVar(&config.sdkConfig.DiscoveryServerInsecure,
80+
config.flags.BoolVar(&config.sdkConfig.DiscoveryServerInsecure,
8181
"discovery-server-insecure",
82-
false,
82+
os.Getenv("TTNV2_DISCOVERY_SERVER_INSECURE") == "true",
8383
"(only for private networks) Not recommended")
84-
flags.BoolVar(&config.withSession,
84+
config.flags.BoolVar(&config.withSession,
8585
"with-session",
86-
true,
86+
os.Getenv("TTNV2_WITH_SESSION") == "true",
8787
"Export device session keys and frame counters")
88-
flags.BoolVar(&config.resetsToFrequencyPlan,
88+
config.flags.BoolVar(&config.resetsToFrequencyPlan,
8989
"resets-to-frequency-plan",
90-
false,
90+
os.Getenv("TTNV2_RESETS_TO_FREQUENCY_PLAN") == "true",
9191
"Configure preset frequencies for ABP devices so that they match the used Frequency Plan")
9292

93-
return config, flags
93+
return config
9494
}
9595

9696
type Config struct {
@@ -106,10 +106,18 @@ type Config struct {
106106
dryRun bool
107107
resetsToFrequencyPlan bool
108108

109+
flags *pflag.FlagSet
109110
fpStore *frequencyplans.Store
110111
}
111112

112113
func (c *Config) Initialize(rootConfig source.Config) error {
114+
if appAccessKey := os.Getenv("TTNV2_APP_ACCESS_KEY"); appAccessKey != "" && c.appAccessKey == "" {
115+
c.appAccessKey = appAccessKey
116+
}
117+
if accountServerClientSecret := os.Getenv("TTNV2_ACCOUNT_SERVER_CLIENT_SECRET"); accountServerClientSecret != "" && c.sdkConfig.AccountServerClientSecret == "" {
118+
c.sdkConfig.AccountServerClientSecret = accountServerClientSecret
119+
}
120+
113121
if c.caCert != "" {
114122
if c.sdkConfig.TLSConfig == nil {
115123
c.sdkConfig.TLSConfig = new(tls.Config)
@@ -128,6 +136,9 @@ func (c *Config) Initialize(rootConfig source.Config) error {
128136
rootCAs.AppendCertsFromPEM(pemBytes)
129137
}
130138

139+
if c.appID == "" {
140+
return errNoAppID.New()
141+
}
131142
if c.appAccessKey == "" {
132143
return errNoAppAccessKey.New()
133144
}
@@ -155,3 +166,8 @@ func (c *Config) Initialize(rootConfig source.Config) error {
155166

156167
return nil
157168
}
169+
170+
// Flags returns the flags for the configuration.
171+
func (c *Config) Flags() *pflag.FlagSet {
172+
return c.flags
173+
}

pkg/source/ttnv2/source.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ func createNewSource(cfg *Config) source.CreateSource {
5050

5151
// NewSource creates a new TTNv2 Source.
5252
func NewSource(ctx context.Context, cfg *Config, rootCfg source.Config) (source.Source, error) {
53+
if err := cfg.Initialize(rootCfg); err != nil {
54+
return nil, err
55+
}
5356
s := &Source{
5457
ctx: ctx,
5558
config: cfg,
@@ -60,7 +63,7 @@ func NewSource(ctx context.Context, cfg *Config, rootCfg source.Config) (source.
6063
return nil, err
6164
}
6265
s.mgr = newDeviceManager(ctx, mgr)
63-
return s, cfg.Initialize(rootCfg)
66+
return s, nil
6467
}
6568

6669
// ExportDevice implements the source.Source interface.

pkg/source/ttnv2/ttnv2.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ package ttnv2
1717
import "go.thethings.network/lorawan-stack-migrate/pkg/source"
1818

1919
func init() {
20-
cfg, flags := New()
20+
cfg := NewConfig()
2121

2222
source.RegisterSource(source.Registration{
2323
Name: "ttnv2",
2424
Description: "Migrate from The Things Network Stack V2",
25-
FlagSet: flags,
25+
FlagSet: cfg.Flags(),
2626
Create: createNewSource(cfg),
2727
})
2828
}

0 commit comments

Comments
 (0)