Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLI improvements proposal: subcommands #71

Merged
merged 17 commits into from
May 1, 2023
Merged
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 .hooks/install-hooks.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion .hooks/run-hooks.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

### Added

- Each source has it's own dedicated command.

### Changed

- `ttnv3` source is named `tts` now.

### Deprecated

- `--source` flag is now depreciated.

### Removed

### Fixed
Expand Down
62 changes: 35 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ Binaries are available on [GitHub](https://github.com/TheThingsNetwork/lorawan-s

## Support

- [X] The Things Network Stack V2
- [X] [ChirpStack Network Server](https://www.chirpstack.io/)
- [X] [The Things Stack](https://www.github.com/TheThingsNetwork/lorawan-stack/)
- [x] The Things Network Stack V2
- [x] [ChirpStack Network Server](https://www.chirpstack.io/)
- [x] [The Things Stack](https://www.github.com/TheThingsNetwork/lorawan-stack/)
- [ ] [Firefly](https://fireflyiot.com/)
- [ ] [LORIOT Network Server](https://www.loriot.io/)

Expand Down Expand Up @@ -71,9 +71,9 @@ To export a single device using its Device ID (e.g. `mydevice`):

```bash
# dry run first, verify that no errors occur
$ ttn-lw-migrate device --source ttnv2 "mydevice" --dry-run --verbose > devices.json
$ ttn-lw-migrate ttnv2 device 'mydevice' --dry-run --verbose > devices.json
# export device
$ ttn-lw-migrate device --source ttnv2 "mydevice" > devices.json
$ ttn-lw-migrate ttnv2 device 'mydevice' > devices.json
```

In order to export a large number of devices, create a file named `device_ids.txt` with one device ID per line:
Expand All @@ -90,9 +90,9 @@ And then export with:

```bash
# dry run first, verify that no errors occur
$ ttn-lw-migrate devices --source ttnv2 "mydevice" --dry-run --verbose < device_ids.txt > devices.json
$ ttn-lw-migrate ttnv2 devices 'mydevice' --dry-run --verbose < device_ids.txt > devices.json
# export devices
$ ttn-lw-migrate devices --source ttnv2 < device_ids.txt > devices.json
$ ttn-lw-migrate ttnv2 devices < device_ids.txt > devices.json
```

### Export Applications
Expand All @@ -101,9 +101,9 @@ Similarly, to export all devices of application `my-app-id`:

```bash
# dry run first, verify that no errors occur
$ ttn-lw-migrate application --source ttnv2 "my-app-id" --dry-run --verbose > devices.json
$ ttn-lw-migrate ttnv2 application 'my-app-id' --dry-run --verbose > devices.json
# export devices
$ ttn-lw-migrate application --source ttnv2 "my-app-id" > devices.json
$ ttn-lw-migrate ttnv2 application 'my-app-id' > devices.json
```

## ChirpStack
Expand All @@ -121,7 +121,7 @@ $ export FREQUENCY_PLAN_ID="EU_863_870" # Frequency Plan for exported de

See [Frequency Plans](https://thethingsstack.io/reference/frequency-plans/) for the list of frequency plans available on The Things Stack. For example, to use `United States 902-928 MHz, FSB 1`, you need to specify the `US_902_928_FSB_1` frequency plan ID.

> *NOTE*: `JoinEUI` and `FrequencyPlanID` are required because ChirpStack does not store these fields.
> _NOTE_: `JoinEUI` and `FrequencyPlanID` are required because ChirpStack does not store these fields.

### Notes

Expand All @@ -134,7 +134,7 @@ See [Frequency Plans](https://thethingsstack.io/reference/frequency-plans/) for
To export a single device using its DevEUI (e.g. `0102030405060708`):

```
$ ttn-lw-migrate device --source chirpstack "0102030405060708" > devices.json
$ ttn-lw-migrate chirpstack device '0102030405060708' > devices.json
```

In order to export a large number of devices, create a file named `device_euis.txt` with one DevEUI per line:
Expand All @@ -151,15 +151,15 @@ In order to export a large number of devices, create a file named `device_euis.t
And then export with:

```bash
$ ttn-lw-migrate device --source chirpstack < device_euis.txt > devices.json
$ ttn-lw-migrate chirpstack device < device_euis.txt > devices.json
```

### Export Applications

Similarly, to export all devices of application `chirpstack-app-1`:

```bash
$ ttn-lw-migrate application --source chirpstack "chirpstack-app-1" > devices.json
$ ttn-lw-migrate chirpstack application 'chirpstack-app-1' > devices.json
```

In order to export multiple applications, create a file named `application_names.txt` with one Application name per line:
Expand All @@ -173,7 +173,7 @@ chirpstack-app-3
And export with:

```bash
$ ttn-lw-migrate application --source chirpstack < application_names.txt > devices.json
$ ttn-lw-migrate chirpstack application < application_names.txt > devices.json
```

## The Things Stack
Expand All @@ -183,13 +183,13 @@ $ ttn-lw-migrate application --source chirpstack < application_names.txt > devic
Configure with environment variables, or command-line arguments. See `--help` for more details:

```bash
$ export TTNV3_APP_ID="my-tts-app" # TTS App ID
$ export TTNV3_APP_API_KEY="NNSXS.U..." # TTS App API Key (needs `device` permissions)
$ export TTNV3_APPLICATION_SERVER_GRPC_ADDRESS="eu1.cloud.thethings.network:8884" # TTS Application Server URL Address
$ export TTNV3_IDENTITY_SERVER_GRPC_ADDRESS="eu1.cloud.thethings.network:8884" # TTS Identity Server URL Address
$ export TTNV3_JOIN_SERVER_GRPC_ADDRESS="eu1.cloud.thethings.network:8884" # TTS Join Server URL Address
$ export TTNV3_NETWORK_SERVER_GRPC_ADDRESS="eu1.cloud.thethings.network:8884" # TTS Network Server URL Address
$ export TTNV3_CA_FILE="/path/to/ca.file" # Path to a CA file (optional)
$ export TTS_APP_ID="my-tts-app" # TTS App ID
$ export TTS_APP_API_KEY="NNSXS.U..." # TTS App API Key (needs `device` permissions)
$ export TTS_APPLICATION_SERVER_GRPC_ADDRESS="eu1.cloud.thethings.network:8884" # TTS Application Server URL Address
$ export TTS_IDENTITY_SERVER_GRPC_ADDRESS="eu1.cloud.thethings.network:8884" # TTS Identity Server URL Address
$ export TTS_JOIN_SERVER_GRPC_ADDRESS="eu1.cloud.thethings.network:8884" # TTS Join Server URL Address
$ export TTS_NETWORK_SERVER_GRPC_ADDRESS="eu1.cloud.thethings.network:8884" # TTS Network Server URL Address
$ export TTS_CA_FILE="/path/to/ca.file" # Path to a CA file (optional)
```

### Notes
Expand All @@ -203,9 +203,9 @@ To export a single device using its Device ID (e.g. `mydevice`):

```bash
# dry run first, verify that no errors occur
$ ttn-lw-migrate device --source ttnv3 "mydevice" --dry-run --verbose > devices.json
$ ttn-lw-migrate tts device 'mydevice' --dry-run --verbose > devices.json
# export device
$ ttn-lw-migrate device --source ttnv3 "mydevice" > devices.json
$ ttn-lw-migrate tts device 'mydevice' > devices.json
```

In order to export a large number of devices, create a file named `device_ids.txt` with one device ID per line:
Expand All @@ -222,9 +222,9 @@ And then export with:

```bash
# dry run first, verify that no errors occur
$ ttn-lw-migrate devices --source ttnv3 "mydevice" --dry-run --verbose < device_ids.txt > devices.json
$ ttn-lw-migrate tts devices 'mydevice' --dry-run --verbose < device_ids.txt > devices.json
# export devices
$ ttn-lw-migrate devices --source ttnv3 < device_ids.txt > devices.json
$ ttn-lw-migrate tts devices < device_ids.txt > devices.json
```

### Export Applications
Expand All @@ -233,9 +233,9 @@ Similarly, to export all devices of application `my-app-id`:

```bash
# dry run first, verify that no errors occur
$ ttn-lw-migrate application --source ttnv3 "my-app-id" --dry-run --verbose > devices.json
$ ttn-lw-migrate tts application 'my-app-id' --dry-run --verbose > devices.json
# export devices
$ ttn-lw-migrate application --source ttnv3 "my-app-id" > devices.json
$ ttn-lw-migrate tts application 'my-app-id' > devices.json
```

## Development Environment
Expand Down Expand Up @@ -293,16 +293,21 @@ This will compile binaries for all supported platforms, `deb`, `rpm`, Snapcraft
### Release from master

1. Create a `release/${version}` branch off the `master` branch.

```bash
$ git checkout master
$ git checkout -b release/${version}
```

2. Update the `CHANGELOG.md` file as explained below:

- Change the **Unreleased** section to the new version and add date obtained via `date +%Y-%m-%d` (e.g. `## [1.0.0] - 2020-10-18`)

- Check if we didn't forget anything important
- Remove empty subsections
- Update the list of links in the bottom of the file
- Add new **Unreleased** section:

```md
## [Unreleased]

Expand All @@ -318,12 +323,15 @@ $ git checkout -b release/${version}

### Security
```

4. Create a pull request targeting `master`.
5. Once this PR is approved and merged, checkout the latest `master` branch locally.
6. Create a version tag, and push to GitHub:

```bash
$ git tag -s -a "v${version}" -m "ttn-lw-migrate v${version}"
$ git push origin "v${version}"
```

7. CI will automatically start building and pushing to package managers. When this is done, you'll find a new release on the [releases page](https://github.com/TheThingsNetwork/lorawan-stack-migrate/releases).
8. Edit the release notes on the GitHub releases page, typically copied from `CHANGELOG.md`.
17 changes: 11 additions & 6 deletions cmd/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,27 @@
package cmd

import (
"fmt"
"strings"

"github.com/spf13/cobra"
"go.thethings.network/lorawan-stack-migrate/pkg/commands"
"go.thethings.network/lorawan-stack-migrate/pkg/source"
)

var applicationsCmd = &cobra.Command{
Use: "application [app-id] ...",
Aliases: []string{"applications", "app"},
Short: "Export all devices of an application",
Use: "application [app-id] ...",
Short: "Export all devices of an application",
Aliases: []string{"applications", "app"},
Deprecated: fmt.Sprintf("use [%s] commands instead", strings.Join(source.Names(), "|")),
RunE: func(cmd *cobra.Command, args []string) error {
return exportCommand(cmd, args, func(s source.Source, item string) error {
return s.RangeDevices(item, exportCfg.exportDev)
return commands.Export(cmd, args, func(s source.Source, item string) error {
return s.RangeDevices(item, exportCfg.ExportDev)
})
},
}

func init() {
applicationsCmd.Flags().AddFlagSet(source.FlagSet())
applicationsCmd.Flags().AddFlagSet(source.AllFlagSets())
rootCmd.AddCommand(applicationsCmd)
}
22 changes: 22 additions & 0 deletions cmd/chirpstack/chirpstack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package chirpstack

import "go.thethings.network/lorawan-stack-migrate/pkg/commands"

const sourceName = "chirpstack"

// ChirpStackCmd represents the chirpstack source.
var ChirpStackCmd = commands.Source(sourceName, "Export devices from ChirpStack V3")
15 changes: 10 additions & 5 deletions cmd/devices.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,25 @@
package cmd

import (
"fmt"
"strings"

"github.com/spf13/cobra"
"go.thethings.network/lorawan-stack-migrate/pkg/commands"
"go.thethings.network/lorawan-stack-migrate/pkg/source"
)

var devicesCmd = &cobra.Command{
Use: "device [dev-id] ...",
Short: "Export devices by DevEUI",
Aliases: []string{"end-devices", "end-device", "devices", "dev"},
Use: "device [dev-id] ...",
Short: "Export devices by DevEUI",
Aliases: []string{"end-devices", "end-device", "devices", "dev"},
Deprecated: fmt.Sprintf("use [%s] commands instead", strings.Join(source.Names(), "|")),
RunE: func(cmd *cobra.Command, args []string) error {
return exportCommand(cmd, args, exportCfg.exportDev)
return commands.Export(cmd, args, exportCfg.ExportDev)
},
}

func init() {
devicesCmd.Flags().AddFlagSet(source.FlagSet())
devicesCmd.Flags().AddFlagSet(source.AllFlagSets())
rootCmd.AddCommand(devicesCmd)
}
25 changes: 19 additions & 6 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,20 @@ import (
"os"

"github.com/spf13/cobra"
"go.thethings.network/lorawan-stack-migrate/cmd/chirpstack"
"go.thethings.network/lorawan-stack-migrate/cmd/ttnv2"
"go.thethings.network/lorawan-stack-migrate/cmd/tts"
"go.thethings.network/lorawan-stack-migrate/pkg/export"
"go.thethings.network/lorawan-stack-migrate/pkg/source"
"go.thethings.network/lorawan-stack/v3/pkg/log"
"go.thethings.network/lorawan-stack/v3/pkg/rpcmiddleware/rpclog"
)

var (
logger *log.Logger
ctx context.Context
ctx = context.Background()
exportCfg = export.Config{}
rootCfg = &source.RootConfig
exportCfg = exportConfig{}
rootCmd = &cobra.Command{
Use: "ttn-lw-migrate",
Short: "Migrate from other LoRaWAN network servers to The Things Stack",
Expand All @@ -47,12 +51,14 @@ var (
logHandler,
log.WithLevel(logLevel),
)
ctx = log.NewContext(context.Background(), logger)
rpclog.ReplaceGrpcLogger(logger)
ctx = log.NewContext(ctx, logger)

exportCfg.devIDPrefix, _ = cmd.Flags().GetString("dev-id-prefix")
exportCfg.euiForID, _ = cmd.Flags().GetBool("set-eui-as-id")
exportCfg.DevIDPrefix, _ = cmd.Flags().GetString("dev-id-prefix")
exportCfg.EUIForID, _ = cmd.Flags().GetBool("set-eui-as-id")
ctx = export.NewContext(ctx, exportCfg)

rpclog.ReplaceGrpcLogger(logger)
cmd.SetContext(ctx)
return nil
},
}
Expand Down Expand Up @@ -80,4 +86,11 @@ func init() {
"frequency-plans-url",
"https://raw.githubusercontent.com/TheThingsNetwork/lorawan-frequency-plans/master",
"URL for fetching frequency plans")

// TODO: After dependency update (https://github.com/TheThingsNetwork/lorawan-stack-migrate/issues/72)
// Create "sources" group in `rootCmd`

rootCmd.AddCommand(ttnv2.TTNv2Cmd)
rootCmd.AddCommand(tts.TTSCmd)
rootCmd.AddCommand(chirpstack.ChirpStackCmd)
}
2 changes: 1 addition & 1 deletion cmd/sources.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down
4 changes: 2 additions & 2 deletions cmd/ttn-lw-migrate/main.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -19,7 +19,7 @@ import (

_ "go.thethings.network/lorawan-stack-migrate/pkg/source/chirpstack" // ChirpStack source
_ "go.thethings.network/lorawan-stack-migrate/pkg/source/ttnv2" // TTNv2 source
_ "go.thethings.network/lorawan-stack-migrate/pkg/source/ttnv3" // TTS source
_ "go.thethings.network/lorawan-stack-migrate/pkg/source/tts" // TTS source

"go.thethings.network/lorawan-stack-migrate/cmd"
)
Expand Down
Loading