From a437caa1416260c6ba5ccd16671da96f2cfa8101 Mon Sep 17 00:00:00 2001 From: Drew Walters Date: Fri, 21 Feb 2020 10:28:19 -0600 Subject: [PATCH] [#56] Add use-context subcommand Currently, airshipctl users switch their current context by modifying the airshipctl config file or executing airshipctl config set-context [NAME]. This change introduces the use-context subcommand, which replaces the current behavior of using set-context without flags. After this change, set-context will only be used to modify contexts. Change-Id: If3980138a0abeeb6c59c07615b5373654073610a Signed-off-by: Drew Walters --- cmd/config/config.go | 1 + .../config-cmd-with-defaults.golden | 1 + .../config-cmd-with-help.golden | 1 + .../config-use-context-does-not-exist.golden | 12 ++++ .../config-use-context-no-args.golden | 12 ++++ .../config-use-context.golden | 1 + cmd/config/use_context.go | 59 +++++++++++++++++++ cmd/config/use_context_test.go | 58 ++++++++++++++++++ pkg/config/cmds.go | 15 +++++ pkg/config/cmds_test.go | 14 +++++ 10 files changed, 174 insertions(+) create mode 100644 cmd/config/testdata/TestConfigUseContextGoldenOutput/config-use-context-does-not-exist.golden create mode 100644 cmd/config/testdata/TestConfigUseContextGoldenOutput/config-use-context-no-args.golden create mode 100644 cmd/config/testdata/TestConfigUseContextGoldenOutput/config-use-context.golden create mode 100644 cmd/config/use_context.go create mode 100644 cmd/config/use_context_test.go diff --git a/cmd/config/config.go b/cmd/config/config.go index 2e203d00a..de07050bf 100644 --- a/cmd/config/config.go +++ b/cmd/config/config.go @@ -22,6 +22,7 @@ like "airshipctl config set-context my-context" `, configRootCmd.AddCommand(NewCmdConfigInit(rootSettings)) configRootCmd.AddCommand(NewCmdConfigSetAuthInfo(rootSettings)) configRootCmd.AddCommand(NewCmdConfigGetAuthInfo(rootSettings)) + configRootCmd.AddCommand(NewCmdConfigUseContext(rootSettings)) return configRootCmd } diff --git a/cmd/config/testdata/TestConfigGoldenOutput/config-cmd-with-defaults.golden b/cmd/config/testdata/TestConfigGoldenOutput/config-cmd-with-defaults.golden index aa5b24d6e..4d8e91389 100644 --- a/cmd/config/testdata/TestConfigGoldenOutput/config-cmd-with-defaults.golden +++ b/cmd/config/testdata/TestConfigGoldenOutput/config-cmd-with-defaults.golden @@ -13,6 +13,7 @@ Available Commands: set-cluster Sets a cluster entry in the airshipctl config set-context Switch to a new context or update context values in the airshipctl config set-credentials Sets a user entry in the airshipctl config + use-context Switch to a different airshipctl context. Flags: -h, --help help for config diff --git a/cmd/config/testdata/TestConfigGoldenOutput/config-cmd-with-help.golden b/cmd/config/testdata/TestConfigGoldenOutput/config-cmd-with-help.golden index aa5b24d6e..4d8e91389 100644 --- a/cmd/config/testdata/TestConfigGoldenOutput/config-cmd-with-help.golden +++ b/cmd/config/testdata/TestConfigGoldenOutput/config-cmd-with-help.golden @@ -13,6 +13,7 @@ Available Commands: set-cluster Sets a cluster entry in the airshipctl config set-context Switch to a new context or update context values in the airshipctl config set-credentials Sets a user entry in the airshipctl config + use-context Switch to a different airshipctl context. Flags: -h, --help help for config diff --git a/cmd/config/testdata/TestConfigUseContextGoldenOutput/config-use-context-does-not-exist.golden b/cmd/config/testdata/TestConfigUseContextGoldenOutput/config-use-context-does-not-exist.golden new file mode 100644 index 000000000..6c33a616d --- /dev/null +++ b/cmd/config/testdata/TestConfigUseContextGoldenOutput/config-use-context-does-not-exist.golden @@ -0,0 +1,12 @@ +Error: Missing configuration: Context with name 'foo' +Usage: + use-context NAME [flags] + +Examples: + +# Switch to a context named "e2e" +airshipctl config use-context e2e + +Flags: + -h, --help help for use-context + diff --git a/cmd/config/testdata/TestConfigUseContextGoldenOutput/config-use-context-no-args.golden b/cmd/config/testdata/TestConfigUseContextGoldenOutput/config-use-context-no-args.golden new file mode 100644 index 000000000..0b38331b6 --- /dev/null +++ b/cmd/config/testdata/TestConfigUseContextGoldenOutput/config-use-context-no-args.golden @@ -0,0 +1,12 @@ +Error: accepts 1 arg(s), received 0 +Usage: + use-context NAME [flags] + +Examples: + +# Switch to a context named "e2e" +airshipctl config use-context e2e + +Flags: + -h, --help help for use-context + diff --git a/cmd/config/testdata/TestConfigUseContextGoldenOutput/config-use-context.golden b/cmd/config/testdata/TestConfigUseContextGoldenOutput/config-use-context.golden new file mode 100644 index 000000000..028074bc3 --- /dev/null +++ b/cmd/config/testdata/TestConfigUseContextGoldenOutput/config-use-context.golden @@ -0,0 +1 @@ +Switched to context "dummy_context". diff --git a/cmd/config/use_context.go b/cmd/config/use_context.go new file mode 100644 index 000000000..cc6ced789 --- /dev/null +++ b/cmd/config/use_context.go @@ -0,0 +1,59 @@ +/* +Copyright 2016 The Kubernetes Authors. + +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 config + +import ( + "fmt" + + "github.com/spf13/cobra" + + "opendev.org/airship/airshipctl/pkg/config" + "opendev.org/airship/airshipctl/pkg/environment" +) + +var ( + useContextLong = "Switch to a new context defined in the airshipctl config file." + + useContextExample = ` +# Switch to a context named "e2e" +airshipctl config use-context e2e` +) + +// NewCmdConfigUseContext creates a command object for the "use-context" action, which +// switches to a defined airshipctl context. +func NewCmdConfigUseContext(rootSettings *environment.AirshipCTLSettings) *cobra.Command { + cmd := &cobra.Command{ + Use: "use-context NAME", + Short: "Switch to a different airshipctl context.", + Long: useContextLong, + Example: useContextExample, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + contextName := args[0] + err := config.RunUseContext(contextName, rootSettings.Config()) + if err != nil { + return err + } + + fmt.Fprintf(cmd.OutOrStdout(), "Switched to context %q.\n", contextName) + + return nil + }, + } + + return cmd +} diff --git a/cmd/config/use_context_test.go b/cmd/config/use_context_test.go new file mode 100644 index 000000000..a7a0df49b --- /dev/null +++ b/cmd/config/use_context_test.go @@ -0,0 +1,58 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 config_test + +import ( + "errors" + "testing" + + cmd "opendev.org/airship/airshipctl/cmd/config" + "opendev.org/airship/airshipctl/pkg/config" + "opendev.org/airship/airshipctl/pkg/environment" + "opendev.org/airship/airshipctl/testutil" +) + +func TestConfigUseContext(t *testing.T) { + conf := config.DummyConfig() + + settings := &environment.AirshipCTLSettings{} + settings.SetConfig(conf) + + cmdTests := []*testutil.CmdTest{ + { + Name: "config-use-context", + CmdLine: "dummy_context", + Cmd: cmd.NewCmdConfigUseContext(settings), + }, + { + Name: "config-use-context-no-args", + CmdLine: "", + Cmd: cmd.NewCmdConfigUseContext(settings), + Error: errors.New("accepts 1 arg(s), received 0"), + }, + { + Name: "config-use-context-does-not-exist", + CmdLine: "foo", + Cmd: cmd.NewCmdConfigUseContext(settings), + Error: errors.New("Missing configuration: Context with name 'foo'"), + }, + } + + for _, tt := range cmdTests { + testutil.RunTest(t, tt) + } +} diff --git a/pkg/config/cmds.go b/pkg/config/cmds.go index 075333802..a89a86e1c 100644 --- a/pkg/config/cmds.go +++ b/pkg/config/cmds.go @@ -237,3 +237,18 @@ func RunSetContext(o *ContextOptions, airconfig *Config, writeToStorage bool) (b return modified, nil } + +func RunUseContext(desiredContext string, airconfig *Config) error { + if _, err := airconfig.GetContext(desiredContext); err != nil { + return err + } + + if airconfig.CurrentContext != desiredContext { + airconfig.CurrentContext = desiredContext + if err := airconfig.PersistConfig(); err != nil { + return err + } + } + + return nil +} diff --git a/pkg/config/cmds_test.go b/pkg/config/cmds_test.go index 84a714b01..f344c5775 100644 --- a/pkg/config/cmds_test.go +++ b/pkg/config/cmds_test.go @@ -247,3 +247,17 @@ func TestRunSetContext(t *testing.T) { assert.Equal(t, "new_namespace", conf.Contexts["dummy_context"].kContext.Namespace) }) } + +func TestRunUseContext(t *testing.T) { + t.Run("testUseContext", func(t *testing.T) { + conf := DummyConfig() + err := RunUseContext("dummy_context", conf) + assert.Nil(t, err) + }) + + t.Run("testUseContextDoesNotExist", func(t *testing.T) { + conf := NewConfig() + err := RunUseContext("foo", conf) + assert.Error(t, err) + }) +}