diff --git a/internal/controller/runtime/fsm/runtime_fsm_configure_oidc.go b/internal/controller/runtime/fsm/runtime_fsm_configure_oidc.go index a58ec0eb..e3f3d37a 100644 --- a/internal/controller/runtime/fsm/runtime_fsm_configure_oidc.go +++ b/internal/controller/runtime/fsm/runtime_fsm_configure_oidc.go @@ -2,9 +2,11 @@ package fsm import ( "context" + "fmt" gardener "github.com/gardener/gardener/pkg/apis/core/v1beta1" authenticationv1alpha1 "github.com/gardener/oidc-webhook-authenticator/apis/authentication/v1alpha1" imv1 "github.com/kyma-project/infrastructure-manager/api/v1" + "github.com/kyma-project/infrastructure-manager/internal/gardener/shoot/extender" "github.com/pkg/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ctrl "sigs.k8s.io/controller-runtime" @@ -13,34 +15,9 @@ import ( func sFnConfigureOidc(ctx context.Context, m *fsm, s *systemState) (stateFn, *ctrl.Result, error) { m.log.Info("Configure OIDC state") - //done 0. plug in to the state machine without actually doing anything - //TODO: - check condition if going into this state is necessary - // - extension enabled - // - OIDC config present - //TODO: - revisit the default OIDC requirements, implementation drafted in https://github.com/kyma-project/infrastructure-manager/commit/32f016d38dafdee0ff1f9e772183825c703f046d - //done - double check RBACs if they're in the right context (right client shoot vs gardener vs kcp ) - //done - create OpenID resource on the shoot - //TODO: - openID resource using non-fake values - //TODO: - (???) remove existing "additionalOidcs" from the Shoot spec - //TODO: - recreate "additionalOidcs" in the Shoot spec - //TODO: - extract rest client to a separate interface - //TODO: - consider if we should stop in case of a failure - //TODO: - possibly merge with CRB state - //TODO: - the condition set should reflect framefrog condition strategy - //TODO: - unit test the function - - //s.instance.UpdateStatePending(imv1.ConditionTypeRuntimeKubeconfigReady, imv1.ConditionReasonGardenerCRCreated, "Unknown", "Gardener Cluster CR created, waiting for readiness") - //return updateStatusAndRequeueAfter(controlPlaneRequeueDuration) - - // wait section - is it needed? - - //prepare subresource client to request admin kubeconfig - srscClient := m.ShootClient.SubResource("adminkubeconfig") - shootAdminClient, err := GetShootClient(ctx, srscClient, s.shoot) - - if err != nil { - //TODO: handle error before updating status - return updateStatusAndStopWithError(err) + if !isOidcExtensionEnabled(*s.shoot) { + m.log.Info("OIDC extension is disabled") + updateStatusAndStop() } if s.instance.Spec.Shoot.Kubernetes.KubeAPIServer.AdditionalOidcConfig == nil { @@ -49,12 +26,10 @@ func sFnConfigureOidc(ctx context.Context, m *fsm, s *systemState) (stateFn, *ct return updateStatusAndStopWithError(error) } - additionalOidcConfig := (*s.instance.Spec.Shoot.Kubernetes.KubeAPIServer.AdditionalOidcConfig)[0] - openIDConnectResource := createOpenIDConnectResource(additionalOidcConfig) - errResourceCreation := shootAdminClient.Create(ctx, openIDConnectResource) + err := createOpenIdConnectResources(ctx, m, s) - if errResourceCreation != nil { - m.log.Error(errResourceCreation, "Failed to create OpenIDConnect resource") + if err != nil { + m.log.Error(err, "Failed to create OpenIDConnect resource") } s.instance.UpdateStateReady( @@ -68,14 +43,41 @@ func sFnConfigureOidc(ctx context.Context, m *fsm, s *systemState) (stateFn, *ct return updateStatusAndStop() } -func createOpenIDConnectResource(additionalOidcConfig gardener.OIDCConfig) *authenticationv1alpha1.OpenIDConnect { +func createOpenIdConnectResources(ctx context.Context, m *fsm, s *systemState) error { + srscClient := m.ShootClient.SubResource("adminkubeconfig") + shootAdminClient, shootClientError := GetShootClient(ctx, srscClient, s.shoot) + + if shootClientError != nil { + return shootClientError + } + + additionalOidcConfigs := *s.instance.Spec.Shoot.Kubernetes.KubeAPIServer.AdditionalOidcConfig + + var errResourceCreation error + for id, additionalOidcConfig := range additionalOidcConfigs { + openIDConnectResource := createOpenIDConnectResource(additionalOidcConfig, id) + errResourceCreation = shootAdminClient.Create(ctx, openIDConnectResource) + } + return errResourceCreation +} + +func isOidcExtensionEnabled(shoot gardener.Shoot) bool { + for _, extension := range shoot.Spec.Extensions { + if extension.Type == extender.OidcExtensionType { + return !(*extension.Disabled) + } + } + return false +} + +func createOpenIDConnectResource(additionalOidcConfig gardener.OIDCConfig, oidcId int) *authenticationv1alpha1.OpenIDConnect { cr := &authenticationv1alpha1.OpenIDConnect{ TypeMeta: metav1.TypeMeta{ Kind: "OpenIDConnect", APIVersion: "authentication.gardener.cloud/v1alpha1", }, ObjectMeta: metav1.ObjectMeta{ - Name: "to-be-changed", + Name: fmt.Sprintf("kyma-oidc-%v", oidcId), }, Spec: authenticationv1alpha1.OIDCAuthenticationSpec{ IssuerURL: *additionalOidcConfig.IssuerURL, @@ -88,24 +90,5 @@ func createOpenIDConnectResource(additionalOidcConfig gardener.OIDCConfig) *auth }, } - //cr := &authenticationv1alpha1.OpenIDConnect{ - // TypeMeta: metav1.TypeMeta{ - // Kind: "OpenIDConnect", - // APIVersion: "authentication.gardener.cloud/v1alpha1", - // }, - // ObjectMeta: metav1.ObjectMeta{ - // Name: "my-oidc", - // }, - // Spec: authenticationv1alpha1.OIDCAuthenticationSpec{ - // IssuerURL: "https://token.actions.githubusercontent.com", - // ClientID: "my-kubernetes-cluster", - // UsernameClaim: ptr.To("sub"), - // UsernamePrefix: ptr.To("actions-oidc:"), - // GroupsPrefix: ptr.To("deploy-kubernetes"), - // GroupsClaim: ptr.To("myOrg/myRepo"), - // RequiredClaims: map[string]string{}, - // }, - //} - return cr }