github.com/ironcore-dev/gardener-extension-provider-ironcore@v0.3.2-0.20240314231816-8336447fb9a0/pkg/admission/validator/secretbinding.go (about)

     1  // SPDX-FileCopyrightText: 2022 SAP SE or an SAP affiliate company and IronCore contributors
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package validator
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  
    10  	extensionswebhook "github.com/gardener/gardener/extensions/pkg/webhook"
    11  	"github.com/gardener/gardener/pkg/apis/core"
    12  	kutil "github.com/gardener/gardener/pkg/utils/kubernetes"
    13  	corev1 "k8s.io/api/core/v1"
    14  	"k8s.io/apimachinery/pkg/api/equality"
    15  	"sigs.k8s.io/controller-runtime/pkg/client"
    16  	"sigs.k8s.io/controller-runtime/pkg/manager"
    17  
    18  	ironcorevalidation "github.com/ironcore-dev/gardener-extension-provider-ironcore/pkg/apis/ironcore/validation"
    19  )
    20  
    21  type secretBinding struct {
    22  	apiReader client.Reader
    23  }
    24  
    25  // NewSecretBindingValidator returns a new instance of a secret binding validator.
    26  func NewSecretBindingValidator(mgr manager.Manager) extensionswebhook.Validator {
    27  	return &secretBinding{
    28  		apiReader: mgr.GetAPIReader(),
    29  	}
    30  }
    31  
    32  // Validate checks whether the given SecretBinding refers to a Secret with a valid ironcore service account.
    33  func (sb *secretBinding) Validate(ctx context.Context, newObj, oldObj client.Object) error {
    34  	secretBinding, ok := newObj.(*core.SecretBinding)
    35  	if !ok {
    36  		return fmt.Errorf("wrong object type %T", newObj)
    37  	}
    38  
    39  	if oldObj != nil {
    40  		oldSecretBinding, ok := oldObj.(*core.SecretBinding)
    41  		if !ok {
    42  			return fmt.Errorf("wrong object type %T for old object", oldObj)
    43  		}
    44  
    45  		// If the provider type did not change, we exit early.
    46  		if oldSecretBinding.Provider != nil && equality.Semantic.DeepEqual(secretBinding.Provider.Type, oldSecretBinding.Provider.Type) {
    47  			return nil
    48  		}
    49  	}
    50  
    51  	var (
    52  		secret    = &corev1.Secret{}
    53  		secretKey = kutil.Key(secretBinding.SecretRef.Namespace, secretBinding.SecretRef.Name)
    54  	)
    55  	// Explicitly use the client.Reader to prevent controller-runtime to start Informer for Secrets
    56  	// under the hood. The latter increases the memory usage of the component.
    57  	if err := sb.apiReader.Get(ctx, secretKey, secret); err != nil {
    58  		return err
    59  	}
    60  
    61  	return ironcorevalidation.ValidateCloudProviderSecret(secret)
    62  }