From 8689e08d02e76b7aa77bb004e3807f882b17db42 Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Fri, 5 Nov 2021 10:13:38 +0100 Subject: [PATCH 1/4] Delete devices by tags or id --- cli/device/delete.go | 17 ++++++++++++++--- command/device/delete.go | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/cli/device/delete.go b/cli/device/delete.go index 6d0c3154..4bacc544 100644 --- a/cli/device/delete.go +++ b/cli/device/delete.go @@ -28,7 +28,8 @@ import ( ) var deleteFlags struct { - id string + id string + tags map[string]string } func initDeleteCommand() *cobra.Command { @@ -39,14 +40,24 @@ func initDeleteCommand() *cobra.Command { Run: runDeleteCommand, } deleteCommand.Flags().StringVarP(&deleteFlags.id, "id", "i", "", "Device ID") - deleteCommand.MarkFlagRequired("id") + // delete only the devices that have all the passed tags + deleteCommand.Flags().StringToStringVar( + &deleteFlags.tags, + "tags", + nil, + "List of comma-separated tags. A tag has this format: =", + ) return deleteCommand } func runDeleteCommand(cmd *cobra.Command, args []string) { logrus.Infof("Deleting device %s\n", deleteFlags.id) - params := &device.DeleteParams{ID: deleteFlags.id} + params := &device.DeleteParams{Tags: deleteFlags.tags} + if deleteFlags.id != "" { + params.ID = &deleteFlags.id + } + err := device.Delete(params) if err != nil { feedback.Errorf("Error during device delete: %v", err) diff --git a/command/device/delete.go b/command/device/delete.go index 26a1a856..b9b75cfe 100644 --- a/command/device/delete.go +++ b/command/device/delete.go @@ -18,19 +18,31 @@ package device import ( + "errors" + "github.com/arduino/arduino-cloud-cli/internal/config" "github.com/arduino/arduino-cloud-cli/internal/iot" ) // DeleteParams contains the parameters needed to // delete a device from Arduino IoT Cloud. +// ID and Tags parameters are mutually exclusive +// and one among them is required: An error is returned +// if they are both nil or if they are both not nil. type DeleteParams struct { - ID string + ID *string // Should be nil if Tags is not nil + Tags map[string]string // Should be nil if ID is not nil } // Delete command is used to delete a device // from Arduino IoT Cloud. func Delete(params *DeleteParams) error { + if params.ID == nil && params.Tags == nil { + return errors.New("provide either ID or Tags") + } else if params.ID != nil && params.Tags != nil { + return errors.New("cannot use both ID and Tags. only one of them should be not nil") + } + conf, err := config.Retrieve() if err != nil { return err @@ -40,5 +52,27 @@ func Delete(params *DeleteParams) error { return err } - return iotClient.DeviceDelete(params.ID) + if params.ID != nil { + // Delete by id + return iotClient.DeviceDelete(*params.ID) + + } else if params.Tags != nil { + // Delete by tags + dev, err := iotClient.DeviceList(params.Tags) + if err != nil { + return err + } + for _, d := range dev { + err = iotClient.DeviceDelete(d.Id) + if err != nil { + return err + } + } + + } else { + // should not be reachable + return errors.New("provide either '--id' or '--tags' flag") + } + + return nil } From 31d1c3597908195eb15bc519fba9f2f7d0fc8f0c Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Fri, 5 Nov 2021 11:12:58 +0100 Subject: [PATCH 2/4] Delete things by tags or id --- cli/thing/delete.go | 17 ++++++++++++++--- command/thing/delete.go | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/cli/thing/delete.go b/cli/thing/delete.go index 6ab5f737..fc597745 100644 --- a/cli/thing/delete.go +++ b/cli/thing/delete.go @@ -28,7 +28,8 @@ import ( ) var deleteFlags struct { - id string + id string + tags map[string]string } func initDeleteCommand() *cobra.Command { @@ -39,14 +40,24 @@ func initDeleteCommand() *cobra.Command { Run: runDeleteCommand, } deleteCommand.Flags().StringVarP(&deleteFlags.id, "id", "i", "", "Thing ID") - deleteCommand.MarkFlagRequired("id") + // delete only the things that have all the passed tags + deleteCommand.Flags().StringToStringVar( + &deleteFlags.tags, + "tags", + nil, + "List of comma-separated tags. A tag has this format: =", + ) return deleteCommand } func runDeleteCommand(cmd *cobra.Command, args []string) { logrus.Infof("Deleting thing %s\n", deleteFlags.id) - params := &thing.DeleteParams{ID: deleteFlags.id} + params := &thing.DeleteParams{Tags: deleteFlags.tags} + if deleteFlags.id != "" { + params.ID = &deleteFlags.id + } + err := thing.Delete(params) if err != nil { feedback.Errorf("Error during thing delete: %v", err) diff --git a/command/thing/delete.go b/command/thing/delete.go index 2a7b1f33..b019d3cc 100644 --- a/command/thing/delete.go +++ b/command/thing/delete.go @@ -18,19 +18,31 @@ package thing import ( + "errors" + "github.com/arduino/arduino-cloud-cli/internal/config" "github.com/arduino/arduino-cloud-cli/internal/iot" ) // DeleteParams contains the parameters needed to // delete a thing from Arduino IoT Cloud. +// ID and Tags parameters are mutually exclusive +// and one among them is required: An error is returned +// if they are both nil or if they are both not nil. type DeleteParams struct { - ID string + ID *string // Should be nil if Tags is not nil + Tags map[string]string // Should be nil if ID is not nil } // Delete command is used to delete a thing // from Arduino IoT Cloud. func Delete(params *DeleteParams) error { + if params.ID == nil && params.Tags == nil { + return errors.New("provide either ID or Tags") + } else if params.ID != nil && params.Tags != nil { + return errors.New("cannot use both ID and Tags. only one of them should be not nil") + } + conf, err := config.Retrieve() if err != nil { return err @@ -40,5 +52,26 @@ func Delete(params *DeleteParams) error { return err } - return iotClient.ThingDelete(params.ID) + if params.ID != nil { + // Delete by ID + return iotClient.ThingDelete(*params.ID) + + } else if params.Tags != nil { + things, err := iotClient.ThingList(nil, nil, false, params.Tags) + if err != nil { + return err + } + for _, t := range things { + err = iotClient.ThingDelete(t.Id) + if err != nil { + return err + } + } + + } else { + // should not be reachable + return errors.New("provide either '--id' or '--tags' flag") + } + + return nil } From 70e4e8a77eba4e0e3cfa37ad23e70c44bc9d7505 Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Mon, 8 Nov 2021 16:54:56 +0100 Subject: [PATCH 3/4] Update delete command --- cli/device/delete.go | 5 +++-- cli/thing/delete.go | 5 +++-- command/device/delete.go | 4 ++-- command/thing/delete.go | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/cli/device/delete.go b/cli/device/delete.go index 4bacc544..b5fd74ee 100644 --- a/cli/device/delete.go +++ b/cli/device/delete.go @@ -40,12 +40,13 @@ func initDeleteCommand() *cobra.Command { Run: runDeleteCommand, } deleteCommand.Flags().StringVarP(&deleteFlags.id, "id", "i", "", "Device ID") - // delete only the devices that have all the passed tags deleteCommand.Flags().StringToStringVar( &deleteFlags.tags, "tags", nil, - "List of comma-separated tags. A tag has this format: =", + "Comma-separated list of tags with format =.\n"+ + "Delete all devices that match the provided tags.\n"+ + "Mutually exclusive with `--id`.", ) return deleteCommand } diff --git a/cli/thing/delete.go b/cli/thing/delete.go index fc597745..8d9ab7ca 100644 --- a/cli/thing/delete.go +++ b/cli/thing/delete.go @@ -40,12 +40,13 @@ func initDeleteCommand() *cobra.Command { Run: runDeleteCommand, } deleteCommand.Flags().StringVarP(&deleteFlags.id, "id", "i", "", "Thing ID") - // delete only the things that have all the passed tags deleteCommand.Flags().StringToStringVar( &deleteFlags.tags, "tags", nil, - "List of comma-separated tags. A tag has this format: =", + "Comma-separated list of tags with format =.\n"+ + "Delete all things that match the provided tags.\n"+ + "Mutually exclusive with `--id`.", ) return deleteCommand } diff --git a/command/device/delete.go b/command/device/delete.go index b9b75cfe..0abae209 100644 --- a/command/device/delete.go +++ b/command/device/delete.go @@ -30,8 +30,8 @@ import ( // and one among them is required: An error is returned // if they are both nil or if they are both not nil. type DeleteParams struct { - ID *string // Should be nil if Tags is not nil - Tags map[string]string // Should be nil if ID is not nil + ID *string + Tags map[string]string } // Delete command is used to delete a device diff --git a/command/thing/delete.go b/command/thing/delete.go index b019d3cc..83ec4495 100644 --- a/command/thing/delete.go +++ b/command/thing/delete.go @@ -30,8 +30,8 @@ import ( // and one among them is required: An error is returned // if they are both nil or if they are both not nil. type DeleteParams struct { - ID *string // Should be nil if Tags is not nil - Tags map[string]string // Should be nil if ID is not nil + ID *string + Tags map[string]string } // Delete command is used to delete a thing From aad6762da69239f7e321056ac6a36316beeafff3 Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Mon, 8 Nov 2021 17:32:46 +0100 Subject: [PATCH 4/4] Update readme delete --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 27f6d4ed..c2422bb6 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,14 @@ Use this command to provision a device: ## Device commands +Devices can be deleted using the device delete command. This command accepts two mutually exclusive flags: `--id` and `--tags`. Only one of them must be passed. When the `--id` is passed, the device having such ID gets deleted: + +`$ arduino-cloud-cli device delete --id ` + +When `--tags` is passed, the devices having all the specified tags get deleted: + +`$ arduino-cloud-cli device delete --tags =,=` + Devices currently present on Arduino IoT Cloud can be retrieved with: `$ arduino-cloud-cli device list` @@ -112,6 +120,12 @@ Print only the things that have all the passed tags: Things can be deleted using the thing delete command. This command accepts two mutually exclusive flags: `--id` and `--tags`. Only one of them must be passed. When the `--id` is passed, the thing having such ID gets deleted: +`$ arduino-cloud-cli thing delete --id ` + +When `--tags` is passed, the things having all the specified tags get deleted: + +`$ arduino-cloud-cli thing delete --tags =,=` + Delete a thing with the following command: `$ arduino-cloud-cli thing delete --id `