From 383cffed4d2a704cf8beedeb3e6f96dbe4183503 Mon Sep 17 00:00:00 2001 From: Drew Walters Date: Tue, 5 May 2020 22:39:09 +0000 Subject: [PATCH] Add set-management-configuration command This change adds a set-management-configuration command that allows the user, typically CI, to change management configuration settings imperatively. Change-Id: I7a106a46f57fef0ea2a8c5dd8c8786d8a103305c Signed-off-by: Drew Walters --- cmd/config/config.go | 20 ++- cmd/config/set_management_configuration.go | 105 +++++++++++ .../set_management_configuration_test.go | 166 ++++++++++++++++++ .../config-cmd-with-help.golden | 21 +-- ...d-set-management-config-excess-args.golden | 10 ++ ...g-cmd-set-management-config-no-args.golden | 10 ++ ...cmd-set-management-config-not-found.golden | 10 ++ ...cmd-set-management-config-with-help.golden | 10 ++ ...t-management-config-change-insecure.golden | 1 + ...d-set-management-config-change-type.golden | 2 + ...d-set-management-config-change-type.golden | 1 + ...-set-management-config-unknown-type.golden | 10 ++ ...-management-config-change-use-proxy.golden | 1 + pkg/config/config.go | 10 ++ pkg/config/config_test.go | 17 ++ pkg/config/errors.go | 10 ++ 16 files changed, 387 insertions(+), 17 deletions(-) create mode 100644 cmd/config/set_management_configuration.go create mode 100644 cmd/config/set_management_configuration_test.go create mode 100644 cmd/config/testdata/TestConfigSetManagementConfigurationCmdGoldenOutput/config-cmd-set-management-config-excess-args.golden create mode 100644 cmd/config/testdata/TestConfigSetManagementConfigurationCmdGoldenOutput/config-cmd-set-management-config-no-args.golden create mode 100644 cmd/config/testdata/TestConfigSetManagementConfigurationCmdGoldenOutput/config-cmd-set-management-config-not-found.golden create mode 100644 cmd/config/testdata/TestConfigSetManagementConfigurationCmdGoldenOutput/config-cmd-set-management-config-with-help.golden create mode 100644 cmd/config/testdata/TestConfigSetManagementConfigurationInsecureGoldenOutput/config-cmd-set-management-config-change-insecure.golden create mode 100644 cmd/config/testdata/TestConfigSetManagementConfigurationMultipleOptionsGoldenOutput/config-cmd-set-management-config-change-type.golden create mode 100644 cmd/config/testdata/TestConfigSetManagementConfigurationTypeGoldenOutput/config-cmd-set-management-config-change-type.golden create mode 100644 cmd/config/testdata/TestConfigSetManagementConfigurationTypeGoldenOutput/config-cmd-set-management-config-unknown-type.golden create mode 100644 cmd/config/testdata/TestConfigSetManagementConfigurationUseProxyGoldenOutput/config-cmd-set-management-config-change-use-proxy.golden diff --git a/cmd/config/config.go b/cmd/config/config.go index 234e1039d..a8f82068f 100644 --- a/cmd/config/config.go +++ b/cmd/config/config.go @@ -34,15 +34,21 @@ func NewConfigCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Comma rootSettings.InitConfig() }, } - configRootCmd.AddCommand(NewSetClusterCommand(rootSettings)) - configRootCmd.AddCommand(NewGetClusterCommand(rootSettings)) - configRootCmd.AddCommand(NewSetContextCommand(rootSettings)) - configRootCmd.AddCommand(NewGetContextCommand(rootSettings)) - configRootCmd.AddCommand(NewInitCommand(rootSettings)) - configRootCmd.AddCommand(NewSetAuthInfoCommand(rootSettings)) + configRootCmd.AddCommand(NewGetAuthInfoCommand(rootSettings)) - configRootCmd.AddCommand(NewUseContextCommand(rootSettings)) + configRootCmd.AddCommand(NewSetAuthInfoCommand(rootSettings)) + + configRootCmd.AddCommand(NewGetClusterCommand(rootSettings)) + configRootCmd.AddCommand(NewSetClusterCommand(rootSettings)) + + configRootCmd.AddCommand(NewGetContextCommand(rootSettings)) + configRootCmd.AddCommand(NewSetContextCommand(rootSettings)) + + configRootCmd.AddCommand(NewSetManagementConfigCommand(rootSettings)) + configRootCmd.AddCommand(NewImportCommand(rootSettings)) + configRootCmd.AddCommand(NewInitCommand(rootSettings)) + configRootCmd.AddCommand(NewUseContextCommand(rootSettings)) return configRootCmd } diff --git a/cmd/config/set_management_configuration.go b/cmd/config/set_management_configuration.go new file mode 100644 index 000000000..9f33d5832 --- /dev/null +++ b/cmd/config/set_management_configuration.go @@ -0,0 +1,105 @@ +/* + 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/environment" + "opendev.org/airship/airshipctl/pkg/remote/redfish" +) + +const ( + flagInsecure = "insecure" + flagInsecureDescription = "Ignore SSL certificate verification on out-of-band management requests" + + flagManagementType = "management-type" + flagManagementTypeDescription = "Set the out-of-band management type" + + flagUseProxy = "use-proxy" + flagUseProxyDescription = "Use the proxy configuration specified in the local environment" +) + +// NewSetManagementConfigCommand creates a command for creating and modifying clusters +// in the airshipctl config file. +func NewSetManagementConfigCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command { + var insecure bool + var managementType string + var useProxy bool + + cmd := &cobra.Command{ + Use: "set-management-config NAME", + Short: "Modify an out-of-band management configuration", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + name := args[0] + managementCfg, err := rootSettings.Config.GetManagementConfiguration(name) + if err != nil { + return err + } + + var modified bool + if cmd.Flags().Changed(flagInsecure) && insecure != managementCfg.Insecure { + modified = true + managementCfg.Insecure = insecure + + fmt.Fprintf(cmd.OutOrStdout(), + "Option 'insecure' set to '%t' for management configuration '%s'.\n", + managementCfg.Insecure, name) + } + + if cmd.Flags().Changed(flagManagementType) && managementType != managementCfg.Type { + modified = true + if err = managementCfg.SetType(managementType); err != nil { + return err + } + + fmt.Fprintf(cmd.OutOrStdout(), + "Option 'type' set to '%s' for management configuration '%s'.\n", + managementCfg.Type, name) + } + + if cmd.Flags().Changed(flagUseProxy) && useProxy != managementCfg.UseProxy { + modified = true + managementCfg.UseProxy = useProxy + + fmt.Fprintf(cmd.OutOrStdout(), + "Option 'useproxy' set to '%t' for management configuration '%s'\n", + managementCfg.UseProxy, name) + } + + if !modified { + fmt.Fprintf(cmd.OutOrStdout(), + "Management configuration '%s' not modified. No new settings.\n", name) + return nil + } + + if err = rootSettings.Config.PersistConfig(); err != nil { + return err + } + + return nil + }, + } + + flags := cmd.Flags() + flags.BoolVar(&insecure, flagInsecure, false, flagInsecureDescription) + flags.StringVar(&managementType, flagManagementType, redfish.ClientType, flagManagementTypeDescription) + flags.BoolVar(&useProxy, flagUseProxy, true, flagUseProxyDescription) + + return cmd +} diff --git a/cmd/config/set_management_configuration_test.go b/cmd/config/set_management_configuration_test.go new file mode 100644 index 000000000..d25f78751 --- /dev/null +++ b/cmd/config/set_management_configuration_test.go @@ -0,0 +1,166 @@ +/* + 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 ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + cmd "opendev.org/airship/airshipctl/cmd/config" + "opendev.org/airship/airshipctl/pkg/config" + "opendev.org/airship/airshipctl/pkg/environment" + redfishdell "opendev.org/airship/airshipctl/pkg/remote/redfish/vendors/dell" + "opendev.org/airship/airshipctl/testutil" +) + +func TestConfigSetManagementConfigurationCmd(t *testing.T) { + conf, cleanup := testutil.InitConfig(t) + defer cleanup(t) + + settings := &environment.AirshipCTLSettings{ + Config: conf, + } + + cmdTests := []*testutil.CmdTest{ + { + Name: "config-cmd-set-management-config-with-help", + CmdLine: "--help", + Cmd: cmd.NewSetManagementConfigCommand(nil), + }, + { + Name: "config-cmd-set-management-config-no-args", + CmdLine: "", + Cmd: cmd.NewSetManagementConfigCommand(nil), + Error: fmt.Errorf("accepts %d arg(s), received %d", 1, 0), + }, + { + Name: "config-cmd-set-management-config-excess-args", + CmdLine: "arg1 arg2", + Cmd: cmd.NewSetManagementConfigCommand(nil), + Error: fmt.Errorf("accepts %d arg(s), received %d", 1, 2), + }, + { + Name: "config-cmd-set-management-config-not-found", + CmdLine: fmt.Sprintf("%s-test", config.AirshipDefaultContext), + Cmd: cmd.NewSetManagementConfigCommand(settings), + Error: config.ErrManagementConfigurationNotFound{ + Name: fmt.Sprintf("%s-test", config.AirshipDefaultContext), + }, + }, + } + + for _, tt := range cmdTests { + testutil.RunTest(t, tt) + } +} + +func TestConfigSetManagementConfigurationInsecure(t *testing.T) { + conf, cleanup := testutil.InitConfig(t) + defer cleanup(t) + + settings := &environment.AirshipCTLSettings{ + Config: conf, + } + + require.False(t, settings.Config.ManagementConfiguration[config.AirshipDefaultContext].Insecure) + + testutil.RunTest(t, &testutil.CmdTest{ + Name: "config-cmd-set-management-config-change-insecure", + CmdLine: fmt.Sprintf("%s --insecure=true", config.AirshipDefaultContext), + Cmd: cmd.NewSetManagementConfigCommand(settings), + }) + + assert.True(t, settings.Config.ManagementConfiguration[config.AirshipDefaultContext].Insecure) +} + +func TestConfigSetManagementConfigurationType(t *testing.T) { + conf, cleanup := testutil.InitConfig(t) + defer cleanup(t) + + settings := &environment.AirshipCTLSettings{ + Config: conf, + } + + require.NotEqual(t, redfishdell.ClientType, + settings.Config.ManagementConfiguration[config.AirshipDefaultContext].Type) + + cmdTests := []*testutil.CmdTest{ + { + Name: "config-cmd-set-management-config-unknown-type", + CmdLine: fmt.Sprintf("%s --management-type=foo", config.AirshipDefaultContext), + Cmd: cmd.NewSetManagementConfigCommand(settings), + Error: config.ErrUnknownManagementType{Type: "foo"}, + }, + { + Name: "config-cmd-set-management-config-change-type", + CmdLine: fmt.Sprintf("%s --management-type=%s", config.AirshipDefaultContext, + redfishdell.ClientType), + Cmd: cmd.NewSetManagementConfigCommand(settings), + }, + } + + for _, tt := range cmdTests { + testutil.RunTest(t, tt) + } + + assert.Equal(t, redfishdell.ClientType, + settings.Config.ManagementConfiguration[config.AirshipDefaultContext].Type) +} + +func TestConfigSetManagementConfigurationUseProxy(t *testing.T) { + conf, cleanup := testutil.InitConfig(t) + defer cleanup(t) + + settings := &environment.AirshipCTLSettings{ + Config: conf, + } + + require.False(t, settings.Config.ManagementConfiguration[config.AirshipDefaultContext].UseProxy) + + testutil.RunTest(t, &testutil.CmdTest{ + Name: "config-cmd-set-management-config-change-use-proxy", + CmdLine: fmt.Sprintf("%s --use-proxy=true", config.AirshipDefaultContext), + Cmd: cmd.NewSetManagementConfigCommand(settings), + }) + + assert.True(t, settings.Config.ManagementConfiguration[config.AirshipDefaultContext].UseProxy) +} + +func TestConfigSetManagementConfigurationMultipleOptions(t *testing.T) { + conf, cleanup := testutil.InitConfig(t) + defer cleanup(t) + + settings := &environment.AirshipCTLSettings{ + Config: conf, + } + + require.NotEqual(t, redfishdell.ClientType, + settings.Config.ManagementConfiguration[config.AirshipDefaultContext].Type) + require.False(t, settings.Config.ManagementConfiguration[config.AirshipDefaultContext].UseProxy) + + testutil.RunTest(t, &testutil.CmdTest{ + Name: "config-cmd-set-management-config-change-type", + CmdLine: fmt.Sprintf("%s --management-type=%s --use-proxy=true", config.AirshipDefaultContext, + redfishdell.ClientType), + Cmd: cmd.NewSetManagementConfigCommand(settings), + }) + + assert.Equal(t, redfishdell.ClientType, + settings.Config.ManagementConfiguration[config.AirshipDefaultContext].Type) + assert.True(t, settings.Config.ManagementConfiguration[config.AirshipDefaultContext].UseProxy) +} diff --git a/cmd/config/testdata/TestConfigGoldenOutput/config-cmd-with-help.golden b/cmd/config/testdata/TestConfigGoldenOutput/config-cmd-with-help.golden index dfb58713f..cbe175fa9 100644 --- a/cmd/config/testdata/TestConfigGoldenOutput/config-cmd-with-help.golden +++ b/cmd/config/testdata/TestConfigGoldenOutput/config-cmd-with-help.golden @@ -4,16 +4,17 @@ Usage: config [command] Available Commands: - get-cluster Get cluster information from the airshipctl config - get-context Get context information from the airshipctl config - get-credential Get user credentials from the airshipctl config - help Help about any command - import Merge information from a kubernetes config file - init Generate initial configuration files for airshipctl - set-cluster Manage clusters - set-context Manage contexts - set-credentials Manage user credentials - use-context Switch to a different context + get-cluster Get cluster information from the airshipctl config + get-context Get context information from the airshipctl config + get-credential Get user credentials from the airshipctl config + help Help about any command + import Merge information from a kubernetes config file + init Generate initial configuration files for airshipctl + set-cluster Manage clusters + set-context Manage contexts + set-credentials Manage user credentials + set-management-config Modify an out-of-band management configuration + use-context Switch to a different context Flags: -h, --help help for config diff --git a/cmd/config/testdata/TestConfigSetManagementConfigurationCmdGoldenOutput/config-cmd-set-management-config-excess-args.golden b/cmd/config/testdata/TestConfigSetManagementConfigurationCmdGoldenOutput/config-cmd-set-management-config-excess-args.golden new file mode 100644 index 000000000..7aab308db --- /dev/null +++ b/cmd/config/testdata/TestConfigSetManagementConfigurationCmdGoldenOutput/config-cmd-set-management-config-excess-args.golden @@ -0,0 +1,10 @@ +Error: accepts 1 arg(s), received 2 +Usage: + set-management-config NAME [flags] + +Flags: + -h, --help help for set-management-config + --insecure Ignore SSL certificate verification on out-of-band management requests + --management-type string Set the out-of-band management type (default "redfish") + --use-proxy Use the proxy configuration specified in the local environment (default true) + diff --git a/cmd/config/testdata/TestConfigSetManagementConfigurationCmdGoldenOutput/config-cmd-set-management-config-no-args.golden b/cmd/config/testdata/TestConfigSetManagementConfigurationCmdGoldenOutput/config-cmd-set-management-config-no-args.golden new file mode 100644 index 000000000..6710716d8 --- /dev/null +++ b/cmd/config/testdata/TestConfigSetManagementConfigurationCmdGoldenOutput/config-cmd-set-management-config-no-args.golden @@ -0,0 +1,10 @@ +Error: accepts 1 arg(s), received 0 +Usage: + set-management-config NAME [flags] + +Flags: + -h, --help help for set-management-config + --insecure Ignore SSL certificate verification on out-of-band management requests + --management-type string Set the out-of-band management type (default "redfish") + --use-proxy Use the proxy configuration specified in the local environment (default true) + diff --git a/cmd/config/testdata/TestConfigSetManagementConfigurationCmdGoldenOutput/config-cmd-set-management-config-not-found.golden b/cmd/config/testdata/TestConfigSetManagementConfigurationCmdGoldenOutput/config-cmd-set-management-config-not-found.golden new file mode 100644 index 000000000..ded746177 --- /dev/null +++ b/cmd/config/testdata/TestConfigSetManagementConfigurationCmdGoldenOutput/config-cmd-set-management-config-not-found.golden @@ -0,0 +1,10 @@ +Error: Unknown management configuration 'default-test'. +Usage: + set-management-config NAME [flags] + +Flags: + -h, --help help for set-management-config + --insecure Ignore SSL certificate verification on out-of-band management requests + --management-type string Set the out-of-band management type (default "redfish") + --use-proxy Use the proxy configuration specified in the local environment (default true) + diff --git a/cmd/config/testdata/TestConfigSetManagementConfigurationCmdGoldenOutput/config-cmd-set-management-config-with-help.golden b/cmd/config/testdata/TestConfigSetManagementConfigurationCmdGoldenOutput/config-cmd-set-management-config-with-help.golden new file mode 100644 index 000000000..800abe719 --- /dev/null +++ b/cmd/config/testdata/TestConfigSetManagementConfigurationCmdGoldenOutput/config-cmd-set-management-config-with-help.golden @@ -0,0 +1,10 @@ +Modify an out-of-band management configuration + +Usage: + set-management-config NAME [flags] + +Flags: + -h, --help help for set-management-config + --insecure Ignore SSL certificate verification on out-of-band management requests + --management-type string Set the out-of-band management type (default "redfish") + --use-proxy Use the proxy configuration specified in the local environment (default true) diff --git a/cmd/config/testdata/TestConfigSetManagementConfigurationInsecureGoldenOutput/config-cmd-set-management-config-change-insecure.golden b/cmd/config/testdata/TestConfigSetManagementConfigurationInsecureGoldenOutput/config-cmd-set-management-config-change-insecure.golden new file mode 100644 index 000000000..94d743d1d --- /dev/null +++ b/cmd/config/testdata/TestConfigSetManagementConfigurationInsecureGoldenOutput/config-cmd-set-management-config-change-insecure.golden @@ -0,0 +1 @@ +Option 'insecure' set to 'true' for management configuration 'default'. diff --git a/cmd/config/testdata/TestConfigSetManagementConfigurationMultipleOptionsGoldenOutput/config-cmd-set-management-config-change-type.golden b/cmd/config/testdata/TestConfigSetManagementConfigurationMultipleOptionsGoldenOutput/config-cmd-set-management-config-change-type.golden new file mode 100644 index 000000000..65ee457e1 --- /dev/null +++ b/cmd/config/testdata/TestConfigSetManagementConfigurationMultipleOptionsGoldenOutput/config-cmd-set-management-config-change-type.golden @@ -0,0 +1,2 @@ +Option 'type' set to 'redfish-dell' for management configuration 'default'. +Option 'useproxy' set to 'true' for management configuration 'default' diff --git a/cmd/config/testdata/TestConfigSetManagementConfigurationTypeGoldenOutput/config-cmd-set-management-config-change-type.golden b/cmd/config/testdata/TestConfigSetManagementConfigurationTypeGoldenOutput/config-cmd-set-management-config-change-type.golden new file mode 100644 index 000000000..ebcd15167 --- /dev/null +++ b/cmd/config/testdata/TestConfigSetManagementConfigurationTypeGoldenOutput/config-cmd-set-management-config-change-type.golden @@ -0,0 +1 @@ +Option 'type' set to 'redfish-dell' for management configuration 'default'. diff --git a/cmd/config/testdata/TestConfigSetManagementConfigurationTypeGoldenOutput/config-cmd-set-management-config-unknown-type.golden b/cmd/config/testdata/TestConfigSetManagementConfigurationTypeGoldenOutput/config-cmd-set-management-config-unknown-type.golden new file mode 100644 index 000000000..4cd480161 --- /dev/null +++ b/cmd/config/testdata/TestConfigSetManagementConfigurationTypeGoldenOutput/config-cmd-set-management-config-unknown-type.golden @@ -0,0 +1,10 @@ +Error: Unknown management type 'foo'. Known types include 'redfish' and 'redfish-dell'. +Usage: + set-management-config NAME [flags] + +Flags: + -h, --help help for set-management-config + --insecure Ignore SSL certificate verification on out-of-band management requests + --management-type string Set the out-of-band management type (default "redfish") + --use-proxy Use the proxy configuration specified in the local environment (default true) + diff --git a/cmd/config/testdata/TestConfigSetManagementConfigurationUseProxyGoldenOutput/config-cmd-set-management-config-change-use-proxy.golden b/cmd/config/testdata/TestConfigSetManagementConfigurationUseProxyGoldenOutput/config-cmd-set-management-config-change-use-proxy.golden new file mode 100644 index 000000000..3f04824bf --- /dev/null +++ b/cmd/config/testdata/TestConfigSetManagementConfigurationUseProxyGoldenOutput/config-cmd-set-management-config-change-use-proxy.golden @@ -0,0 +1 @@ +Option 'useproxy' set to 'true' for management configuration 'default' diff --git a/pkg/config/config.go b/pkg/config/config.go index cf230645b..4c1878565 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -568,6 +568,16 @@ func (c *Config) GetContexts() []*Context { return contexts } +// GetManagementConfiguration retrieves a management configuration by name. +func (c *Config) GetManagementConfiguration(name string) (*ManagementConfiguration, error) { + managementCfg, exists := c.ManagementConfiguration[name] + if !exists { + return nil, ErrManagementConfigurationNotFound{Name: name} + } + + return managementCfg, nil +} + // AddContext creates a new context and returns the instance of // newly created context func (c *Config) AddContext(theContext *ContextOptions) *Context { diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 4d6be2025..91632ec5e 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -731,3 +731,20 @@ func TestImportErrors(t *testing.T) { assert.Contains(t, err.Error(), "json parse error") }) } + +func TestManagementConfigurationByName(t *testing.T) { + conf, cleanupConfig := testutil.InitConfig(t) + defer cleanupConfig(t) + + mgmtCfg, err := conf.GetManagementConfiguration(config.AirshipDefaultContext) + require.NoError(t, err) + assert.Equal(t, conf.ManagementConfiguration[config.AirshipDefaultContext], mgmtCfg) +} + +func TestManagementConfigurationByNameDoesNotExist(t *testing.T) { + conf, cleanupConfig := testutil.InitConfig(t) + defer cleanupConfig(t) + + _, err := conf.GetManagementConfiguration(fmt.Sprintf("%s-test", config.AirshipDefaultContext)) + assert.Error(t, err) +} diff --git a/pkg/config/errors.go b/pkg/config/errors.go index 0edb7b839..1abddf00d 100644 --- a/pkg/config/errors.go +++ b/pkg/config/errors.go @@ -106,6 +106,16 @@ func (e ErrConfigFailed) Error() string { return "Configuration failed to complete." } +// ErrManagementConfigurationNotFound describes a situation in which a user has attempted to reference a management +// configuration that cannot be referenced. +type ErrManagementConfigurationNotFound struct { + Name string +} + +func (e ErrManagementConfigurationNotFound) Error() string { + return fmt.Sprintf("Unknown management configuration '%s'.", e.Name) +} + // ErrMissingCurrentContext returned in case --current used without setting current-context type ErrMissingCurrentContext struct { }