From 32a11b14ee786b923e401abd49e8fcd40f2ac460 Mon Sep 17 00:00:00 2001 From: Luca Bernstein Date: Wed, 2 Oct 2024 13:12:51 +0200 Subject: [PATCH] Add NamespacedCloudProfile support to Shoot validation. Switch from CloudProfile to CloudProfileSpec as a generic foundation for CloudProfile and NamespacedCloudProfile. Improve log message for possibly artificially crafted CloudProfile from NamespacedCloudProfile in Cluster resource. --- .../charts/application/templates/rbac.yaml | 1 + docs/operations/operations.md | 3 ++- pkg/admission/validator/shoot.go | 17 +++++++++++++---- pkg/apis/ironcore/helper/scheme.go | 8 ++++++-- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/charts/gardener-extension-admission-ironcore/charts/application/templates/rbac.yaml b/charts/gardener-extension-admission-ironcore/charts/application/templates/rbac.yaml index d002308c..ca9ee00d 100644 --- a/charts/gardener-extension-admission-ironcore/charts/application/templates/rbac.yaml +++ b/charts/gardener-extension-admission-ironcore/charts/application/templates/rbac.yaml @@ -10,6 +10,7 @@ rules: - core.gardener.cloud resources: - cloudprofiles + - namespacedcloudprofiles verbs: - get - list diff --git a/docs/operations/operations.md b/docs/operations/operations.md index 8899b512..ad00c9d1 100644 --- a/docs/operations/operations.md +++ b/docs/operations/operations.md @@ -134,7 +134,8 @@ metadata: name: my-shoot namespace: my-namespace spec: - cloudProfileName: ironcore + cloudProfile: + name: ironcore secretBindingName: my-credentials region: my-region networking: diff --git a/pkg/admission/validator/shoot.go b/pkg/admission/validator/shoot.go index 1c1c411e..b2bada35 100644 --- a/pkg/admission/validator/shoot.go +++ b/pkg/admission/validator/shoot.go @@ -11,6 +11,7 @@ import ( extensionswebhook "github.com/gardener/gardener/extensions/pkg/webhook" "github.com/gardener/gardener/pkg/apis/core" gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1" + "github.com/gardener/gardener/pkg/utils/gardener" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/util/validation/field" @@ -68,7 +69,7 @@ type validationContext struct { shoot *core.Shoot infrastructureConfig *apisironcore.InfrastructureConfig controlPlaneConfig *apisironcore.ControlPlaneConfig - cloudProfile *gardencorev1beta1.CloudProfile + cloudProfileSpec *gardencorev1beta1.CloudProfileSpec } func (s *shoot) validateContext(valContext *validationContext) field.ErrorList { @@ -142,10 +143,18 @@ func newValidationContext(ctx context.Context, decoder runtime.Decoder, c client return nil, fmt.Errorf("error decoding controlPlaneConfig: %v", err) } - cloudProfile := &gardencorev1beta1.CloudProfile{} - if err := c.Get(ctx, client.ObjectKey{Name: shoot.Spec.CloudProfile.Name}, cloudProfile); err != nil { + shootV1Beta1 := &gardencorev1beta1.Shoot{} + err = gardencorev1beta1.Convert_core_Shoot_To_v1beta1_Shoot(shoot, shootV1Beta1, nil) + if err != nil { return nil, err } + cloudProfile, err := gardener.GetCloudProfile(ctx, c, shootV1Beta1) + if err != nil { + return nil, err + } + if cloudProfile == nil { + return nil, fmt.Errorf("cloudprofile could not be found") + } if cloudProfile.Spec.ProviderConfig == nil { return nil, fmt.Errorf("providerConfig is not given for cloud profile %q", cloudProfile.Name) @@ -155,6 +164,6 @@ func newValidationContext(ctx context.Context, decoder runtime.Decoder, c client shoot: shoot, infrastructureConfig: infrastructureConfig, controlPlaneConfig: controlPlaneConfig, - cloudProfile: cloudProfile, + cloudProfileSpec: &cloudProfile.Spec, }, nil } diff --git a/pkg/apis/ironcore/helper/scheme.go b/pkg/apis/ironcore/helper/scheme.go index b0815169..53b387a1 100644 --- a/pkg/apis/ironcore/helper/scheme.go +++ b/pkg/apis/ironcore/helper/scheme.go @@ -11,7 +11,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" - "sigs.k8s.io/controller-runtime/pkg/client" + k8sclient "sigs.k8s.io/controller-runtime/pkg/client" api "github.com/ironcore-dev/gardener-extension-provider-ironcore/pkg/apis/ironcore" "github.com/ironcore-dev/gardener-extension-provider-ironcore/pkg/apis/ironcore/install" @@ -65,9 +65,13 @@ func InfrastructureStatusFromRaw(raw *runtime.RawExtension) (*api.Infrastructure func CloudProfileConfigFromCluster(cluster *controller.Cluster) (*api.CloudProfileConfig, error) { var cloudProfileConfig *api.CloudProfileConfig if cluster != nil && cluster.CloudProfile != nil && cluster.CloudProfile.Spec.ProviderConfig != nil && cluster.CloudProfile.Spec.ProviderConfig.Raw != nil { + cloudProfileSpecifier := fmt.Sprintf("CloudProfile %q", k8sclient.ObjectKeyFromObject(cluster.CloudProfile)) + if cluster.Shoot != nil && cluster.Shoot.Spec.CloudProfile != nil { + cloudProfileSpecifier = fmt.Sprintf("%s '%s/%s'", cluster.Shoot.Spec.CloudProfile.Kind, cluster.Shoot.Namespace, cluster.Shoot.Spec.CloudProfile.Name) + } cloudProfileConfig = &api.CloudProfileConfig{} if _, _, err := decoder.Decode(cluster.CloudProfile.Spec.ProviderConfig.Raw, nil, cloudProfileConfig); err != nil { - return nil, fmt.Errorf("could not decode providerConfig of cloudProfile for '%s': %w", client.ObjectKeyFromObject(cluster.CloudProfile), err) + return nil, fmt.Errorf("could not decode providerConfig of %s: %w", cloudProfileSpecifier, err) } } return cloudProfileConfig, nil