diff --git a/cli/cmd/changeCommit.go b/cli/cmd/changeCommit.go index 49e035eed2141b1324c441b9383a6534b45cb0f8..406da9e9c17198b04e6b39b63822c0597c7cb0fe 100644 --- a/cli/cmd/changeCommit.go +++ b/cli/cmd/changeCommit.go @@ -49,10 +49,12 @@ Change UUID must be specified as positional argument.`, cuid, err := uuid.Parse(args[0]) if err != nil { pterm.Error.Println(err) + return } resp, err := pndAdapter.Commit(createContextWithAuthorization(), cuid) if err != nil { pterm.Error.Println(err) + return } for _, r := range resp.GetResponses() { pterm.Info.Printfln("Change with ID: %s has been committed.", r.GetId()) diff --git a/cli/cmd/changeConfirm.go b/cli/cmd/changeConfirm.go index 249738c6e8550fbff5eacd5359a90b2404276c0a..41550ede05caa6f6fd3763dfa70e6bb217be973b 100644 --- a/cli/cmd/changeConfirm.go +++ b/cli/cmd/changeConfirm.go @@ -49,11 +49,13 @@ Change UUID must be specified as positional argument`, cuid, err := uuid.Parse(args[0]) if err != nil { pterm.Error.Println(err) + return } resp, err := pndAdapter.Confirm(createContextWithAuthorization(), cuid) if err != nil { pterm.Error.Println(err) + return } for _, r := range resp.GetResponses() { pterm.Info.Printfln("Change with ID: %s has been confirmed.", r.GetId()) diff --git a/cli/cmd/changeGet.go b/cli/cmd/changeGet.go index a7c1aa331ab6ab0a408f011303d96b15efae573e..ff8e3c3b44a624aec1a00cb6db67ef75913beb89 100644 --- a/cli/cmd/changeGet.go +++ b/cli/cmd/changeGet.go @@ -49,6 +49,7 @@ var getCmd = &cobra.Command{ changes, err := pndAdapter.GetChange(createContextWithAuthorization(), args[0]) if err != nil { pterm.Error.Println(err) + return } for _, c := range changes.GetChange() { title := pterm.Sprintf("Change with ID: %s", c.GetId()) diff --git a/cli/cmd/changeList.go b/cli/cmd/changeList.go index d5b0ea11e877663e38d199f08c2a0ecff570aa7f..2b1a57501ee11f171bc077d59df5b30935bb8313 100644 --- a/cli/cmd/changeList.go +++ b/cli/cmd/changeList.go @@ -43,17 +43,17 @@ var changeListCmd = &cobra.Command{ Short: "list all changes", Long: `Lists all configuration changes with their UUIDs.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Process change list request") committed, err := pndAdapter.CommittedChanges(createContextWithAuthorization()) if err != nil { spinner.Fail(err) - return err + return } pending, err := pndAdapter.PendingChanges(createContextWithAuthorization()) if err != nil { spinner.Fail(err) - return err + return } // TODO: maybe we want to return more information about changes? E.g., @@ -70,10 +70,9 @@ var changeListCmd = &cobra.Command{ spinner.Success() err = pterm.DefaultTable.WithHasHeader().WithData(data).Render() if err != nil { - return err + pterm.Error.Println(err) + return } - - return nil }, } diff --git a/cli/cmd/list.go b/cli/cmd/list.go index 7ff31bcbf4b03fde3963bc09f1855722ea51e1f6..2e476d4e7487361d53504ee1d3b51d7505237cab 100644 --- a/cli/cmd/list.go +++ b/cli/cmd/list.go @@ -33,6 +33,7 @@ package cmd import ( "code.fbi.h-da.de/danet/gosdn/controller/api" + "github.com/pterm/pterm" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -44,16 +45,18 @@ var listCmd = &cobra.Command{ Short: "List all PNDs, SBIs and MNEs on the controller", Long: `List all PNDs, SBIs and MNEs on the controller.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { addr := viper.GetString("controllerApiEndpoint") resp, err := api.GetIds(createContextWithAuthorization(), addr) if err != nil { - return err + pterm.Error.Println(err) + return } for i, pnd := range resp { mneResp, err := api.GetFlattenedNetworkElements(createContextWithAuthorization(), addr, pnd.GetId()) if err != nil { - return err + pterm.Error.Println(err) + return } log.Infof("PND %v: name: %v, uuid: %v", i+1, pnd.Name, pnd.Id) for k, mne := range mneResp.GetMne() { @@ -61,7 +64,6 @@ var listCmd = &cobra.Command{ log.Infof(" Plugin %v: uuid: %v", k+1, mne.GetPid()) } } - return nil }, } diff --git a/cli/cmd/login.go b/cli/cmd/login.go index ac210be646fd12778915ccf1b3429dcae938daa0..babf01ee8f167ae75a396faf306e0debc2c30ca1 100644 --- a/cli/cmd/login.go +++ b/cli/cmd/login.go @@ -47,12 +47,13 @@ var loginCmd = &cobra.Command{ Long: `Logs the user in to allow further actions on the controller. User credentials need to be provided in the body`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Login attempt for user: ", nbUserName) if controllerAPIEndpoint != "" { if err := viper.WriteConfig(); err != nil { pterm.Error.Println("Could not write config:", err) + return } pterm.Info.Println("New controller address: ", viper.GetString("controllerAPIEndpoint")) } @@ -66,7 +67,7 @@ var loginCmd = &cobra.Command{ resp, err := api.Login(context.TODO(), viper.GetString("controllerAPIEndpoint"), nbUserName, nbUserPwd) if err != nil { spinner.Fail("Login failed: ", err) - return err + return } spinner.Success("Authentication for ", nbUserName, " was successful.") @@ -78,12 +79,10 @@ var loginCmd = &cobra.Command{ err = viper.WriteConfig() if err != nil { pterm.Error.Println(err) - return err + return } pterm.Info.Println("Authentication-User-Token:", userToken) - - return nil }, PostRun: func(cmd *cobra.Command, args []string) { // Necessary for prompt mode. The flag variables have to be resetted, diff --git a/cli/cmd/logout.go b/cli/cmd/logout.go index 997b035aaef9979073c94e7a8815454a3657dbcc..68bc8a7394c6ed7bf2c9ab91fa72de9b1c39c2f5 100644 --- a/cli/cmd/logout.go +++ b/cli/cmd/logout.go @@ -46,13 +46,13 @@ var logoutCmd = &cobra.Command{ Short: "Logs the current user out", Long: `Logs the current user out. Further actions on the controller are not permitted after this.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Logout attempt for user: ", nbUserName) resp, err := api.Logout(createContextWithAuthorization(), viper.GetString("controllerAPIEndpoint"), nbUserName) if err != nil { spinner.Fail("Logout failed: ", err) - return err + return } userToken = "" @@ -61,12 +61,10 @@ var logoutCmd = &cobra.Command{ err = viper.WriteConfig() if err != nil { pterm.Error.Println(err) - return err + return } spinner.Success("User ", nbUserName, " successfully logged out at ", time.Unix((resp.Timestamp/1000000000), 0), ".") - - return nil }, PostRun: func(cmd *cobra.Command, args []string) { // Necessary for prompt mode. The flag variables have to be resetted, diff --git a/cli/cmd/networkElementCreate.go b/cli/cmd/networkElementCreate.go index 4cc764922249e65e4e0418f65eb2eb791b54b5e0..e2ed6cb9d14f741d73ffc1a34cda9a2cd6833dc4 100644 --- a/cli/cmd/networkElementCreate.go +++ b/cli/cmd/networkElementCreate.go @@ -47,12 +47,12 @@ var networkElementCreateCmd = &cobra.Command{ Network element address must be provided with IP and port,e.g., 192.168.1.1:6030. User credentials need to be provided as parameters if they diverge from the default credentials (user:'admin' and pw:'arista').`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Creating new network element") err := checkIPPort(address) if err != nil { spinner.Fail(err) - return err + return } opt := &tpb.TransportOption{ @@ -68,20 +68,18 @@ if they diverge from the default credentials (user:'admin' and pw:'arista').`, pluginUUID, err := uuid.Parse(pluginID) if err != nil { spinner.Fail(err) - return err + return } resp, err := pndAdapter.AddNetworkElement(createContextWithAuthorization(), mneName, opt, pluginUUID) if err != nil { spinner.Fail(err) - return err + return } for _, r := range resp.GetResponses() { spinner.Success("Network element has been created with ID: ", r.GetId()) } - - return nil }, PostRun: func(cmd *cobra.Command, args []string) { // Necessary for prompt mode. The flag variables have to be resetted, diff --git a/cli/cmd/networkElementList.go b/cli/cmd/networkElementList.go index d61c2ea781f82ac1c3c393c99bdf000ee30cd39f..be6ce028a0a9353f445bc687cca7e86676d6561e 100644 --- a/cli/cmd/networkElementList.go +++ b/cli/cmd/networkElementList.go @@ -44,13 +44,13 @@ var networkElementListCmd = &cobra.Command{ Short: "list all network elements in current PND", Long: "List all orchestrated network network elements within the current PND.", - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Fetching data from controller") resp, err := pndAdapter.GetFlattenedNetworkElements(createContextWithAuthorization()) if err != nil { spinner.Fail(err) - return err + return } data := pterm.TableData{[]string{"UUID", "Name", "Plugin-UUID"}} @@ -62,10 +62,8 @@ var networkElementListCmd = &cobra.Command{ err = pterm.DefaultTable.WithHasHeader().WithData(data).Render() if err != nil { - return err + return } - - return nil }, } diff --git a/cli/cmd/networkElementPathDelete.go b/cli/cmd/networkElementPathDelete.go index 51f1c9f34593aae20206bdbedabab8b5a812f56e..b40bdccc1d266436da657cd069d03241ce20b7ef 100644 --- a/cli/cmd/networkElementPathDelete.go +++ b/cli/cmd/networkElementPathDelete.go @@ -48,18 +48,18 @@ var networkElementPathDeleteCmd = &cobra.Command{ Long: `Delete a path for a given orchestrated network network element. The network element UUID and request path must be specified as a positional arguments.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Create a path deletion request.") mneid, err := uuid.Parse(args[0]) if err != nil { spinner.Fail(err) - return err + return } path, err := ygot.StringToStructuredPath(args[1]) if err != nil { spinner.Fail(err) - return err + return } resp, err := pndAdapter.ChangeMNE( @@ -71,7 +71,7 @@ The network element UUID and request path must be specified as a positional argu ) if err != nil { spinner.Fail(err) - return err + return } for _, r := range resp.Responses { @@ -81,7 +81,6 @@ The network element UUID and request path must be specified as a positional argu spinner.Fail("An error occurred while creating a path deletion request for network element with ID: ", r.GetId(), r.GetStatus()) } } - return nil }, } diff --git a/cli/cmd/networkElementPathGet.go b/cli/cmd/networkElementPathGet.go index d02fccf2e8ea5e5668f36daffecb264847699206..f7ab234e4003296400b3bd7275fc43cda1018078 100644 --- a/cli/cmd/networkElementPathGet.go +++ b/cli/cmd/networkElementPathGet.go @@ -47,11 +47,11 @@ var networkElementPathGetCmd = &cobra.Command{ Long: `Requests a path from a specified managed network element on the controller. The network element UUID and request path must be specified as a positional arguments.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { mneid, err := uuid.Parse(args[0]) if err != nil { pterm.Error.Println(err) - return err + return } res, err := pndAdapter.RequestPath( @@ -61,7 +61,7 @@ The network element UUID and request path must be specified as a positional argu ) if err != nil { pterm.Error.Println(err) - return err + return } for _, n := range res.MneNotification { @@ -91,7 +91,6 @@ The network element UUID and request path must be specified as a positional argu pterm.Info.Println(panels) } - return nil }, } diff --git a/cli/cmd/networkElementPathGetIntended.go b/cli/cmd/networkElementPathGetIntended.go index 1e7e3c3a4c0632f298daa57f378c2c3419f05b2c..ceb8f50ed9eb4055ae580734213c74d48cf43dc5 100644 --- a/cli/cmd/networkElementPathGetIntended.go +++ b/cli/cmd/networkElementPathGetIntended.go @@ -49,11 +49,11 @@ var networkElementPathGetIntendedCmd = &cobra.Command{ Long: `Requests the intended path from a specified managed network element on the controller. The network element UUID and request path must be specified as a positional arguments.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { mneid, err := uuid.Parse(args[0]) if err != nil { pterm.Error.Println(err) - return err + return } res, err := pndAdapter.RequestIntendedPath( @@ -63,7 +63,7 @@ The network element UUID and request path must be specified as a positional argu ) if err != nil { pterm.Error.Println(err) - return err + return } var stringVal = "Update: " @@ -100,8 +100,6 @@ The network element UUID and request path must be specified as a positional argu if panel3 == "" { fmt.Println(stringVal) } - - return nil }, } diff --git a/cli/cmd/networkElementPathSet.go b/cli/cmd/networkElementPathSet.go index 6dd9e1ddcc072a8328c0ef03153eb3fb826ce2ff..e29cbf332ade8f9cae822ec0f9713d90a3108b78 100644 --- a/cli/cmd/networkElementPathSet.go +++ b/cli/cmd/networkElementPathSet.go @@ -32,7 +32,6 @@ POSSIBILITY OF SUCH DAMAGE. package cmd import ( - "fmt" "os" mnepb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/networkelement" @@ -58,17 +57,17 @@ only one value supported for now. The network element UUID, request path and value must be specified as positional arguments. To enable replacing behaviour (destructive!), set the --replace flag."`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Create a path set request.") //NOTE: this currently only works in prompt mode if c == nil { spinner.Fail("Currently the SET command is only supported with 'gosdnc prompt'") - return fmt.Errorf("Currently the SET command is only supported with 'gosdnc prompt'") + return } mneid, err := uuid.Parse(args[0]) if err != nil { spinner.Fail(err) - return err + return } var value string var operation mnepb.ApiOperation @@ -83,7 +82,7 @@ To enable replacing behaviour (destructive!), set the --replace flag."`, completer, ok := c.YangSchemaCompleterMap[mneid] if !ok { spinner.Fail("No schema completer found for network element ", mneid.String()) - return fmt.Errorf("No schema completer found for network element %s", mneid.String()) + return } var typedValue *gnmi.TypedValue @@ -93,11 +92,11 @@ To enable replacing behaviour (destructive!), set the --replace flag."`, typedValue, err = convertStringToGnmiTypedValue(args[2], completer.Entry.Type) if err != nil { spinner.Fail(err) - return err + return } } else { spinner.Fail("The provided path is no leaf. Please provide a file with JSON-encoded text per RFC7951. Use '--file path' for this.") - return fmt.Errorf("The provided path is no leaf. Please provide a file with JSON-encoded text per RFC7951. Use '--file path' for this.") + return } } else { @@ -105,7 +104,7 @@ To enable replacing behaviour (destructive!), set the --replace flag."`, value, err = fileContentToString(file) if err != nil { spinner.Fail(err) - return err + return } typedValue = &gnmi.TypedValue{ Value: &gnmi.TypedValue_JsonIetfVal{ @@ -117,7 +116,7 @@ To enable replacing behaviour (destructive!), set the --replace flag."`, path, err := ygot.StringToStructuredPath(args[1]) if err != nil { spinner.Fail(err) - return err + return } resp, err := pndAdapter.ChangeMNE( @@ -130,7 +129,7 @@ To enable replacing behaviour (destructive!), set the --replace flag."`, if err != nil { spinner.Fail(err) - return err + return } for _, r := range resp.GetResponses() { @@ -140,7 +139,6 @@ To enable replacing behaviour (destructive!), set the --replace flag."`, executeFunc("change confirm " + r.GetId()) } } - return nil }, PostRun: func(cmd *cobra.Command, args []string) { // Necessary for prompt mode. The flag variables have to be resetted, diff --git a/cli/cmd/networkElementRemove.go b/cli/cmd/networkElementRemove.go index f278b6460793616961e2459108c7228876c1332c..b31fa14459e95b9d353eb7a867c0ec51af0c0c58 100644 --- a/cli/cmd/networkElementRemove.go +++ b/cli/cmd/networkElementRemove.go @@ -47,20 +47,19 @@ var networkElementRemoveCmd = &cobra.Command{ Long: `Deletes an orchestrated network network element on the controller. The network element UUID must be specified as a positional argument.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Removing network element with ID: ", args[0]) mneid, err := uuid.Parse(args[0]) if err != nil { spinner.Fail(err) - return err + return } _, err = pndAdapter.RemoveNetworkElement(createContextWithAuthorization(), mneid) if err != nil { spinner.Fail(err) - return err + return } spinner.Success("Network element has been deleted, ID: ", mneid.String()) - return nil }, } diff --git a/cli/cmd/networkElementShow.go b/cli/cmd/networkElementShow.go index 71581aec891e30e6ad6f2796c59e69d5834e629b..6e150c4da08ab88bce3a172ee08886553cc25bf2 100644 --- a/cli/cmd/networkElementShow.go +++ b/cli/cmd/networkElementShow.go @@ -46,11 +46,11 @@ Network element UUID or name must be specified as a positional argument. The network element information returned is the information as currently stored in the controller. The actual network element is not queried directly.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { resp, err := pndAdapter.GetNetworkElement(createContextWithAuthorization(), args[0]) if err != nil { pterm.Error.Println(err) - return err + return } mne := resp.GetMne() @@ -64,8 +64,6 @@ The actual network element is not queried directly.`, }).Srender() pterm.DefaultBox.WithRightPadding(0).WithBottomPadding(0).Println(panels) - - return nil }, } diff --git a/cli/cmd/networkElementSubscribe.go b/cli/cmd/networkElementSubscribe.go index 245d9f6fb8c4820d65719cda5a5d3087bd4fe0da..5b96828188d306b1b23e08366bce354487e20c3c 100644 --- a/cli/cmd/networkElementSubscribe.go +++ b/cli/cmd/networkElementSubscribe.go @@ -50,11 +50,11 @@ var deviceSubscribeCmd = &cobra.Command{ Long: `Requests a subscription on paths from a specified orchestrated network device on the controller. The device UUID and requested paths must be specified as a positional arguments.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { did, err := uuid.Parse(args[0]) if err != nil { pterm.Error.Println(err) - return err + return } subClient, err := pndAdapter.SubscribeMNEPath( @@ -73,7 +73,7 @@ The device UUID and requested paths must be specified as a positional arguments. ) if err != nil { pterm.Error.Println(err) - return err + return } for i := 0; i < 5; i++ { @@ -95,8 +95,6 @@ The device UUID and requested paths must be specified as a positional arguments. pterm.Println(subscribeResponse.String()) } - - return nil }, } diff --git a/cli/cmd/pluginList.go b/cli/cmd/pluginList.go index 2a87fc24617970c22e0f4ef067cb57b1e662b56c..8594f28364ff1973b34892daaed394ba88ff946f 100644 --- a/cli/cmd/pluginList.go +++ b/cli/cmd/pluginList.go @@ -44,12 +44,12 @@ var pluginListCmd = &cobra.Command{ Short: "List all information about available plugins.", Long: `List all information about abailable plugins.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Fetching list of available plugins from the controller.") resp, err := pndAdapter.GetAvailablePlugins(createContextWithAuthorization()) if err != nil { spinner.Fail(err) - return err + return } data := pterm.TableData{[]string{"UUID", "Name", "Author", "Firmware", "Version"}} @@ -62,10 +62,8 @@ var pluginListCmd = &cobra.Command{ err = pterm.DefaultTable.WithHasHeader().WithData(data).Render() if err != nil { - return err + return } - - return nil }, } diff --git a/cli/cmd/pndCreate.go b/cli/cmd/pndCreate.go index 5c3c83d53cbf3946cf23854cbd72b2538d291fb1..dc4c6c6c632b72e709452a8ed47063f89a141cd3 100644 --- a/cli/cmd/pndCreate.go +++ b/cli/cmd/pndCreate.go @@ -49,12 +49,12 @@ campus building or site. A description must be passed as positional argument.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Creating new PND") resp, err := api.AddPnd(createContextWithAuthorization(), viper.GetString("controllerApiEndpoint"), pndName, pndDescription) if err != nil { spinner.Fail(err) - return err + return } if resp.Status == ppb.Status_STATUS_OK { @@ -62,8 +62,6 @@ A description must be passed as positional argument.`, } else { spinner.Fail("Failed creating the PND with name: ", pndName) } - - return nil }, PostRun: func(cmd *cobra.Command, args []string) { // Necessary for prompt mode. The flag variables have to be resetted, diff --git a/cli/cmd/pndGet.go b/cli/cmd/pndGet.go index 1c2c0a4d6ca1bad19b05b811a03c43f396286d23..7fdabe07fa67e4c2e44077076a9b3fc88e32d96f 100644 --- a/cli/cmd/pndGet.go +++ b/cli/cmd/pndGet.go @@ -44,12 +44,12 @@ var pndGetCmd = &cobra.Command{ Short: "Request a PND by uuid.", Long: `Request a PND specified by uuid. The PND's UUID, Name and Description are returned.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Fetching requested PNDs from controller.") resp, err := api.GetPnd(createContextWithAuthorization(), viper.GetString("controllerApiEndpoint"), args[0]) if err != nil { spinner.Fail(err) - return err + return } pnd := resp.Pnd @@ -65,7 +65,6 @@ var pndGetCmd = &cobra.Command{ spinner.Success() pterm.DefaultBox.WithRightPadding(0).WithBottomPadding(0).Println(panels) - return nil }, } diff --git a/cli/cmd/pndList.go b/cli/cmd/pndList.go index 8e77bbb30bea376aad5c47ccc770180d3a4ef6cc..f6b15d422ac28f12f0a5a943caf56c5d6bdb9714 100644 --- a/cli/cmd/pndList.go +++ b/cli/cmd/pndList.go @@ -45,12 +45,12 @@ var pndListCmd = &cobra.Command{ Short: "List all information about the current PND", Long: `List all information about the current PND.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Fetching PND list from controller") resp, err := api.GetPnds(createContextWithAuthorization(), pndAdapter.Endpoint()) if err != nil { spinner.Fail(err) - return err + return } data := pterm.TableData{[]string{"UUID", "Name", "Description"}} @@ -62,10 +62,8 @@ var pndListCmd = &cobra.Command{ err = pterm.DefaultTable.WithHasHeader().WithData(data).Render() if err != nil { - return err + return } - - return nil }, } diff --git a/cli/cmd/pndRemove.go b/cli/cmd/pndRemove.go index 9b4eafca334f35733af1af290c40420ddcf84d72..3c641a8174032adf143882012caa98c4ad2a2a49 100644 --- a/cli/cmd/pndRemove.go +++ b/cli/cmd/pndRemove.go @@ -45,20 +45,19 @@ var pndRemoveCmd = &cobra.Command{ Short: "Removes the PND with the provided ID", Long: "Removes the PND with the provided ID", - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Removing PND with ID: ", args[0]) pid, err := uuid.Parse(args[0]) if err != nil { spinner.Fail(err) - return err + return } _, err = pndAdapter.RemovePnd(createContextWithAuthorization(), pid) if err != nil { spinner.Fail(err) - return err + return } spinner.Success("PND has been deleted, ID: ", pid.String()) - return nil }, } diff --git a/cli/cmd/pndUse.go b/cli/cmd/pndUse.go index 5e849e2b31367fa8982966ec246bff953c486f54..b1c0cee7c69399785812db70ccbfcd77859f9f65 100644 --- a/cli/cmd/pndUse.go +++ b/cli/cmd/pndUse.go @@ -46,19 +46,19 @@ var pndUseCmd = &cobra.Command{ Short: "change currently used PND for the CLI", Long: `Change currently used PND for the CLI.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { var newPND = args[0] newPndAdapter, err := adapter.NewPndAdapter(newPND, viper.GetString("controllerAPIEndpoint")) if err != nil { pterm.Error.Println(err) - return err + return } _, err = api.GetPnd(createContextWithAuthorization(), viper.GetString("controllerAPIEndpoint"), newPND) if err != nil { pterm.Error.Println(err) - return err + return } viper.Set("CLI_PND", newPND) @@ -66,11 +66,10 @@ var pndUseCmd = &cobra.Command{ err = viper.WriteConfig() if err != nil { pterm.Error.Println(err) - return err + return } pndAdapter = newPndAdapter pterm.Info.Printf("PND with ID: %s has been set for usage.\n", pndAdapter.ID().String()) - return nil }, } diff --git a/cli/cmd/prompt.go b/cli/cmd/prompt.go index af3559c09c67231d811752be1a201b3714e908e3..f297fe392b72c7f0b4bde44bc7e5bbcbd215b787 100644 --- a/cli/cmd/prompt.go +++ b/cli/cmd/prompt.go @@ -51,10 +51,17 @@ import ( var c *PromptCompleter +// suggestionTracker is used to keep track of the last used command in +// combination with the resulting suggestions. +type suggestionTracker struct { + lastCommand *cobra.Command + lastSuggestion []prompt.Suggest +} + // PromptCompleter provides completion for a Network Element. type PromptCompleter struct { YangSchemaCompleterMap map[uuid.UUID]*completer.YangSchemaCompleter - currentSuggestions []prompt.Suggest + lastSuggestions *suggestionTracker // nolint:unused document *prompt.Document history []string @@ -137,14 +144,14 @@ func filterFlagSlice(input []string) (commandSlice []string, flagSlice []string) return commandSlice, flagSlice } -func networkElementPathCompletion(c *PromptCompleter, d prompt.Document, inputSplit []string) []prompt.Suggest { +func networkElementPathCompletion(c *PromptCompleter, command *cobra.Command, d prompt.Document, inputSplit []string) []prompt.Suggest { switch inputLen := len(inputSplit); inputLen { case 3: - return c.updateSuggestionsThroughFunc(d, getNetworkElements) + return c.updateSuggestionsThroughFunc(d, command, getNetworkElements) case 4: id, err := uuid.Parse(inputSplit[inputLen-1]) if err != nil { - return c.updateSuggestionsThroughFunc(d, getNetworkElements) + return c.updateSuggestionsThroughFunc(d, command, getNetworkElements) } if c, ok := c.YangSchemaCompleterMap[id]; ok { return c.Complete(d) @@ -161,7 +168,7 @@ func networkElementPathCompletion(c *PromptCompleter, d prompt.Document, inputSp if d.GetWordBeforeCursor() == "" || d.GetWordAfterCursor() != "" { id, err := uuid.Parse(inputSplit[inputLen-2]) if err != nil { - return c.updateSuggestionsThroughFunc(d, getNetworkElements) + return c.updateSuggestionsThroughFunc(d, command, getNetworkElements) } if yc, ok := c.YangSchemaCompleterMap[id]; ok { err := yc.UpdateEntry(inputSplit[inputLen-1]) @@ -173,7 +180,7 @@ func networkElementPathCompletion(c *PromptCompleter, d prompt.Document, inputSp } id, err := uuid.Parse(inputSplit[inputLen-2]) if err != nil { - return c.updateSuggestionsThroughFunc(d, getNetworkElements) + return c.updateSuggestionsThroughFunc(d, command, getNetworkElements) } if yc, ok := c.YangSchemaCompleterMap[id]; ok { return yc.Complete(d) @@ -184,15 +191,19 @@ func networkElementPathCompletion(c *PromptCompleter, d prompt.Document, inputSp return []prompt.Suggest{} } -func (pc *PromptCompleter) updateSuggestionsThroughFunc(d prompt.Document, fn func() ([]prompt.Suggest, error)) []prompt.Suggest { - if pc.currentSuggestions == nil { +func (pc *PromptCompleter) updateSuggestionsThroughFunc(d prompt.Document, c *cobra.Command, fn func() ([]prompt.Suggest, error)) []prompt.Suggest { + if pc.lastSuggestions == nil { var err error - pc.currentSuggestions, err = fn() + newSuggestions, err := fn() + pc.lastSuggestions = &suggestionTracker{ + lastCommand: c, + lastSuggestion: newSuggestions, + } if err != nil { - return prompt.FilterHasPrefix(pc.currentSuggestions, d.GetWordBeforeCursor(), true) + return prompt.FilterHasPrefix(pc.lastSuggestions.lastSuggestion, d.GetWordBeforeCursor(), true) } } - return prompt.FilterHasPrefix(pc.currentSuggestions, d.GetWordBeforeCursor(), true) + return prompt.FilterHasPrefix(pc.lastSuggestions.lastSuggestion, d.GetWordBeforeCursor(), true) } func cobraCommandCompletion(currCmd *cobra.Command, d prompt.Document, inputFlags []string, loaded []prompt.Suggest) []prompt.Suggest { @@ -218,27 +229,53 @@ func completionBasedOnCmd(c *PromptCompleter, cmd *cobra.Command, inputSplit []s switch cmd { case pndUseCmd, pndGetCmd, pndRemoveCmd: if len(inputSplitFiltered) < 3 || (len(inputSplitFiltered) == 3 && d.GetWordBeforeCursor() != "") { - suggestions := c.updateSuggestionsThroughFunc(d, getPnds) + if c.lastSuggestions != nil { + lastCommand := c.lastSuggestions.lastCommand + if lastCommand != pndUseCmd && lastCommand != pndGetCmd && lastCommand != pndRemoveCmd { + c.lastSuggestions = nil + } + } + suggestions := c.updateSuggestionsThroughFunc(d, cmd, getPnds) return cobraCommandCompletion(cmd, d, inputFlags, suggestions) } case commitCmd: + if c.lastSuggestions != nil { + if c.lastSuggestions.lastCommand != commitCmd { + c.lastSuggestions = nil + } + } if len(inputSplitFiltered) < 3 || (len(inputSplitFiltered) == 3 && d.GetWordBeforeCursor() != "") { - return c.updateSuggestionsThroughFunc(d, getPendingChanges) + return c.updateSuggestionsThroughFunc(d, cmd, getPendingChanges) } case confirmCmd: + if c.lastSuggestions != nil { + if c.lastSuggestions.lastCommand != confirmCmd { + c.lastSuggestions = nil + } + } if len(inputSplitFiltered) < 3 || (len(inputSplitFiltered) == 3 && d.GetWordBeforeCursor() != "") { - return c.updateSuggestionsThroughFunc(d, getCommittedChanges) + return c.updateSuggestionsThroughFunc(d, cmd, getCommittedChanges) } case networkElementRemoveCmd: + if c.lastSuggestions != nil { + if c.lastSuggestions.lastCommand != networkElementRemoveCmd { + c.lastSuggestions = nil + } + } if len(inputSplitFiltered) < 3 || (len(inputSplitFiltered) == 3 && d.GetWordBeforeCursor() != "") { - return c.updateSuggestionsThroughFunc(d, getNetworkElements) + return c.updateSuggestionsThroughFunc(d, cmd, getNetworkElements) } case networkElementCreateCmd: + if c.lastSuggestions != nil { + if c.lastSuggestions.lastCommand != networkElementCreateCmd { + c.lastSuggestions = nil + } + } if len(inputFlags) != 0 { if inputFlags[len(inputFlags)-1] == "--plugin-id" && ((inputSplit[len(inputSplit)-1] == "--plugin-id" && d.GetWordBeforeCursor() == "") || (inputSplit[len(inputSplit)-2] == "--plugin-id" && d.GetWordBeforeCursor() != "")) { - return c.updateSuggestionsThroughFunc(d, getAvailablePlugins) + return c.updateSuggestionsThroughFunc(d, cmd, getAvailablePlugins) } else { return cobraCommandCompletion(cmd, d, inputFlags, []prompt.Suggest{}) } @@ -246,7 +283,13 @@ func completionBasedOnCmd(c *PromptCompleter, cmd *cobra.Command, inputSplit []s return cobraCommandCompletion(cmd, d, inputFlags, []prompt.Suggest{}) } case networkElementPathGetCmd, networkElementPathGetIntendedCmd, networkElementPathSetCmd: - return networkElementPathCompletion(c, d, inputSplitFiltered) + if c.lastSuggestions != nil { + lastCommand := c.lastSuggestions.lastCommand + if lastCommand != networkElementPathGetCmd && lastCommand != networkElementPathGetIntendedCmd && lastCommand != networkElementPathSetCmd { + c.lastSuggestions = nil + } + } + return networkElementPathCompletion(c, cmd, d, inputSplitFiltered) case networkElementShowCmd: networkElements, err := getNetworkElements() if err != nil { @@ -254,7 +297,7 @@ func completionBasedOnCmd(c *PromptCompleter, cmd *cobra.Command, inputSplit []s } return networkElements case networkElementCmd, pndCmd, changeCmd: - c.currentSuggestions = nil + c.lastSuggestions = nil return cobraCommandCompletion(cmd, d, inputFlags, []prompt.Suggest{}) default: return cobraCommandCompletion(cmd, d, inputFlags, []prompt.Suggest{}) @@ -387,7 +430,7 @@ var exitCmd = &cobra.Command{ Short: "The exit command exits the interactive prompt mode.", Long: `The exit command exits the interactive prompt mode.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { rawModeOff := exec.Command("/bin/stty", "-raw", "echo") rawModeOff.Stdin = os.Stdin @@ -396,9 +439,7 @@ var exitCmd = &cobra.Command{ logrus.Error(err) os.Exit(1) } - os.Exit(0) - return nil }, } @@ -408,11 +449,9 @@ var promptCmd = &cobra.Command{ Long: `The prompt command rund the CLI in an interactive shell and provides the user with autocompletion and more...`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { c = NewPromptCompleter() c.Run() - - return nil }, } diff --git a/cli/cmd/userCreate.go b/cli/cmd/userCreate.go index f233acaf81e021c16198cf91b2d6a98d5df6fa02..8a07b75ce3ebae205769dbc0fdb36349d751a6ec 100644 --- a/cli/cmd/userCreate.go +++ b/cli/cmd/userCreate.go @@ -34,6 +34,7 @@ package cmd import ( apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac" "code.fbi.h-da.de/danet/gosdn/controller/api" + "github.com/pterm/pterm" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -47,7 +48,7 @@ var userCreateCmd = &cobra.Command{ User name and password hashed with (add hash method here!) required, role is optional but needed to operate on PNDs.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { roles := map[string]string{} // only active pnd for now, add option for additional param later @@ -64,11 +65,10 @@ var userCreateCmd = &cobra.Command{ resp, err := api.CreateUsers(createContextWithAuthorization(), viper.GetString("controllerAPIEndpoint"), users) if err != nil { - return err + pterm.Error.Println(err) + return } log.Infof("Users created: %v", resp.Status) - - return nil }, PostRun: func(cmd *cobra.Command, args []string) { // Necessary for prompt mode. The flag variables have to be resetted, diff --git a/cli/cmd/userDelete.go b/cli/cmd/userDelete.go index 160ed5f49260bb15662e7c08f7e4411b17ec8e85..aa9fdc610d1af052c60da902101bb2db495dbc91 100644 --- a/cli/cmd/userDelete.go +++ b/cli/cmd/userDelete.go @@ -33,6 +33,7 @@ package cmd import ( "code.fbi.h-da.de/danet/gosdn/controller/api" + "github.com/pterm/pterm" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -45,18 +46,17 @@ var userDeleteCmd = &cobra.Command{ Long: `Deletes a user with provided data. Requires the user name of the user which should be deleted.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { // only one user for now, add more later if needed users := []string{nbUserName} resp, err := api.DeleteUsers(createContextWithAuthorization(), viper.GetString("controllerAPIEndpoint"), users) if err != nil { - return err + pterm.Error.Println(err) + return } log.Infof("Users deleted: %v", resp.Status) - - return nil }, PostRun: func(cmd *cobra.Command, args []string) { // Necessary for prompt mode. The flag variables have to be resetted, diff --git a/cli/cmd/userGet.go b/cli/cmd/userGet.go index f235141dc04f50ec9b2eef8007c7c11c5ad402c0..357966913129735b7c630689224ac698b96bf017 100644 --- a/cli/cmd/userGet.go +++ b/cli/cmd/userGet.go @@ -34,6 +34,7 @@ package cmd import ( "code.fbi.h-da.de/danet/gosdn/controller/api" "github.com/google/uuid" + "github.com/pterm/pterm" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -45,7 +46,7 @@ var userGetCmd = &cobra.Command{ Short: "Requests one user", Long: `Requests one user using the provided name to search for it in the stored users.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { resp, err := api.GetUser( createContextWithAuthorization(), viper.GetString("controllerAPIEndpoint"), @@ -53,15 +54,14 @@ var userGetCmd = &cobra.Command{ uuid.Nil, ) if err != nil { - return err + pterm.Error.Println(err) + return } log.Infof("ID: %v, Name: %v \n", resp.User.Id, resp.User.Name) for key, elem := range resp.User.Roles { log.Infof("Role on PND: %v %v \n", key, elem) } - - return nil }, PostRun: func(cmd *cobra.Command, args []string) { // Necessary for prompt mode. The flag variables have to be resetted, diff --git a/cli/cmd/userGetAll.go b/cli/cmd/userGetAll.go index cc9fa09734915861c6149b268d35c66bce5d6eb8..8a5c650f0a1a396cfad9d8f2d7fd272149841f1f 100644 --- a/cli/cmd/userGetAll.go +++ b/cli/cmd/userGetAll.go @@ -33,6 +33,7 @@ package cmd import ( "code.fbi.h-da.de/danet/gosdn/controller/api" + "github.com/pterm/pterm" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -44,10 +45,11 @@ var userGetAllCmd = &cobra.Command{ Short: "Requests all the available users", Long: `Requests all the available users.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { resp, err := api.GetAllUsers(createContextWithAuthorization(), viper.GetString("controllerAPIEndpoint")) if err != nil { - return err + pterm.Error.Println(err) + return } for i, u := range resp.User { @@ -56,8 +58,6 @@ var userGetAllCmd = &cobra.Command{ log.Infof("Role on PND: %v %v \n", key, elem) } } - - return nil }, } diff --git a/cli/cmd/userUpdate.go b/cli/cmd/userUpdate.go index 23c62b3215582fdb318d703deae1ec4a65d66a1a..7849d583595cef4396e23508b2c9d3093b03917f 100644 --- a/cli/cmd/userUpdate.go +++ b/cli/cmd/userUpdate.go @@ -35,6 +35,7 @@ import ( apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac" "code.fbi.h-da.de/danet/gosdn/controller/api" "github.com/google/uuid" + "github.com/pterm/pterm" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -48,7 +49,7 @@ var userUpdateCmd = &cobra.Command{ User name and password hashed with (add hash method here!) required, role is optional but needed to operate on PNDs.`, - RunE: func(cmd *cobra.Command, args []string) error { + Run: func(cmd *cobra.Command, args []string) { existingUser, err := api.GetUser( createContextWithAuthorization(), viper.GetString("controllerAPIEndpoint"), @@ -56,7 +57,8 @@ var userUpdateCmd = &cobra.Command{ uuid.Nil, ) if err != nil { - return err + pterm.Error.Println(err) + return } roles := map[string]string{} @@ -76,11 +78,10 @@ var userUpdateCmd = &cobra.Command{ resp, err := api.UpdateUsers(createContextWithAuthorization(), viper.GetString("controllerAPIEndpoint"), users) if err != nil { - return err + pterm.Error.Println(err) + return } log.Infof("Users updated: %v", resp.Status) - - return nil }, PostRun: func(cmd *cobra.Command, args []string) { // Necessary for prompt mode. The flag variables have to be resetted, diff --git a/go.sum b/go.sum index 30bfd8d308e7b4f5ffb3b5f18957435efb520de6..c68dd12cd1a79d1195616fe64fa05a71c174d499 100644 --- a/go.sum +++ b/go.sum @@ -547,8 +547,6 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.17.0 h1:Rme6CE1aUTyV9WmrEPyGf1V+7W3iQzZ1DZkKnT6z9B0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.17.0/go.mod h1:Hbb13e3/WtqQ8U5hLGkek9gJvBLasHuPFI0UEGfnQ10= github.com/grpc-ecosystem/grpc-gateway/v2 v2.17.1 h1:LSsiG61v9IzzxMkqEr6nrix4miJI62xlRjwT7BYD2SM= github.com/grpc-ecosystem/grpc-gateway/v2 v2.17.1/go.mod h1:Hbb13e3/WtqQ8U5hLGkek9gJvBLasHuPFI0UEGfnQ10= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= @@ -882,8 +880,6 @@ github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEej github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE= github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8= github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s= -github.com/pterm/pterm v0.12.66 h1:bjsoMyUstaarzJ1NG7+1HGT7afR0JVMYsR3ooPeh4bo= -github.com/pterm/pterm v0.12.66/go.mod h1:nFuT9ZVkkCi8o4L1dtWuYPwDQxggLh4C263qG5nTLpQ= github.com/pterm/pterm v0.12.67 h1:5iB7ajIQROYfxYD7+sFJ4+KJhFJ+xn7QOVBm4s6RUF0= github.com/pterm/pterm v0.12.67/go.mod h1:nFuT9ZVkkCi8o4L1dtWuYPwDQxggLh4C263qG5nTLpQ= github.com/rabbitmq/amqp091-go v1.8.1 h1:RejT1SBUim5doqcL6s7iN6SBmsQqyTgXb1xMlH0h1hA=