From 3d8e796a76f08c967ea05b67b54027f948947c94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Drzewiecki?= Date: Mon, 26 Aug 2024 08:59:45 +0200 Subject: [PATCH 1/3] [WiP] OIDC extender --- api/v1/runtime_types.go | 1 + .../runtime/fsm/runtime_fsm_configure_oidc.go | 31 +++++++++ internal/gardener/shoot/extender/oidc.go | 66 ++++++++++++++++++- internal/gardener/shoot/extender/oidc_test.go | 10 ++- 4 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 internal/controller/runtime/fsm/runtime_fsm_configure_oidc.go diff --git a/api/v1/runtime_types.go b/api/v1/runtime_types.go index 1e6af618..098c1dd8 100644 --- a/api/v1/runtime_types.go +++ b/api/v1/runtime_types.go @@ -64,6 +64,7 @@ const ( ConditionTypeRuntimeProvisioned RuntimeConditionType = "Provisioned" ConditionTypeRuntimeProvisionedDryRun RuntimeConditionType = "ProvisionedDryRun" ConditionTypeRuntimeKubeconfigReady RuntimeConditionType = "KubeconfigReady" + ConditionTypeOidcConfigured RuntimeConditionType = "OidcConfigured" ConditionTypeRuntimeConfigured RuntimeConditionType = "Configured" ConditionTypeRuntimeDeprovisioned RuntimeConditionType = "Deprovisioned" ) diff --git a/internal/controller/runtime/fsm/runtime_fsm_configure_oidc.go b/internal/controller/runtime/fsm/runtime_fsm_configure_oidc.go new file mode 100644 index 00000000..bf045a0a --- /dev/null +++ b/internal/controller/runtime/fsm/runtime_fsm_configure_oidc.go @@ -0,0 +1,31 @@ +package fsm + +import ( + "context" + imv1 "github.com/kyma-project/infrastructure-manager/api/v1" + ctrl "sigs.k8s.io/controller-runtime" +) + +func sFnConfigureOidc(ctx context.Context, m *fsm, s *systemState) (stateFn, *ctrl.Result, error) { + m.log.Info("Configure OIDC state") + + //TODO: 2/3.check if doing this is necessary + //TODO: 2/3. remove existing "additionalOidcs" from the Shoot spec + //TODO: 1. recreate "additionalOidcs" in the Shoot spec + //TODO: 4. extract rest client to a separate interface + //TODO: 5. unit test the function + // create OIDCConnect CR in shoot + + //s.instance.UpdateStatePending(imv1.ConditionTypeRuntimeKubeconfigReady, imv1.ConditionReasonGardenerCRCreated, "Unknown", "Gardener Cluster CR created, waiting for readiness") + //return updateStatusAndRequeueAfter(controlPlaneRequeueDuration) + + // wait section - is it needed? + + //m.log.Info("OIDC has been configured", "Name", runtimeID) + + return ensureStatusConditionIsSetAndContinue(&s.instance, + imv1.ConditionTypeRuntimeKubeconfigReady, + imv1.ConditionReasonGardenerCRReady, + "Gardener Cluster CR is ready.", + sFnApplyClusterRoleBindings) +} diff --git a/internal/gardener/shoot/extender/oidc.go b/internal/gardener/shoot/extender/oidc.go index fdaadf46..199da8bb 100644 --- a/internal/gardener/shoot/extender/oidc.go +++ b/internal/gardener/shoot/extender/oidc.go @@ -3,11 +3,46 @@ package extender import ( gardener "github.com/gardener/gardener/pkg/apis/core/v1beta1" imv1 "github.com/kyma-project/infrastructure-manager/api/v1" + "k8s.io/utils/ptr" ) -func ExtendWithOIDC(runtime imv1.Runtime, shoot *gardener.Shoot) error { +const ( + OidcExtensionType = "shoot-oidc-service" +) + +// Extends Shoot spec with OIDC configuration and mutates Runtime spec with necessary OIDC defaults if missing +func ExtendWithOIDC(runtime *imv1.Runtime, shoot *gardener.Shoot) error { + oidcConfig := runtime.Spec.Shoot.Kubernetes.KubeAPIServer.OidcConfig + + defaultAdditionalOidcIfNotPresent(runtime) + setOIDCExtension(shoot) + setKubeAPIServerOIDCConfig(shoot, oidcConfig) + + return nil +} + +func defaultAdditionalOidcIfNotPresent(runtime *imv1.Runtime) { oidcConfig := runtime.Spec.Shoot.Kubernetes.KubeAPIServer.OidcConfig + additionalOidcConfig := runtime.Spec.Shoot.Kubernetes.KubeAPIServer.AdditionalOidcConfig + + if nil == additionalOidcConfig { + additionalOidcConfig = &[]gardener.OIDCConfig{} + *additionalOidcConfig = append(*additionalOidcConfig, oidcConfig) + } + + runtime.Spec.Shoot.Kubernetes.KubeAPIServer.AdditionalOidcConfig = additionalOidcConfig +} + +func setOIDCExtension(shoot *gardener.Shoot) { + oidcService := gardener.Extension{ + Type: OidcExtensionType, + Disabled: ptr.To(false), + } + shoot.Spec.Extensions = append(shoot.Spec.Extensions, oidcService) +} + +func setKubeAPIServerOIDCConfig(shoot *gardener.Shoot, oidcConfig gardener.OIDCConfig) { shoot.Spec.Kubernetes.KubeAPIServer = &gardener.KubeAPIServerConfig{ OIDCConfig: &gardener.OIDCConfig{ CABundle: oidcConfig.CABundle, @@ -21,6 +56,33 @@ func ExtendWithOIDC(runtime imv1.Runtime, shoot *gardener.Shoot) error { UsernamePrefix: oidcConfig.UsernamePrefix, }, } +} - return nil +//main OIDC task https://github.com/kyma-project/kyma/issues/18305#issuecomment-2128866460 + +func setOIDCConfig(shoot *gardener.Shoot, oidcConfig gardener.OIDCConfig) { + shoot.Spec.Kubernetes.KubeAPIServer = &gardener.KubeAPIServerConfig{ + OIDCConfig: &oidcConfig, + } +} + +func getDefaultOIDCConfig() *gardener.OIDCConfig { + return &gardener.OIDCConfig{ + + // taken from https://github.tools.sap/kyma/management-plane-config/blob/20474fc793b147845b884160954d280f75b98a85/argoenv/keb/dev/values.yaml + + //TODO: move below's default configuration to: + // - config file for local development + // - management-plane-charts/config + + //CABundle: //TODO: is it needed? + ClientID: ptr.To("xyz"), //TODO: move to config file + GroupsClaim: ptr.To("groups"), //TODO: move to config file + //GroupsPrefix: TODO: is it needed? + IssuerURL: ptr.To("https://kymatest.accounts400.ondemand.com"), //TODO: move to config file + //RequiredClaims: TODO: is it needed? + SigningAlgs: []string{"RS256"}, //TODO: move to config file + UsernameClaim: ptr.To("sub"), //TODO: move to config file + UsernamePrefix: ptr.To("-"), //TODO: move to config file + } } diff --git a/internal/gardener/shoot/extender/oidc_test.go b/internal/gardener/shoot/extender/oidc_test.go index 9303024e..67ad56f4 100644 --- a/internal/gardener/shoot/extender/oidc_test.go +++ b/internal/gardener/shoot/extender/oidc_test.go @@ -39,10 +39,18 @@ func TestOidcExtender(t *testing.T) { } // when - err := ExtendWithOIDC(runtimeShoot, &shoot) + err := ExtendWithOIDC(&runtimeShoot, &shoot) // then require.NoError(t, err) + assert.Equal(t, runtimeShoot.Spec.Shoot.Kubernetes.KubeAPIServer.OidcConfig, *shoot.Spec.Kubernetes.KubeAPIServer.OIDCConfig) + + // Default additionalOidcConfig is set when missing + defaultAdditionalOidcConfig := runtimeShoot.Spec.Shoot.Kubernetes.KubeAPIServer.AdditionalOidcConfig + assert.Equal(t, runtimeShoot.Spec.Shoot.Kubernetes.KubeAPIServer.OidcConfig, (*defaultAdditionalOidcConfig)[0]) + + assert.Equal(t, false, *shoot.Spec.Extensions[0].Disabled) + assert.Equal(t, "shoot-oidc-service", shoot.Spec.Extensions[0].Type) }) } From 32f016d38dafdee0ff1f9e772183825c703f046d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Drzewiecki?= Date: Thu, 5 Sep 2024 14:52:47 +0200 Subject: [PATCH 2/3] removes draft of oidc FSM state and adjusts the oidc extender --- api/v1/runtime_types.go | 1 - .../runtime/fsm/runtime_fsm_configure_oidc.go | 31 ------------- internal/gardener/shoot/extender/oidc.go | 44 +------------------ internal/gardener/shoot/extender/oidc_test.go | 7 +-- 4 files changed, 2 insertions(+), 81 deletions(-) delete mode 100644 internal/controller/runtime/fsm/runtime_fsm_configure_oidc.go diff --git a/api/v1/runtime_types.go b/api/v1/runtime_types.go index 098c1dd8..1e6af618 100644 --- a/api/v1/runtime_types.go +++ b/api/v1/runtime_types.go @@ -64,7 +64,6 @@ const ( ConditionTypeRuntimeProvisioned RuntimeConditionType = "Provisioned" ConditionTypeRuntimeProvisionedDryRun RuntimeConditionType = "ProvisionedDryRun" ConditionTypeRuntimeKubeconfigReady RuntimeConditionType = "KubeconfigReady" - ConditionTypeOidcConfigured RuntimeConditionType = "OidcConfigured" ConditionTypeRuntimeConfigured RuntimeConditionType = "Configured" ConditionTypeRuntimeDeprovisioned RuntimeConditionType = "Deprovisioned" ) diff --git a/internal/controller/runtime/fsm/runtime_fsm_configure_oidc.go b/internal/controller/runtime/fsm/runtime_fsm_configure_oidc.go deleted file mode 100644 index bf045a0a..00000000 --- a/internal/controller/runtime/fsm/runtime_fsm_configure_oidc.go +++ /dev/null @@ -1,31 +0,0 @@ -package fsm - -import ( - "context" - imv1 "github.com/kyma-project/infrastructure-manager/api/v1" - ctrl "sigs.k8s.io/controller-runtime" -) - -func sFnConfigureOidc(ctx context.Context, m *fsm, s *systemState) (stateFn, *ctrl.Result, error) { - m.log.Info("Configure OIDC state") - - //TODO: 2/3.check if doing this is necessary - //TODO: 2/3. remove existing "additionalOidcs" from the Shoot spec - //TODO: 1. recreate "additionalOidcs" in the Shoot spec - //TODO: 4. extract rest client to a separate interface - //TODO: 5. unit test the function - // create OIDCConnect CR in shoot - - //s.instance.UpdateStatePending(imv1.ConditionTypeRuntimeKubeconfigReady, imv1.ConditionReasonGardenerCRCreated, "Unknown", "Gardener Cluster CR created, waiting for readiness") - //return updateStatusAndRequeueAfter(controlPlaneRequeueDuration) - - // wait section - is it needed? - - //m.log.Info("OIDC has been configured", "Name", runtimeID) - - return ensureStatusConditionIsSetAndContinue(&s.instance, - imv1.ConditionTypeRuntimeKubeconfigReady, - imv1.ConditionReasonGardenerCRReady, - "Gardener Cluster CR is ready.", - sFnApplyClusterRoleBindings) -} diff --git a/internal/gardener/shoot/extender/oidc.go b/internal/gardener/shoot/extender/oidc.go index 199da8bb..3de05d9f 100644 --- a/internal/gardener/shoot/extender/oidc.go +++ b/internal/gardener/shoot/extender/oidc.go @@ -11,28 +11,15 @@ const ( ) // Extends Shoot spec with OIDC configuration and mutates Runtime spec with necessary OIDC defaults if missing -func ExtendWithOIDC(runtime *imv1.Runtime, shoot *gardener.Shoot) error { +func ExtendWithOIDC(runtime imv1.Runtime, shoot *gardener.Shoot) error { oidcConfig := runtime.Spec.Shoot.Kubernetes.KubeAPIServer.OidcConfig - defaultAdditionalOidcIfNotPresent(runtime) setOIDCExtension(shoot) setKubeAPIServerOIDCConfig(shoot, oidcConfig) return nil } -func defaultAdditionalOidcIfNotPresent(runtime *imv1.Runtime) { - oidcConfig := runtime.Spec.Shoot.Kubernetes.KubeAPIServer.OidcConfig - additionalOidcConfig := runtime.Spec.Shoot.Kubernetes.KubeAPIServer.AdditionalOidcConfig - - if nil == additionalOidcConfig { - additionalOidcConfig = &[]gardener.OIDCConfig{} - *additionalOidcConfig = append(*additionalOidcConfig, oidcConfig) - } - - runtime.Spec.Shoot.Kubernetes.KubeAPIServer.AdditionalOidcConfig = additionalOidcConfig -} - func setOIDCExtension(shoot *gardener.Shoot) { oidcService := gardener.Extension{ Type: OidcExtensionType, @@ -57,32 +44,3 @@ func setKubeAPIServerOIDCConfig(shoot *gardener.Shoot, oidcConfig gardener.OIDCC }, } } - -//main OIDC task https://github.com/kyma-project/kyma/issues/18305#issuecomment-2128866460 - -func setOIDCConfig(shoot *gardener.Shoot, oidcConfig gardener.OIDCConfig) { - shoot.Spec.Kubernetes.KubeAPIServer = &gardener.KubeAPIServerConfig{ - OIDCConfig: &oidcConfig, - } -} - -func getDefaultOIDCConfig() *gardener.OIDCConfig { - return &gardener.OIDCConfig{ - - // taken from https://github.tools.sap/kyma/management-plane-config/blob/20474fc793b147845b884160954d280f75b98a85/argoenv/keb/dev/values.yaml - - //TODO: move below's default configuration to: - // - config file for local development - // - management-plane-charts/config - - //CABundle: //TODO: is it needed? - ClientID: ptr.To("xyz"), //TODO: move to config file - GroupsClaim: ptr.To("groups"), //TODO: move to config file - //GroupsPrefix: TODO: is it needed? - IssuerURL: ptr.To("https://kymatest.accounts400.ondemand.com"), //TODO: move to config file - //RequiredClaims: TODO: is it needed? - SigningAlgs: []string{"RS256"}, //TODO: move to config file - UsernameClaim: ptr.To("sub"), //TODO: move to config file - UsernamePrefix: ptr.To("-"), //TODO: move to config file - } -} diff --git a/internal/gardener/shoot/extender/oidc_test.go b/internal/gardener/shoot/extender/oidc_test.go index 67ad56f4..2fda2db5 100644 --- a/internal/gardener/shoot/extender/oidc_test.go +++ b/internal/gardener/shoot/extender/oidc_test.go @@ -39,17 +39,12 @@ func TestOidcExtender(t *testing.T) { } // when - err := ExtendWithOIDC(&runtimeShoot, &shoot) + err := ExtendWithOIDC(runtimeShoot, &shoot) // then require.NoError(t, err) assert.Equal(t, runtimeShoot.Spec.Shoot.Kubernetes.KubeAPIServer.OidcConfig, *shoot.Spec.Kubernetes.KubeAPIServer.OIDCConfig) - - // Default additionalOidcConfig is set when missing - defaultAdditionalOidcConfig := runtimeShoot.Spec.Shoot.Kubernetes.KubeAPIServer.AdditionalOidcConfig - assert.Equal(t, runtimeShoot.Spec.Shoot.Kubernetes.KubeAPIServer.OidcConfig, (*defaultAdditionalOidcConfig)[0]) - assert.Equal(t, false, *shoot.Spec.Extensions[0].Disabled) assert.Equal(t, "shoot-oidc-service", shoot.Spec.Extensions[0].Type) }) From 7856f533b35479e77b5c4cdb192f823b99934fb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Drzewiecki?= Date: Thu, 5 Sep 2024 15:04:09 +0200 Subject: [PATCH 3/3] removes obsolete comment on oidc extender --- internal/gardener/shoot/extender/oidc.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/gardener/shoot/extender/oidc.go b/internal/gardener/shoot/extender/oidc.go index 3de05d9f..8e8da762 100644 --- a/internal/gardener/shoot/extender/oidc.go +++ b/internal/gardener/shoot/extender/oidc.go @@ -10,7 +10,6 @@ const ( OidcExtensionType = "shoot-oidc-service" ) -// Extends Shoot spec with OIDC configuration and mutates Runtime spec with necessary OIDC defaults if missing func ExtendWithOIDC(runtime imv1.Runtime, shoot *gardener.Shoot) error { oidcConfig := runtime.Spec.Shoot.Kubernetes.KubeAPIServer.OidcConfig