From 1d67db9a5dbe7197784058f2dfdf50034959b007 Mon Sep 17 00:00:00 2001 From: Rohan Kumar Date: Mon, 11 Nov 2024 19:40:51 +0530 Subject: [PATCH] feat : Add config option to set developer password for cluster (#2539) Add option to set developer password for the user. ``` $ crc config set developer-password mypassword $ crc start [...] INFO Adding crc-admin and crc-developer contexts to kubeconfig... Started the OpenShift cluster. The server is accessible via web console at: https://console-openshift-console.apps-crc.testing Log in as user: Username: developer Password: mypassword ``` Signed-off-by: Rohan Kumar --- cmd/crc/cmd/start.go | 1 + pkg/crc/api/handlers.go | 1 + pkg/crc/cluster/kubeadmin_password.go | 4 +- pkg/crc/config/settings.go | 3 + pkg/crc/config/settings_test.go | 202 ++++++++++++++++++++++++++ pkg/crc/machine/start.go | 2 +- pkg/crc/machine/types/types.go | 3 + 7 files changed, 213 insertions(+), 3 deletions(-) diff --git a/cmd/crc/cmd/start.go b/cmd/crc/cmd/start.go index e33d1fba2b..c8e9779e20 100644 --- a/cmd/crc/cmd/start.go +++ b/cmd/crc/cmd/start.go @@ -75,6 +75,7 @@ func runStart(ctx context.Context) (*types.StartResult, error) { NameServer: config.Get(crcConfig.NameServer).AsString(), PullSecret: cluster.NewInteractivePullSecretLoader(config), KubeAdminPassword: config.Get(crcConfig.KubeAdminPassword).AsString(), + DeveloperPassword: config.Get(crcConfig.DeveloperPassword).AsString(), Preset: crcConfig.GetPreset(config), IngressHTTPPort: config.Get(crcConfig.IngressHTTPPort).AsUInt(), IngressHTTPSPort: config.Get(crcConfig.IngressHTTPSPort).AsUInt(), diff --git a/pkg/crc/api/handlers.go b/pkg/crc/api/handlers.go index 82221f6620..870abf0621 100644 --- a/pkg/crc/api/handlers.go +++ b/pkg/crc/api/handlers.go @@ -127,6 +127,7 @@ func getStartConfig(cfg crcConfig.Storage, args client.StartConfig) types.StartC NameServer: cfg.Get(crcConfig.NameServer).AsString(), PullSecret: cluster.NewNonInteractivePullSecretLoader(cfg, args.PullSecretFile), KubeAdminPassword: cfg.Get(crcConfig.KubeAdminPassword).AsString(), + DeveloperPassword: cfg.Get(crcConfig.DeveloperPassword).AsString(), IngressHTTPPort: cfg.Get(crcConfig.IngressHTTPPort).AsUInt(), IngressHTTPSPort: cfg.Get(crcConfig.IngressHTTPSPort).AsUInt(), Preset: crcConfig.GetPreset(cfg), diff --git a/pkg/crc/cluster/kubeadmin_password.go b/pkg/crc/cluster/kubeadmin_password.go index 20cb8a1b19..505f984f84 100644 --- a/pkg/crc/cluster/kubeadmin_password.go +++ b/pkg/crc/cluster/kubeadmin_password.go @@ -50,7 +50,7 @@ func UpdateUserPassword(ctx context.Context, ocConfig oc.Config, newKubeAdminPas return nil } - logging.Infof("Changing the password for the kubeadmin user") + logging.Infof("Changing the password for the users") expected, err := getHtpasswd(credentials, externals) if err != nil { return err @@ -60,7 +60,7 @@ func UpdateUserPassword(ctx context.Context, ocConfig oc.Config, newKubeAdminPas "-n", "openshift-config", "--type", "merge"} _, stderr, err = ocConfig.RunOcCommandPrivate(cmdArgs...) if err != nil { - return fmt.Errorf("Failed to update kubeadmin password %v: %s", err, stderr) + return fmt.Errorf("failed to update user passwords %v: %s", err, stderr) } return nil } diff --git a/pkg/crc/config/settings.go b/pkg/crc/config/settings.go index d4236d6a5c..e3044f6c30 100644 --- a/pkg/crc/config/settings.go +++ b/pkg/crc/config/settings.go @@ -29,6 +29,7 @@ const ( ConsentTelemetry = "consent-telemetry" EnableClusterMonitoring = "enable-cluster-monitoring" KubeAdminPassword = "kubeadmin-password" + DeveloperPassword = "developer-password" Preset = "preset" EnableSharedDirs = "enable-shared-dirs" SharedDirPassword = "shared-dir-password" // #nosec G101 @@ -134,6 +135,8 @@ func RegisterSettings(cfg *Config) { cfg.AddSetting(KubeAdminPassword, "", validateString, SuccessfullyApplied, "User defined kubeadmin password") + cfg.AddSetting(DeveloperPassword, "", validateString, SuccessfullyApplied, + "User defined developer password") cfg.AddSetting(IngressHTTPPort, constants.OpenShiftIngressHTTPPort, validatePort, RequiresHTTPPortChangeWarning, fmt.Sprintf("HTTP port to use for OpenShift ingress/routes on the host (1024-65535, default: %d)", constants.OpenShiftIngressHTTPPort)) cfg.AddSetting(IngressHTTPSPort, constants.OpenShiftIngressHTTPSPort, validatePort, RequiresHTTPSPortChangeWarning, diff --git a/pkg/crc/config/settings_test.go b/pkg/crc/config/settings_test.go index f815ed5644..f845f75373 100644 --- a/pkg/crc/config/settings_test.go +++ b/pkg/crc/config/settings_test.go @@ -182,3 +182,205 @@ func TestPath(t *testing.T) { IsSecret: false, }, cfg.Get(ProxyCAFile)) } + +func TestWhenInvalidKeySetThenErrorIsThrown(t *testing.T) { + // Given + cfg, err := newInMemoryConfig() + require.NoError(t, err) + + // When + Then + _, err = cfg.Set("i-dont-exist", "i-should-not-be-set") + assert.Error(t, err, "Configuration property 'i-dont-exist' does not exist") +} + +func TestSetDeveloperPasswordIsSetInConfig(t *testing.T) { + // Given + cfg, err := newInMemoryConfig() + require.NoError(t, err) + + // When + _, err = cfg.Set(DeveloperPassword, "secret-developer-password") + require.NoError(t, err) + + // Then + assert.Equal(t, SettingValue{ + Value: "secret-developer-password", + Invalid: false, + }, cfg.Get(DeveloperPassword)) +} + +var configDefaultValuesTestArguments = []struct { + key string + defaultValue interface{} +}{ + { + KubeAdminPassword, "", + }, + { + DeveloperPassword, "", + }, + { + CPUs, uint(4), + }, + { + Memory, uint(10752), + }, + { + DiskSize, 31, + }, + { + NameServer, "", + }, + { + PullSecretFile, "", + }, + { + DisableUpdateCheck, false, + }, + { + ExperimentalFeatures, false, + }, + { + EmergencyLogin, false, + }, + { + PersistentVolumeSize, 15, + }, + { + HostNetworkAccess, false, + }, + { + HTTPProxy, "", + }, + { + HTTPSProxy, "", + }, + { + NoProxy, "", + }, + { + ProxyCAFile, Path(""), + }, + { + EnableClusterMonitoring, false, + }, + { + ConsentTelemetry, "", + }, + { + IngressHTTPPort, 80, + }, + { + IngressHTTPSPort, 443, + }, + { + EnableBundleQuayFallback, false, + }, + { + Preset, "openshift", + }, +} + +func TestDefaultKeyValuesSetInConfig(t *testing.T) { + for _, tt := range configDefaultValuesTestArguments { + t.Run(tt.key, func(t *testing.T) { + // Given + cfg, err := newInMemoryConfig() + require.NoError(t, err) + + // When + Then + assert.Equal(t, SettingValue{ + Value: tt.defaultValue, + Invalid: false, + IsDefault: true, + }, cfg.Get(tt.key)) + }) + } +} + +var configProvidedValuesTestArguments = []struct { + key string + providedValue interface{} +}{ + { + KubeAdminPassword, "kubeadmin-secret-password", + }, + { + DeveloperPassword, "developer-secret-password", + }, + { + CPUs, uint(8), + }, + { + Memory, uint(21504), + }, + { + DiskSize, 62, + }, + { + NameServer, "127.0.0.1", + }, + { + DisableUpdateCheck, true, + }, + { + ExperimentalFeatures, true, + }, + { + EmergencyLogin, true, + }, + { + PersistentVolumeSize, 20, + }, + { + HTTPProxy, "http://proxy-via-http-proxy-property:3128", + }, + { + HTTPSProxy, "https://proxy-via-http-proxy-property:3128", + }, + { + NoProxy, "http://no-proxy-property:3128", + }, + { + EnableClusterMonitoring, true, + }, + { + ConsentTelemetry, "yes", + }, + { + IngressHTTPPort, 8080, + }, + { + IngressHTTPSPort, 6443, + }, + { + EnableBundleQuayFallback, true, + }, + { + Preset, "microshift", + }, +} + +func TestSetProvidedValuesOverrideDefaultValuesInConfig(t *testing.T) { + for _, tt := range configProvidedValuesTestArguments { + t.Run(tt.key, func(t *testing.T) { + + // When + Then + + // Given + cfg, err := newInMemoryConfig() + require.NoError(t, err) + + // When + _, err = cfg.Set(tt.key, tt.providedValue) + require.NoError(t, err) + + // Then + assert.Equal(t, SettingValue{ + Value: tt.providedValue, + Invalid: false, + IsDefault: false, + }, cfg.Get(tt.key)) + }) + } +} diff --git a/pkg/crc/machine/start.go b/pkg/crc/machine/start.go index b87e13b6ca..97cf482417 100644 --- a/pkg/crc/machine/start.go +++ b/pkg/crc/machine/start.go @@ -575,7 +575,7 @@ func (client *client) Start(ctx context.Context, startConfig types.StartConfig) return nil, errors.Wrap(err, "Failed to update pull secret on the disk") } - if err := cluster.UpdateKubeAdminUserPassword(ctx, ocConfig, startConfig.KubeAdminPassword); err != nil { + if err := cluster.UpdateUserPassword(ctx, ocConfig, startConfig.KubeAdminPassword, startConfig.DeveloperPassword); err != nil { return nil, errors.Wrap(err, "Failed to update kubeadmin user password") } diff --git a/pkg/crc/machine/types/types.go b/pkg/crc/machine/types/types.go index ef810a7218..1e8c1e48ea 100644 --- a/pkg/crc/machine/types/types.go +++ b/pkg/crc/machine/types/types.go @@ -26,6 +26,9 @@ type StartConfig struct { // User defined kubeadmin password KubeAdminPassword string + // User defined developer password + DeveloperPassword string + // Preset Preset crcpreset.Preset