diff --git a/cli/cmd/changeCommit.go b/cli/cmd/changeCommit.go index 744a90eeb22053b718c5a0b55489e9c78dfc2454..46d3acd19873d18035345d1d48ea2c742b819bc9 100644 --- a/cli/cmd/changeCommit.go +++ b/cli/cmd/changeCommit.go @@ -52,10 +52,7 @@ Change UUID must be specified as positional argument.`, return } - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - resp, err := pndAdapter.Commit(ctx, cuid) + resp, err := pndAdapter.Commit(cmd.Context(), cuid) if err != nil { pterm.Error.Println(err) return diff --git a/cli/cmd/changeConfirm.go b/cli/cmd/changeConfirm.go index a67b8392687bd74990b216fbfb6082f044206ca1..51ad315945bdc0d8eb66c1d8e64643875fa53b84 100644 --- a/cli/cmd/changeConfirm.go +++ b/cli/cmd/changeConfirm.go @@ -52,10 +52,7 @@ Change UUID must be specified as positional argument`, return } - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - resp, err := pndAdapter.Confirm(ctx, cuid) + resp, err := pndAdapter.Confirm(cmd.Context(), cuid) if err != nil { pterm.Error.Println(err) return diff --git a/cli/cmd/changeGet.go b/cli/cmd/changeGet.go index debb73d8a1b318cf69e7903d3c82d2a498f0a12e..470646c77344b0bf1c36c49008d6709643044a4a 100644 --- a/cli/cmd/changeGet.go +++ b/cli/cmd/changeGet.go @@ -46,10 +46,7 @@ var getCmd = &cobra.Command{ changes UUID has to be specified via a positional argument.`, Run: func(cmd *cobra.Command, args []string) { - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - changes, err := pndAdapter.GetChange(ctx, args[0]) + changes, err := pndAdapter.GetChange(cmd.Context(), args[0]) if err != nil { pterm.Error.Println(err) return diff --git a/cli/cmd/changeList.go b/cli/cmd/changeList.go index bbe5834614fa6f81445a94ce14ed7f01026fb9e7..bf86def5d6bca6799f10e2b61e214ebbb6db01cc 100644 --- a/cli/cmd/changeList.go +++ b/cli/cmd/changeList.go @@ -45,19 +45,13 @@ var changeListCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Process change list request") - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - committed, err := pndAdapter.CommittedChanges(ctx) + committed, err := pndAdapter.CommittedChanges(cmd.Context()) if err != nil { spinner.Fail(err) return } - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - pending, err := pndAdapter.PendingChanges(ctx) + pending, err := pndAdapter.PendingChanges(cmd.Context()) if err != nil { spinner.Fail(err) return diff --git a/cli/cmd/list.go b/cli/cmd/list.go index 6427712a7a591f86896bc0e784ec5478f9bdca5d..885dc6741b98b3b42405866cd336d14114b32e54 100644 --- a/cli/cmd/list.go +++ b/cli/cmd/list.go @@ -47,18 +47,14 @@ var listCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { addr := viper.GetString("controllerApiEndpoint") - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - resp, err := api.GetIds(ctx, addr) + resp, err := api.GetIds(cmd.Context(), addr) if err != nil { pterm.Error.Println(err) return } for i, pnd := range resp { - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - mneResp, err := api.GetFlattenedNetworkElements(ctx, addr, pnd.GetId()) + mneResp, err := api.GetFlattenedNetworkElements(cmd.Context(), addr, pnd.GetId()) if err != nil { pterm.Error.Println(err) return diff --git a/cli/cmd/login.go b/cli/cmd/login.go index 60a685bcd32ffe7fcbcda7f51ea32326d6e8f12b..7439ca243c2d3bcf050eb8137173b38bf7ddf224 100644 --- a/cli/cmd/login.go +++ b/cli/cmd/login.go @@ -56,10 +56,7 @@ var loginCmd = &cobra.Command{ pterm.Info.Println("New controller address: ", viper.GetString("controllerAPIEndpoint")) } - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - resp, err := api.Login(ctx, viper.GetString("controllerAPIEndpoint"), nbUserName, nbUserPwd) + resp, err := api.Login(cmd.Context(), viper.GetString("controllerAPIEndpoint"), nbUserName, nbUserPwd) if err != nil { spinner.Fail("Login failed: ", err) return diff --git a/cli/cmd/logout.go b/cli/cmd/logout.go index f042097b4fcc42742ebbcc432b757270b8fb93c7..662e89c97ecfa2ce65fa05fac4c722a73638808d 100644 --- a/cli/cmd/logout.go +++ b/cli/cmd/logout.go @@ -48,11 +48,7 @@ var logoutCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Logout attempt for user: ", nbUserName) - - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - resp, err := api.Logout(ctx, viper.GetString("controllerAPIEndpoint"), nbUserName) + resp, err := api.Logout(cmd.Context(), viper.GetString("controllerAPIEndpoint"), nbUserName) if err != nil { spinner.Fail("Logout failed: ", err) return diff --git a/cli/cmd/networkElementCreate.go b/cli/cmd/networkElementCreate.go index ffffd5e25c35922713a5d9299febd91ca08ad7bf..25aac3d4d276f6953361ed81a43a8f2791c63b85 100644 --- a/cli/cmd/networkElementCreate.go +++ b/cli/cmd/networkElementCreate.go @@ -71,10 +71,7 @@ if they diverge from the default credentials (user:'admin' and pw:'arista').`, return } - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - resp, err := pndAdapter.AddNetworkElement(ctx, mneName, opt, pluginUUID) + resp, err := pndAdapter.AddNetworkElement(cmd.Context(), mneName, opt, pluginUUID) if err != nil { spinner.Fail(err) return diff --git a/cli/cmd/networkElementList.go b/cli/cmd/networkElementList.go index 1ec9fdb7bcaac6cabc225631d85f41502ca1c06d..941b86a918aeb914b9d6b222cd331c9fb1c0d1fc 100644 --- a/cli/cmd/networkElementList.go +++ b/cli/cmd/networkElementList.go @@ -47,10 +47,7 @@ var networkElementListCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Fetching data from controller") - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - resp, err := pndAdapter.GetFlattenedNetworkElements(ctx) + resp, err := pndAdapter.GetFlattenedNetworkElements(cmd.Context()) if err != nil { spinner.Fail(err) return diff --git a/cli/cmd/networkElementPathDelete.go b/cli/cmd/networkElementPathDelete.go index ee81e442565f368de90a791d33a78328af305191..3a0e56497fbbc77745bf9f310bd41e1fade115bd 100644 --- a/cli/cmd/networkElementPathDelete.go +++ b/cli/cmd/networkElementPathDelete.go @@ -62,11 +62,8 @@ The network element UUID and request path must be specified as a positional argu return } - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - resp, err := pndAdapter.ChangeMNE( - ctx, + cmd.Context(), mneid, mnepb.ApiOperation_API_OPERATION_DELETE, path, diff --git a/cli/cmd/networkElementPathGet.go b/cli/cmd/networkElementPathGet.go index 56c99dab9a9ede72a7305606accf30b331755b72..476116686ca522b8b5546fc7a99c2f454844be7f 100644 --- a/cli/cmd/networkElementPathGet.go +++ b/cli/cmd/networkElementPathGet.go @@ -54,11 +54,8 @@ The network element UUID and request path must be specified as a positional argu return } - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - res, err := pndAdapter.RequestPath( - ctx, + cmd.Context(), mneid, args[1], ) diff --git a/cli/cmd/networkElementPathGetIntended.go b/cli/cmd/networkElementPathGetIntended.go index b8ceba56cf7e4c785a7ab7bbcf88b8dac0636c21..ca422869f3264dcd5d85e9c7183048f489c08c60 100644 --- a/cli/cmd/networkElementPathGetIntended.go +++ b/cli/cmd/networkElementPathGetIntended.go @@ -56,11 +56,8 @@ The network element UUID and request path must be specified as a positional argu return } - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - res, err := pndAdapter.RequestIntendedPath( - ctx, + cmd.Context(), mneid, args[1], ) diff --git a/cli/cmd/networkElementPathSet.go b/cli/cmd/networkElementPathSet.go index 087b95e6a8a0e6f6927eff03319f5ac82b238718..937fcf1e7a84f5e82e0ca5d7604f0026399d29ab 100644 --- a/cli/cmd/networkElementPathSet.go +++ b/cli/cmd/networkElementPathSet.go @@ -119,11 +119,8 @@ To enable replacing behaviour (destructive!), set the --replace flag."`, return } - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - resp, err := pndAdapter.ChangeMNE( - ctx, + cmd.Context(), mneid, operation, path, diff --git a/cli/cmd/networkElementRemove.go b/cli/cmd/networkElementRemove.go index 1e80546a8085993d0d615f71847aeaf6860c1f6e..ec1a912938238db41f47c49f14ec47a950dfad6a 100644 --- a/cli/cmd/networkElementRemove.go +++ b/cli/cmd/networkElementRemove.go @@ -55,10 +55,7 @@ The network element UUID must be specified as a positional argument.`, return } - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - _, err = pndAdapter.RemoveNetworkElement(ctx, mneid) + _, err = pndAdapter.RemoveNetworkElement(cmd.Context(), mneid) if err != nil { spinner.Fail(err) return diff --git a/cli/cmd/networkElementShow.go b/cli/cmd/networkElementShow.go index 7213814866527d6cc702dbcd649d0aace15683c5..683f2350f88ad02b022f4582a1a2e749f96f3792 100644 --- a/cli/cmd/networkElementShow.go +++ b/cli/cmd/networkElementShow.go @@ -47,10 +47,7 @@ The network element information returned is the information as currently stored The actual network element is not queried directly.`, Run: func(cmd *cobra.Command, args []string) { - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - resp, err := pndAdapter.GetNetworkElement(ctx, args[0]) + resp, err := pndAdapter.GetNetworkElement(cmd.Context(), args[0]) if err != nil { pterm.Error.Println(err) return diff --git a/cli/cmd/networkElementSubscribe.go b/cli/cmd/networkElementSubscribe.go index 554e1e12a58ec93c6e7b474e0e36e31d5b3e9982..1180af84325aee999b8323d22d2aedfb4f9e0863 100644 --- a/cli/cmd/networkElementSubscribe.go +++ b/cli/cmd/networkElementSubscribe.go @@ -57,11 +57,8 @@ The device UUID and requested paths must be specified as a positional arguments. return } - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - subClient, err := pndAdapter.SubscribeMNEPath( - ctx, + cmd.Context(), did, &mnepb.SubscriptionList{ Subscription: []*mnepb.Subscription{ diff --git a/cli/cmd/pluginList.go b/cli/cmd/pluginList.go index 4b6e189353b77ada597d3d0a8f5ce1e2140be084..cb64ca5f04f0194031e432dd661352ef245facc2 100644 --- a/cli/cmd/pluginList.go +++ b/cli/cmd/pluginList.go @@ -47,10 +47,7 @@ var pluginListCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Fetching list of available plugins from the controller.") - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - resp, err := pndAdapter.GetAvailablePlugins(ctx) + resp, err := pndAdapter.GetAvailablePlugins(cmd.Context()) if err != nil { spinner.Fail(err) return diff --git a/cli/cmd/pndCreate.go b/cli/cmd/pndCreate.go index 4e2ed18088949c9012aafcca2d8477dd41601f07..fdfb3cb944c52e3c9c58acabd8e4f5bd757a1d8b 100644 --- a/cli/cmd/pndCreate.go +++ b/cli/cmd/pndCreate.go @@ -52,10 +52,7 @@ A description must be passed as positional argument.`, Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Creating new PND") - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - resp, err := api.AddPnd(ctx, viper.GetString("controllerApiEndpoint"), pndName, pndDescription) + resp, err := api.AddPnd(cmd.Context(), viper.GetString("controllerApiEndpoint"), pndName, pndDescription) if err != nil { spinner.Fail(err) return diff --git a/cli/cmd/pndGet.go b/cli/cmd/pndGet.go index 5fecaed109d83a06505269e8cd65c082d086e6f2..b9f82172fd29308f5f294bdc74da0a68036756a1 100644 --- a/cli/cmd/pndGet.go +++ b/cli/cmd/pndGet.go @@ -47,10 +47,7 @@ var pndGetCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Fetching requested PNDs from controller.") - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - resp, err := api.GetPnd(ctx, viper.GetString("controllerApiEndpoint"), args[0]) + resp, err := api.GetPnd(cmd.Context(), viper.GetString("controllerApiEndpoint"), args[0]) if err != nil { spinner.Fail(err) return diff --git a/cli/cmd/pndList.go b/cli/cmd/pndList.go index 51adf9946f52a1107e105c5b83c6ede3f0612949..9e216b82f035e0ca215f3ef88a09595312d6fced 100644 --- a/cli/cmd/pndList.go +++ b/cli/cmd/pndList.go @@ -48,10 +48,7 @@ var pndListCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Fetching PND list from controller") - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - resp, err := api.GetPnds(ctx, pndAdapter.Endpoint()) + resp, err := api.GetPnds(cmd.Context(), pndAdapter.Endpoint()) if err != nil { spinner.Fail(err) return diff --git a/cli/cmd/pndRemove.go b/cli/cmd/pndRemove.go index 4ed1032816777c35cd589f5ab4a67e6f56b73bea..24b9081b742c7ef586c71babe87910959e6563be 100644 --- a/cli/cmd/pndRemove.go +++ b/cli/cmd/pndRemove.go @@ -53,10 +53,7 @@ var pndRemoveCmd = &cobra.Command{ return } - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - _, err = pndAdapter.RemovePnd(ctx, pid) + _, err = pndAdapter.RemovePnd(cmd.Context(), pid) if err != nil { spinner.Fail(err) return diff --git a/cli/cmd/pndUse.go b/cli/cmd/pndUse.go index 03835c08132e5f94ff39a398054e5708eaf2213b..750eac3773a3ab8aedb90ef280f0f6b2e783f330 100644 --- a/cli/cmd/pndUse.go +++ b/cli/cmd/pndUse.go @@ -55,10 +55,7 @@ var pndUseCmd = &cobra.Command{ return } - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - _, err = api.GetPnd(ctx, viper.GetString("controllerAPIEndpoint"), newPND) + _, err = api.GetPnd(cmd.Context(), viper.GetString("controllerAPIEndpoint"), newPND) if err != nil { pterm.Error.Println(err) return diff --git a/cli/cmd/prompt.go b/cli/cmd/prompt.go index 4fe3141ff4d7b19ceeb88dbe8eb37490c4b24b87..fcbfb97cc48ea67e80b49110fd5b3e153b2ae328 100644 --- a/cli/cmd/prompt.go +++ b/cli/cmd/prompt.go @@ -32,24 +32,31 @@ POSSIBILITY OF SUCH DAMAGE. package cmd import ( + "context" "os" "os/exec" "strings" + "syscall" "code.fbi.h-da.de/danet/gosdn/cli/completer" "code.fbi.h-da.de/danet/gosdn/controller/api" "github.com/c-bata/go-prompt" "github.com/google/uuid" "github.com/openconfig/goyang/pkg/yang" + "github.com/pkg/term/termios" "github.com/pterm/pterm" "github.com/pterm/pterm/putils" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/spf13/viper" + "golang.org/x/sys/unix" ) var c *PromptCompleter +var fd int +var originalTermios *unix.Termios +var mutContext *ContextMutable // suggestionTracker is used to keep track of the last used command in // combination with the resulting suggestions. @@ -67,6 +74,10 @@ type PromptCompleter struct { history []string } +type ContextMutable struct { + context.Context +} + // NewPromptCompleter returns a new promptCompleter. func NewPromptCompleter() *PromptCompleter { return &PromptCompleter{ @@ -105,6 +116,19 @@ func (pc *PromptCompleter) Run() { prompt.OptionSelectedDescriptionTextColor(prompt.DarkGray), ) + var err error + + fd, err = syscall.Open("/dev/tty", syscall.O_RDONLY, 0) + if err != nil { + panic(err) + } + + // get the original settings + originalTermios, err = termios.Tcgetattr(uintptr(fd)) + if err != nil { + panic(err) + } + p.Run() } @@ -112,8 +136,18 @@ func executeFunc(s string) { if s := strings.TrimSpace(s); s == "" { return } + // restore the original settings to allow ctrl-c to generate signal + if err := termios.Tcsetattr(uintptr(fd), termios.TCSANOW, (*unix.Termios)(originalTermios)); err != nil { + panic(err) + } + + ctx, ctxCancelFn := createContextWithAuthorization() + + mutContext.Context = ctx + + startContextListener(mutContext, ctxCancelFn) rootCmd.SetArgs(strings.Fields(s)) - err := rootCmd.Execute() + err := rootCmd.ExecuteContext(mutContext) if err != nil { pterm.Error.Println("Could not execute:", err) @@ -312,7 +346,8 @@ func completionBasedOnCmd(c *PromptCompleter, cmd *cobra.Command, inputSplit []s func getNetworkElements() ([]prompt.Suggest, error) { spinner, _ := pterm.DefaultSpinner.Start("Fetching Network Elements from controller.") // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() + ctx, ctxCancelFn := createContextWithAuthorization() + startContextListener(ctx, ctxCancelFn) resp, err := pndAdapter.GetFlattenedNetworkElements(ctx) if err != nil { spinner.Fail(err) @@ -330,7 +365,8 @@ func getNetworkElements() ([]prompt.Suggest, error) { func getAvailablePlugins() ([]prompt.Suggest, error) { spinner, _ := pterm.DefaultSpinner.Start("Fetching available plugins from controller.") // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() + ctx, ctxCancelFn := createContextWithAuthorization() + startContextListener(ctx, ctxCancelFn) resp, err := pndAdapter.GetAvailablePlugins(ctx) if err != nil { spinner.Fail(err) @@ -351,7 +387,8 @@ func getAvailablePlugins() ([]prompt.Suggest, error) { func getSchemaTreeForNetworkElementID(id uuid.UUID) (map[string]*yang.Entry, error) { spinner, _ := pterm.DefaultSpinner.Start("Fetching schema tree for Device with ID: ", id) // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() + ctx, ctxCancelFn := createContextWithAuthorization() + startContextListener(ctx, ctxCancelFn) networkElement, err := pndAdapter.GetFlattenedNetworkElement(ctx, id.String()) if err != nil { spinner.Fail(err) @@ -362,6 +399,7 @@ func getSchemaTreeForNetworkElementID(id uuid.UUID) (map[string]*yang.Entry, err pluginUUID := uuid.MustParse(pluginID) // create a authorizedContext for further requests ctx, ctxCancelFn = createContextWithAuthorization() + startContextListener(ctx, ctxCancelFn) schemaTree, err := pndAdapter.GetPluginSchemaTree(ctx, pluginUUID) if err != nil { spinner.Fail(err) @@ -377,7 +415,8 @@ func getSchemaTreeForNetworkElementID(id uuid.UUID) (map[string]*yang.Entry, err func getPnds() ([]prompt.Suggest, error) { spinner, _ := pterm.DefaultSpinner.Start("Fetching PNDs from controller.") // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() + ctx, ctxCancelFn := createContextWithAuthorization() + startContextListener(ctx, ctxCancelFn) resp, err := api.GetIds(ctx, viper.GetString("controllerAPIEndpoint")) if err != nil { spinner.Fail(err) @@ -399,7 +438,8 @@ func getPnds() ([]prompt.Suggest, error) { func getPendingChanges() ([]prompt.Suggest, error) { spinner, _ := pterm.DefaultSpinner.Start("Fetching committed changes.") // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() + ctx, ctxCancelFn := createContextWithAuthorization() + startContextListener(ctx, ctxCancelFn) resp, err := pndAdapter.PendingChanges(ctx) if err != nil { spinner.Fail(err) @@ -421,7 +461,8 @@ func getPendingChanges() ([]prompt.Suggest, error) { func getCommittedChanges() ([]prompt.Suggest, error) { spinner, _ := pterm.DefaultSpinner.Start("Fetching pending changes.") // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() + ctx, ctxCancelFn := createContextWithAuthorization() + startContextListener(ctx, ctxCancelFn) resp, err := pndAdapter.CommittedChanges(ctx) if err != nil { spinner.Fail(err) @@ -461,6 +502,7 @@ var promptCmd = &cobra.Command{ provides the user with autocompletion and more...`, Run: func(cmd *cobra.Command, args []string) { + mutContext = &ContextMutable{Context: nil} c = NewPromptCompleter() c.Run() }, diff --git a/cli/cmd/root.go b/cli/cmd/root.go index bb88e3c96dd43d05e4bb6a479ea8ae495eca0c93..15aec3bcc0965ed5a80898434bb1576dc81f58d4 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -31,11 +31,9 @@ POSSIBILITY OF SUCH DAMAGE. package cmd import ( - "context" "errors" "fmt" "os" - "os/signal" "code.fbi.h-da.de/danet/gosdn/cli/adapter" @@ -55,9 +53,6 @@ var nbUserName string var nbUserPwd string var userToken string -var ctx context.Context -var ctxCancelFn context.CancelFunc - var pndAdapter *adapter.PndAdapter // rootCmd represents the base command when called without any subcommands. @@ -76,7 +71,9 @@ The login command must be called for authorization. // Execute adds all child commands to the root command and sets flags appropriately. // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { - err := rootCmd.Execute() + ctx, ctxCancelFn := createContextWithAuthorization() + startContextListener(ctx, ctxCancelFn) + err := rootCmd.ExecuteContext(ctx) if err != nil { log.Error("Could not execute root command: ", err) } @@ -84,8 +81,7 @@ func Execute() { } func init() { - ctx, ctxCancelFn = context.WithCancel(context.Background()) - cobra.OnInitialize(initConfig, startContextListener) + cobra.OnInitialize(initConfig) // add CLI global parameters rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (./.gosdnc.toml)") @@ -95,19 +91,6 @@ func init() { rootCmd.Flags().StringVar(&grpcPort, "grpc-port", "55055", "port for gRPC NBI") } -func startContextListener() { - // listen for CTRL-C as interrupt - ch := make(chan os.Signal, 1) - signal.Notify(ch, os.Interrupt) - go func() { - select { - case <-ch: - ctxCancelFn() - case <-ctx.Done(): - } - }() -} - // initConfig reads in config file and ENV variables if set. func initConfig() { configFileName := ".gosdnc.toml" diff --git a/cli/cmd/userCreate.go b/cli/cmd/userCreate.go index fab47e9d24d09fdf060aea693002f5ffe5d652f2..6f969e2c019170705c3d3c11a8f9767371628462 100644 --- a/cli/cmd/userCreate.go +++ b/cli/cmd/userCreate.go @@ -63,10 +63,7 @@ var userCreateCmd = &cobra.Command{ }, } - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - resp, err := api.CreateUsers(ctx, viper.GetString("controllerAPIEndpoint"), users) + resp, err := api.CreateUsers(cmd.Context(), viper.GetString("controllerAPIEndpoint"), users) if err != nil { pterm.Error.Println(err) return diff --git a/cli/cmd/userDelete.go b/cli/cmd/userDelete.go index 4fd0bc5251453e55b43da112bd38a10c083b5503..a12a03c508e94e234c359e1adc081163790c57ec 100644 --- a/cli/cmd/userDelete.go +++ b/cli/cmd/userDelete.go @@ -51,10 +51,7 @@ var userDeleteCmd = &cobra.Command{ // only one user for now, add more later if needed users := []string{nbUserName} - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - resp, err := api.DeleteUsers(ctx, viper.GetString("controllerAPIEndpoint"), users) + resp, err := api.DeleteUsers(cmd.Context(), viper.GetString("controllerAPIEndpoint"), users) if err != nil { pterm.Error.Println(err) return diff --git a/cli/cmd/userGet.go b/cli/cmd/userGet.go index 0aadd3767922ffed9361a0e5ddd4d840c3c5663b..db387fe89c78d8419b84909843462f51235b6269 100644 --- a/cli/cmd/userGet.go +++ b/cli/cmd/userGet.go @@ -47,11 +47,8 @@ var userGetCmd = &cobra.Command{ Long: `Requests one user using the provided name to search for it in the stored users.`, Run: func(cmd *cobra.Command, args []string) { - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - resp, err := api.GetUser( - ctx, + cmd.Context(), viper.GetString("controllerAPIEndpoint"), nbUserName, uuid.Nil, diff --git a/cli/cmd/userGetAll.go b/cli/cmd/userGetAll.go index a2611d3400334fe745feb9e426d80120fcc81869..d262c821e1e617ff2b71a117242bc16c258b082f 100644 --- a/cli/cmd/userGetAll.go +++ b/cli/cmd/userGetAll.go @@ -46,10 +46,7 @@ var userGetAllCmd = &cobra.Command{ Long: `Requests all the available users.`, Run: func(cmd *cobra.Command, args []string) { - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - resp, err := api.GetAllUsers(ctx, viper.GetString("controllerAPIEndpoint")) + resp, err := api.GetAllUsers(cmd.Context(), viper.GetString("controllerAPIEndpoint")) if err != nil { pterm.Error.Println(err) return diff --git a/cli/cmd/userUpdate.go b/cli/cmd/userUpdate.go index 2130f9867cbfc653f10616cd701c7b084d03faba..70f122231b114bdda88a9adf6df47101afc8d085 100644 --- a/cli/cmd/userUpdate.go +++ b/cli/cmd/userUpdate.go @@ -51,10 +51,10 @@ var userUpdateCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() + //ctx, ctxCancelFn = createContextWithAuthorization() existingUser, err := api.GetUser( - ctx, + cmd.Context(), viper.GetString("controllerAPIEndpoint"), nbUserName, uuid.Nil, @@ -79,10 +79,7 @@ var userUpdateCmd = &cobra.Command{ }, } - // create a authorizedContext for further requests - ctx, ctxCancelFn = createContextWithAuthorization() - - resp, err := api.UpdateUsers(ctx, viper.GetString("controllerAPIEndpoint"), users) + resp, err := api.UpdateUsers(cmd.Context(), viper.GetString("controllerAPIEndpoint"), users) if err != nil { pterm.Error.Println(err) return diff --git a/cli/cmd/utils.go b/cli/cmd/utils.go index 10c1b95b24546fb414dd8316943001782180f7fb..2a849b02a5d1bccc564be2207f92758023c0313d 100644 --- a/cli/cmd/utils.go +++ b/cli/cmd/utils.go @@ -36,6 +36,8 @@ import ( "errors" "fmt" "net" + "os" + "os/signal" "strconv" "time" @@ -122,3 +124,16 @@ func convertStringToUintTypedValue(s string) (*gpb.TypedValue, error) { }, }, nil } + +func startContextListener(ctx context.Context, ctxCancelFn context.CancelFunc) { + // listen for CTRL-C as interrupt + ch := make(chan os.Signal, 1) + signal.Notify(ch, os.Interrupt) + go func() { + select { + case <-ch: + ctxCancelFn() + case <-ctx.Done(): + } + }() +}