Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/chirpstack/chirpstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const sourceName = "chirpstack"

// ChirpStackCmd represents the chirpstack source.
var ChirpStackCmd = commands.Source(sourceName,
"Export devices from ChirpStack V3",
"Export devices from ChirpStack v4",
commands.WithDevicesOptions(
commands.WithShort("Export devices by DevEUI"),
),
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/TheThingsNetwork/ttn/core/types v0.0.0-20190516112328-fcd38e2b9dc6
github.com/apex/log v1.9.0
github.com/brocaar/chirpstack-api/go/v3 v3.12.5
github.com/chirpstack/chirpstack/api/go/v4 v4.6.0
github.com/mdempsky/unconvert v0.0.0-20230125054757-2661c2c99a9b
github.com/mgechev/revive v1.3.6
github.com/smarty/assertions v1.15.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chavacava/garif v0.1.0 h1:2JHa3hbYf5D9dsgseMKAmc/MZ109otzgNFk5s87H9Pc=
github.com/chavacava/garif v0.1.0/go.mod h1:XMyYCkEL58DF0oyW4qDjjnPWONs2HBqYKI+UIPD+Gww=
github.com/chirpstack/chirpstack/api/go/v4 v4.6.0 h1:l+nr/QhFab1y9E8LVOJq/lDG+o0+mShcZOCNBvFYXUA=
github.com/chirpstack/chirpstack/api/go/v4 v4.6.0/go.mod h1:6+68s1PGHq2QWZ216RTwXhp7h1vCiMc6kX3f4s74ZzQ=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
Expand Down
6 changes: 3 additions & 3 deletions pkg/source/chirpstack/chirpstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ import (
)

func init() {
cfg, flags := config.New()
cfg := config.New()

source.RegisterSource(source.Registration{
Name: "chirpstack",
Description: "Migrate from ChirpStack LoRaWAN Network Server",
FlagSet: flags,
Description: "Migrate from ChirpStack LoRaWAN Network Server v4",
FlagSet: cfg.Flags(),
Create: createNewSource(cfg),
})
}
110 changes: 62 additions & 48 deletions pkg/source/chirpstack/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,87 +22,96 @@ import (

"github.com/spf13/pflag"
"go.thethings.network/lorawan-stack-migrate/pkg/source"
"go.thethings.network/lorawan-stack/v3/pkg/frequencyplans"
"go.thethings.network/lorawan-stack/v3/pkg/types"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
)

func New() (*Config, *pflag.FlagSet) {
var (
config = &Config{}
flags = &pflag.FlagSet{}
)
type Config struct {
src source.Config

token, caCertPath, url, joinEUI string
flags *pflag.FlagSet
fpStore *frequencyplans.Store
insecure bool

ClientConn *grpc.ClientConn

ExportVars,
ExportSession bool
FrequencyPlanID string
JoinEUI *types.EUI64
}

flags.StringVar(&config.url,
func New() *Config {
config := &Config{
flags: &pflag.FlagSet{},
}

config.flags.StringVar(&config.url,
"api-url",
os.Getenv("CHIRPSTACK_API_URL"),
"",
"ChirpStack API URL")
flags.StringVar(&config.token,
config.flags.StringVar(&config.token,
"api-token",
os.Getenv("CHIRPSTACK_API_TOKEN"),
"",
"ChirpStack API Token")
flags.StringVar(&config.caPath,
"api-ca",
os.Getenv("CHIRPSTACK_API_CA"),
"(optional) CA for TLS")
flags.BoolVar(&config.insecure,
"api-insecure",
os.Getenv("CHIRPSTACK_API_INSECURE") == "1",
config.flags.StringVar(&config.caCertPath,
"ca-cert-path",
"",
"(optional) Path to the CA certificate file for ChirpStack API TLS connections")
config.flags.BoolVar(&config.insecure,
"insecure",
false,
"Do not connect to ChirpStack over TLS")
flags.BoolVar(&config.ExportVars,
config.flags.BoolVar(&config.ExportVars,
"export-vars",
false,
"Export device variables from ChirpStack")
flags.BoolVar(&config.ExportSession,
config.flags.BoolVar(&config.ExportSession,
"export-session",
true,
false,
"Export device session keys from ChirpStack")
flags.StringVar(&config.joinEUI,
config.flags.StringVar(&config.joinEUI,
"join-eui",
os.Getenv("JOIN_EUI"),
"",
"JoinEUI of exported devices")
flags.StringVar(&config.FrequencyPlanID,
config.flags.StringVar(&config.FrequencyPlanID,
"frequency-plan-id",
os.Getenv("FREQUENCY_PLAN_ID"),
"",
"Frequency Plan ID of exported devices")

return config, flags
return config
}

type Config struct {
source.Config

ClientConn *grpc.ClientConn

token, caPath, url,
FrequencyPlanID string

joinEUI string
JoinEUI *types.EUI64

insecure,
ExportVars,
ExportSession bool
}
func (c *Config) Initialize(src source.Config) error {
c.src = src

func (c *Config) Initialize() error {
if c.token == "" {
if c.token = os.Getenv("CHIRPSTACK_API_TOKEN"); c.token == "" {
return errNoAPIToken.New()
}
if c.url == "" {
if c.url = os.Getenv("CHIRPSTACK_API_URL"); c.url == "" {
return errNoAPIURL.New()
}
if c.FrequencyPlanID == "" {
if c.FrequencyPlanID = os.Getenv("FREQUENCY_PLAN_ID"); c.FrequencyPlanID == "" {
return errNoFrequencyPlan.New()
}

if c.joinEUI = os.Getenv("JOIN_EUI"); c.joinEUI == "" {
return errNoJoinEUI.New()
}
c.JoinEUI = &types.EUI64{}
if err := c.JoinEUI.UnmarshalText([]byte(c.joinEUI)); err != nil {
return errInvalidJoinEUI.WithAttributes("join_eui", c.joinEUI)
}
c.insecure = os.Getenv("CHIRPSTACK_INSECURE") == "true"
c.caCertPath = os.Getenv("CHIRPSTACK_CA_CERT_PATH")
c.ExportVars = os.Getenv("CHIRPSTACK_EXPORT_VARS") == "true"
c.ExportSession = os.Getenv("CHIRPSTACK_EXPORT_SESSION") == "true"

if !c.insecure || c.caPath != "" {
if err := setCustomCA(c.caPath); err != nil {
if !c.insecure && c.caCertPath != "" {
if err := setCustomCA(c.caCertPath); err != nil {
return err
}
}
Expand All @@ -119,9 +128,14 @@ func (c *Config) Initialize() error {
return nil
}

// Flags returns the flags for the configuration.
func (c *Config) Flags() *pflag.FlagSet {
return c.flags
}

func (c *Config) dialGRPC(opts ...grpc.DialOption) error {
if c.insecure && c.caPath == "" {
opts = append(opts, grpc.WithInsecure())
if c.insecure || c.caCertPath == "" {
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
}
if tls := http.DefaultTransport.(*http.Transport).TLSClientConfig; tls != nil {
opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(tls)))
Expand Down
1 change: 1 addition & 0 deletions pkg/source/chirpstack/config/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var (
errNoAPIToken = errors.DefineInvalidArgument("no_api_token", "no API token")
errNoAPIURL = errors.DefineInvalidArgument("no_api_url", "no API URL")
errNoFrequencyPlan = errors.DefineInvalidArgument("no_frequency_plan", "no Frequency Plan")
errNoJoinEUI = errors.DefineInvalidArgument("no_join_eui", "no join eui")

errInvalidJoinEUI = errors.DefineInvalidArgument("invalid_join_eui", "invalid JoinEUI `{join_eui}`")
)
Loading