github.com/verrazzano/verrazzano@v1.7.1/cluster-operator/apis/clusters/v1alpha1/oke_webhook.go (about)

     1  // Copyright (c) 2023, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package v1alpha1
     5  
     6  import (
     7  	"errors"
     8  	"fmt"
     9  	"k8s.io/apimachinery/pkg/runtime"
    10  	"reflect"
    11  	ctrl "sigs.k8s.io/controller-runtime"
    12  	"sigs.k8s.io/controller-runtime/pkg/webhook"
    13  )
    14  
    15  // OCNEOCIQuickCreate should be both a validating and defaulting webhook
    16  var _ webhook.Validator = &OKEQuickCreate{}
    17  
    18  // SetupWebhookWithManager is used to let the controller manager know about the webhook
    19  func (o *OKEQuickCreate) SetupWebhookWithManager(mgr ctrl.Manager) error {
    20  	return ctrl.NewWebhookManagedBy(mgr).
    21  		For(o).
    22  		Complete()
    23  }
    24  
    25  func (o *OKEQuickCreate) ValidateCreate() error {
    26  	ctx, err := NewValidationContext()
    27  	if err != nil {
    28  		return fmt.Errorf("failed to create validation context: %w", err)
    29  	}
    30  	nsn := o.Spec.IdentityRef.AsNamespacedName()
    31  	creds, err := ctx.CredentialsLoader.GetCredentialsIfAllowed(ctx.Ctx, ctx.Cli, nsn, o.Namespace)
    32  	if err != nil {
    33  		return fmt.Errorf("cannot access OCI credentials %s/%s: %v", nsn.Namespace, nsn.Name, err)
    34  	}
    35  	ociClient, err := ctx.OCIClientGetter(creds)
    36  	if err != nil {
    37  		return fmt.Errorf("failed to create OCI Client: %w", err)
    38  	}
    39  	// Validate the OCI Network
    40  	if o.Spec.OKE.Network != nil {
    41  		addCNITypeErrors(ctx, o.Spec.OKE.Network.CNIType, "spec.oke.network")
    42  		numSubnets := 3 // controlplane-endpoint, worker, service-lb
    43  		if o.Spec.OKE.Network.CNIType == VCNNative {
    44  			numSubnets++ // pod subnet
    45  		}
    46  		addOCINetworkErrors(ctx, ociClient, o.Spec.OKE.Network.Config, numSubnets, "spec.oke.network.config")
    47  	}
    48  	for i, np := range o.Spec.OKE.NodePools {
    49  		addOCINodeErrors(ctx, np.OCINode, fmt.Sprintf("spec.oke.nodePools[%d]", i))
    50  	}
    51  	if ctx.Errors.HasError() {
    52  		return ctx.Errors
    53  	}
    54  	return nil
    55  }
    56  
    57  func addCNITypeErrors(ctx *validationContext, cniType CNIType, field string) {
    58  	switch cniType {
    59  	case FlannelOverlay, VCNNative:
    60  		return
    61  	default:
    62  		ctx.Errors.Addf("%s.cniType is invalid", field)
    63  	}
    64  }
    65  
    66  func (o *OKEQuickCreate) ValidateUpdate(old runtime.Object) error {
    67  	oldCluster, ok := old.(*OKEQuickCreate)
    68  	if !ok {
    69  		return errors.New("update resource must be of kind OKEQuickCreate")
    70  	}
    71  	if !reflect.DeepEqual(o.Spec, oldCluster.Spec) {
    72  		return errors.New("spec updates are not permitted")
    73  	}
    74  	return nil
    75  }
    76  func (o *OKEQuickCreate) ValidateDelete() error {
    77  	return nil
    78  }