@@ -22,9 +22,12 @@ import (
2222	"net" 
2323
2424	"github.com/apparentlymart/go-cidr/cidr" 
25+ 	"github.com/aws/aws-sdk-go-v2/aws" 
26+ 	ekstypes "github.com/aws/aws-sdk-go-v2/service/eks/types" 
2527	"github.com/pkg/errors" 
2628	apierrors "k8s.io/apimachinery/pkg/api/errors" 
2729	"k8s.io/apimachinery/pkg/runtime" 
30+ 	"k8s.io/apimachinery/pkg/util/sets" 
2831	"k8s.io/apimachinery/pkg/util/validation/field" 
2932	"k8s.io/apimachinery/pkg/util/version" 
3033	"k8s.io/klog/v2" 
@@ -52,6 +55,9 @@ const (
5255	cidrSizeMin     =  16 
5356	vpcCniAddon     =  "vpc-cni" 
5457	kubeProxyAddon  =  "kube-proxy" 
58+ 
59+ 	autoModeComputeNodePoolSystem   =  "system" 
60+ 	autoModeComputeNodePoolGeneral  =  "general-purpose" 
5561)
5662
5763// SetupWebhookWithManager will setup the webhooks for the AWSManagedControlPlane. 
@@ -102,6 +108,8 @@ func (*awsManagedControlPlaneWebhook) ValidateCreate(_ context.Context, obj runt
102108	allErrs  =  append (allErrs , r .validateSecondaryCIDR ()... )
103109	allErrs  =  append (allErrs , r .validateEKSAddons ()... )
104110	allErrs  =  append (allErrs , r .validateDisableVPCCNI ()... )
111+ 	allErrs  =  append (allErrs , r .validateAccessConfig (nil )... )
112+ 	allErrs  =  append (allErrs , r .validateAutoMode (nil )... )
105113	allErrs  =  append (allErrs , r .validateRestrictPrivateSubnets ()... )
106114	allErrs  =  append (allErrs , r .validateKubeProxy ()... )
107115	allErrs  =  append (allErrs , r .Spec .AdditionalTags .Validate ()... )
@@ -142,6 +150,8 @@ func (*awsManagedControlPlaneWebhook) ValidateUpdate(ctx context.Context, oldObj
142150	allErrs  =  append (allErrs , r .Spec .Bastion .Validate ()... )
143151	allErrs  =  append (allErrs , r .validateIAMAuthConfig ()... )
144152	allErrs  =  append (allErrs , r .validateSecondaryCIDR ()... )
153+ 	allErrs  =  append (allErrs , r .validateAccessConfig (oldAWSManagedControlplane )... )
154+ 	allErrs  =  append (allErrs , r .validateAutoMode (oldAWSManagedControlplane )... )
145155	allErrs  =  append (allErrs , r .validateEKSAddons ()... )
146156	allErrs  =  append (allErrs , r .validateDisableVPCCNI ()... )
147157	allErrs  =  append (allErrs , r .validateRestrictPrivateSubnets ()... )
@@ -423,6 +433,90 @@ func validateDisableVPCCNI(vpcCni VpcCni, addons *[]Addon, path *field.Path) fie
423433	return  allErrs 
424434}
425435
436+ func  (r  * AWSManagedControlPlane ) validateAccessConfig (old  * AWSManagedControlPlane ) field.ErrorList  {
437+ 	return  validateAccessConfig (r .Spec .AccessConfig , old , field .NewPath ("spec" , "accessConfig" ))
438+ }
439+ 
440+ func  validateAccessConfig (accessConfig  AccessConfig , old  * AWSManagedControlPlane , path  * field.Path ) field.ErrorList  {
441+ 	var  (
442+ 		allErrs     field.ErrorList 
443+ 		authModeOK  bool 
444+ 	)
445+ 
446+ 	authConfigField  :=  path .Child ("authenticationMode" )
447+ 
448+ 	for  _ , accessMode  :=  range  ekstypes .AuthenticationMode ("" ).Values () {
449+ 		if  ekstypes .AuthenticationMode (* accessConfig .AuthenticationMode ) ==  accessMode  {
450+ 			authModeOK  =  true 
451+ 		}
452+ 	}
453+ 
454+ 	if  ! authModeOK  {
455+ 		allErrs  =  append (allErrs , field .Invalid (authConfigField , * accessConfig .AuthenticationMode , "unsupported authenticationMode provided" ))
456+ 	}
457+ 
458+ 	if  old  !=  nil  {
459+ 		if  * old .Spec .AccessConfig .AuthenticationMode  !=  * accessConfig .AuthenticationMode  {
460+ 			if  ekstypes .AuthenticationMode (* accessConfig .AuthenticationMode ) ==  ekstypes .AuthenticationModeConfigMap  {
461+ 				allErrs  =  append (allErrs , field .Invalid (authConfigField , * accessConfig .AuthenticationMode , "cannot switch authenticationMode to legacy CONFIG_MAP mode" ))
462+ 			}
463+ 		}
464+ 	}
465+ 
466+ 	if  * accessConfig .BootstrapAdminPermissions  &&  ekstypes .AuthenticationMode (* accessConfig .AuthenticationMode ) ==  ekstypes .AuthenticationModeConfigMap  {
467+ 		authConfigField  :=  path .Child ("bootstrapAdminPermissions" )
468+ 		allErrs  =  append (allErrs , field .Invalid (authConfigField , * accessConfig .BootstrapAdminPermissions , "authenticationMode CONFIG_MAP has no effect with the bootstrapAdminPermissions parameter" ))
469+ 	}
470+ 
471+ 	return  allErrs 
472+ }
473+ 
474+ func  (r  * AWSManagedControlPlane ) validateAutoMode (old  * AWSManagedControlPlane ) field.ErrorList  {
475+ 	return  validateAutoMode (r .Spec , old , field .NewPath ("spec" ))
476+ }
477+ 
478+ func  validateAutoMode (spec  AWSManagedControlPlaneSpec , old  * AWSManagedControlPlane , path  * field.Path ) field.ErrorList  {
479+ 	var  allErrs  field.ErrorList 
480+ 
481+ 	if  spec .AutoMode  ==  nil  {
482+ 		return  nil 
483+ 	}
484+ 
485+ 	if  spec .AutoMode .Enabled  {
486+ 		// EKS Auto mode is not compatible with configmap AuthenticationMode. 
487+ 		if  * spec .AccessConfig .AuthenticationMode  ==  string (ekstypes .AuthenticationModeConfigMap ) {
488+ 			authConfigField  :=  path .Child ("accessConfig" , "authenticationMode" )
489+ 			allErrs  =  append (allErrs , field .Invalid (authConfigField , spec .AccessConfig .AuthenticationMode , "authenticationMode CONFIG_MAP couldn't be used with autoMode" ))
490+ 		}
491+ 
492+ 		if  old  !=  nil  {
493+ 			// nodeRoleArn cannot be changed after the compute capability of EKS Auto Mode is enabled. 
494+ 			if  old .Spec .AutoMode .Compute .NodeRoleArn  !=  spec .AutoMode .Compute .NodeRoleArn  {
495+ 				nodeRoleArnField  :=  path .Child ("autoMode" , "compute" , "nodeRoleArn" )
496+ 				allErrs  =  append (allErrs , field .Invalid (nodeRoleArnField , spec .AutoMode .Compute .NodeRoleArn , "nodeRoleArn could not be changed" ))
497+ 			}
498+ 		}
499+ 
500+ 		if  len (spec .AutoMode .Compute .NodePools ) >  0  {
501+ 			// nodeRoleArn should be always defined with node pools. 
502+ 			if  spec .AutoMode .Compute .NodeRoleArn  ==  nil  {
503+ 				nodeRoleArnField  :=  path .Child ("autoMode" , "compute" , "nodeRoleArn" )
504+ 				allErrs  =  append (allErrs , field .Invalid (nodeRoleArnField , spec .AutoMode .Compute .NodeRoleArn , "nodeRoleArn is required when nodePools specified" ))
505+ 			}
506+ 
507+ 			allowedPoolNames  :=  sets .New [string ](autoModeComputeNodePoolSystem , autoModeComputeNodePoolGeneral )
508+ 			for  _ , poolName  :=  range  spec .AutoMode .Compute .NodePools  {
509+ 				nodePoolsField  :=  path .Child ("autoMode" , "compute" , "nodePools" )
510+ 				if  ! allowedPoolNames .Has (poolName ) {
511+ 					allErrs  =  append (allErrs , field .Invalid (nodePoolsField , poolName , "nodePools contains an invalid pool" ))
512+ 				}
513+ 			}
514+ 		}
515+ 	}
516+ 
517+ 	return  allErrs 
518+ }
519+ 
426520func  (r  * AWSManagedControlPlane ) validateRestrictPrivateSubnets () field.ErrorList  {
427521	return  validateRestrictPrivateSubnets (r .Spec .RestrictPrivateSubnets , r .Spec .NetworkSpec , r .Spec .EKSClusterName , field .NewPath ("spec" ))
428522}
@@ -568,10 +662,16 @@ func (*awsManagedControlPlaneWebhook) Default(_ context.Context, obj runtime.Obj
568662		}
569663	}
570664
665+ 	if  r .Spec .BootstrapSelfManagedAddons  ==  nil  {
666+ 		r .Spec .BootstrapSelfManagedAddons  =  aws .Bool (true )
667+ 	}
668+ 
669+ 	if  r .Spec .AccessConfig .AuthenticationMode  ==  nil  {
670+ 		r .Spec .AccessConfig .AuthenticationMode  =  aws .String (string (ekstypes .AuthenticationModeConfigMap ))
671+ 	}
672+ 
571673	infrav1 .SetDefaults_Bastion (& r .Spec .Bastion )
572674	infrav1 .SetDefaults_NetworkSpec (& r .Spec .NetworkSpec )
573675
574- 	// Set default value for BootstrapSelfManagedAddons 
575- 	r .Spec .BootstrapSelfManagedAddons  =  true 
576676	return  nil 
577677}
0 commit comments