diff --git a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml index 29cc567267..2241271f38 100644 --- a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml +++ b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml @@ -2228,10 +2228,11 @@ spec: default: overwrite description: |- ConflictResolution is used to declare what should happen if there - are parameter conflicts. Defaults to none + are parameter conflicts. Defaults to overwrite enum: - overwrite - none + - preserve type: string name: description: Name is the name of the addon diff --git a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml index 369829fbb1..853f0e0aed 100644 --- a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml +++ b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml @@ -73,10 +73,11 @@ spec: default: overwrite description: |- ConflictResolution is used to declare what should happen if there - are parameter conflicts. Defaults to none + are parameter conflicts. Defaults to overwrite enum: - overwrite - none + - preserve type: string name: description: Name is the name of the addon diff --git a/controlplane/eks/api/v1beta2/types.go b/controlplane/eks/api/v1beta2/types.go index c740f868f1..ba355089ef 100644 --- a/controlplane/eks/api/v1beta2/types.go +++ b/controlplane/eks/api/v1beta2/types.go @@ -134,9 +134,9 @@ type Addon struct { // +optional Configuration string `json:"configuration,omitempty"` // ConflictResolution is used to declare what should happen if there - // are parameter conflicts. Defaults to none + // are parameter conflicts. Defaults to overwrite // +kubebuilder:default=overwrite - // +kubebuilder:validation:Enum=overwrite;none + // +kubebuilder:validation:Enum=overwrite;none;preserve ConflictResolution *AddonResolution `json:"conflictResolution,omitempty"` // ServiceAccountRoleArn is the ARN of an IAM role to bind to the addons service account // +optional @@ -154,6 +154,10 @@ var ( // AddonResolutionNone indicates that if there are parameter conflicts then // resolution will not be done and an error will be reported. AddonResolutionNone = AddonResolution("none") + + // AddonResolutionPreserve indicates that if there are parameter conflicts then + // resolution will result in preserving the existing value + AddonResolutionPreserve = AddonResolution("preserve") ) // AddonStatus defines the status for an addon. diff --git a/docs/book/src/topics/eks/addons.md b/docs/book/src/topics/eks/addons.md index 063a6c83fe..d8963d9691 100644 --- a/docs/book/src/topics/eks/addons.md +++ b/docs/book/src/topics/eks/addons.md @@ -23,8 +23,15 @@ spec: conflictResolution: "overwrite" ``` +Valid values are: +``` +none +overwrite +preserve +``` + _Note_: For `conflictResolution` `overwrite` is the **default** behaviour. That means, if not otherwise specified, it's -set to `overwrite`. +set to `overwrite`. Review [API Documentation](https://docs.aws.amazon.com/eks/latest/APIReference/API_CreateAddon.html#AmazonEKS-CreateAddon-request-resolveConflicts) for detailed behavior. Additionally, there is a cluster [flavor](https://cluster-api.sigs.k8s.io/clusterctl/commands/generate-cluster.html#flavors) called [eks-managedmachinepool-vpccni](https://github.com/kubernetes-sigs/cluster-api-provider-aws/blob/main/templates/cluster-template-eks-managedmachinepool-vpccni.yaml) that you can use with **clusterctl**: @@ -46,6 +53,8 @@ To update the version of an addon you need to edit the `AWSManagedControlPlane` ... ``` +_Note_: For `conflictResolution` `none`, updating may fail if a change was made to the addon that is unexpected by EKS. Review [API Documentation](https://docs.aws.amazon.com/eks/latest/APIReference/API_UpdateAddon.html#AmazonEKS-UpdateAddon-request-resolveConflicts) for detailed behavior on conflict resolution. + ## Deleting Addons To delete an addon from a cluster you need to edit the `AWSManagedControlPlane` instance and remove the entry for the addon you want to delete. diff --git a/pkg/cloud/services/eks/addons.go b/pkg/cloud/services/eks/addons.go index 3d2e75f0a5..be0160aca1 100644 --- a/pkg/cloud/services/eks/addons.go +++ b/pkg/cloud/services/eks/addons.go @@ -196,12 +196,16 @@ func (s *Service) translateAPIToAddon(addons []ekscontrolplanev1.Addon) []*eksad for i := range addons { addon := addons[i] + conflict, err := convertConflictResolution(*addon.ConflictResolution) + if err != nil { + s.scope.Error(err, err.Error()) + } convertedAddon := &eksaddons.EKSAddon{ Name: &addon.Name, Version: &addon.Version, Configuration: convertConfiguration(addon.Configuration), Tags: ngTags(s.scope.Cluster.Name, s.scope.AdditionalTags()), - ResolveConflict: convertConflictResolution(*addon.ConflictResolution), + ResolveConflict: conflict, ServiceAccountRoleARN: addon.ServiceAccountRoleArn, } @@ -220,14 +224,21 @@ func (k *EKSClient) WaitUntilAddonDeleted(ctx context.Context, input *eks.Descri return waiter.Wait(ctx, input, maxWait) } -func convertConflictResolution(conflict ekscontrolplanev1.AddonResolution) *string { - if conflict == ekscontrolplanev1.AddonResolutionNone { - res := string(ekstypes.ResolveConflictsNone) - return aws.String(res) - } +func convertConflictResolution(conflict ekscontrolplanev1.AddonResolution) (*string, error) { + switch conflict { + case ekscontrolplanev1.AddonResolutionNone: + return aws.String(string(ekstypes.ResolveConflictsNone)), nil - res := string(ekstypes.ResolveConflictsOverwrite) - return aws.String(res) + case ekscontrolplanev1.AddonResolutionOverwrite: + return aws.String(string(ekstypes.ResolveConflictsOverwrite)), nil + + case ekscontrolplanev1.AddonResolutionPreserve: + return aws.String(string(ekstypes.ResolveConflictsPreserve)), nil + + // Defaulting to behavior "Overwrite" as documented + default: + return aws.String(string(ekstypes.ResolveConflictsOverwrite)), fmt.Errorf("failed to determine adddonResolution; defaulting to Overwrite") + } } func convertConfiguration(configuration string) *string {