From e5e45d972d3ea113300992c5d73118cc8c8bdb9e Mon Sep 17 00:00:00 2001 From: Jim White Date: Mon, 17 May 2021 11:11:33 -0500 Subject: [PATCH 1/2] feat: upgrade to v2 apis with base files and status and version commands working Signed-off-by: Jim White --- Attribution.txt | 17 ++ cmd/addressable/addressable.go | 35 ----- cmd/addressable/list/list.go | 52 ------- cmd/command/command.go | 35 ----- cmd/command/exec/get/get.go | 40 ----- cmd/command/exec/put/put.go | 57 ------- cmd/command/list/list.go | 92 ----------- cmd/db/db.go | 36 ----- cmd/db/purge/purge.go | 89 ----------- cmd/device/add/add.go | 140 ----------------- cmd/device/adminstate/adminstatus.go | 69 --------- cmd/device/device.go | 42 ----- cmd/device/list/list.go | 72 --------- cmd/device/operstatus/operstatus.go | 69 --------- cmd/device/rm/rm.go | 64 -------- cmd/device/update/update.go | 160 ------------------- cmd/deviceservice/add/add.go | 125 --------------- cmd/deviceservice/deviceservice.go | 57 ------- cmd/deviceservice/list/list.go | 77 --------- cmd/deviceservice/rm/rm.go | 57 ------- cmd/deviceservice/update/update.go | 151 ------------------ cmd/event/add/add.go | 169 -------------------- cmd/event/count/count.go | 48 ------ cmd/event/event.go | 40 ----- cmd/event/list/list.go | 83 ---------- cmd/event/rm/rm.go | 114 -------------- cmd/event/scrub/scrub.go | 56 ------- cmd/interval/add/add.go | 201 ------------------------ cmd/interval/interval.go | 37 ----- cmd/interval/list/list.go | 72 --------- cmd/interval/rm/rm.go | 66 -------- cmd/interval/update/update.go | 150 ------------------ cmd/notification/add/add.go | 198 ------------------------ cmd/notification/list/list.go | 117 -------------- cmd/notification/notification.go | 35 ----- cmd/notification/rm/rm.go | 80 ---------- cmd/profile/add/add.go | 223 --------------------------- cmd/profile/list/list.go | 62 -------- cmd/profile/profile.go | 42 ----- cmd/profile/rm/rm.go | 61 -------- cmd/profile/update/update.go | 113 -------------- cmd/reading/count/count.go | 40 ----- cmd/reading/list/list.go | 72 --------- cmd/reading/reading.go | 34 ---- cmd/root.go | 57 +++---- cmd/status/status.go | 2 +- cmd/subscription/add/add.go | 73 --------- cmd/subscription/list/list.go | 55 ------- cmd/subscription/rm/rm.go | 59 ------- cmd/subscription/subscription.go | 36 ----- cmd/watcher/add/add.go | 196 ----------------------- cmd/watcher/list/list.go | 72 --------- cmd/watcher/rm/rm.go | 49 ------ cmd/watcher/watcher.go | 35 ----- go.mod | 5 +- pkg/cmd/purge/coredata.go | 42 ++--- pkg/cmd/purge/metadata.go | 47 +++--- pkg/cmd/purge/scheduler.go | 8 +- pkg/cmd/version/version.go | 2 +- pkg/request.go | 4 +- 60 files changed, 103 insertions(+), 4288 deletions(-) delete mode 100644 cmd/addressable/addressable.go delete mode 100644 cmd/addressable/list/list.go delete mode 100644 cmd/command/command.go delete mode 100644 cmd/command/exec/get/get.go delete mode 100644 cmd/command/exec/put/put.go delete mode 100644 cmd/command/list/list.go delete mode 100644 cmd/db/db.go delete mode 100644 cmd/db/purge/purge.go delete mode 100644 cmd/device/add/add.go delete mode 100644 cmd/device/adminstate/adminstatus.go delete mode 100644 cmd/device/device.go delete mode 100644 cmd/device/list/list.go delete mode 100644 cmd/device/operstatus/operstatus.go delete mode 100644 cmd/device/rm/rm.go delete mode 100644 cmd/device/update/update.go delete mode 100644 cmd/deviceservice/add/add.go delete mode 100644 cmd/deviceservice/deviceservice.go delete mode 100644 cmd/deviceservice/list/list.go delete mode 100644 cmd/deviceservice/rm/rm.go delete mode 100644 cmd/deviceservice/update/update.go delete mode 100644 cmd/event/add/add.go delete mode 100644 cmd/event/count/count.go delete mode 100644 cmd/event/event.go delete mode 100644 cmd/event/list/list.go delete mode 100644 cmd/event/rm/rm.go delete mode 100644 cmd/event/scrub/scrub.go delete mode 100644 cmd/interval/add/add.go delete mode 100644 cmd/interval/interval.go delete mode 100644 cmd/interval/list/list.go delete mode 100644 cmd/interval/rm/rm.go delete mode 100644 cmd/interval/update/update.go delete mode 100644 cmd/notification/add/add.go delete mode 100644 cmd/notification/list/list.go delete mode 100644 cmd/notification/notification.go delete mode 100644 cmd/notification/rm/rm.go delete mode 100644 cmd/profile/add/add.go delete mode 100644 cmd/profile/list/list.go delete mode 100644 cmd/profile/profile.go delete mode 100644 cmd/profile/rm/rm.go delete mode 100644 cmd/profile/update/update.go delete mode 100644 cmd/reading/count/count.go delete mode 100644 cmd/reading/list/list.go delete mode 100644 cmd/reading/reading.go delete mode 100644 cmd/subscription/add/add.go delete mode 100644 cmd/subscription/list/list.go delete mode 100644 cmd/subscription/rm/rm.go delete mode 100644 cmd/subscription/subscription.go delete mode 100644 cmd/watcher/add/add.go delete mode 100644 cmd/watcher/list/list.go delete mode 100644 cmd/watcher/rm/rm.go delete mode 100644 cmd/watcher/watcher.go diff --git a/Attribution.txt b/Attribution.txt index fb263e1c..dbae9d6f 100644 --- a/Attribution.txt +++ b/Attribution.txt @@ -55,6 +55,9 @@ https://github.com/BurntSushi/toml/blob/master/COPYING edgexfoundry/go-mod-core-contracts (Apache 2.0) https://github.com/edgexfoundry/go-mod-core-contracts https://github.com/edgexfoundry/go-mod-core-contracts/blob/master/LICENSE +edgexfoundry/go-mod-core-contracts (Apache 2.0) https://github.com/edgexfoundry/go-mod-core-contracts/v2 +https://github.com/edgexfoundry/go-mod-core-contracts/blob/master/LICENSE + niemeyer/pretty (MIT) https://github.com/niemeyer/pretty https://github.com/niemeyer/pretty/blob/master/License @@ -85,3 +88,17 @@ https://github.com/go-yaml/yaml/blob/v2.3.0/LICENSE gopkg.in/yaml.v3 (MIT) https://github.com/go-yaml/yaml/tree/v3 https://github.com/go-yaml/yaml/blob/v3/LICENSE +go-playground/locales (MIT) https://github.com/go-playground/locales +https://github.com/go-playground/locales/blob/master/LICENSE + +go-playground/universal-translator (MIT) https://github.com/go-playground/universal-translator +https://github.com/go-playground/universal-translator/blob/master/LICENSE + +github.com/go-playground/validator/v10 (MIT) https://github.com/go-playground/validator +https://github.com/go-playground/validator/blob/master/LICENSE + +leodido/go-urn (MIT) https://github.com/leodido/go-urn +https://github.com/leodido/go-urn + +golang.org/x/crypto (Unspecified) https://github.com/golang/crypto +https://github.com/golang/crypto/blob/master/LICENSE \ No newline at end of file diff --git a/cmd/addressable/addressable.go b/cmd/addressable/addressable.go deleted file mode 100644 index 9b55fe3e..00000000 --- a/cmd/addressable/addressable.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 addressable - -import ( - // addsubscription "github.com/edgexfoundry/edgex-cli/cmd/subscription/add" - listaddressable "github.com/edgexfoundry/edgex-cli/cmd/addressable/list" - // rmsubscription "github.com/edgexfoundry/edgex-cli/cmd/subscription/rm" - "github.com/spf13/cobra" -) - -// NewCommand returns addressable command -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "addressable", - Short: "Addressable command", - Long: `Actions related to addressable.`, - } - cmd.AddCommand(listaddressable.NewCommand()) - // cmd.AddCommand(rmsubscription.NewCommand()) - // cmd.AddCommand(listsubscription.NewCommand()) - return cmd -} diff --git a/cmd/addressable/list/list.go b/cmd/addressable/list/list.go deleted file mode 100644 index 852df03b..00000000 --- a/cmd/addressable/list/list.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 list - -import ( - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - "github.com/edgexfoundry/edgex-cli/pkg/formatters" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/models" - "github.com/spf13/cobra" -) - -const addrTempl = "Id\tName\tProtocol\tHTTPMethod\tAddress\tPort\n" + - "{{range .}}" + - "{{.Id}}\t{{.Name}}\t{{.Protocol}}\t{{.HTTPMethod}}\t{{.Address}}\t{{.Port}}\n" + - "{{end}}" - -// NewCommand returns the list device command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "A list of all addressable", - Long: `Return all addressable sorted by id.`, - RunE: listHandler, - } - return cmd -} -func listHandler(cmd *cobra.Command, args []string) (err error) { - url := config.Conf.Clients["Metadata"].Url() + clients.ApiAddressableRoute - var addr []models.Addressable - err = request.Get(cmd.Context(), url, &addr) - if err != nil { - return - } - formatter := formatters.NewFormatter(addrTempl, nil) - err = formatter.Write(addr) - return -} diff --git a/cmd/command/command.go b/cmd/command/command.go deleted file mode 100644 index 85245cc6..00000000 --- a/cmd/command/command.go +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright 2020 VMWare. - * - * 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 command - -import ( - "github.com/edgexfoundry/edgex-cli/cmd/command/exec/get" - "github.com/edgexfoundry/edgex-cli/cmd/command/exec/put" - "github.com/edgexfoundry/edgex-cli/cmd/command/list" - - "github.com/spf13/cobra" -) - -// NewCommand returns addressable command -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "command", - Short: "`Command` command", - Long: `Actions related to commands.`, - } - cmd.AddCommand(list.NewCommand()) - cmd.AddCommand(get.NewCommand()) - cmd.AddCommand(put.NewCommand()) - return cmd -} diff --git a/cmd/command/exec/get/get.go b/cmd/command/exec/get/get.go deleted file mode 100644 index 8a4a8c0d..00000000 --- a/cmd/command/exec/get/get.go +++ /dev/null @@ -1,40 +0,0 @@ -package get - -import ( - "fmt" - "github.com/edgexfoundry/edgex-cli/config" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/command" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - - "github.com/spf13/cobra" -) - -var deviceName string -var cmdName string -var data string - -// NewCommand returns `issue Get command` command -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "get", - Short: "Issue GET command", - Long: `Issue GET command referenced by the command name to the device also referenced by name`, - RunE: handler, - } - cmd.Flags().StringVarP(&deviceName, "device", "d", "", "Specify the name of device") - cmd.Flags().StringVarP(&cmdName, "cmd", "n", "", "Specify the name of the command to be executed") - cmd.MarkFlagRequired("device") - cmd.MarkFlagRequired("cmd") - return cmd -} - -func handler(cmd *cobra.Command, args []string) error { - client := local.New(config.Conf.Clients["Command"].Url() + clients.ApiDeviceRoute) - res, err := command.NewCommandClient(client).GetDeviceCommandByNames(cmd.Context(), deviceName, cmdName) - if err == nil { - fmt.Printf("%s\n", res) - } - return err -} diff --git a/cmd/command/exec/put/put.go b/cmd/command/exec/put/put.go deleted file mode 100644 index 4754eee8..00000000 --- a/cmd/command/exec/put/put.go +++ /dev/null @@ -1,57 +0,0 @@ -package put - -import ( - "errors" - "fmt" - "io/ioutil" - - "github.com/edgexfoundry/edgex-cli/config" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/command" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - - "github.com/spf13/cobra" -) - -var device string -var cmdName string -var body string -var file string - -// NewCommand returns `issue Put command` command -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "put", - Short: "Issue PUT command", - Long: `Issue PUT command referenced by the command name to the device also referenced by name`, - RunE: handler, - } - cmd.Flags().StringVarP(&device, "device", "d", "", "Specify the name of the device") - cmd.Flags().StringVarP(&cmdName, "cmd", "n", "", "Specify the name of the command to be executed") - cmd.Flags().StringVarP(&body, "body", "b", "", "Specify PUT requests body/data inline") - cmd.Flags().StringVarP(&file, "file", "f", "", "File containing PUT requests body/data") - cmd.MarkFlagRequired("device") - cmd.MarkFlagRequired("cmdName") - return cmd -} - -func handler(cmd *cobra.Command, args []string) (err error) { - if (file != "" && body != "") || (file == "" && body == "") { - return errors.New("please specify request data using one of the provided ways: --body or --file ") - } - if file != "" { - content, err := ioutil.ReadFile(file) - if err != nil { - return err - } - body = string(content) - } - - client := local.New(config.Conf.Clients["Command"].Url() + clients.ApiDeviceRoute) - res, err := command.NewCommandClient(client).PutDeviceCommandByNames(cmd.Context(), device, cmdName, body) - if res != "" { - fmt.Printf("%s\n", res) - } - return err -} diff --git a/cmd/command/list/list.go b/cmd/command/list/list.go deleted file mode 100644 index 225ef034..00000000 --- a/cmd/command/list/list.go +++ /dev/null @@ -1,92 +0,0 @@ -/******************************************************************************* - * Copyright 2020 VMWare. - * - * 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 list - -import ( - "context" - "html/template" - "strings" - - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - "github.com/edgexfoundry/edgex-cli/pkg/formatters" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -var device string - -const cmdsTempl = "Name\tDevice Id\tDevice Name\tMethods\tURL\t\n" + - "{{range .}}" + - "{{ $deviceId :=.Id}}" + - "{{ $deviceName :=.Name}}" + - "{{range $i, $c := .Commands}}" + - "{{$c.Name}}\t{{$deviceId}}\t{{$deviceName}}\t{{supportedMethods $c}}\t{{if $c.Get.URL}}{{$c.Get.URL}}{{else}}{{$c.Put.URL}}{{end}}\t\n" + - "{{end}}" + - "{{end}}" - -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "A list of device supported commands", - Long: "Return a list of all device `commands`", - RunE: listHandler, - } - cmd.Flags().StringVarP(&device, "device", "d", "", "List commands associated with device specified by name") - return cmd -} - -func listHandler(cmd *cobra.Command, args []string) (err error) { - var responses []models.CommandResponse - if device != "" { - responses, err = getCommandsByDeviceName(cmd.Context(), device) - } else { - responses, err = getCommands(cmd.Context()) - } - if err != nil { - return - } - formatter := formatters.NewFormatter(cmdsTempl, template.FuncMap{"supportedMethods": supportedMethods}) - err = formatter.Write(responses) - return -} - -func getCommands(ctx context.Context) ([]models.CommandResponse, error) { - var responses []models.CommandResponse - url := config.Conf.Clients["Command"].Url() + clients.ApiDeviceRoute - err := request.Get(ctx, url, &responses) - return responses, err -} - -func getCommandsByDeviceName(ctx context.Context, d string) ([]models.CommandResponse, error) { - var response models.CommandResponse - url := config.Conf.Clients["Command"].Url() + clients.ApiDeviceRoute + "/name/" + device - err := request.Get(ctx, url, &response) - responses := []models.CommandResponse{response} - return responses, err -} - -func supportedMethods(cmd models.Command) (methods string) { - if cmd.Get.Path != "" { - methods = "Get," - } - if cmd.Put.Path != "" { - methods = methods + " Put" - } - methods = strings.TrimSpace(methods) - return strings.TrimSuffix(methods, ",") -} diff --git a/cmd/db/db.go b/cmd/db/db.go deleted file mode 100644 index 42e01a02..00000000 --- a/cmd/db/db.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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. - -// The purgedb command purges the entire Database. It performs the same action as the -// clean_mongo.js developer script. Unlike the clean_mongo.js, this command purges the -// database using API calls only. clean_mongo.js accesses the DB directly, which might -// always be possible using the CLI. -package db - -import ( - purgedb "github.com/edgexfoundry/edgex-cli/cmd/db/purge" - - "github.com/spf13/cobra" -) - -// NewCommand returns the db command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "db", - Short: "Purges entire EdgeX Database. [USE WITH CAUTION]", - Long: `Purge DB`, - } - cmd.AddCommand(purgedb.NewCommand()) - return cmd -} diff --git a/cmd/db/purge/purge.go b/cmd/db/purge/purge.go deleted file mode 100644 index 04026bbd..00000000 --- a/cmd/db/purge/purge.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 purgedb command purges the entire Database. It performs the same action as the -// clean_mongo.js developer script. Unlike the clean_mongo.js, this command purges the -// database using API calls only. clean_mongo.js accesses the DB directly, which might -// always be possible using the CLI. -package purgedb - -import ( - "context" - "fmt" - "strconv" - "time" - - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - cleaners "github.com/edgexfoundry/edgex-cli/pkg/cmd/purge" - "github.com/edgexfoundry/edgex-cli/pkg/confirmation" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - - "github.com/spf13/cobra" -) - -// NewCommand returns the db command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "purge", - Short: "Purges entire EdgeX Database. [USE WITH CAUTION]", - Long: `Purge DB - -USE WITH CAUTION. The effect of this command is irreversible. - -The end goal for this command is to clean all data from the underlying -database. - -`, - RunE: func(cmd *cobra.Command, args []string) (err error) { - // asking user to confirm the purge action - if !confirmation.New().Confirm() { - return - } - purge(cmd.Context()) - return - }, - } - return cmd -} - -func purge(ctx context.Context) { - cleaners.NewMetadataCleaner(ctx).Purge() - cleaners.NewCoredataCleaner(ctx).Purge() - removeLogs(ctx) - cleaners.NewSchedulerCleaner(ctx).Purge() - removeNotifications(ctx) -} - -func removeLogs(ctx context.Context) { - fmt.Println("\n * Logs") - ts := time.Now().Unix() * 1000 - url := config.Conf.Clients["Logging"].Url() + clients.ApiLoggingRoute + "/0/" + strconv.FormatInt(ts, 10) - err := request.Delete(ctx, url) - if err == nil { - //TODO fix the message - fmt.Print("Logs have been removed\n") - } -} - -func removeNotifications(ctx context.Context) { - fmt.Println("\n * Notifications") - url := config.Conf.Clients["Notification"].Url() + "/api/v1/cleanup" - err := request.Delete(ctx, url) - if err == nil { - //TODO fix the message - fmt.Println("Notifications have been removed") - } -} diff --git a/cmd/device/add/add.go b/cmd/device/add/add.go deleted file mode 100644 index 5d6333c7..00000000 --- a/cmd/device/add/add.go +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (C) 2019 IOTech Ltd -// -// SPDX-License-Identifier: Apache-2.0 - -package add - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "html/template" - - "github.com/edgexfoundry/edgex-cli/cmd/device/update" - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/editor" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/metadata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -const DeviceTemplate = `[{{range $d := .}}` + update.DeviceTemp + `{{end}}]` - -var interactiveMode bool -var name string -var description string -var adminState string -var operState string -var profileName string -var serviceName string -var file string - -// NewCommand returns the update device command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "add", - Short: "Add devices", - Long: `Create devices described in a given JSON file or use the interactive mode with additional flags.`, - RunE: deviceHandler, - } - cmd.Flags().BoolVarP(&interactiveMode, editor.InteractiveModeLabel, "i", false, "Open a default editor to customize the Event information") - cmd.Flags().StringVarP(&name, "name", "n", "", "Name") - cmd.Flags().StringVarP(&description, "description", "d", "", "Description") - cmd.Flags().StringVar(&adminState, "adminState", "", "Admin Status") - cmd.Flags().StringVar(&operState, "operatingStatus", "", "Operating Status") - cmd.Flags().StringVar(&profileName, "profileName", "", "Device Profile name") - cmd.Flags().StringVar(&serviceName, "serviceName", "", "Device Service name") - - cmd.Flags().StringVarP(&file, "file", "f", "", "File containing device configuration in json format") - return cmd -} - -func deviceHandler(cmd *cobra.Command, args []string) error { - if interactiveMode && file != "" { - return errors.New("you could work with interactive mode or file, but not with both") - } - - if file != "" { - return createDevicesFromFile(cmd.Context()) - } - - devices, err := parseDevice(cmd.Context(), interactiveMode) - if err != nil { - return err - } - - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceRoute) - for _, d := range devices { - _, err = metadata.NewDeviceClient(client).Add(cmd.Context(), &d) - if err != nil { - return err - } - } - - return nil -} - -func createDevicesFromFile(ctx context.Context) error { - devices, err := update.LoadDevicesFromFile(file) - if err != nil { - return err - } - - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceRoute) - for _, d := range devices { - _, err = metadata.NewDeviceClient(client).Add(ctx, &d) - if err != nil { - fmt.Println("Error: ", err.Error()) - } - } - return nil -} - -func parseDevice(ctx context.Context, interactiveMode bool) ([]models.Device, error) { - //parse Device based on interactive mode and the other provided flags - var err error - var devices []models.Device - if name != "" { - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceRoute) - from, _ := metadata.NewDeviceClient(client).DeviceForName(ctx, name) - devices = append(devices, from) - } else { - populateDevice(&devices) - } - - var updatedDeviceBytes []byte - if interactiveMode { - updatedDeviceBytes, err = editor.OpenInteractiveEditor(devices, DeviceTemplate, template.FuncMap{ - "inc": func(i int) int { - return i + 1 - }, - "lastElem": editor.IsLastElementOfSlice, - }) - } - if err != nil { - return nil, err - } - - var updatedDevices []models.Device - err = json.Unmarshal(updatedDeviceBytes, &updatedDevices) - if err != nil { - return nil, errors.New("Unable to execute the command. The provided information is not valid:" + err.Error()) - } - return updatedDevices, err -} - -func populateDevice(devices *[]models.Device) { - d := models.Device{} - d.Name = name - d.Description = description - d.AdminState = models.AdminState(adminState) - d.OperatingState = models.OperatingState(operState) - d.Profile = models.DeviceProfile{Name: profileName} - d.Service = models.DeviceService{Name: serviceName} - *devices = append(*devices, d) -} diff --git a/cmd/device/adminstate/adminstatus.go b/cmd/device/adminstate/adminstatus.go deleted file mode 100644 index 028574e8..00000000 --- a/cmd/device/adminstate/adminstatus.go +++ /dev/null @@ -1,69 +0,0 @@ -package adminstate - -import ( - "errors" - "fmt" - "strings" - - "github.com/edgexfoundry/edgex-cli/config" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/metadata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - "github.com/edgexfoundry/go-mod-core-contracts/models" - "github.com/edgexfoundry/go-mod-core-contracts/requests/states/admin" - - "github.com/spf13/cobra" -) - -var deviceName string -var deviceId string -var state string - -// NewCommand returns device adminstate -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "adminstate", - Short: "Update deviceName admin state", - Long: `Update deviceName admin state`, - RunE: updateAdminStatusHandler, - } - cmd.Flags().StringVarP(&state, "state", "s", "", fmt.Sprintf("Admin State \nValues: [%s]", strings.Join([]string{models.Locked, models.Unlocked}, ","))) - cmd.Flags().StringVarP(&deviceName, "name", "n", "", "Name of the deviceName to be updated") - cmd.Flags().StringVarP(&deviceId, "id", "i", "", "Id of the deviceName to be updated") - return cmd -} - -func updateAdminStatusHandler(cmd *cobra.Command, args []string) error { - state = strings.ToUpper(state) - if err := validate(); err != nil { - return err - } - url := config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceRoute - mdc := metadata.NewDeviceClient( - local.New(url), - ) - var err error - if deviceName != "" { - err = mdc.UpdateAdminStateByName(cmd.Context(), deviceName, admin.UpdateRequest{AdminState: models.AdminState(state)}) - } else { - err = mdc.UpdateAdminState(cmd.Context(), deviceId, admin.UpdateRequest{AdminState: models.AdminState(state)}) - } - return err -} - -func validate() error { - if state == "" { - return errors.New("admin state should be specified") - } else if state != "" { - valid, err := models.AdminState(state).Validate() - if !valid { - return err - } - } else if deviceName == "" && deviceId == "" { - return errors.New("deviceName or deviceId should be specified") - } else if deviceName != "" && deviceId != "" { - return errors.New("only one deviceName or deviceId should be specified") - } - return nil -} diff --git a/cmd/device/device.go b/cmd/device/device.go deleted file mode 100644 index 8dffd7f7..00000000 --- a/cmd/device/device.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 device - -import ( - "github.com/edgexfoundry/edgex-cli/cmd/device/add" - "github.com/edgexfoundry/edgex-cli/cmd/device/adminstate" - "github.com/edgexfoundry/edgex-cli/cmd/device/list" - "github.com/edgexfoundry/edgex-cli/cmd/device/operstatus" - "github.com/edgexfoundry/edgex-cli/cmd/device/rm" - "github.com/edgexfoundry/edgex-cli/cmd/device/update" - - "github.com/spf13/cobra" -) - -// NewCommand returns the device command of type cobra.Command -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "device", - Short: "Device command", - Long: `Actions related to devices.`, - } - cmd.AddCommand(rm.NewCommand()) - cmd.AddCommand(list.NewCommand()) - cmd.AddCommand(add.NewCommand()) - cmd.AddCommand(update.NewCommand()) - cmd.AddCommand(adminstate.NewCommand()) - cmd.AddCommand(operstatus.NewCommand()) - return cmd -} diff --git a/cmd/device/list/list.go b/cmd/device/list/list.go deleted file mode 100644 index 3d8ffd5e..00000000 --- a/cmd/device/list/list.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 list - -import ( - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/formatters" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/metadata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -const deviceTempl = "Device ID\tDevice Name\tDescription\tOperating State\tAdmin State\tDevice Service\tDevice Profile\n" + - "{{range .}}" + - "{{.Id}}\t{{.Name}}\t{{.Description}}\t{{.OperatingState}}\t{{.AdminState}}\t{{.Service.Name}}\t{{.Profile.Name}}\n" + - "{{end}}" - -var name string - -// NewCommand returns the list device command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "A list of all devices", - Long: `Return all devices sorted by id.`, - RunE: listHandler, - } - cmd.Flags().StringVarP(&name, "name", "n", "", "Returns Device matching the given name") - return cmd -} - -func listHandler(cmd *cobra.Command, args []string) (err error) { - url := config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceRoute - mdc := metadata.NewDeviceClient( - local.New(url), - ) - var devices []models.Device - var device models.Device - - if name != "" { - device, err = mdc.DeviceForName(cmd.Context(), name) - if err != nil { - return - } - devices = append(devices, device) - } else { - devices, err = mdc.Devices(cmd.Context()) - if err != nil { - return - } - } - - formatter := formatters.NewFormatter(deviceTempl, nil) - err = formatter.Write(devices) - return -} diff --git a/cmd/device/operstatus/operstatus.go b/cmd/device/operstatus/operstatus.go deleted file mode 100644 index bd2bd60a..00000000 --- a/cmd/device/operstatus/operstatus.go +++ /dev/null @@ -1,69 +0,0 @@ -package operstatus - -import ( - "errors" - "fmt" - "strings" - - "github.com/edgexfoundry/edgex-cli/config" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/metadata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - "github.com/edgexfoundry/go-mod-core-contracts/models" - "github.com/edgexfoundry/go-mod-core-contracts/requests/states/operating" - - "github.com/spf13/cobra" -) - -var deviceName string -var deviceId string -var state string - -// NewCommand returns device operstatus -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "operstate", - Short: "Update deviceName operating state", - Long: `Update deviceName operating state`, - RunE: updateOperStatusHandler, - } - cmd.Flags().StringVarP(&state, "state", "s", "", fmt.Sprintf("Operating State \nValues: [%s]", strings.Join([]string{models.Disabled, models.Enabled}, ","))) - cmd.Flags().StringVarP(&deviceName, "name", "n", "", "Name of the deviceName to be updated") - cmd.Flags().StringVarP(&deviceId, "id", "i", "", "Id of the deviceName to be updated") - return cmd -} - -func updateOperStatusHandler(cmd *cobra.Command, args []string) error { - state = strings.ToUpper(state) - if err := validate(); err != nil { - return err - } - url := config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceRoute - mdc := metadata.NewDeviceClient( - local.New(url), - ) - var err error - if deviceName != "" { - err = mdc.UpdateOpStateByName(cmd.Context(), deviceName, operating.UpdateRequest{OperatingState: models.OperatingState(state)}) - } else { - err = mdc.UpdateOpState(cmd.Context(), deviceId, operating.UpdateRequest{OperatingState: models.OperatingState(state)}) - } - return err -} - -func validate() error { - if state == "" { - return errors.New("operating state should be specified") - } else if state != "" { - valid, err := models.OperatingState(state).Validate() - if !valid { - return err - } - } else if deviceName == "" && deviceId == "" { - return errors.New("deviceName or deviceId should be specified") - } else if deviceName != "" && deviceId != "" { - return errors.New("only one deviceName or deviceId should be specified") - } - return nil -} diff --git a/cmd/device/rm/rm.go b/cmd/device/rm/rm.go deleted file mode 100644 index 7f03678c..00000000 --- a/cmd/device/rm/rm.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 rm - -import ( - "errors" - "fmt" - - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/metadata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - - "github.com/spf13/cobra" -) - -var name string - -// NewCommand returns the rm command of type cobra.Command -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "rm [ | --name ]", - Short: "Removes device by name or ID", - Long: `Removes a device given its name or ID. -You can use: '$ edgex device list' to find a device's name and ID.`, - RunE: func(cmd *cobra.Command, args []string) (err error) { - if len(args) == 0 && name == "" { - return errors.New("no device id/name provided") - } - mdc := metadata.NewDeviceClient( - local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceRoute), - ) - - if name != "" { - err = mdc.DeleteByName(cmd.Context(), name) - if err == nil { - fmt.Printf("Removed: %s\n", name) - } - return err - } - - if len(args[0]) != 0 { - return request.DeleteByIds(cmd.Context(), mdc, args) - } - return nil - }, - } - cmd.Flags().StringVarP(&name, "name", "n", "", "Delete Device by name") - return cmd -} diff --git a/cmd/device/update/update.go b/cmd/device/update/update.go deleted file mode 100644 index a1aab1f4..00000000 --- a/cmd/device/update/update.go +++ /dev/null @@ -1,160 +0,0 @@ -package update - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "html/template" - "io/ioutil" - - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/editor" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/metadata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -const DeviceTemp = `{ - "Id": "{{.Id}}", - "Name": "{{.Name}}", - "Description":"{{.Description}}", - "Adminstate":"{{.AdminState}}", - "OperatingState": "{{.OperatingState}}", - "Protocols":{ - {{- $length := len .Protocols }}{{$idx:=0}} - {{- range $k,$ProtocolProperties := .Protocols}} - "{{$k}}":{ - {{- $innerLength := len $ProtocolProperties }}{{$innerIdx:=0}} - {{- range $ki,$vi := $ProtocolProperties}} - "{{- $ki}}":"{{$vi}}"{{if not (lastElem $innerIdx $innerLength)}},{{end}}{{$innerIdx = inc $innerIdx}} - {{end}}} {{if not (lastElem $idx $length)}},{{end}}{{$idx = inc $idx}} - {{end}}}, - "Service": { - "Name": "{{.Service.Name}}" - }, - "Profile": { - "Name": "{{.Profile.Name}}" - } -}` - -var name string -var file string - -// NewCommand returns the update device command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "update", - Short: "Update device", - Long: `Update device(s) described in the given JSON file or use the interactive mode enabled by providing - name of existing device service`, - RunE: deviceHandler, - } - cmd.Flags().StringVarP(&name, "name", "n", "", "Device name. Device with given name is loaded into default editor, ready to be customized") - cmd.Flags().StringVarP(&file, "file", "f", "", "Json file containing device configuration to update") - return cmd -} - -func deviceHandler(cmd *cobra.Command, args []string) error { - if name != "" && file != "" { - return errors.New("you could work with interactive mode by providing the name of the device you want to update or by providing a file, but not with both") - } - - if name == "" && file == "" { - return errors.New("Please, provide file or device name ") - } - - if file != "" { - return updateDevicesFromFile(cmd.Context()) - } - //Update the device provided by name using interactive mode to alter it - d, err := parseDevice(cmd, name) - if err != nil { - return err - } - - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceRoute) - err = metadata.NewDeviceClient(client).Update(cmd.Context(), d) - if err != nil { - return err - } - - return nil -} - -func updateDevicesFromFile(ctx context.Context) error { - devices, err := LoadDevicesFromFile(file) - if err != nil { - return err - } - - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceRoute) - for _, d := range devices { - err = metadata.NewDeviceClient(client).Update(ctx, d) - if err != nil { - fmt.Println("Error: ", err.Error()) - } - } - return nil -} - -//loads a device service to be updated and open a default editor for customization -func parseDevice(cmd *cobra.Command, name string) (models.Device, error) { - //load Device from database - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceRoute) - device, err := metadata.NewDeviceClient(client).DeviceForName(cmd.Context(), name) - if err != nil { - return models.Device{}, err - } - - //populate the template with the loaded device and open default editor, so the client could customize the data - updatedDeviceBytes, err := editor.OpenInteractiveEditor(device, DeviceTemp, template.FuncMap{ - "inc": func(i int) int { - return i + 1 - }, - "lastElem": editor.IsLastElementOfSlice, - }) - if err != nil { - return models.Device{}, err - } - - var d models.Device - err = json.Unmarshal(updatedDeviceBytes, &d) - if err != nil { - return models.Device{}, errors.New("Unable to execute the command. The provided information is invalid: " + err.Error()) - } - return d, nil -} - -//LoadDevicesFromFile could read a file that contains single Device or list of Device -func LoadDevicesFromFile(filePath string) ([]models.Device, error) { - defer func() { - if r := recover(); r != nil { - fmt.Println("Error: Invalid Json") - } - }() - file, err := ioutil.ReadFile(filePath) - if err != nil { - return nil, err - } - - var devices []models.Device - - //check if the file contains just one Device - var d models.Device - err = json.Unmarshal(file, &d) - if err != nil { - //check if the file contains list of Device - err = json.Unmarshal(file, &devices) - if err != nil { - return nil, err - } - } else { - devices = append(devices, d) - } - return devices, nil -} diff --git a/cmd/deviceservice/add/add.go b/cmd/deviceservice/add/add.go deleted file mode 100644 index 5c5c7179..00000000 --- a/cmd/deviceservice/add/add.go +++ /dev/null @@ -1,125 +0,0 @@ -package add - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "html/template" - - "github.com/edgexfoundry/edgex-cli/cmd/deviceservice/update" - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/editor" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/metadata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -var interactiveMode bool -var name string -var description string -var adminState string -var operState string -var addrName string -var file string - -const DeviceServicesTempl = `[{{range $ds := .}}` + update.DeviceServiceTempl + - `{{end}}]` - -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "add", - Short: "Add device service", - Long: `Create device service(s) described in the given JSON file or use the interactive mode with additional flags.`, - RunE: newDeviceServiceHandler, - } - cmd.Flags().BoolVarP(&interactiveMode, editor.InteractiveModeLabel, "i", false, "Open a default editor to customize the Event information") - cmd.Flags().StringVarP(&name, "name", "n", "", "Name") - cmd.Flags().StringVarP(&description, "description", "d", "", "Description") - cmd.Flags().StringVar(&adminState, "adminState", "", "Admin Status") - cmd.Flags().StringVar(&operState, "operatingStatus", "", "Operating Status") - cmd.Flags().StringVar(&addrName, "addrName", "", "Addressable name the device service will be linked with.") - - cmd.Flags().StringVarP(&file, "file", "f", "", "Json file containing device service(s) configuration") - return cmd -} - -func newDeviceServiceHandler(cmd *cobra.Command, args []string) error { - if interactiveMode && file != "" { - return errors.New("you could work with interactive mode or file, but not with both") - } - - if file != "" { - return createDeviceServicesFromFile(cmd.Context()) - } - - deviceServices, err := parseDeviceService(interactiveMode) - if err != nil { - return err - } - - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceServiceRoute) - for _, ds := range deviceServices { - _, err = metadata.NewDeviceServiceClient(client).Add(cmd.Context(), &ds) - if err != nil { - return err - } - } - return nil -} - -func populateDeviceService(deviceServices *[]models.DeviceService) { - ds := models.DeviceService{} - ds.Name = name - ds.Description = description - ds.AdminState = models.AdminState(adminState) - ds.OperatingState = models.OperatingState(operState) - ds.Addressable = models.Addressable{Name: addrName} - *deviceServices = append(*deviceServices, ds) -} - -func createDeviceServicesFromFile(ctx context.Context) error { - deviceServices, err := update.LoadDSFromFile(file) - if err != nil { - return err - } - - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceServiceRoute) - for _, ds := range deviceServices { - _, err = metadata.NewDeviceServiceClient(client).Add(ctx, &ds) - if err != nil { - fmt.Println("Error: ", err.Error()) - } - } - return nil -} - -func parseDeviceService(interactiveMode bool) ([]models.DeviceService, error) { - //parse Device Service based on interactive mode and the other provided flags - var err error - var deviceServices []models.DeviceService - populateDeviceService(&deviceServices) - - var updatedDeviceServiceBytes []byte - if interactiveMode { - updatedDeviceServiceBytes, err = editor.OpenInteractiveEditor(deviceServices, DeviceServicesTempl, template.FuncMap{ - "lastElem": editor.IsLastElementOfSlice, - }) - } else { - updatedDeviceServiceBytes, err = json.Marshal(deviceServices) - } - if err != nil { - return nil, err - } - - var updatedDeviceServices []models.DeviceService - err = json.Unmarshal(updatedDeviceServiceBytes, &updatedDeviceServices) - if err != nil { - return nil, errors.New("Unable to execute the command. The provided information is not valid: " + err.Error()) - } - return updatedDeviceServices, err -} diff --git a/cmd/deviceservice/deviceservice.go b/cmd/deviceservice/deviceservice.go deleted file mode 100644 index 777955ee..00000000 --- a/cmd/deviceservice/deviceservice.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 deviceservice - -import ( - "github.com/edgexfoundry/edgex-cli/cmd/deviceservice/add" - "github.com/edgexfoundry/edgex-cli/cmd/deviceservice/list" - "github.com/edgexfoundry/edgex-cli/cmd/deviceservice/rm" - "github.com/edgexfoundry/edgex-cli/cmd/deviceservice/update" - - "github.com/spf13/cobra" -) - -// NewCommand returns the device command of type cobra.Command -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "deviceservice", - Short: "Device service command", - Long: `Device service - -Device Services (DS) are the edge connectors interacting with the devices -or IoT objects that include, but are not limited to: appliances -in your home, alarm systems, HVAC equipment, lighting, machines in any -industry, irrigation systems, drones, traffic signals, automated transportation, -and so forth. - -Device services may service one or a number of devices, including sensors, -actuators, and so forth, at one time. A “device” that a DS manages, -could be something other than a simple single physical device and -could be another gateway and all of that gateway’s devices, a device -manager, or a device aggregator that acts as a device, or collection -of devices, to EdgeX Foundry. - -The Device Services layer’s microservices communicate with the devices, -sensors, actuators, and other IoT objects through protocols native to the IoT object. -The DS Layer converts the data produced and communicated by the IoT object, into a -common EdgeX Foundry data structure, and sends that converted data into the Core Services -layer, and to other microservices in other layers of EdgeX Foundry.`, - } - cmd.AddCommand(rm.NewCommand()) - cmd.AddCommand(list.NewCommand()) - cmd.AddCommand(add.NewCommand()) - cmd.AddCommand(update.NewCommand()) - return cmd -} diff --git a/cmd/deviceservice/list/list.go b/cmd/deviceservice/list/list.go deleted file mode 100644 index 85070689..00000000 --- a/cmd/deviceservice/list/list.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright © 2019 NAME HERE -// -// 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 list - -import ( - "html/template" - - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - "github.com/edgexfoundry/edgex-cli/pkg/formatters" - "github.com/edgexfoundry/edgex-cli/pkg/utils" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -const dsTemplate = "Service ID\tService Name\tOperating State\tAdmin State\tAddressable Name\tDescription\tCreated\n" + - "{{range .}}" + - "{{.Id}}\t{{.Name}}\t{{.OperatingState}}\t{{.AdminState}}\t{{.Addressable.Name}}\t{{.Description}}\t{{DisplayDuration .Created}}\n" + - "{{end}}" - -var name string - -// NewCommand returns the list device services command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "list []\",", - Short: "Lists existing devices services", - Long: `Return the list of current device services or Device Service matching the given id`, - RunE: listHandler, - } - cmd.Flags().StringVarP(&name, "name", "n", "", "Returns Device Service matching the given name") - return cmd -} - -func listHandler(cmd *cobra.Command, args []string) (err error) { - url := config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceServiceRoute - var deviceServices []models.DeviceService - var ds models.DeviceService - if name != "" { - err = request.Get(cmd.Context(), url+"/name/"+name, &ds) - if err != nil { - return - } - deviceServices = append(deviceServices, ds) - } else if len(args) != 0 { - var ds models.DeviceService - err = request.Get(cmd.Context(), url+"/"+args[0], &ds) - if err != nil { - return err - } - deviceServices = append(deviceServices, ds) - } else { - err = request.Get(cmd.Context(), url, &deviceServices) - if err != nil { - return - } - } - - formatter := formatters.NewFormatter(dsTemplate, template.FuncMap{"DisplayDuration": utils.DisplayDuration}) - err = formatter.Write(deviceServices) - return -} diff --git a/cmd/deviceservice/rm/rm.go b/cmd/deviceservice/rm/rm.go deleted file mode 100644 index d94519e4..00000000 --- a/cmd/deviceservice/rm/rm.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright © 2019 NAME HERE -// -// 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 rm - -import ( - "errors" - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - - "github.com/spf13/cobra" -) - -var name string - -// NewCommand returns the rm device service command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "rm [--name|]", - Example: "deviceservice rm \n" + - "deviceservice rm --name ", - Short: "Removes device service by name or ID", - Long: `Removes a device service from the core-metadata DB.`, - RunE: func(cmd *cobra.Command, args []string) (err error) { - if len(args) == 0 && name == "" { - return errors.New("no device service id/name provided") - } - url := config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceServiceRoute - url, deletedBy := constructUrl(url, args) - return request.DeletePrt(cmd.Context(), url, deletedBy) - }, - } - cmd.Flags().StringVar(&name, "name", "", "Delete Device Service by given name") - return cmd -} - -func constructUrl(url string, args []string) (string, string) { - if name != "" { - url = url + config.PathName + name - return url, name - } - url = url + config.PathId + args[0] - return url, args[0] -} diff --git a/cmd/deviceservice/update/update.go b/cmd/deviceservice/update/update.go deleted file mode 100644 index c5ce6d8a..00000000 --- a/cmd/deviceservice/update/update.go +++ /dev/null @@ -1,151 +0,0 @@ -package update - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "html/template" - "io/ioutil" - - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/editor" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/metadata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -const DeviceServiceTempl = `{ - "Id": "{{.Id}}", - "Name" : "{{.Name}}", - "Description" : "{{.Description}}", - "AdminState" : "{{.AdminState}}", - "OperatingState" : "{{.OperatingState}}", - "Labels" : [ - {{- $labelsLenght := len .Labels}} - {{- range $idx, $l := .Labels}} - "{{$l}}" {{if not (lastElem $idx $labelsLenght)}},{{end}} - {{- end}} - ], - "Addressable" : - { - "Name" : "{{.Addressable.Name}}" - } - }` - -var name string -var file string - -// NewCommand returns the update device service command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "update", - Short: "Update device service", - Long: `Update device service(s) described in the given JSON file or use the interactive mode enabled by providing - name of existing device service`, - RunE: deviceServiceHandler, - } - cmd.Flags().StringVarP(&name, "name", "n", "", "Device Service name. Service with given name is loaded into default editor, ready to be customized") - cmd.Flags().StringVarP(&file, "file", "f", "", "Json file containing device service configuration to update") - return cmd -} - -func deviceServiceHandler(cmd *cobra.Command, args []string) error { - if name != "" && file != "" { - return errors.New("DeviceService could be updated by providing a file, or by specifying device service name to be updated using interactive mode. ") - } - - if name == "" && file == "" { - return errors.New("Please, provide file or device service name ") - } - - if file != "" { - return updateDeviceServiceFromFile(cmd.Context()) - } - - updatedDeviceService, err := parseDeviceService(cmd.Context(), name) - if err != nil { - return err - } - - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceServiceRoute) - err = metadata.NewDeviceServiceClient(client).Update(cmd.Context(), updatedDeviceService) - if err != nil { - return err - } - - return nil -} - -//parseDeviceService loads a device service to be updated and open a default editor for customization -func parseDeviceService(ctx context.Context, name string) (models.DeviceService, error) { - var err error - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceServiceRoute) - ds, err := metadata.NewDeviceServiceClient(client).DeviceServiceForName(ctx, name) - if err != nil { - return models.DeviceService{}, err - } - - updatedDeviceServiceBytes, err := editor.OpenInteractiveEditor(ds, DeviceServiceTempl, template.FuncMap{ - "lastElem": editor.IsLastElementOfSlice, - }) - - if err != nil { - return models.DeviceService{}, err - } - var updatedDeviceService models.DeviceService - err = json.Unmarshal(updatedDeviceServiceBytes, &updatedDeviceService) - if err != nil { - return models.DeviceService{}, errors.New("Unable to execute the command. The provided information is invalid: " + err.Error()) - } - return updatedDeviceService, err -} - -func updateDeviceServiceFromFile(ctx context.Context) error { - deviceServices, err := LoadDSFromFile(file) - if err != nil { - return err - } - - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceServiceRoute) - for _, ds := range deviceServices { - err = metadata.NewDeviceServiceClient(client).Update(ctx, ds) - if err != nil { - fmt.Println("Error: ", err.Error()) - } - } - return nil -} - -//loadJsonFile could read a file that contains single Device service or list of Device Services -func LoadDSFromFile(filePath string) ([]models.DeviceService, error) { - defer func() { - if r := recover(); r != nil { - fmt.Println("Error: Invalid Json") - } - }() - file, err := ioutil.ReadFile(filePath) - if err != nil { - return nil, err - } - - var deviceServices []models.DeviceService - - //check if the file contains just one DeviceService - var ds models.DeviceService - err = json.Unmarshal(file, &ds) - if err != nil { - //check if the file contains list of DeviceServices - err = json.Unmarshal(file, &deviceServices) - if err != nil { - return nil, err - } - } else { - deviceServices = append(deviceServices, ds) - } - return deviceServices, nil -} diff --git a/cmd/event/add/add.go b/cmd/event/add/add.go deleted file mode 100644 index 5dc72e44..00000000 --- a/cmd/event/add/add.go +++ /dev/null @@ -1,169 +0,0 @@ -/******************************************************************************* - * Copyright 2020 Dell Inc. - * - * 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 add - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "html/template" - - "github.com/edgexfoundry/go-mod-core-contracts/clients/coredata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/editor" - - "github.com/spf13/cobra" -) - -// EventTemplate is a Go template which is used to generate a JSON representation of an Event. The data associated with -// this template is a modes.Event -// -// This template requires a function 'lastElem' which accepts and index(int) and a slice of Readings and determines if -// the index is the last one in the array. -const EventTemplate = ` -{ - "Device" : "{{.Device}}", - "Created" : {{.Created}}, - "Modified" : {{.Modified}}, - "Origin" : {{.Origin}}, - "Pushed" : {{.Pushed}}{{if .Readings}},{{$readings := .Readings}} - "Readings" : [{{range $index, $reading := .Readings}} - { - "Name" : "{{$reading.Name}}", - "Device": "{{.Device}}", - "Value": "{{$reading.Value}}", - "ValueType": "", - "FloatEncoding": "", - "BinaryValue": "", - "MediaType": "", - "Origin": {{.Origin}}, - "Pushed": {{.Pushed}}, - "Created": {{.Created}}, - "Origin": {{.Origin}}, - "Modified": {{.Modified}} - } {{if not (lastElem $index $readings)}},{{end}}{{end}} - ]{{end}} -}` - -// Global variables that hold information passed in as flags. -var pushed int64 -var origin int64 -var created int64 -var modified int64 -var device string -var numberOfReadings int -var interactiveMode bool - -// NewCommand returns the add event command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - - Use: "add", - Short: "Create an event", - Long: `Create a new event`, - RunE: func(cmd *cobra.Command, args []string) error { - - url := config.Conf.Clients["CoreData"].Url() + clients.ApiEventRoute - newEvent := models.Event{} - populateEvent(&newEvent) - var newEventBytes []byte - var err error - if interactiveMode { - newEventBytes, err = openInteractiveEditor(newEvent) - } else { - newEventBytes, err = json.Marshal(newEvent) - } - - if err != nil { - return err - } - - updatedEvent := models.Event{} - err = json.Unmarshal(newEventBytes, &updatedEvent) - if err != nil { - return errors.New("Unable to create an Event. The provided information is not valid") - } - - client := local.New(url) - ec := coredata.NewEventClient(client) - _, err = ec.Add(cmd.Context(), &newEvent) - if err != nil { - return err - } - - return nil - }, - } - cmd.Flags().BoolVarP(&interactiveMode, editor.InteractiveModeLabel, "i", false, "Open a default editor to customize the Event information") - cmd.Flags().StringVarP(&device, "device", "d", "", "Device to which the Event is associated") - cmd.Flags().Int64VarP(&pushed, "pushed", "p", 0, "Mark the Event as Pushed") - cmd.Flags().Int64VarP(&created, "created", "c", 0, "Created timestamp") - cmd.Flags().Int64VarP(&modified, "modified", "m", 0, "Modified timestamp") - cmd.Flags().Int64VarP(&origin, "origin", "o", 0, "Origin") - cmd.Flags().IntVarP(&numberOfReadings, "readings", "r", 0, "Number of Readings for the Event") - return cmd -} - -// populateEvent adds data to the event that have been passed as CLI flags. -func populateEvent(event *models.Event) { - event.Device = device - event.Pushed = pushed - event.Created = created - event.Modified = modified - event.Origin = origin - if numberOfReadings > 0 { - readings := make([]models.Reading, numberOfReadings) - for i := 0; i < numberOfReadings; i++ { - tempReading := models.Reading{ - Name: fmt.Sprintf("Reading-%d", i), - Value: "Example Value", // This is a required field - } - readings[i] = tempReading - } - event.Readings = readings - } -} - -// openInteractiveEditor opens the users default editor and with a JSON representation of the Event. -func openInteractiveEditor(event models.Event) ([]byte, error) { - funcMap := template.FuncMap{ - "lastElem": isLastElementOfSlice, - } - - eventJsonTemplate, err := template.New("Event").Funcs(funcMap).Parse(EventTemplate) - if err != nil { - return nil, err - } - - buff := bytes.NewBuffer([]byte{}) - err = eventJsonTemplate.Execute(buff, event) - if err != nil { - return nil, err - } - - return editor.CaptureInputFromEditor(buff.Bytes()) -} - -// isLastElementOfSlice is a function which is used in the EventTemplate to determine the last element in a slice of -// Readings. -func isLastElementOfSlice(index int, arr []models.Reading) bool { - return len(arr)-1 == index -} diff --git a/cmd/event/count/count.go b/cmd/event/count/count.go deleted file mode 100644 index 78c88b8b..00000000 --- a/cmd/event/count/count.go +++ /dev/null @@ -1,48 +0,0 @@ -package count - -import ( - "fmt" - - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/formatters" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/coredata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - - "github.com/spf13/cobra" -) - -var device string - -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "count [--device ]", - Short: "Returns the count of core-data events", - Long: `Return a count of the number of events in core data.`, - RunE: countHandler, - } - cmd.Flags().StringVarP(&device, "device", "d", "", "Returns the count of the events generated by device specified by name.") - return cmd -} - -func countHandler(cmd *cobra.Command, args []string) (err error) { - client := coredata.NewEventClient( - local.New(config.Conf.Clients["CoreData"].Url() + clients.ApiEventRoute), - ) - var countNumber int - var template string - if device != "" { - countNumber, err = client.EventCountForDevice(cmd.Context(), device) - template = fmt.Sprintf("Events count generated by device %s: %v", device, countNumber) - } else { - countNumber, err = client.EventCount(cmd.Context()) - template = fmt.Sprintf("Total events count: %v", countNumber) - } - if err != nil { - return err - } - formatter := formatters.NewFormatter(template, nil) - err = formatter.Write(countNumber) - return -} diff --git a/cmd/event/event.go b/cmd/event/event.go deleted file mode 100644 index 1e64ff80..00000000 --- a/cmd/event/event.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 event - -import ( - addevent "github.com/edgexfoundry/edgex-cli/cmd/event/add" - "github.com/edgexfoundry/edgex-cli/cmd/event/count" - listevent "github.com/edgexfoundry/edgex-cli/cmd/event/list" - rmevent "github.com/edgexfoundry/edgex-cli/cmd/event/rm" - "github.com/edgexfoundry/edgex-cli/cmd/event/scrub" - - "github.com/spf13/cobra" -) - -// NewCommand returns the device command of type cobra.Command -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "event", - Short: "Event command", - Long: `Actions related to device-generated events.`, - } - cmd.AddCommand(rmevent.NewCommand()) - cmd.AddCommand(addevent.NewCommand()) - cmd.AddCommand(listevent.NewCommand()) - cmd.AddCommand(count.NewCommand()) - cmd.AddCommand(scrub.NewCommand()) - return cmd -} diff --git a/cmd/event/list/list.go b/cmd/event/list/list.go deleted file mode 100644 index e4f219bf..00000000 --- a/cmd/event/list/list.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 list - -import ( - "context" - "html/template" - - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/formatters" - "github.com/edgexfoundry/edgex-cli/pkg/utils" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/coredata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -const eventTemplate = "Event ID\tDevice\tOrigin\tCreated\tModified\n" + - "{{range .}}" + - "{{.ID}}\t{{.Device}}\t{{.Origin}}\t{{DisplayDuration .Created}}\t{{DisplayDuration .Modified}}\n" + - "{{end}}" - -var limit int -var device string - -// NewCommand returns the list device command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "A list of Events", - Long: `Return list of Events.`, - Args: cobra.MaximumNArgs(1), - RunE: listHandler, - } - cmd.Flags().IntVarP(&limit, "limit", "l", 50, "Limit number of results") - cmd.Flags().StringVarP(&device, "device", "d", "", "Events generated by specific device with given name.") - return cmd -} - -func listHandler(cmd *cobra.Command, args []string) (err error) { - client := coredata.NewEventClient( - local.New(config.Conf.Clients["CoreData"].Url() + clients.ApiEventRoute), - ) - - var events []models.Event - if device != "" { - events, err = client.EventsForDevice(cmd.Context(), device, limit) - } else if len(args) > 0 { - events, err = getEvent(cmd.Context(), client, args[0]) - } else { - events, err = client.Events(cmd.Context()) - } - if err != nil { - return err - } - - formatter := formatters.NewFormatter(eventTemplate, template.FuncMap{"DisplayDuration": utils.DisplayDuration}) - err = formatter.Write(events) - return -} - -func getEvent(ctx context.Context, client coredata.EventClient, id string) ([]models.Event, error) { - event, err := client.Event(ctx, id) - if err != nil { - return nil, err - } - return []models.Event{event}, nil -} diff --git a/cmd/event/rm/rm.go b/cmd/event/rm/rm.go deleted file mode 100644 index d4795eb4..00000000 --- a/cmd/event/rm/rm.go +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 rm - -import ( - "context" - "errors" - "fmt" - "strconv" - - "github.com/edgexfoundry/edgex-cli/cmd/notification/rm" - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/utils" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/coredata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - - "github.com/spf13/cobra" -) - -var age string -var unit string -var device string - -const errMsg = "events could be removed by one criteria: by id(s), by device name or by age. " + - "please provide id(s) as argument(s) or provide one flag (--device/--age)" - -// NewCommand return rm events command -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "rm [ id | --device]", - Short: "Removes event by its id or removes all events generated by given device", - Long: `Removes event by its id or removes all the events generated by a device.`, - RunE: eventHandler, - } - cmd.Flags().StringVarP(&device, "device", "d", "", "Delete Events by given device name") - cmd.Flags().StringVarP(&age, "age", "a", "", "Event age (by default in milliseconds). To customize the time unit use --unit flag") - cmd.Flags().StringVar(&unit, "unit", "ms", rm.TimeUnitUsage) - return cmd -} - -func eventHandler(cmd *cobra.Command, args []string) (err error) { - if err = validate(args); err != nil { - return err - } - dc := coredata.NewEventClient(local.New(config.Conf.Clients["CoreData"].Url() + clients.ApiEventRoute)) - if age != "" { - return deleteOld(cmd.Context(), dc) - } else if len(args) != 0 { - return deleteByIds(cmd.Context(), dc, args) - } - return deleteForDevice(cmd.Context(), dc) -} - -func deleteOld(ctx context.Context, dc coredata.EventClient) error { - ageInt, err := strconv.ParseInt(age, 10, 64) - if err != nil { - return err - } - if _, present := utils.TimeUnitsMap[unit]; !present { - return errors.New("List of possible values:\n" + utils.TimeUnitDescriptions) - } - ageMilliseconds := utils.ConvertAgeToMillisecond(unit, ageInt) - err = dc.DeleteOld(ctx, int(ageMilliseconds)) - if err == nil { - fmt.Printf("Removed: %v %v\n", ageInt, unit) - } - return err -} - -func deleteForDevice(ctx context.Context, dc coredata.EventClient) (err error) { - err = dc.DeleteForDevice(ctx, device) - if err == nil { - fmt.Printf("Events generated by device `%s` have been removed\n", device) - } - return -} - -func validate(args []string) error { - if len(args) == 0 && device == "" && age == "" { - return errors.New(errMsg) - } - if len(args) != 0 && device == "" && age == "" || - device != "" && len(args) == 0 && age == "" || - age != "" && len(args) == 0 && device == "" { - return nil - } - return errors.New(errMsg) -} - -func deleteByIds(ctx context.Context, dc coredata.EventClient, eventIds []string) error { - for _, eventId := range eventIds { - err := dc.Delete(ctx, eventId) - if err == nil { - fmt.Printf("Event with id %s removed\n", eventId) - } else { - fmt.Printf("Error: %s \n", err) - } - } - return nil -} diff --git a/cmd/event/scrub/scrub.go b/cmd/event/scrub/scrub.go deleted file mode 100644 index af01c5b0..00000000 --- a/cmd/event/scrub/scrub.go +++ /dev/null @@ -1,56 +0,0 @@ -package scrub - -import ( - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - "github.com/edgexfoundry/edgex-cli/pkg/confirmation" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - - "github.com/spf13/cobra" -) - -var all bool - -const scrubPushedConfirmMsg = "You are trying to remove all pushed events and their associated readings. This cannot be undone. Are you sure you want to proceed? [y/n]" -const scrubAllConfirmMsg = "You are trying to remove all events and their associated readings from the database. This cannot be undone. Are you sure you want to proceed?: [y/n]" - -// NewCommand return scrub events command -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "scrub", - Short: "Remove all (pushed) events and their associated readings [USE WITH CAUTION]", - Long: `[USE WITH CAUTION] The effect of this command is irreversible. -It removes all pushed events and their associated. -When used with "--all" flag, it removes all readings and events from the database`, - RunE: scrubHandler, - } - cmd.Flags().BoolP("all", "a", false, "Removes all readings and events from the database [USE WITH CAUTION]") - return cmd -} - -func scrubHandler(cmd *cobra.Command, args []string) (err error) { - all, err1 := cmd.Flags().GetBool("all") - if err1 != nil { - return err1 - } - - url := config.Conf.Clients["CoreData"].Url() + clients.ApiEventRoute + "/scrub" - confirmMsg := scrubPushedConfirmMsg - if all { - confirmMsg = scrubAllConfirmMsg - url = config.Conf.Clients["CoreData"].Url() + clients.ApiEventRoute + "/scruball" - } - - // asking user to confirm the scrub command - if !confirmation.NewCustom(confirmMsg, "").Confirm() { - return - } - - err = request.Delete(cmd.Context(), url) - if err != nil { - return err - } - - return -} diff --git a/cmd/interval/add/add.go b/cmd/interval/add/add.go deleted file mode 100644 index 09e65e40..00000000 --- a/cmd/interval/add/add.go +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 add - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "io/ioutil" - - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/editor" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/scheduler" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -var interactiveMode bool -var name string -var start string -var end string -var cron string -var runOnce bool -var frequency string - -var file string - -const intervalTempl = `[{{range $interval := .}}` + BaseIntervalTemp + - `{{end}}]` - -const BaseIntervalTemp = `{ - "Name" : "{{.Name}}", - "start" : "{{.Start}}", - "end" : "{{.End}}", - "cron" : "{{.Cron}}", - "runOnce" : {{.RunOnce}}, - "frequency" : "{{.Frequency}}" -} -` - -const IntervalStartUsage = "Interval Start time in format YYYYMMDD'T'HHmmss." -const IntervalEndUsage = "Interval End time in format YYYYMMDD'T'HHmmss." -const CronIntervalUsage = "Styled regular expression indicating " + - "how often the action under interval should occur. Use either runOnce, frequency or cron and not all." -const RunOnceIntervalUsage = "RunOnce - boolean indicating that this interval " + - "runs one time - at the time indicated by the start." -const FrequencyIntervalUsage = "Interval frequency - indicates how frequent the " + - "event should occur. It is a sequence of decimal numbers, each with optional fraction and a unit suffix, " + - "such as \"300ms\", \"1.5h\" or \"2h45m\" or \"1h15m30s10us9ns\".\n" + - "// Valid time units are: " + - "\"ns\" (nanoseconds), " + - "\"us\" (or \"µs\" for microseconds), " + - "\"ms\"(for milliseconds), " + - "\"s\"(seconds), " + - "\"m\"(minutes), " + - "\"h\"(hours)" - -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "add", - Short: "Add interval", - Long: `Create interval(s) described in a given JSON file or use the interactive mode with additional flags.`, - RunE: newIntervalHandler, - } - cmd.Flags().BoolVarP(&interactiveMode, editor.InteractiveModeLabel, "i", false, "Open a default "+ - "editor to customize the Interval information") - cmd.Flags().StringVarP(&name, "name", "n", "", "Interval name") - cmd.Flags().StringVarP(&start, "start", "s", "", IntervalStartUsage) - cmd.Flags().StringVarP(&end, "end", "e", "", IntervalEndUsage) - cmd.Flags().StringVarP(&cron, "cron", "c", "", CronIntervalUsage) - cmd.Flags().BoolVar(&runOnce, "runOnce", false, RunOnceIntervalUsage) - cmd.Flags().StringVar(&frequency, "frequency", "", FrequencyIntervalUsage) - - cmd.Flags().StringVarP(&file, "file", "f", "", "Json file containing interval(s) configuration") - return cmd -} - -func newIntervalHandler(cmd *cobra.Command, args []string) error { - if interactiveMode && file != "" { - return errors.New("you could work with interactive mode or file, but not with both") - } - - if file != "" { - return createIntervalsFromFile(cmd.Context()) - } - - intervals, err := parseInterval(interactiveMode) - if err != nil { - return err - } - - client := scheduler.NewIntervalClient( - local.New(config.Conf.Clients["Scheduler"].Url() + clients.ApiIntervalRoute), - ) - for _, interval := range intervals { - _, err = client.Add(cmd.Context(), &interval) - if err != nil { - return err - } - } - return nil -} - -func populateInterval(intervals *[]models.Interval) { - i := models.Interval{} - i.Name = name - i.Start = start - i.End = end - i.Cron = cron - i.RunOnce = runOnce - i.Frequency = frequency - *intervals = append(*intervals, i) -} - -func createIntervalsFromFile(ctx context.Context) error { - intervals, err := loadIntervalFromFile(file) - if err != nil { - return err - } - - client := scheduler.NewIntervalClient( - local.New(config.Conf.Clients["Scheduler"].Url() + clients.ApiIntervalRoute), - ) - for _, i := range intervals { - _, err = client.Add(ctx, &i) - if err != nil { - fmt.Println("Error: ", err.Error()) - } - } - return nil -} - -func parseInterval(interactiveMode bool) ([]models.Interval, error) { - //parse Intervals based on interactive mode and the other provided flags - var err error - var intervals []models.Interval - populateInterval(&intervals) - - var updatedIntervalBytes []byte - if interactiveMode { - updatedIntervalBytes, err = editor.OpenInteractiveEditor(intervals, intervalTempl, nil) - } else { - updatedIntervalBytes, err = json.Marshal(intervals) - } - if err != nil { - return nil, err - } - - var updatedIntervals []models.Interval - err = json.Unmarshal(updatedIntervalBytes, &updatedIntervals) - if err != nil { - return nil, errors.New("Unable to execute the command. The provided information is invalid: " + err.Error()) - } - return updatedIntervals, err -} - -//loadIntervalFromFile could read a file that contains single Interval or list of Intervals -func loadIntervalFromFile(filePath string) ([]models.Interval, error) { - defer func() { - if r := recover(); r != nil { - fmt.Println("Error: Invalid Json") - } - }() - file, err := ioutil.ReadFile(filePath) - if err != nil { - return nil, err - } - - var intervals []models.Interval - - //check if the file contains just one Interval - var i models.Interval - err = json.Unmarshal(file, &i) - if err != nil { - //check if the file contains list of Interval - err = json.Unmarshal(file, &intervals) - if err != nil { - return nil, err - } - } else { - intervals = append(intervals, i) - } - return intervals, nil -} diff --git a/cmd/interval/interval.go b/cmd/interval/interval.go deleted file mode 100644 index a2201fa8..00000000 --- a/cmd/interval/interval.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 interval - -import ( - "github.com/edgexfoundry/edgex-cli/cmd/interval/add" - "github.com/edgexfoundry/edgex-cli/cmd/interval/list" - "github.com/edgexfoundry/edgex-cli/cmd/interval/rm" - "github.com/edgexfoundry/edgex-cli/cmd/interval/update" - - "github.com/spf13/cobra" -) - -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "interval", - Short: "Interval command", - Long: `Actions related to intervals (scheduler).`, - } - cmd.AddCommand(add.NewCommand()) - cmd.AddCommand(rm.NewCommand()) - cmd.AddCommand(update.NewCommand()) - cmd.AddCommand(list.NewCommand()) - return cmd -} diff --git a/cmd/interval/list/list.go b/cmd/interval/list/list.go deleted file mode 100644 index 7514bce9..00000000 --- a/cmd/interval/list/list.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 list - -import ( - "context" - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/formatters" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/scheduler" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -const intervalTemplate = "Interval ID\tName\tStart\tEnd\tFrequency\tCron\tRunOnce\n" + - "{{range .}}" + - "{{.ID}}\t{{.Name}}\t{{.Start}}\t{{.End}}\t{{.Frequency}}\t{{.Cron}}\t{{.RunOnce}}\n" + - "{{end}}" - -func listHandler(cmd *cobra.Command, args []string) (err error) { - client := scheduler.NewIntervalClient( - local.New(config.Conf.Clients["Scheduler"].Url() + clients.ApiIntervalRoute), - ) - - var intervals []models.Interval - if len(args) == 0 { - intervals, err = client.Intervals(cmd.Context()) - } else { - intervals, err = getInterval(cmd.Context(), client, args[0]) - } - if err != nil { - return err - } - - formatter := formatters.NewFormatter(intervalTemplate, nil) - err = formatter.Write(intervals) - return -} - -func getInterval(ctx context.Context, client scheduler.IntervalClient, id string) ([]models.Interval, error) { - interval, err := client.Interval(ctx, id) - if err != nil { - return nil, err - } - return []models.Interval{interval}, nil -} - -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "A list of all intervals", - Long: `Return a list of all intervals or retrieve an interval by id`, - Args: cobra.MaximumNArgs(1), - RunE: listHandler, - } - return cmd -} diff --git a/cmd/interval/rm/rm.go b/cmd/interval/rm/rm.go deleted file mode 100644 index b92b387e..00000000 --- a/cmd/interval/rm/rm.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 rm - -import ( - "errors" - "fmt" - - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/scheduler" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - - "github.com/spf13/cobra" -) - -var name string - -func removeIntervalHandler(cmd *cobra.Command, args []string) (err error) { - if len(args) == 0 && name == "" { - return errors.New("no device id/name provided.\n") - } - - sc := scheduler.NewIntervalClient( - local.New(config.Conf.Clients["Scheduler"].Url() + clients.ApiIntervalRoute), - ) - var deletedBy string - if name != "" { - deletedBy = name - err = sc.DeleteByName(cmd.Context(), name) - if err != nil { - return - } - fmt.Printf("Removed: %s\n", deletedBy) - } else if len(args[0]) != 0 { - return request.DeleteByIds(cmd.Context(), sc, args) - } - return nil -} - -// NewCommand returns rm interval command -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "rm [ name | id]", - Short: "Removes interval by name or id", - Long: `Removes an interval given its name or id.`, - //Args: cobra.ExactValidArgs(1), - RunE: removeIntervalHandler, - } - cmd.Flags().StringVarP(&name, "name", "n", "", "Delete interval by name") - return cmd -} diff --git a/cmd/interval/update/update.go b/cmd/interval/update/update.go deleted file mode 100644 index 4c27119d..00000000 --- a/cmd/interval/update/update.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 update - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "html/template" - "io/ioutil" - - "github.com/edgexfoundry/edgex-cli/cmd/interval/add" - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/editor" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/scheduler" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -var name string -var file string - -// NewCommand returns the update Interval command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "update", - Short: "Update interval", - Long: "Update interval(s) described in the given JSON file or use the interactive mode enabled by providing " + - "name of existing interval. \n" + - "Parameters description: \n" + - fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n", add.IntervalStartUsage, add.IntervalEndUsage, add.RunOnceIntervalUsage, add.CronIntervalUsage, add.FrequencyIntervalUsage), - RunE: intervalHandler, - } - cmd.Flags().StringVarP(&name, "name", "n", "", "Interval name. Interval with given name is loaded into default editor, ready to be customized") - cmd.Flags().StringVarP(&file, "file", "f", "", "Json file containing interval configuration to update") - return cmd -} - -func intervalHandler(cmd *cobra.Command, args []string) error { - if name != "" && file != "" { - return errors.New("Interval could be updated by providing a file, or by specifying interval name to be updated using interactive mode. ") - } - - if name == "" && file == "" { - return errors.New("Please, provide file or interval name ") - } - - if file != "" { - return updateIntervalFromFile(cmd.Context()) - } - - updatedInterval, err := parseInterval(cmd.Context(), name) - if err != nil { - return err - } - - client := local.New(config.Conf.Clients["Scheduler"].Url() + clients.ApiIntervalRoute) - err = scheduler.NewIntervalClient(client).Update(cmd.Context(), updatedInterval) - if err != nil { - return err - } - - return nil -} - -//parseInterval loads a Interval to be updated and open a default editor for customization -func parseInterval(ctx context.Context, name string) (models.Interval, error) { - var err error - client := local.New(config.Conf.Clients["Scheduler"].Url() + clients.ApiIntervalRoute) - i, err := scheduler.NewIntervalClient(client).IntervalForName(ctx, name) - if err != nil { - return models.Interval{}, err - } - - updatedIntervalBytes, err := editor.OpenInteractiveEditor(i, add.BaseIntervalTemp, template.FuncMap{ - "lastElem": editor.IsLastElementOfSlice, - }) - - if err != nil { - return models.Interval{}, err - } - var updatedInterval models.Interval - err = json.Unmarshal(updatedIntervalBytes, &updatedInterval) - if err != nil { - return models.Interval{}, errors.New("Unable to execute the command. The provided information is invalid: " + err.Error()) - } - return updatedInterval, err -} - -func updateIntervalFromFile(ctx context.Context) error { - intervals, err := LoadDSFromFile(file) - if err != nil { - return err - } - - client := local.New(config.Conf.Clients["Scheduler"].Url() + clients.ApiIntervalRoute) - for _, ds := range intervals { - err = scheduler.NewIntervalClient(client).Update(ctx, ds) - if err != nil { - fmt.Println("Error: ", err.Error()) - } - } - return nil -} - -//loadJsonFile could read a file that contains single Interval or list of Intervals -func LoadDSFromFile(filePath string) ([]models.Interval, error) { - defer func() { - if r := recover(); r != nil { - fmt.Println("Error: Invalid Json") - } - }() - file, err := ioutil.ReadFile(filePath) - if err != nil { - return nil, err - } - - var intervals []models.Interval - - //check if the file contains just one Interval - var ds models.Interval - err = json.Unmarshal(file, &ds) - if err != nil { - //check if the file contains list of Interval - err = json.Unmarshal(file, &intervals) - if err != nil { - return nil, err - } - } else { - intervals = append(intervals, ds) - } - return intervals, nil -} diff --git a/cmd/notification/add/add.go b/cmd/notification/add/add.go deleted file mode 100644 index 852cfbd6..00000000 --- a/cmd/notification/add/add.go +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 add - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "html/template" - "io/ioutil" - "strings" - - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - "github.com/edgexfoundry/edgex-cli/pkg/editor" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -var categories = []string{models.Security, models.Hwhealth, models.Swhealth} -var severities = []string{models.Normal, models.Critical} -var statuses = []string{models.New, models.Processed, models.Escalated} - -const NotificationsTemplate = `[{{range $d := .}}` + NotificationTemplate + `{{end}}]` -const NotificationTemplate = `{ - "Slug": "{{.Slug}}", - "Sender" : "{{.Sender}}", - "Category" : "{{.Category}}", - "Severity" : "{{.Severity}}", - "Content" : "{{.Content}}", - "Description" : "{{.Description}}", - "ContentType" : "{{.ContentType}}", - "Status" : "{{.Status}}", - "Labels" : [ - {{- $labelsLenght := len .Labels}} - {{- range $idx, $l := .Labels}} - "{{$l}}" {{if not (lastElem $idx $labelsLenght)}},{{end}} - {{- end}} - ] - }` - -var interactiveMode bool -var slug string -var sender string -var category string -var severity string -var content string -var description string -var labels string -var contentType string -var status string - -var file string - -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "add", - Short: "Add notification", - Long: `Create notifications described in a given JSON file or use the interactive mode with additional flags.`, - RunE: addNotificationHandler, - } - cmd.Flags().BoolVarP(&interactiveMode, editor.InteractiveModeLabel, "i", false, "Open a default editor to customize the Notification information") - cmd.Flags().StringVarP(&slug, "slug", "s", "", "Slug") - cmd.Flags().StringVar(&sender, "sender", "", "Sender") - cmd.Flags().StringVarP(&category, "category", "c", "", fmt.Sprintf("Status\nValues: [%s]", strings.Join(categories, ","))) - cmd.Flags().StringVar(&severity, "severity", "", fmt.Sprintf("Status\nValues: [%s]", strings.Join(severities, ","))) - cmd.Flags().StringVar(&content, "content", "", "Content") - cmd.Flags().StringVarP(&description, "description", "d", "", "Description") - cmd.Flags().StringVarP(&labels, "labels", "l", "", "Comma separated string") - cmd.Flags().StringVar(&contentType, "contentType", "", "ContentType") - cmd.Flags().StringVar(&status, "status", "", fmt.Sprintf("Status\nValues: [%s]", strings.Join(statuses, ","))) - - cmd.Flags().StringVarP(&file, "file", "f", "", "File containing notification configuration in json format") - return cmd -} - -func addNotificationHandler(cmd *cobra.Command, args []string) error { - if interactiveMode && file != "" { - return errors.New("you could work with interactive mode or file, but not with both") - } - - if file != "" { - return createNotificationsFromFile(cmd.Context()) - } - - notifications, err := parseNotification(interactiveMode) - if err != nil { - return err - } - - createNotification(cmd.Context(), notifications) - return nil -} - -func parseNotification(interactiveMode bool) ([]models.Notification, error) { - //parse Notification based on interactive mode and the other provided flags - var err error - var notifications []models.Notification - populateNotification(¬ifications) - - var updatedNotificationBytes []byte - if interactiveMode { - updatedNotificationBytes, err = editor.OpenInteractiveEditor(notifications, NotificationsTemplate, template.FuncMap{ - "lastElem": editor.IsLastElementOfSlice, - }) - } else { - updatedNotificationBytes, err = json.Marshal(notifications) - } - if err != nil { - return nil, err - } - var updatedNotification []models.Notification - err = json.Unmarshal(updatedNotificationBytes, &updatedNotification) - if err != nil { - return nil, errors.New("Unable to execute the command. The provided information is not valid: " + err.Error()) - } - return updatedNotification, err -} - -func populateNotification(notifications *[]models.Notification) { - i := models.Notification{} - i.Slug = slug - i.Sender = sender - i.Category = models.NotificationsCategory(strings.ToUpper(category)) - i.Status = models.NotificationsStatus(strings.ToUpper(status)) - i.Severity = models.NotificationsSeverity(strings.ToUpper(severity)) - i.Content = content - i.Description = description - ls := strings.Split(labels, ",") - for i := range ls { - ls[i] = strings.TrimSpace(ls[i]) - } - i.Labels = ls - i.ContentType = contentType - *notifications = append(*notifications, i) -} - -func createNotificationsFromFile(ctx context.Context) error { - notifications, err := LoadNotificationFromFile(file) - if err != nil { - return err - } - - createNotification(ctx, notifications) - return nil -} - -//LoadNotificationFromFile could read a file that contains single Notification or list of Notifications -func LoadNotificationFromFile(filePath string) ([]models.Notification, error) { - defer func() { - if r := recover(); r != nil { - fmt.Println("Error: Invalid Json") - } - }() - file, err := ioutil.ReadFile(filePath) - if err != nil { - return nil, err - } - - var notifications []models.Notification - - //check if the file contains just one Notification - var n models.Notification - err = json.Unmarshal(file, &n) - if err != nil { - //check if the file contains list of Notifications - err = json.Unmarshal(file, ¬ifications) - if err != nil { - return nil, err - } - } else { - notifications = append(notifications, n) - } - return notifications, nil -} - -func createNotification(ctx context.Context, notifications []models.Notification) { - url := config.Conf.Clients["Notification"].Url() + clients.ApiNotificationRoute - for _, n := range notifications { - request.Post(ctx, url, n) - } -} diff --git a/cmd/notification/list/list.go b/cmd/notification/list/list.go deleted file mode 100644 index 2d345e69..00000000 --- a/cmd/notification/list/list.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 list - -import ( - "html/template" - "strconv" - - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - "github.com/edgexfoundry/edgex-cli/pkg/formatters" - "github.com/edgexfoundry/edgex-cli/pkg/utils" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -// See https://github.com/edgexfoundry/edgex-go/blob/master/api/openapi/v1/support-notifications.yaml -var limit int32 -var start string -var end string -var slug string -var labels string -var sender string -var onlyNew bool - -const notificationTemplate = "Notification ID\tSlug\tSender\tStatus\tSeverity\tCategory\tContent\tLabels\tCreated\tModified\n" + - "{{range .}}" + - "{{.ID}}\t{{.Slug}}\t{{.Sender}}\t{{.Status}}\t{{.Severity}}\t{{.Category}}\t{{.Content}}\t{{.Labels}}\t{{DisplayDuration .Created}}\t{{DisplayDuration .Modified}}\n" + - "{{end}}" - -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "A list of all notifications", - Long: `Return a list of all notifications filtered by slug/sender/labels/start/end/new and limited by limit. Defaults to new notifications.`, - Args: cobra.MaximumNArgs(3), - RunE: listHandler, - FParseErrWhitelist: cobra.FParseErrWhitelist{}, - } - - cmd.Flags().Int32VarP(&limit, "limit", "l", 50, "Limit number of results") - cmd.Flags().StringVar(&start, "start", "", "Filter results by start date") - cmd.Flags().StringVar(&end, "end", "", "Filter results by end date") - cmd.Flags().StringVar(&slug, "slug", "", "Filter results by slug") - cmd.Flags().StringVar(&sender, "sender", "", "Filter results by sender") - cmd.Flags().StringVar(&labels, "labels", "", "Filter results by labels") - cmd.Flags().BoolVar(&onlyNew, "new", false, "Filter results by new") - - return cmd -} - -func listHandler(cmd *cobra.Command, args []string) (err error) { - var url string - multi := true - url = config.Conf.Clients["Notification"].Url() + clients.ApiNotificationRoute - - // For slug and id based retrieval, response will be a single item at most - if slug != "" { - url += "/slug/" + slug - multi = false // no limit with slug - } else if len(args) == 1 { - // notification id provided - multi = false - url = url + "/" + args[0] - } else if onlyNew { - url += "/new" - } else if labels != "" { - url += "/labels/" + labels - } else if sender != "" { - url += "/sender/" + sender - } else if start != "" { - url += "/start/" + start - // end could also be specified - if end != "" { - url += "/end/" + end - } - } else if end != "" { - url += "/end/" + end - } else { // default behavior whgen no flags specified - url += "/new" - } - - if multi { - url = url + "/" + strconv.FormatInt(int64(limit), 10) - } - var notifications []models.Notification - var aNotification models.Notification - if !multi { - err = request.Get(cmd.Context(), url, &aNotification) - } else { - err = request.Get(cmd.Context(), url, ¬ifications) - } - if err != nil { - return - } - if !multi { // to use the same display code - notifications = []models.Notification{aNotification} - } - formatter := formatters.NewFormatter(notificationTemplate, template.FuncMap{"DisplayDuration": utils.DisplayDuration}) - err = formatter.Write(notifications) - return -} diff --git a/cmd/notification/notification.go b/cmd/notification/notification.go deleted file mode 100644 index 06ffd5b2..00000000 --- a/cmd/notification/notification.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 notification - -import ( - addnotification "github.com/edgexfoundry/edgex-cli/cmd/notification/add" - listnotification "github.com/edgexfoundry/edgex-cli/cmd/notification/list" - rmdnotification "github.com/edgexfoundry/edgex-cli/cmd/notification/rm" - - "github.com/spf13/cobra" -) - -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "notification", - Short: "Notification command", - Long: `Actions related to notifications.`, - } - cmd.AddCommand(rmdnotification.NewCommand()) - cmd.AddCommand(addnotification.NewCommand()) - cmd.AddCommand(listnotification.NewCommand()) - return cmd -} diff --git a/cmd/notification/rm/rm.go b/cmd/notification/rm/rm.go deleted file mode 100644 index a6832fae..00000000 --- a/cmd/notification/rm/rm.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 rm - -import ( - "errors" - "fmt" - "strconv" - - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - "github.com/edgexfoundry/edgex-cli/pkg/utils" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - - "github.com/spf13/cobra" -) - -const TimeUnitUsage = "Specify the time unit used with the --age flag\nList of possible values:\n" + utils.TimeUnitDescriptions - -var age string -var unit string -var slug string - -// NewCommand returns the rm command of type cobra.Command -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "rm [--slug | --age]", - Short: "Removes notification by slug or age", - Long: "Removes notifications by slug or age (the current notifications timestamp minus their last modification timestamp should be greater than the age parameter)", - RunE: removeNotificationHandler, - } - cmd.Flags().StringVarP(&age, "age", "a", "", "Notification age (by default in milliseconds). To customize the unit use --unit flag") - cmd.Flags().StringVarP(&slug, "slug", "s", "", "Meaningful, case insensitive identifier") - cmd.Flags().StringVar(&unit, "unit", "ms", TimeUnitUsage) - return cmd -} - -func removeNotificationHandler(cmd *cobra.Command, args []string) (err error) { - if age == "" && slug == "" { - return errors.New("at least one flag should be provided") - } else if age != "" && slug != "" { - return errors.New("age or slug flag should be provided, not both") - } - - url, deletedBy, err := constructUrl() - if err != nil { - return err - } - return request.DeletePrt(cmd.Context(), url, deletedBy) -} - -func constructUrl() (string, string, error) { - baseUrl := config.Conf.Clients["Notification"].Url() + clients.ApiNotificationRoute - url := fmt.Sprintf("%s/slug/%s", baseUrl, slug) - if age != "" { - if _, present := utils.TimeUnitsMap[unit]; !present { - return "", "", errors.New("List of possible values:\n" + utils.TimeUnitDescriptions) - } - ageInt, err := strconv.ParseInt(age, 10, 64) - if err != nil { - return "", "", err - } - ageMilliseconds := utils.ConvertAgeToMillisecond(unit, ageInt) - return fmt.Sprintf("%s/age/%v", baseUrl, ageMilliseconds), age + unit, nil - } - return url, slug, nil -} diff --git a/cmd/profile/add/add.go b/cmd/profile/add/add.go deleted file mode 100644 index e0b6ac6b..00000000 --- a/cmd/profile/add/add.go +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright © 2020 VMware, INC -// -// 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 add - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "gopkg.in/yaml.v2" - "html/template" - "io/ioutil" - "path/filepath" - "strings" - - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/editor" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/metadata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -const ProfilesTemplate = `[{{range $d := .}}` + ProfileTemplate + `{{end}}]` - -const ProfileTemplate = `{ - "Description": "{{.Description}}", - "Name" : "{{.Name}}", - "Manufacturer" : "{{.Manufacturer}}", - "Model" : "{{.Model}}", - "Labels" : [ - {{- $labelsLenght := len .Labels}} - {{- range $idx, $l := .Labels}} - "{{$l}}" {{if not (lastElem $idx $labelsLenght)}},{{end}} - {{- end}} - ], - "DeviceResources": {{if .DeviceResources}}{{EscapeHTML .DeviceResources}}{{end}} {{if not .DeviceResources}}[]{{end}}, - "DeviceCommands": {{if .DeviceCommands}}{{EscapeHTML .DeviceCommands}}{{end}} {{if not .DeviceCommands}}[]{{end}}, - "CoreCommands": {{if .CoreCommands}}{{EscapeHTML .CoreCommands}}{{end}} {{if not .CoreCommands}}[]{{end}} - }` - -var interactiveMode bool -var file string - -var name string -var description string -var manufacturer string -var model string -var labels string - -// NewCommand returns the update device profile command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "add", - Short: "Add profiles", - Long: `Create device profiles described in a given JSON file or use the interactive mode with additional flags.`, - RunE: handler, - } - cmd.Flags().BoolVarP(&interactiveMode, editor.InteractiveModeLabel, "i", false, "Open a default editor to customize the Event information") - cmd.Flags().StringVarP(&name, "name", "n", "", "Name") - cmd.Flags().StringVarP(&description, "description", "d", "", "Description") - cmd.Flags().StringVar(&manufacturer, "manufacturer", "", "Manufacturer") - cmd.Flags().StringVar(&model, "model", "", "Model") - cmd.Flags().StringVar(&labels, "labels", "", "Comma separated strings") - - cmd.Flags().StringVarP(&file, "file", "f", "", "File containing profile configuration in json format") - return cmd -} - -func handler(cmd *cobra.Command, args []string) error { - if interactiveMode && file != "" { - return errors.New("you could work with interactive mode or file, but not with both") - } - - if file != "" { - return createProfilesFromFile(cmd.Context()) - } - - profiles, err := parseProfile(interactiveMode) - if err != nil { - return err - } - - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceProfileRoute) - for _, p := range profiles { - _, err = metadata.NewDeviceProfileClient(client).Add(cmd.Context(), &p) - if err != nil { - return err - } - } - - return nil -} - -func createProfilesFromFile(ctx context.Context) error { - profiles, err := LoadFromFile(file) - if err != nil { - return err - } - - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceProfileRoute) - for _, d := range profiles { - _, err = metadata.NewDeviceProfileClient(client).Add(ctx, &d) - if err != nil { - fmt.Println("Error: ", err.Error()) - } - } - return nil -} - -func parseProfile(interactiveMode bool) ([]models.DeviceProfile, error) { - //parse DeviceProfile based on interactive mode and the other provided flags - var err error - var profiles []models.DeviceProfile - populateProfile(&profiles) - - var updatedProfilesBytes []byte - if interactiveMode { - updatedProfilesBytes, err = editor.OpenInteractiveEditor(profiles, ProfilesTemplate, template.FuncMap{ - "inc": func(i int) int { - return i + 1 - }, - "lastElem": editor.IsLastElementOfSlice, - "EscapeHTML": editor.EscapeHTML, - }) - } - if err != nil { - return nil, err - } - - var updatedProfiles []models.DeviceProfile - err = json.Unmarshal(updatedProfilesBytes, &updatedProfiles) - if err != nil { - return nil, errors.New("Unable to execute the command. The provided information is not valid:" + err.Error()) - } - return updatedProfiles, err -} - -func populateProfile(profiles *[]models.DeviceProfile) { - d := models.DeviceProfile{} - d.Name = name - d.Description = description - d.Model = model - d.Manufacturer = manufacturer - ls := strings.Split(labels, ",") - for i := range ls { - ls[i] = strings.TrimSpace(ls[i]) - } - d.Labels = ls - *profiles = append(*profiles, d) -} - -//LoadFromFile could read a file (json/yaml) that contains single DeviceProfile or list of DeviceProfile -func LoadFromFile(fPath string) ([]models.DeviceProfile, error) { - defer func() { - if r := recover(); r != nil { - fmt.Println("Error: Invalid Json/Yaml") - } - }() - file, err := ioutil.ReadFile(fPath) - if err != nil { - return nil, err - } - - var profiles []models.DeviceProfile - fExtension := strings.ToLower(filepath.Ext(fPath)) - err = errors.New("supported file format are yaml and json") - if fExtension == ".yaml" || fExtension == ".yml" { - err = unmarshalYaml(file, &profiles) - } - - if fExtension == ".json" { - err = unmarshalJSON(file, &profiles) - } - return profiles, err -} - -//unmarshalJSON checks if the file contains just one Device Profile or list of Device Profiles in json format -func unmarshalJSON(file []byte, profiles *[]models.DeviceProfile) error { - var p models.DeviceProfile - var err error - //check if the file contains a Device Profile in Json format - if err = json.Unmarshal(file, &p); err != nil { - //check if the file contains list of Device Profiles in Json format - if err = json.Unmarshal(file, profiles); err != nil { - return err - } - } else { - *profiles = append(*profiles, p) - } - return nil -} - -//unmarshalYaml checks if the file contains just one Device Profile or list of Device Profiles in yaml format -func unmarshalYaml(file []byte, profiles *[]models.DeviceProfile) error { - var p models.DeviceProfile - var err error - //Then check if the file contains a Device Profile in Yaml format - if err = yaml.Unmarshal(file, &p); err != nil { - //Then check if the file contains list of Device Profiles in Yaml format - if err = yaml.Unmarshal(file, profiles); err != nil { - return err - } - } else { - *profiles = append(*profiles, p) - } - return nil -} diff --git a/cmd/profile/list/list.go b/cmd/profile/list/list.go deleted file mode 100644 index 56807ffd..00000000 --- a/cmd/profile/list/list.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 list - -import ( - "html/template" - - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/formatters" - "github.com/edgexfoundry/edgex-cli/pkg/utils" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/metadata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - - "github.com/spf13/cobra" -) - -const profileTemplate = "Profile ID\tProfile Name\tManufacturer\tModel\tCreated\tModified\n" + - "{{range .}}" + - "{{.Id}}\t{{.Name}}\t{{.Manufacturer}}\t{{.Model}}\t{{DisplayDuration .Created}}\t{{DisplayDuration .Modified}}\n" + - "{{end}}" - -// NewCommand return the list profiles command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "Returns a list of device profiles", - Long: `Returns the list of device profiles currently in the core-metadata database.`, - RunE: listHandler, - } - return cmd -} - -func listHandler(cmd *cobra.Command, args []string) (err error) { - url := config.Conf.Clients["Metadata"].Url() - mdc := metadata.NewDeviceProfileClient( - local.New(url + clients.ApiDeviceProfileRoute), - ) - - profiles, err := mdc.DeviceProfiles(cmd.Context()) - if err != nil { - return - } - - // TODO: Add commands and resources? They both are lists, so we need to think about how to display them - formatter := formatters.NewFormatter(profileTemplate, template.FuncMap{"DisplayDuration": utils.DisplayDuration}) - err = formatter.Write(profiles) - return -} diff --git a/cmd/profile/profile.go b/cmd/profile/profile.go deleted file mode 100644 index 3300d624..00000000 --- a/cmd/profile/profile.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 profile - -import ( - "github.com/edgexfoundry/edgex-cli/cmd/profile/add" - "github.com/edgexfoundry/edgex-cli/cmd/profile/list" - "github.com/edgexfoundry/edgex-cli/cmd/profile/rm" - "github.com/edgexfoundry/edgex-cli/cmd/profile/update" - - "github.com/spf13/cobra" -) - -// NewCommand returns the profile command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "profile [option]", - Short: "Device profile command.", - Long: `Device profile - -Device profiles define general characteristics about devices, -the data they provide, and how to command them.`, - } - - cmd.AddCommand(rm.NewCommand()) - cmd.AddCommand(list.NewCommand()) - cmd.AddCommand(add.NewCommand()) - cmd.AddCommand(update.NewCommand()) - return cmd -} diff --git a/cmd/profile/rm/rm.go b/cmd/profile/rm/rm.go deleted file mode 100644 index 9c5fa7f7..00000000 --- a/cmd/profile/rm/rm.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 rm - -import ( - "errors" - "fmt" - - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/metadata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - - "github.com/spf13/cobra" -) - -var name string - -// NewCommand return the rm profile command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "rm [ | --name ]", - Short: "Remove profile by name or ID", - Long: `Removes the device profile given a device profile name or ID.`, - RunE: func(cmd *cobra.Command, args []string) (err error) { - if len(args) == 0 && name == "" { - return errors.New("no profile id/name provided.\n") - } - - mdc := metadata.NewDeviceProfileClient( - local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceProfileRoute), - ) - if name != "" { - err = mdc.DeleteByName(cmd.Context(), name) - if err == nil { - fmt.Printf("Removed: %s\n", name) - } - return - } else if len(args) != 0 { - return request.DeleteByIds(cmd.Context(), mdc, args) - } - return nil - }, - } - cmd.Flags().StringVarP(&name, "name", "n", "", "Delete device profile by name") - return cmd -} diff --git a/cmd/profile/update/update.go b/cmd/profile/update/update.go deleted file mode 100644 index 869bfd99..00000000 --- a/cmd/profile/update/update.go +++ /dev/null @@ -1,113 +0,0 @@ -package update - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "github.com/edgexfoundry/edgex-cli/cmd/profile/add" - - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/editor" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/metadata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" - "html/template" -) - -var file string -var name string -var description string -var manufacturer string -var model string -var labels string - -// NewCommand returns the update device profile command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "update", - Short: "Update device profile", - Long: `Update device profile(s) described in the given JSON/YAML file or use the interactive mode enabled by providing - name of existing device profile`, - RunE: handler, - } - cmd.Flags().StringVarP(&name, "name", "n", "", "Name") - cmd.Flags().StringVarP(&description, "description", "d", "", "Description") - cmd.Flags().StringVar(&manufacturer, "manufacturer", "", "Manufacturer") - cmd.Flags().StringVar(&model, "model", "", "Model") - cmd.Flags().StringVar(&labels, "labels", "", "Comma separated strings") - - cmd.Flags().StringVarP(&file, "file", "f", "", "Json/YAML file containing device profile configuration to update") - return cmd -} - -func handler(cmd *cobra.Command, args []string) error { - if name != "" && file != "" { - return errors.New("Profile could be updated by providing a file, or by specifying device profile name to be updated using interactive mode. ") - } - - if name == "" && file == "" { - return errors.New("Please, provide file or profile name ") - } - - if file != "" { - return updateProfileFromFile(cmd.Context()) - } - - updatedProfile, err := parseProfile(cmd.Context(), name) - if err != nil { - return err - } - - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceProfileRoute) - err = metadata.NewDeviceProfileClient(client).Update(cmd.Context(), updatedProfile) - if err != nil { - return err - } - - return nil -} - -//parseProfile loads a DeviceProfile to be updated and open a default editor for customization -func parseProfile(ctx context.Context, name string) (models.DeviceProfile, error) { - var err error - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceProfileRoute) - ds, err := metadata.NewDeviceProfileClient(client).DeviceProfileForName(ctx, name) - if err != nil { - return models.DeviceProfile{}, err - } - updatedProfileBytes, err := editor.OpenInteractiveEditor(ds, add.ProfileTemplate, template.FuncMap{ - "lastElem": editor.IsLastElementOfSlice, - "EscapeHTML": editor.EscapeHTML, - }) - - if err != nil { - return models.DeviceProfile{}, err - } - var updatedProfile models.DeviceProfile - err = json.Unmarshal(updatedProfileBytes, &updatedProfile) - if err != nil { - return models.DeviceProfile{}, errors.New("Unable to execute the command. The provided information is invalid: " + err.Error()) - } - return updatedProfile, err -} - -func updateProfileFromFile(ctx context.Context) error { - profiles, err := add.LoadFromFile(file) - if err != nil { - return err - } - - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiDeviceServiceRoute) - for _, ds := range profiles { - err = metadata.NewDeviceProfileClient(client).Update(ctx, ds) - if err != nil { - fmt.Println("Error: ", err.Error()) - } - } - return nil -} diff --git a/cmd/reading/count/count.go b/cmd/reading/count/count.go deleted file mode 100644 index e29b15d8..00000000 --- a/cmd/reading/count/count.go +++ /dev/null @@ -1,40 +0,0 @@ -package count - -import ( - "fmt" - - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/formatters" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/coredata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - - "github.com/spf13/cobra" -) - -// NewCommand returns the count reading command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "count", - Short: "Returns the count of core-data readings", - Long: `Return a count of the number of readings in core data.`, - Args: cobra.MaximumNArgs(0), - RunE: countHandler, - } - return cmd -} - -func countHandler(cmd *cobra.Command, args []string) (err error) { - client := coredata.NewReadingClient( - local.New(config.Conf.Clients["CoreData"].Url() + clients.ApiReadingRoute), - ) - count, err := client.ReadingCount(cmd.Context()) - if err != nil { - return - } - - formatter := formatters.NewFormatter(fmt.Sprintf("Total readings count: %v", count), nil) - err = formatter.Write(count) - return -} diff --git a/cmd/reading/list/list.go b/cmd/reading/list/list.go deleted file mode 100644 index cd6a46b9..00000000 --- a/cmd/reading/list/list.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 list - -import ( - "html/template" - "strconv" - - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - "github.com/edgexfoundry/edgex-cli/pkg/formatters" - "github.com/edgexfoundry/edgex-cli/pkg/utils" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -var limit int32 -var device string - -const readingTemplate = "Reading ID\tName\tDevice\tOrigin\tValue\tCreated\tModified\tPushed\n" + - "{{range .}}" + - "{{.Id}}\t{{.Name}}\t{{.Device}}\t{{.Origin}}\t{{.Value}}\t{{DisplayDuration .Created}}\t{{DisplayDuration .Modified}}\t{{DisplayDuration .Pushed}}\n" + - "{{end}}" - -// NewCommand returns the list device command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "A list of readings across devices or pertaining to a specified device", - Long: `Return list of readings across devices or pertaining to a specified device.`, - Args: cobra.MaximumNArgs(1), - RunE: listHandler, - } - cmd.Flags().StringVarP(&device, "device", "d", "", "Readings generated by specific device with given name.") - cmd.Flags().Int32VarP(&limit, "limit", "l", 50, "Limit number of results") - return cmd -} - -func listHandler(cmd *cobra.Command, args []string) (err error) { - var url string - if device != "" { - limitUrl := strconv.FormatInt(int64(limit), 10) - url = config.Conf.Clients["CoreData"].Url() + clients.ApiReadingRoute + "/device/" + device + "/" + limitUrl - } else { - url = config.Conf.Clients["CoreData"].Url() + clients.ApiReadingRoute - } - - var readings []models.Reading - err = request.Get(cmd.Context(), url, &readings) - if err != nil { - return - } - - formatter := formatters.NewFormatter(readingTemplate, template.FuncMap{"DisplayDuration": utils.DisplayDuration}) - err = formatter.Write(readings) - return -} diff --git a/cmd/reading/reading.go b/cmd/reading/reading.go deleted file mode 100644 index ec238580..00000000 --- a/cmd/reading/reading.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 reading - -import ( - "github.com/edgexfoundry/edgex-cli/cmd/reading/count" - listevent "github.com/edgexfoundry/edgex-cli/cmd/reading/list" - - "github.com/spf13/cobra" -) - -// NewCommand returns the reading commands of type cobra.Command -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "reading", - Short: "Reading command", - Long: `Actions related to device-generated readings.`, - } - cmd.AddCommand(listevent.NewCommand()) - cmd.AddCommand(count.NewCommand()) - return cmd -} diff --git a/cmd/root.go b/cmd/root.go index 14ff960a..6f907bba 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -20,24 +20,28 @@ import ( "io" "os" - "github.com/edgexfoundry/edgex-cli/cmd/addressable" - "github.com/edgexfoundry/edgex-cli/cmd/command" - "github.com/edgexfoundry/edgex-cli/cmd/db" - "github.com/edgexfoundry/edgex-cli/cmd/device" - "github.com/edgexfoundry/edgex-cli/cmd/deviceservice" - "github.com/edgexfoundry/edgex-cli/cmd/event" - "github.com/edgexfoundry/edgex-cli/cmd/interval" - "github.com/edgexfoundry/edgex-cli/cmd/notification" - "github.com/edgexfoundry/edgex-cli/cmd/profile" - "github.com/edgexfoundry/edgex-cli/cmd/reading" + // TODO (jpw) - put back in + // "github.com/edgexfoundry/edgex-cli/cmd/addressable" + // "github.com/edgexfoundry/edgex-cli/cmd/command" + // "github.com/edgexfoundry/edgex-cli/cmd/db" + // "github.com/edgexfoundry/edgex-cli/cmd/device" + // "github.com/edgexfoundry/edgex-cli/cmd/deviceservice" + // "github.com/edgexfoundry/edgex-cli/cmd/event" + // "github.com/edgexfoundry/edgex-cli/cmd/interval" + // "github.com/edgexfoundry/edgex-cli/cmd/notification" + // "github.com/edgexfoundry/edgex-cli/cmd/profile" + // "github.com/edgexfoundry/edgex-cli/cmd/reading" "github.com/edgexfoundry/edgex-cli/cmd/status" - "github.com/edgexfoundry/edgex-cli/cmd/subscription" - "github.com/edgexfoundry/edgex-cli/cmd/version" - "github.com/edgexfoundry/edgex-cli/cmd/watcher" "github.com/edgexfoundry/edgex-cli/config" "github.com/edgexfoundry/edgex-cli/pkg/pager" - "github.com/edgexfoundry/go-mod-core-contracts/clients" + // "github.com/edgexfoundry/edgex-cli/cmd/subscription" + "github.com/edgexfoundry/edgex-cli/cmd/version" + // "github.com/edgexfoundry/edgex-cli/cmd/watcher" + // "github.com/edgexfoundry/edgex-cli/config" + // "github.com/edgexfoundry/edgex-cli/pkg/pager" + + "github.com/edgexfoundry/go-mod-core-contracts/v2/clients" "github.com/google/uuid" "github.com/spf13/cobra" @@ -106,21 +110,22 @@ https://www.edgexfoundry.org/ `, } + // TODO (jpw) - put back in // Add all subcommands below: - cmd.AddCommand(device.NewCommand()) - cmd.AddCommand(deviceservice.NewCommand()) - cmd.AddCommand(profile.NewCommand()) - cmd.AddCommand(event.NewCommand()) - cmd.AddCommand(reading.NewCommand()) + // cmd.AddCommand(device.NewCommand()) + // cmd.AddCommand(deviceservice.NewCommand()) + // cmd.AddCommand(profile.NewCommand()) + // cmd.AddCommand(event.NewCommand()) + // cmd.AddCommand(reading.NewCommand()) cmd.AddCommand(status.NewCommand()) - cmd.AddCommand(db.NewCommand()) - cmd.AddCommand(addressable.NewCommand()) - cmd.AddCommand(command.NewCommand()) + // cmd.AddCommand(db.NewCommand()) + // cmd.AddCommand(addressable.NewCommand()) + // cmd.AddCommand(command.NewCommand()) // --- Support Services Commands --- - cmd.AddCommand(notification.NewCommand()) - cmd.AddCommand(subscription.NewCommand()) - cmd.AddCommand(interval.NewCommand()) - cmd.AddCommand(watcher.NewCommand()) + // cmd.AddCommand(notification.NewCommand()) + // cmd.AddCommand(subscription.NewCommand()) + // cmd.AddCommand(interval.NewCommand()) + // cmd.AddCommand(watcher.NewCommand()) cmd.AddCommand(version.NewCommand()) // global flags diff --git a/cmd/status/status.go b/cmd/status/status.go index 83fccf8c..56aa8872 100644 --- a/cmd/status/status.go +++ b/cmd/status/status.go @@ -22,7 +22,7 @@ import ( "github.com/edgexfoundry/edgex-cli/config" "github.com/edgexfoundry/edgex-cli/pkg/formatters" - "github.com/edgexfoundry/go-mod-core-contracts/clients" + "github.com/edgexfoundry/go-mod-core-contracts/v2/clients" "github.com/spf13/cobra" ) diff --git a/cmd/subscription/add/add.go b/cmd/subscription/add/add.go deleted file mode 100644 index d76d909d..00000000 --- a/cmd/subscription/add/add.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 add - -import ( - "fmt" - "io/ioutil" - - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/pelletier/go-toml" - "github.com/spf13/cobra" -) - -type SubscriptionFile struct { - Subscriptions []models.Subscription -} - -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "add", - Short: "Add subscription", - Long: `Create the subscription described in the given TOML files.`, - Run: addSubscriptionHandler, - } - return cmd -} - -func addSubscriptionHandler(cmd *cobra.Command, args []string) { - for _, fname := range args { - subscriptions, err := parseToml(fname) - if err != nil { - fmt.Println("Error: ", err.Error()) - } - for _, s := range subscriptions { - request.Post(cmd.Context(), config.Conf.Clients["Notification"].Url()+clients.ApiSubscriptionRoute, &s) - } - } -} - -func parseToml(fname string) ([]models.Subscription, error) { - defer func() { - if r := recover(); r != nil { - fmt.Println("Error: Invalid TOML") - } - }() - var subscriptionFile = &SubscriptionFile{} - file, err := ioutil.ReadFile(fname) - if err != nil { - return nil, err - } - err = toml.Unmarshal(file, subscriptionFile) - if err != nil { - return nil, err - } - return subscriptionFile.Subscriptions, nil -} diff --git a/cmd/subscription/list/list.go b/cmd/subscription/list/list.go deleted file mode 100644 index eba2c083..00000000 --- a/cmd/subscription/list/list.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 list - -import ( - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - "github.com/edgexfoundry/edgex-cli/pkg/formatters" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -const subscriptionTemplate = "Subscription ID\tSlug\tReceiver\tDescription\tOrigin\n" + - "{{range .}}" + - "{{.ID}}\t{{.Slug}}\t{{.Receiver}}t{{.Description}}t{{.Origin}}\n" + - "{{end}}" - -// NewCommand returns the list device command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "A list of all subscriptions", - Long: `Return all Subscriptions`, - RunE: listHandler, - } - return cmd -} - -func listHandler(cmd *cobra.Command, args []string) (err error) { - url := config.Conf.Clients["Notification"].Url() + clients.ApiSubscriptionRoute - var subscriptions []models.Subscription - err = request.Get(cmd.Context(), url, &subscriptions) - if err != nil { - return - } - - formatter := formatters.NewFormatter(subscriptionTemplate, nil) - err = formatter.Write(subscriptions) - return -} diff --git a/cmd/subscription/rm/rm.go b/cmd/subscription/rm/rm.go deleted file mode 100644 index 55a1f963..00000000 --- a/cmd/subscription/rm/rm.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 rm - -import ( - "errors" - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - - "github.com/spf13/cobra" -) - -var slug string - -// NewCommand returns remove subscription command -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "rm [id | --slug]", - Example: "subscription rm \n" + - "subscription rm --slug ", - Short: "Removes subscription by --slug or id.", - Long: `Removes a subscription given its slug or id.`, - RunE: removeSubscriptionHandler, - } - cmd.Flags().StringVarP(&slug, "slug", "s", "", "Delete Subscription by slug") - return cmd -} - -func removeSubscriptionHandler(cmd *cobra.Command, args []string) (err error) { - if len(args) == 0 && slug == "" { - return errors.New("no subscription id/slug provided") - } - url := config.Conf.Clients["Notification"].Url() + clients.ApiSubscriptionRoute - url, deletedBy := constructUrl(url, args) - return request.DeletePrt(cmd.Context(), url, deletedBy) -} - -func constructUrl(url string, args []string) (string, string) { - if slug != "" { - url = url + "/slug/" + slug - return url, slug - } - url = url + "/" + args[0] - return url, args[0] -} diff --git a/cmd/subscription/subscription.go b/cmd/subscription/subscription.go deleted file mode 100644 index 226e6b19..00000000 --- a/cmd/subscription/subscription.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright © 2019 VMware, INC -// -// 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 subscription - -import ( - addsubscription "github.com/edgexfoundry/edgex-cli/cmd/subscription/add" - listsubscription "github.com/edgexfoundry/edgex-cli/cmd/subscription/list" - rmsubscription "github.com/edgexfoundry/edgex-cli/cmd/subscription/rm" - - "github.com/spf13/cobra" -) - -//deprecated -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "subscription", - Short: "Subscription command", - Long: `Actions related to subscriptions.`, - } - cmd.AddCommand(addsubscription.NewCommand()) - cmd.AddCommand(rmsubscription.NewCommand()) - cmd.AddCommand(listsubscription.NewCommand()) - return cmd -} diff --git a/cmd/watcher/add/add.go b/cmd/watcher/add/add.go deleted file mode 100644 index e0b7f81e..00000000 --- a/cmd/watcher/add/add.go +++ /dev/null @@ -1,196 +0,0 @@ -/******************************************************************************* - * Copyright 2020 VMWare. - * - * 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 add - -import ( - "encoding/json" - "errors" - "fmt" - "html/template" - "io/ioutil" - - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/editor" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/metadata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/spf13/cobra" -) - -const watcherTemplate = `[{{range $d := .}} -{ - "Name": "{{.Name}}", - "AdminState":"{{.AdminState}}", - "OperatingState": "{{.OperatingState}}", - "Service": { - "Name": "{{.Service.Name}}" - }, - "Profile": { - "Name": "{{.Profile.Name}}" - }, - "Identifiers":{ {{$s := separator ", "}}{{range $key, $value := .Identifiers}}{{call $s}} - "{{$key}}": "{{$value}}"{{end}} - }, - "BlockingIdentifiers": { {{$s := separator ", "}}{{range $key, $value := .BlockingIdentifiers}}{{call $s}} - "{{$key}}": [{{range $k, $v := $value}}"{{$v}}"{{end}}]{{end}} - } -} -{{end}} -]` - -var interactiveMode bool -var name string -var adminState string -var profileName string -var serviceName string -var numberOfIdentifiers int -var numberOfBlockingIdentifiers int -var file string - -// NewCommand returns the add watcher command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "add", - Short: "Add watcher(s)", - Long: `Create watchers described in a given JSON file or use the interactive mode with additional flags.`, - RunE: handler, - } - cmd.Flags().BoolVarP(&interactiveMode, editor.InteractiveModeLabel, "i", false, "Open a default editor to customize the watcher information") - cmd.Flags().StringVarP(&name, "name", "n", "", "Watcher Name") - cmd.Flags().StringVarP(&adminState, "adminState", "a", "", "Admin Status") - cmd.Flags().StringVarP(&profileName, "profileName", "p", "", "Device Profile name") - cmd.Flags().StringVarP(&serviceName, "serviceName", "s", "", "Device Service name") - cmd.Flags().IntVar(&numberOfIdentifiers, "identifiers", 0, "Number of Identifiers") - cmd.Flags().IntVarP(&numberOfBlockingIdentifiers, "blockingIdentifiers", "b", 0, "Number of BlockingIdentifiers") - - cmd.Flags().StringVarP(&file, "file", "f", "", "File containing watcher configuration in json format") - return cmd -} - -func handler(cmd *cobra.Command, args []string) (err error) { - if interactiveMode && file != "" { - return errors.New("you could work with interactive mode or file, but not with both") - } - - var watchers []models.ProvisionWatcher - if file != "" { - watchers, err = LoadFromFile(file) - } else { - watchers, err = parse(interactiveMode) - - } - - if err != nil { - return err - } - - client := local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiProvisionWatcherRoute) - for _, w := range watchers { - _, err = metadata.NewProvisionWatcherClient(client).Add(cmd.Context(), &w) - if err != nil { - fmt.Println("Error: ", err.Error()) - } - } - - return nil -} - -//LoadFromFile could read a file that contains single ProvisionWatcher or list of ProvisionWatcher -func LoadFromFile(filePath string) ([]models.ProvisionWatcher, error) { - defer func() { - if r := recover(); r != nil { - fmt.Println("Error: Invalid Json") - } - }() - file, err := ioutil.ReadFile(filePath) - if err != nil { - return nil, err - } - - var watchers []models.ProvisionWatcher - - //check if the file contains just one ProvisionWatcher - var w models.ProvisionWatcher - err = json.Unmarshal(file, &w) - if err != nil { - //check if the file contains list of ProvisionWatcher - err = json.Unmarshal(file, &watchers) - if err != nil { - return nil, err - } - } else { - watchers = append(watchers, w) - } - return watchers, nil -} - -func parse(interactiveMode bool) ([]models.ProvisionWatcher, error) { - //parse ProvisionWatcher based on interactive mode and the other provided flags - var err error - var watchers []models.ProvisionWatcher - populate(&watchers) - var updatedWatchersBytes []byte - if interactiveMode { - updatedWatchersBytes, err = editor.OpenInteractiveEditor(watchers, watcherTemplate, template.FuncMap{ - "separator": separator, - }) - } - if err != nil { - return nil, err - } - - var updatedWatchers []models.ProvisionWatcher - err = json.Unmarshal(updatedWatchersBytes, &updatedWatchers) - if err != nil { - return nil, errors.New("Unable to execute the command. The provided information is not valid:" + err.Error()) - } - return updatedWatchers, err -} - -func populate(watchers *[]models.ProvisionWatcher) { - w := models.ProvisionWatcher{} - w.Name = name - w.AdminState = models.AdminState(adminState) - w.Profile = models.DeviceProfile{Name: profileName} - w.Service = models.DeviceService{Name: serviceName} - if numberOfIdentifiers > 0 { - identifier := make(map[string]string, numberOfIdentifiers) - for i := 0; i < numberOfIdentifiers; i++ { - identifier[fmt.Sprintf("Identifier-%d", i)] = "Example Value" - } - w.Identifiers = identifier - } - if numberOfBlockingIdentifiers > 0 { - bi := make(map[string][]string, numberOfBlockingIdentifiers) - for i := 0; i < numberOfBlockingIdentifiers; i++ { - bi[fmt.Sprintf("Blocking Identifier-%d", i)] = []string{"Example Value-1"} - } - w.BlockingIdentifiers = bi - } - *watchers = append(*watchers, w) -} - -func separator(s string) func() string { - i := -1 - return func() string { - i++ - if i == 0 { - return "" - } - return s - } -} diff --git a/cmd/watcher/list/list.go b/cmd/watcher/list/list.go deleted file mode 100644 index 1aafcf61..00000000 --- a/cmd/watcher/list/list.go +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * Copyright 2020 VMWare. - * - * 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 list - -import ( - "context" - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/metadata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - "github.com/edgexfoundry/go-mod-core-contracts/models" - - "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/edgex-cli/pkg/formatters" - - "github.com/spf13/cobra" -) - -const template = "ID\tName\tProfile\tService\tAdminState\n" + - "{{range .}}" + - "{{.Id}}\t{{.Name}}\t{{.Profile.Name}}\t{{.Service.Name}}\t{{.AdminState}}\n" + - "{{end}}" - -// NewCommand returns the list watcher command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "A list of watchers", - Long: `Return a list of watchers or retrieve a watcher by id`, - Args: cobra.MaximumNArgs(1), - RunE: listHandler, - } - return cmd -} - -func listHandler(cmd *cobra.Command, args []string) (err error) { - client := metadata.NewProvisionWatcherClient( - local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiProvisionWatcherRoute), - ) - - var watchers []models.ProvisionWatcher - if len(args) == 0 { - watchers, err = client.ProvisionWatchers(cmd.Context()) - } else { - watchers, err = provisionWatchers(cmd.Context(), client, args[0]) - } - if err != nil { - return err - } - - formatter := formatters.NewFormatter(template, nil) - err = formatter.Write(watchers) - return -} - -func provisionWatchers(ctx context.Context, client metadata.ProvisionWatcherClient, id string) ([]models.ProvisionWatcher, error) { - watcher, err := client.ProvisionWatcher(ctx, id) - if err != nil { - return nil, err - } - return []models.ProvisionWatcher{watcher}, nil -} diff --git a/cmd/watcher/rm/rm.go b/cmd/watcher/rm/rm.go deleted file mode 100644 index 51ed7677..00000000 --- a/cmd/watcher/rm/rm.go +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * Copyright 2020 VMWare. - * - * 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 rm - -import ( - "errors" - - "github.com/edgexfoundry/edgex-cli/config" - request "github.com/edgexfoundry/edgex-cli/pkg" - - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/metadata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - - "github.com/spf13/cobra" -) - -// NewCommand return the rm watcher command -func NewCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "rm [ ... ]", - Short: "Remove watcher(s) by ID(s)", - Long: `Remove one or more watchers by given ID(s)`, - RunE: removeHandler, - } - return cmd -} - -func removeHandler(cmd *cobra.Command, args []string) error { - if len(args) == 0 { - return errors.New("please provide watcher id(s).\n") - } - - client := metadata.NewProvisionWatcherClient( - local.New(config.Conf.Clients["Metadata"].Url() + clients.ApiProvisionWatcherRoute), - ) - return request.DeleteByIds(cmd.Context(), client, args) -} diff --git a/cmd/watcher/watcher.go b/cmd/watcher/watcher.go deleted file mode 100644 index 93fa4ed4..00000000 --- a/cmd/watcher/watcher.go +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright 2020 VMWare. - * - * 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 watcher - -import ( - "github.com/edgexfoundry/edgex-cli/cmd/watcher/add" - "github.com/edgexfoundry/edgex-cli/cmd/watcher/list" - "github.com/edgexfoundry/edgex-cli/cmd/watcher/rm" - - "github.com/spf13/cobra" -) - -// NewCommand returns the watcher command of type cobra.Command -func NewCommand() *cobra.Command { - var cmd = &cobra.Command{ - Use: "watcher", - Short: "Watcher command", - Long: `Actions related to watchers.`, - } - cmd.AddCommand(list.NewCommand()) - cmd.AddCommand(rm.NewCommand()) - cmd.AddCommand(add.NewCommand()) - return cmd -} diff --git a/go.mod b/go.mod index 2a5eb6cf..5d85f943 100644 --- a/go.mod +++ b/go.mod @@ -2,17 +2,16 @@ module github.com/edgexfoundry/edgex-cli require ( github.com/BurntSushi/toml v0.3.1 - github.com/edgexfoundry/go-mod-core-contracts v0.1.149 + github.com/edgexfoundry/go-mod-core-contracts/v2 v2.0.0-dev.89 github.com/google/uuid v1.2.0 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect - github.com/pelletier/go-toml v1.8.1 + github.com/pelletier/go-toml v1.8.1 // indirect github.com/spf13/afero v1.5.1 github.com/spf13/cobra v0.0.7 github.com/spf13/viper v1.7.1 github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.7.0 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect - gopkg.in/yaml.v2 v2.4.0 ) go 1.16 diff --git a/pkg/cmd/purge/coredata.go b/pkg/cmd/purge/coredata.go index 40ae592a..5ad8c531 100644 --- a/pkg/cmd/purge/coredata.go +++ b/pkg/cmd/purge/coredata.go @@ -7,8 +7,7 @@ import ( "github.com/edgexfoundry/edgex-cli/config" request "github.com/edgexfoundry/edgex-cli/pkg" - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/models" + "github.com/edgexfoundry/go-mod-core-contracts/v2/clients" ) type coredataCleaner struct { @@ -26,27 +25,28 @@ func NewCoredataCleaner(ctx context.Context) Purgeable { } func (d *coredataCleaner) Purge() { d.cleanEventsAndReadings() - d.cleanValueDescriptors() + //d.cleanValueDescriptors() } -func (d *coredataCleaner) cleanValueDescriptors() { - url := d.baseUrl + clients.ApiValueDescriptorRoute - var valueDescriptors []models.ValueDescriptor - err := request.Get(d.ctx, url, valueDescriptors) - if err != nil { - fmt.Printf("Error: %s\n", err.Error()) - return - } - - var count int - for _, valueDescriptor := range valueDescriptors { - err = request.Delete(d.ctx, url+config.PathId+valueDescriptor.Id) - if err == nil { - count = count + 1 - } - } - fmt.Printf("Removed %d Value Descriptors from %d \n", count, len(valueDescriptors)) -} +// TODO (jpw) - rid +// func (d *coredataCleaner) cleanValueDescriptors() { +// url := d.baseUrl + clients.ApiValueDescriptorRoute +// var valueDescriptors []models.ValueDescriptor +// err := request.Get(d.ctx, url, valueDescriptors) +// if err != nil { +// fmt.Printf("Error: %s\n", err.Error()) +// return +// } + +// var count int +// for _, valueDescriptor := range valueDescriptors { +// err = request.Delete(d.ctx, url+config.PathId+valueDescriptor.Id) +// if err == nil { +// count = count + 1 +// } +// } +// fmt.Printf("Removed %d Value Descriptors from %d \n", count, len(valueDescriptors)) +// } func (d *coredataCleaner) cleanEventsAndReadings() { url := d.baseUrl + clients.ApiEventRoute + "/scruball" diff --git a/pkg/cmd/purge/metadata.go b/pkg/cmd/purge/metadata.go index 16d20331..dc177737 100644 --- a/pkg/cmd/purge/metadata.go +++ b/pkg/cmd/purge/metadata.go @@ -7,10 +7,10 @@ import ( "github.com/edgexfoundry/edgex-cli/config" request "github.com/edgexfoundry/edgex-cli/pkg" - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/metadata" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" - "github.com/edgexfoundry/go-mod-core-contracts/models" + "github.com/edgexfoundry/go-mod-core-contracts/v2/clients" + "github.com/edgexfoundry/go-mod-core-contracts/v2/clients/metadata" + "github.com/edgexfoundry/go-mod-core-contracts/v2/clients/urlclient/local" + "github.com/edgexfoundry/go-mod-core-contracts/v2/v2/models" ) type metadataCleaner struct { @@ -31,7 +31,7 @@ func (d *metadataCleaner) Purge() { d.cleanDevices() d.cleanDeviceServices() d.cleanDeviceProfiles() - d.cleanAddressables() + //d.cleanAddressables() } func (d *metadataCleaner) cleanDevices() { @@ -93,21 +93,22 @@ func (d *metadataCleaner) cleanDeviceProfiles() { fmt.Printf("Removed %d Device Profiles from %d \n", count, len(deviceProfiles)) } -func (d *metadataCleaner) cleanAddressables() { - url := d.baseUrl + clients.ApiAddressableRoute - var addressables []models.Addressable - err := request.Get(d.ctx, url, &addressables) - if err != nil { - fmt.Printf("Error: %s\n", err.Error()) - return - } - - var count int - for _, addr := range addressables { - err = request.Delete(d.ctx, url+config.PathId+addr.Id) - if err == nil { - count = count + 1 - } - } - fmt.Printf("Removed %d Addressables from %d \n", count, len(addressables)) -} +// TODO (jpw) - rid +// func (d *metadataCleaner) cleanAddressables() { +// url := d.baseUrl + clients.ApiAddressableRoute +// var addressables []models.Addressable +// err := request.Get(d.ctx, url, &addressables) +// if err != nil { +// fmt.Printf("Error: %s\n", err.Error()) +// return +// } + +// var count int +// for _, addr := range addressables { +// err = request.Delete(d.ctx, url+config.PathId+addr.Id) +// if err == nil { +// count = count + 1 +// } +// } +// fmt.Printf("Removed %d Addressables from %d \n", count, len(addressables)) +// } diff --git a/pkg/cmd/purge/scheduler.go b/pkg/cmd/purge/scheduler.go index 72d7f954..e7c2084e 100644 --- a/pkg/cmd/purge/scheduler.go +++ b/pkg/cmd/purge/scheduler.go @@ -7,8 +7,8 @@ import ( "github.com/edgexfoundry/edgex-cli/config" request "github.com/edgexfoundry/edgex-cli/pkg" - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/models" + "github.com/edgexfoundry/go-mod-core-contracts/v2/clients" + "github.com/edgexfoundry/go-mod-core-contracts/v2/v2/models" ) type schedulerCleaner struct { @@ -41,7 +41,7 @@ func (d *schedulerCleaner) cleanIntervals() { var count int for _, interval := range intervals { - err = request.Delete(d.ctx, url+"/"+interval.ID) + err = request.Delete(d.ctx, url+"/"+interval.Id) if err == nil { count = count + 1 } @@ -60,7 +60,7 @@ func (d *schedulerCleaner) cleanIntervalActions() { var count int for _, intervalAction := range intervalActions { - err = request.Delete(d.ctx, url+"/"+intervalAction.ID) + err = request.Delete(d.ctx, url+"/"+intervalAction.Id) if err == nil { count = count + 1 } diff --git a/pkg/cmd/version/version.go b/pkg/cmd/version/version.go index b5fc115f..0836329e 100644 --- a/pkg/cmd/version/version.go +++ b/pkg/cmd/version/version.go @@ -6,7 +6,7 @@ import ( "github.com/edgexfoundry/edgex-cli/config" - "github.com/edgexfoundry/go-mod-core-contracts/clients" + "github.com/edgexfoundry/go-mod-core-contracts/v2/clients" ) type Version struct { diff --git a/pkg/request.go b/pkg/request.go index d06e9dd2..c99b2191 100644 --- a/pkg/request.go +++ b/pkg/request.go @@ -7,8 +7,8 @@ import ( "net/http" "reflect" - "github.com/edgexfoundry/go-mod-core-contracts/clients" - "github.com/edgexfoundry/go-mod-core-contracts/clients/urlclient/local" + "github.com/edgexfoundry/go-mod-core-contracts/v2/clients" + "github.com/edgexfoundry/go-mod-core-contracts/v2/clients/urlclient/local" "github.com/spf13/viper" ) From 1615725e4a000ba65268ffe6bb44a731bc7cbf88 Mon Sep 17 00:00:00 2001 From: Jim White Date: Tue, 18 May 2021 12:32:37 -0500 Subject: [PATCH 2/2] feat: remove go-mod-core-contracts v1 from attribution.txt Signed-off-by: Jim White --- Attribution.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/Attribution.txt b/Attribution.txt index dbae9d6f..392ada88 100644 --- a/Attribution.txt +++ b/Attribution.txt @@ -52,9 +52,6 @@ https://github.com/mitchellh/mapstructure/blob/master/LICENSE BurntSushi/toml (MIT) https://github.com/BurntSushi/toml https://github.com/BurntSushi/toml/blob/master/COPYING -edgexfoundry/go-mod-core-contracts (Apache 2.0) https://github.com/edgexfoundry/go-mod-core-contracts -https://github.com/edgexfoundry/go-mod-core-contracts/blob/master/LICENSE - edgexfoundry/go-mod-core-contracts (Apache 2.0) https://github.com/edgexfoundry/go-mod-core-contracts/v2 https://github.com/edgexfoundry/go-mod-core-contracts/blob/master/LICENSE