diff --git a/cmd/eksctl-anywhere/cmd/upgradecluster.go b/cmd/eksctl-anywhere/cmd/upgradecluster.go index 0a55d0cd091ce..a10d61c604039 100644 --- a/cmd/eksctl-anywhere/cmd/upgradecluster.go +++ b/cmd/eksctl-anywhere/cmd/upgradecluster.go @@ -11,7 +11,6 @@ import ( "github.com/aws/eks-anywhere/cmd/eksctl-anywhere/cmd/aflag" "github.com/aws/eks-anywhere/pkg/api/v1alpha1" "github.com/aws/eks-anywhere/pkg/dependencies" - "github.com/aws/eks-anywhere/pkg/features" "github.com/aws/eks-anywhere/pkg/kubeconfig" "github.com/aws/eks-anywhere/pkg/logger" "github.com/aws/eks-anywhere/pkg/providers/tinkerbell/hardware" @@ -195,8 +194,7 @@ func (uc *upgradeClusterOptions) upgradeCluster(cmd *cobra.Command, args []strin upgradeValidations := upgradevalidations.New(validationOpts) - if features.ExperimentalSelfManagedClusterUpgrade().IsActive() && clusterConfig.IsSelfManaged() { - logger.Info("Management kindless upgrade") + if clusterConfig.IsSelfManaged() { upgrade := management.NewUpgrade( deps.Provider, deps.CAPIManager, diff --git a/manager/main.go b/manager/main.go index 3dd5dfee5399a..9f998d0ebad1e 100644 --- a/manager/main.go +++ b/manager/main.go @@ -168,14 +168,9 @@ func setupReconcilers(ctx context.Context, setupLog logr.Logger, mgr ctrl.Manage os.Exit(1) } - expUpgrades := features.IsActive(features.ExperimentalSelfManagedClusterUpgrade()) - if expUpgrades { - setupLog.Info("[EXPERIMENTAL] Self-managed cluster upgrades enabled. Proceed with caution, this is not intended for production scenarios.") - } - factory := controllers.NewFactory(ctrl.Log, mgr). WithClusterReconciler( - providers, controllers.WithExperimentalSelfManagedClusterUpgrades(expUpgrades), + providers, ). WithVSphereDatacenterReconciler(). WithSnowMachineConfigReconciler(). diff --git a/pkg/api/v1alpha1/cluster_webhook.go b/pkg/api/v1alpha1/cluster_webhook.go index 0339c7887758b..98849939681c0 100644 --- a/pkg/api/v1alpha1/cluster_webhook.go +++ b/pkg/api/v1alpha1/cluster_webhook.go @@ -26,7 +26,6 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" - "github.com/aws/eks-anywhere/pkg/features" "github.com/aws/eks-anywhere/pkg/semver" ) @@ -374,28 +373,25 @@ func validateImmutableFieldsCluster(new, old *Cluster) field.ErrorList { } } - if !old.IsSelfManaged() || features.IsActive(features.ExperimentalSelfManagedClusterUpgrade()) { - oldAWSIamConfig, newAWSIamConfig := &Ref{}, &Ref{} - for _, identityProvider := range new.Spec.IdentityProviderRefs { - if identityProvider.Kind == AWSIamConfigKind { - newAWSIamConfig = &identityProvider - break - } + oldAWSIamConfig, newAWSIamConfig := &Ref{}, &Ref{} + for _, identityProvider := range new.Spec.IdentityProviderRefs { + if identityProvider.Kind == AWSIamConfigKind { + newAWSIamConfig = &identityProvider + break } + } - for _, identityProvider := range old.Spec.IdentityProviderRefs { - if identityProvider.Kind == AWSIamConfigKind { - oldAWSIamConfig = &identityProvider - break - } + for _, identityProvider := range old.Spec.IdentityProviderRefs { + if identityProvider.Kind == AWSIamConfigKind { + oldAWSIamConfig = &identityProvider + break } + } - if !oldAWSIamConfig.Equal(newAWSIamConfig) { - allErrs = append( - allErrs, - field.Forbidden(specPath.Child("identityProviderRefs", AWSIamConfigKind), fmt.Sprintf("field is immutable %v", newAWSIamConfig.Kind))) - } - return allErrs + if !oldAWSIamConfig.Equal(newAWSIamConfig) { + allErrs = append( + allErrs, + field.Forbidden(specPath.Child("identityProviderRefs", AWSIamConfigKind), fmt.Sprintf("field is immutable %v", newAWSIamConfig.Kind))) } clusterlog.Info("Cluster config is associated with management cluster", "name", old.Name) diff --git a/pkg/api/v1alpha1/cluster_webhook_test.go b/pkg/api/v1alpha1/cluster_webhook_test.go index 891df2fc3f7c7..bc9fd4c838c3f 100644 --- a/pkg/api/v1alpha1/cluster_webhook_test.go +++ b/pkg/api/v1alpha1/cluster_webhook_test.go @@ -30,35 +30,6 @@ func TestClusterDefault(t *testing.T) { g.Expect(cOld.Spec.RegistryMirrorConfiguration.Port).To(Equal(constants.DefaultHttpsPort)) } -func TestClusterValidateUpdateManagementValueMutableExperimental(t *testing.T) { - features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") - cOld := baseCluster() - cOld.Spec.ControlPlaneConfiguration.Labels = map[string]string{"Key1": "Val1"} - cOld.Spec.ControlPlaneConfiguration.Taints = []v1.Taint{ - { - Key: "Key1", - Value: "Val1", - Effect: "PreferNoSchedule", - }, - } - cOld.SetSelfManaged() - cNew := cOld.DeepCopy() - cNew.Spec.ControlPlaneConfiguration.Labels = map[string]string{"Key2": "Val2"} - cNew.Spec.ControlPlaneConfiguration.Taints = []v1.Taint{ - { - Key: "Key2", - Value: "Val2", - Effect: "PreferNoSchedule", - }, - } - cNew.Spec.ControlPlaneConfiguration.Count = 1 - cNew.Spec.ControlPlaneConfiguration.MachineGroupRef.Name = "test" - - g := NewWithT(t) - g.Expect(cNew.ValidateUpdate(cOld)).To(Succeed()) -} - func TestClusterValidateUpdateManagementValueImmutable(t *testing.T) { cOld := baseCluster() cOld.SetSelfManaged() @@ -288,8 +259,6 @@ func TestCloudStackClusterValidateUpdateControlPlaneConfigurationOldPortImmutabl } func TestManagementClusterValidateUpdateControlPlaneConfigurationTaintsImmutable(t *testing.T) { - features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "false") cOld := baseCluster() cOld.Spec.ControlPlaneConfiguration = v1alpha1.ControlPlaneConfiguration{ Taints: []v1.Taint{ @@ -317,8 +286,6 @@ func TestManagementClusterValidateUpdateControlPlaneConfigurationTaintsImmutable } func TestManagementClusterValidateUpdateControlPlaneConfigurationLabelsImmutable(t *testing.T) { - features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "false") cOld := baseCluster() cOld.Spec.ControlPlaneConfiguration = v1alpha1.ControlPlaneConfiguration{ Labels: map[string]string{ @@ -338,8 +305,6 @@ func TestManagementClusterValidateUpdateControlPlaneConfigurationLabelsImmutable } func TestManagementClusterValidateUpdateControlPlaneConfigurationOldMachineGroupRefImmutable(t *testing.T) { - features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "false") cOld := baseCluster() cOld.Spec.ControlPlaneConfiguration = v1alpha1.ControlPlaneConfiguration{ MachineGroupRef: &v1alpha1.Ref{Name: "test1", Kind: "MachineConfig"}, @@ -368,8 +333,6 @@ func TestWorkloadClusterValidateUpdateControlPlaneConfigurationMachineGroupRef(t } func TestManagementClusterValidateUpdateControlPlaneConfigurationOldMachineGroupRefNilImmutable(t *testing.T) { - features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "false") cOld := baseCluster() cOld.Spec.ControlPlaneConfiguration = v1alpha1.ControlPlaneConfiguration{ MachineGroupRef: nil, @@ -398,8 +361,6 @@ func TestWorkloadClusterValidateUpdateControlPlaneConfigurationOldMachineGroupRe } func TestManagementClusterValidateUpdateControlPlaneConfigurationNewMachineGroupRefNilImmutable(t *testing.T) { - features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "false") cOld := baseCluster() cOld.Spec.ControlPlaneConfiguration = v1alpha1.ControlPlaneConfiguration{ MachineGroupRef: &v1alpha1.Ref{Name: "test", Kind: "MachineConfig"}, @@ -1815,7 +1776,6 @@ func TestClusterValidateUpdateInvalidRequest(t *testing.T) { features.ClearCache() cOld := baseCluster() cOld.SetSelfManaged() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "false") cNew := cOld.DeepCopy() cNew.Spec.ControlPlaneConfiguration.Count = cNew.Spec.ControlPlaneConfiguration.Count + 1 diff --git a/pkg/api/v1alpha1/vspheremachineconfig_webhook.go b/pkg/api/v1alpha1/vspheremachineconfig_webhook.go index 16752ef015301..307cf88b7f305 100644 --- a/pkg/api/v1alpha1/vspheremachineconfig_webhook.go +++ b/pkg/api/v1alpha1/vspheremachineconfig_webhook.go @@ -2,7 +2,6 @@ package v1alpha1 import ( "fmt" - "reflect" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" @@ -10,8 +9,6 @@ import ( ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" - - "github.com/aws/eks-anywhere/pkg/features" ) // log is for logging in this package. @@ -131,68 +128,6 @@ func validateImmutableFieldsVSphereMachineConfig(new, old *VSphereMachineConfig) return allErrs } - if features.IsActive(features.ExperimentalSelfManagedClusterUpgrade()) { - return allErrs - } - - vspheremachineconfiglog.Info("Machine config is associated with management cluster's control plane or etcd", "name", old.Name) - - if !reflect.DeepEqual(old.Spec.Users, new.Spec.Users) { - allErrs = append( - allErrs, - field.Forbidden(specPath.Child("users"), "field is immutable"), - ) - } - - if old.Spec.Template != new.Spec.Template { - allErrs = append( - allErrs, - field.Forbidden(specPath.Child("template"), "field is immutable"), - ) - } - - if old.Spec.Datastore != new.Spec.Datastore { - allErrs = append( - allErrs, - field.Forbidden(specPath.Child("datastore"), "field is immutable"), - ) - } - - if old.Spec.Folder != new.Spec.Folder { - allErrs = append( - allErrs, - field.Forbidden(specPath.Child("folder"), "field is immutable"), - ) - } - - if old.Spec.ResourcePool != new.Spec.ResourcePool { - allErrs = append( - allErrs, - field.Forbidden(specPath.Child("resourcePool"), "field is immutable"), - ) - } - - if old.Spec.MemoryMiB != new.Spec.MemoryMiB { - allErrs = append( - allErrs, - field.Forbidden(specPath.Child("memoryMiB"), "field is immutable"), - ) - } - - if old.Spec.NumCPUs != new.Spec.NumCPUs { - allErrs = append( - allErrs, - field.Forbidden(specPath.Child("numCPUs"), "field is immutable"), - ) - } - - if old.Spec.DiskGiB != new.Spec.DiskGiB { - allErrs = append( - allErrs, - field.Forbidden(specPath.Child("diskGiB"), "field is immutable"), - ) - } - return allErrs } diff --git a/pkg/api/v1alpha1/vspheremachineconfig_webhook_test.go b/pkg/api/v1alpha1/vspheremachineconfig_webhook_test.go index 778cd8f7702c2..c36c77f7ecb7f 100644 --- a/pkg/api/v1alpha1/vspheremachineconfig_webhook_test.go +++ b/pkg/api/v1alpha1/vspheremachineconfig_webhook_test.go @@ -9,7 +9,7 @@ import ( "github.com/aws/eks-anywhere/pkg/api/v1alpha1" ) -func TestManagementCPVSphereMachineValidateUpdateTemplateImmutable(t *testing.T) { +func TestManagementCPVSphereMachineValidateUpdateTemplateMutableManagement(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetControlPlane() vOld.Spec.Template = "oldTemplate" @@ -17,7 +17,7 @@ func TestManagementCPVSphereMachineValidateUpdateTemplateImmutable(t *testing.T) c.Spec.Template = "newTemplate" g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.template: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } func TestWorkloadCPVSphereMachineValidateUpdateTemplateSuccess(t *testing.T) { @@ -53,7 +53,7 @@ func TestWorkloadWorkersVSphereMachineValidateUpdateTemplateSuccess(t *testing.T g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestManagementEtcdVSphereMachineValidateUpdateTemplateImmutable(t *testing.T) { +func TestManagementEtcdVSphereMachineValidateEtcdUpdateTemplateMutable(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetEtcd() vOld.Spec.Template = "oldTemplate" @@ -61,7 +61,7 @@ func TestManagementEtcdVSphereMachineValidateUpdateTemplateImmutable(t *testing. c.Spec.Template = "newTemplate" g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.template: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } func TestWorkloadEtcdVSphereMachineValidateUpdateTemplateSuccess(t *testing.T) { @@ -87,7 +87,7 @@ func TestVSphereMachineValidateUpdateOSFamilyImmutable(t *testing.T) { g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.osFamily: Forbidden: field is immutable"))) } -func TestManagementCPVSphereMachineValidateUpdateMemoryMiBImmutable(t *testing.T) { +func TestManagementCPVSphereMachineValidateUpdateMemoryMiBMutableManagement(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetControlPlane() vOld.Spec.MemoryMiB = 2 @@ -95,7 +95,7 @@ func TestManagementCPVSphereMachineValidateUpdateMemoryMiBImmutable(t *testing.T c.Spec.MemoryMiB = 2000000 g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.memoryMiB: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } func TestWorkloadCPVSphereMachineValidateUpdateMemoryMiBSuccess(t *testing.T) { @@ -140,7 +140,7 @@ func TestManagementEtcdVSphereMachineValidateUpdateMemoryMiBImmutable(t *testing c.Spec.MemoryMiB = 2000000 g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.memoryMiB: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } func TestWorkloadEtcdVSphereMachineValidateUpdateMemoryMiBSuccess(t *testing.T) { @@ -155,7 +155,7 @@ func TestWorkloadEtcdVSphereMachineValidateUpdateMemoryMiBSuccess(t *testing.T) g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestManagementCPVSphereMachineValidateUpdateNumCPUsImmutable(t *testing.T) { +func TestManagementCPVSphereMachineValidateUpdateNumCPUsMutableManagement(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetControlPlane() vOld.Spec.NumCPUs = 1 @@ -163,7 +163,7 @@ func TestManagementCPVSphereMachineValidateUpdateNumCPUsImmutable(t *testing.T) c.Spec.NumCPUs = 16 g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.numCPUs: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } func TestWorkloadCPVSphereMachineValidateUpdateNumCPUsSuccess(t *testing.T) { @@ -199,7 +199,7 @@ func TestWorkloadWorkersVSphereMachineValidateUpdateNumCPUsSuccess(t *testing.T) g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestManagementEtcdVSphereMachineValidateUpdateNumCPUsImmutable(t *testing.T) { +func TestManagementEtcdVSphereMachineValidateUpdateNumCPUsMmutableManagement(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetEtcd() vOld.Spec.NumCPUs = 1 @@ -207,7 +207,7 @@ func TestManagementEtcdVSphereMachineValidateUpdateNumCPUsImmutable(t *testing.T c.Spec.NumCPUs = 16 g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.numCPUs: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } func TestWorkloadEtcdVSphereMachineValidateUpdateNumCPUsSuccess(t *testing.T) { @@ -222,7 +222,7 @@ func TestWorkloadEtcdVSphereMachineValidateUpdateNumCPUsSuccess(t *testing.T) { g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestManagementCPVSphereMachineValidateUpdateDiskGiBImmutable(t *testing.T) { +func TestManagementCPVSphereMachineValidateUpdateDiskGiBMutableManagement(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetControlPlane() vOld.Spec.DiskGiB = 1 @@ -230,7 +230,7 @@ func TestManagementCPVSphereMachineValidateUpdateDiskGiBImmutable(t *testing.T) c.Spec.DiskGiB = 160 g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.diskGiB: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } func TestWorkloadCPVSphereMachineValidateUpdateDiskGiBSuccess(t *testing.T) { @@ -266,7 +266,7 @@ func TestWorkloadWorkersVSphereMachineValidateUpdateDiskGiBSuccess(t *testing.T) g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestManagementEtcdVSphereMachineValidateUpdateDiskGiBImmutable(t *testing.T) { +func TestManagementEtcdVSphereMachineValidateUpdateDiskGiBMmutableManagement(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetEtcd() vOld.Spec.DiskGiB = 1 @@ -275,7 +275,7 @@ func TestManagementEtcdVSphereMachineValidateUpdateDiskGiBImmutable(t *testing.T c.Spec.DiskGiB = 160 g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.diskGiB: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } func TestWorkloadEtcdVSphereMachineValidateUpdateDiskGiBSuccess(t *testing.T) { @@ -290,7 +290,7 @@ func TestWorkloadEtcdVSphereMachineValidateUpdateDiskGiBSuccess(t *testing.T) { g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestManagementControlPlaneSphereMachineValidateUpdateSshAuthorizedKeyImmutable(t *testing.T) { +func TestManagementControlPlaneSphereMachineValidateUpdateSshAuthorizedKeyMutableManagement(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetControlPlane() vOld.Spec.Users = []v1alpha1.UserConfiguration{{Name: "Jeff"}} @@ -299,10 +299,10 @@ func TestManagementControlPlaneSphereMachineValidateUpdateSshAuthorizedKeyImmuta c.Spec.Users[0].SshAuthorizedKeys[0] = "rsa-laDeLala" g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.users: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestWorkloadControlPlaneVSphereMachineValidateUpdateSshAuthorizedKeyImmutable(t *testing.T) { +func TestWorkloadControlPlaneVSphereMachineValidateUpdateSshAuthorizedKeyMutable(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetControlPlane() vOld.SetManagedBy("test-cluster") @@ -323,10 +323,10 @@ func TestManagementControlPlaneVSphereMachineValidateUpdateSshUsernameImmutable( c.Spec.Users[0].Name = "Andy" g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.users: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestWorkloadControlPlaneVSphereMachineValidateUpdateSshUsernameImmutable(t *testing.T) { +func TestWorkloadControlPlaneVSphereMachineValidateUpdateSshUsernameMutable(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetControlPlane() vOld.SetManagedBy("test-cluster") @@ -354,7 +354,7 @@ func TestVSphereMachineValidateUpdateWithPausedAnnotation(t *testing.T) { g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestManagementEtcdSphereMachineValidateUpdateSshAuthorizedKeyImmutable(t *testing.T) { +func TestManagementEtcdSphereMachineValidateUpdateSshAuthorizedKeyMutableManagement(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetEtcd() vOld.Spec.Users = []v1alpha1.UserConfiguration{{Name: "Jeff"}} @@ -363,7 +363,7 @@ func TestManagementEtcdSphereMachineValidateUpdateSshAuthorizedKeyImmutable(t *t c.Spec.Users[0].SshAuthorizedKeys[0] = "rsa-laDeLala" g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.users: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } func TestWorkloadEtcdVSphereMachineValidateUpdateSshAuthorizedKeyImmutable(t *testing.T) { @@ -379,7 +379,7 @@ func TestWorkloadEtcdVSphereMachineValidateUpdateSshAuthorizedKeyImmutable(t *te g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestManagementEtcdVSphereMachineValidateUpdateSshUsernameImmutable(t *testing.T) { +func TestManagementEtcdVSphereMachineValidateUpdateSshUsernameMutable(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetEtcd() vOld.Spec.Users[0].Name = "Jeff" @@ -387,10 +387,10 @@ func TestManagementEtcdVSphereMachineValidateUpdateSshUsernameImmutable(t *testi c.Spec.Users[0].Name = "Andy" g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.users: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestWorkloadEtcdVSphereMachineValidateUpdateSshUsernameImmutable(t *testing.T) { +func TestWorkloadEtcdVSphereMachineValidateUpdateSshUsernameMutable(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetEtcd() vOld.SetManagedBy("test-cluster") @@ -402,7 +402,7 @@ func TestWorkloadEtcdVSphereMachineValidateUpdateSshUsernameImmutable(t *testing g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestManagementWorkerNodeSphereMachineValidateUpdateSshAuthorizedKeyImmutable(t *testing.T) { +func TestManagementWorkerNodeSphereMachineValidateUpdateSshAuthorizedKeyMutable(t *testing.T) { vOld := vsphereMachineConfig() vOld.Spec.Users = []v1alpha1.UserConfiguration{{Name: "Jeff"}} vOld.Spec.Users[0].SshAuthorizedKeys = []string{"rsa-blahdeblahbalh"} @@ -413,7 +413,7 @@ func TestManagementWorkerNodeSphereMachineValidateUpdateSshAuthorizedKeyImmutabl g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestWorkloadWorkerNodeVSphereMachineValidateUpdateSshAuthorizedKeyImmutable(t *testing.T) { +func TestWorkloadWorkerNodeVSphereMachineValidateUpdateSshAuthorizedKeyMutable(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetManagedBy("test-cluster") vOld.Spec.Users = []v1alpha1.UserConfiguration{{Name: "Jeff"}} @@ -425,7 +425,7 @@ func TestWorkloadWorkerNodeVSphereMachineValidateUpdateSshAuthorizedKeyImmutable g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestManagementWorkerNodeVSphereMachineValidateUpdateSshUsernameImmutable(t *testing.T) { +func TestManagementWorkerNodeVSphereMachineValidateUpdateSshUsernameMutable(t *testing.T) { vOld := vsphereMachineConfig() vOld.Spec.Users[0].Name = "Jeff" c := vOld.DeepCopy() @@ -435,7 +435,7 @@ func TestManagementWorkerNodeVSphereMachineValidateUpdateSshUsernameImmutable(t g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestWorkloadWorkerNodeVSphereMachineValidateUpdateSshUsernameImmutable(t *testing.T) { +func TestWorkloadWorkerNodeVSphereMachineValidateUpdateSshUsernameMutable(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetManagedBy("test-cluster") vOld.Spec.Users[0].Name = "Jeff" @@ -480,7 +480,7 @@ func TestVSphereMachineValidateUpdateBottleRocketInvalidUserName(t *testing.T) { g.Expect(c.ValidateUpdate(&vOld)).ToNot(Succeed()) } -func TestManagementCPVSphereMachineValidateUpdateDatastoreImmutable(t *testing.T) { +func TestManagementCPVSphereMachineValidateUpdateDatastoreMutableSuccess(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetControlPlane() vOld.Spec.Datastore = "OldDataStore" @@ -488,7 +488,7 @@ func TestManagementCPVSphereMachineValidateUpdateDatastoreImmutable(t *testing.T c.Spec.Datastore = "NewDataStore" g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.datastore: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } func TestWorkloadCPVSphereMachineValidateUpdateDatastoreSuccess(t *testing.T) { @@ -503,7 +503,7 @@ func TestWorkloadCPVSphereMachineValidateUpdateDatastoreSuccess(t *testing.T) { g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestManagementEtcdVSphereMachineValidateUpdateDatastoreImmutable(t *testing.T) { +func TestManagementEtcdVSphereMachineValidateUpdateDatastoreMutableManagement(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetEtcd() vOld.Spec.Datastore = "OldDataStore" @@ -511,7 +511,7 @@ func TestManagementEtcdVSphereMachineValidateUpdateDatastoreImmutable(t *testing c.Spec.Datastore = "NewDataStore" g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.datastore: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } func TestWorkloadEtcdVSphereMachineValidateUpdateDatastoreSuccess(t *testing.T) { @@ -547,7 +547,7 @@ func TestWorkloadWorkersVSphereMachineValidateUpdateDatastoreSuccess(t *testing. g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestManagementCPVSphereMachineValidateUpdateFolderImmutable(t *testing.T) { +func TestManagementCPVSphereMachineValidateUpdateFolderMutableManagement(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetControlPlane() vOld.Spec.Folder = "/dev/null" @@ -555,7 +555,7 @@ func TestManagementCPVSphereMachineValidateUpdateFolderImmutable(t *testing.T) { c.Spec.Folder = "/tmp" g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.folder: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } func TestWorkloadCPVSphereMachineValidateUpdateFolderSuccess(t *testing.T) { @@ -570,7 +570,7 @@ func TestWorkloadCPVSphereMachineValidateUpdateFolderSuccess(t *testing.T) { g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestManagementEtcdVSphereMachineValidateUpdateFolderImmutable(t *testing.T) { +func TestManagementEtcdVSphereMachineValidateUpdateFolderMutableManagement(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetEtcd() vOld.Spec.Folder = "/dev/null" @@ -578,7 +578,7 @@ func TestManagementEtcdVSphereMachineValidateUpdateFolderImmutable(t *testing.T) c.Spec.Folder = "/tmp" g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.folder: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } func TestWorkloadEtcdVSphereMachineValidateUpdateFolderSuccess(t *testing.T) { @@ -614,7 +614,7 @@ func TestWorkloadWorkersVSphereMachineValidateUpdateFolderSuccess(t *testing.T) g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestManagementCPVSphereMachineValidateUpdateResourcePoolImmutable(t *testing.T) { +func TestManagementCPVSphereMachineValidateUpdateResourcePoolMutableManagemenmt(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetControlPlane() vOld.Spec.ResourcePool = "AbovegroundPool" @@ -622,7 +622,7 @@ func TestManagementCPVSphereMachineValidateUpdateResourcePoolImmutable(t *testin c.Spec.ResourcePool = "IngroundPool" g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.resourcePool: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } func TestWorkloadCPVSphereMachineValidateUpdateResourcePoolSuccess(t *testing.T) { @@ -637,7 +637,7 @@ func TestWorkloadCPVSphereMachineValidateUpdateResourcePoolSuccess(t *testing.T) g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } -func TestManagementEtcdVSphereMachineValidateUpdateResourcePoolImmutable(t *testing.T) { +func TestManagementEtcdVSphereMachineValidateUpdateResourcePoolMutableManagement(t *testing.T) { vOld := vsphereMachineConfig() vOld.SetEtcd() vOld.Spec.ResourcePool = "AbovegroundPool" @@ -645,7 +645,7 @@ func TestManagementEtcdVSphereMachineValidateUpdateResourcePoolImmutable(t *test c.Spec.ResourcePool = "IngroundPool" g := NewWithT(t) - g.Expect(c.ValidateUpdate(&vOld)).To(MatchError(ContainSubstring("spec.resourcePool: Forbidden: field is immutable"))) + g.Expect(c.ValidateUpdate(&vOld)).To(Succeed()) } func TestWorkloadEtcdVSphereMachineValidateUpdateResourcePoolSuccess(t *testing.T) { diff --git a/pkg/awsiamauth/reconciler/reconciler_test.go b/pkg/awsiamauth/reconciler/reconciler_test.go index 9586334784db4..2fa1aa1e9d650 100644 --- a/pkg/awsiamauth/reconciler/reconciler_test.go +++ b/pkg/awsiamauth/reconciler/reconciler_test.go @@ -15,6 +15,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" + controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -164,7 +165,7 @@ func TestReconcileBuildClusterSpecError(t *testing.T) { g.Expect(result).To(Equal(controller.Result{})) } -func TestReconcileCAPIClusterNotFound(t *testing.T) { +func TestReconcileKCPObjectNotFound(t *testing.T) { g := NewWithT(t) ctx := context.Background() ctrl := gomock.NewController(t) @@ -181,6 +182,7 @@ func TestReconcileCAPIClusterNotFound(t *testing.T) { _ = releasev1.AddToScheme(scheme) _ = eksdv1.AddToScheme(scheme) _ = clusterv1.AddToScheme(scheme) + _ = controlplanev1.AddToScheme(scheme) cl := cb.WithScheme(scheme).WithRuntimeObjects(objs...).Build() version := test.DevEksaVersion() @@ -233,8 +235,17 @@ func TestReconcileRemoteGetClientError(t *testing.T) { EksaVersion: &version, }, } - capiCluster := test.CAPICluster(func(c *clusterv1.Cluster) { - c.Name = cluster.Name + kcp := test.KubeadmControlPlane(func(kcp *controlplanev1.KubeadmControlPlane) { + kcp.Name = cluster.Name + kcp.Status = controlplanev1.KubeadmControlPlaneStatus{ + Conditions: clusterv1.Conditions{ + { + Type: clusterapi.ReadyCondition, + Status: corev1.ConditionTrue, + LastTransitionTime: metav1.NewTime(time.Now()), + }, + }, + } }) sec := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -242,13 +253,14 @@ func TestReconcileRemoteGetClientError(t *testing.T) { Namespace: constants.EksaSystemNamespace, }, } - objs := []runtime.Object{bundle, eksdRelease, capiCluster, sec, eksaRelease} + objs := []runtime.Object{bundle, eksdRelease, kcp, sec, eksaRelease} cb := fake.NewClientBuilder() scheme := runtime.NewScheme() _ = releasev1.AddToScheme(scheme) _ = eksdv1.AddToScheme(scheme) _ = clusterv1.AddToScheme(scheme) _ = corev1.AddToScheme(scheme) + _ = controlplanev1.AddToScheme(scheme) cl := cb.WithScheme(scheme).WithRuntimeObjects(objs...).Build() remoteClientRegistry.EXPECT().GetClient(context.Background(), gomock.AssignableToTypeOf(client.ObjectKey{})).Return(nil, errors.New("client error")) @@ -297,8 +309,17 @@ func TestReconcileConfigMapNotFoundApplyError(t *testing.T) { EksaVersion: &version, }, } - capiCluster := test.CAPICluster(func(c *clusterv1.Cluster) { - c.Name = cluster.Name + kcp := test.KubeadmControlPlane(func(kcp *controlplanev1.KubeadmControlPlane) { + kcp.Name = cluster.Name + kcp.Status = controlplanev1.KubeadmControlPlaneStatus{ + Conditions: clusterv1.Conditions{ + { + Type: clusterapi.ReadyCondition, + Status: corev1.ConditionTrue, + LastTransitionTime: metav1.NewTime(time.Now()), + }, + }, + } }) sec := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -321,7 +342,7 @@ func TestReconcileConfigMapNotFoundApplyError(t *testing.T) { Namespace: "eksa-system", }, } - objs := []runtime.Object{bundle, eksdRelease, capiCluster, sec, awsiamconfig, caSec, eksaRelease} + objs := []runtime.Object{bundle, eksdRelease, kcp, sec, awsiamconfig, caSec, eksaRelease} cb := fake.NewClientBuilder() scheme := runtime.NewScheme() _ = anywherev1.AddToScheme(scheme) @@ -329,6 +350,7 @@ func TestReconcileConfigMapNotFoundApplyError(t *testing.T) { _ = eksdv1.AddToScheme(scheme) _ = clusterv1.AddToScheme(scheme) _ = corev1.AddToScheme(scheme) + _ = controlplanev1.AddToScheme(scheme) cl := cb.WithScheme(scheme).WithRuntimeObjects(objs...).Build() rCb := fake.NewClientBuilder() diff --git a/pkg/clustermanager/eksa_installer.go b/pkg/clustermanager/eksa_installer.go index c0eb737f5cb6d..090c479c60347 100644 --- a/pkg/clustermanager/eksa_installer.go +++ b/pkg/clustermanager/eksa_installer.go @@ -18,7 +18,6 @@ import ( anywherev1 "github.com/aws/eks-anywhere/pkg/api/v1alpha1" "github.com/aws/eks-anywhere/pkg/cluster" "github.com/aws/eks-anywhere/pkg/constants" - "github.com/aws/eks-anywhere/pkg/features" "github.com/aws/eks-anywhere/pkg/manifests" "github.com/aws/eks-anywhere/pkg/manifests/bundles" "github.com/aws/eks-anywhere/pkg/types" @@ -163,13 +162,7 @@ func setManagerEnvVars(d *appsv1.Deployment, spec *cluster.Spec) { } func managerEnabledGates(spec *cluster.Spec) []string { - g := []string{} - // TODO(pjshah): remove this feature flag after we implement kindless upgrade managaement feature for all the providers. - if features.IsActive(features.ExperimentalSelfManagedClusterUpgrade()) { - g = append(g, features.ExperimentalSelfManagedClusterUpgradeGate) - } - - return g + return nil } func fullLifeCycleControllerForProvider(cluster *anywherev1.Cluster) bool { diff --git a/pkg/clustermanager/eksa_installer_test.go b/pkg/clustermanager/eksa_installer_test.go index 599d5b8e1d4bf..709b60e9cecac 100644 --- a/pkg/clustermanager/eksa_installer_test.go +++ b/pkg/clustermanager/eksa_installer_test.go @@ -2,7 +2,6 @@ package clustermanager_test import ( "context" - "os" "testing" "github.com/go-logr/logr" @@ -214,21 +213,9 @@ func TestSetManagerFlags(t *testing.T) { spec: test.NewClusterSpec(), want: deployment(), }, - { - name: "kindless upgrades, feature flag enabled", - deployment: deployment(), - spec: test.NewClusterSpec(), - featureEnvVars: []string{features.ExperimentalSelfManagedClusterUpgradeEnvVar}, - want: deployment(func(d *appsv1.Deployment) { - d.Spec.Template.Spec.Containers[0].Args = []string{ - "--feature-gates=ExpSelfManagedAPIUpgrade=true", - } - }), - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - os.Unsetenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar) features.ClearCache() for _, e := range tt.featureEnvVars { t.Setenv(e, "true") diff --git a/pkg/controller/clusters/clusterapi.go b/pkg/controller/clusters/clusterapi.go index 4070349e5ee23..f72afdaa5be0f 100644 --- a/pkg/controller/clusters/clusterapi.go +++ b/pkg/controller/clusters/clusterapi.go @@ -11,7 +11,6 @@ import ( anywherev1 "github.com/aws/eks-anywhere/pkg/api/v1alpha1" "github.com/aws/eks-anywhere/pkg/clusterapi" "github.com/aws/eks-anywhere/pkg/controller" - "github.com/aws/eks-anywhere/pkg/features" ) // CheckControlPlaneReady is a controller helper to check whether KCP object for @@ -19,48 +18,27 @@ import ( // due its signature and that it returns controller results with appropriate wait times whenever // the cluster is not ready. func CheckControlPlaneReady(ctx context.Context, client client.Client, log logr.Logger, cluster *anywherev1.Cluster) (controller.Result, error) { - if features.IsActive(features.ExperimentalSelfManagedClusterUpgrade()) { - kcp, err := controller.GetKubeadmControlPlane(ctx, client, cluster) - if err != nil { - return controller.Result{}, err - } - - if kcp == nil { - log.Info("KCP does not exist yet, requeuing") - return controller.ResultWithRequeue(5 * time.Second), nil - } - - // We make sure to check that the status is up to date before using it - if kcp.Status.ObservedGeneration != kcp.ObjectMeta.Generation { - log.Info("KCP information is outdated, requeing") - return controller.ResultWithRequeue(5 * time.Second), nil - } - - if !conditions.IsTrue(kcp, clusterapi.ReadyCondition) { - log.Info("KCP is not ready yet, requeing") - return controller.ResultWithRequeue(30 * time.Second), nil - } - - log.Info("KCP is ready") - return controller.Result{}, nil - } - - capiCluster, err := controller.GetCAPICluster(ctx, client, cluster) + kcp, err := controller.GetKubeadmControlPlane(ctx, client, cluster) if err != nil { return controller.Result{}, err } - if capiCluster == nil { - log.Info("CAPI cluster does not exist yet, requeuing") + if kcp == nil { + log.Info("KCP does not exist yet, requeuing") + return controller.ResultWithRequeue(5 * time.Second), nil + } + + // We make sure to check that the status is up to date before using it + if kcp.Status.ObservedGeneration != kcp.ObjectMeta.Generation { + log.Info("KCP information is outdated, requeing") return controller.ResultWithRequeue(5 * time.Second), nil } - if !conditions.IsTrue(capiCluster, clusterapi.ControlPlaneReadyCondition) { - log.Info("CAPI control plane is not ready yet, requeuing") - // TODO: eventually this can be implemented with controller watches + if !conditions.IsTrue(kcp, clusterapi.ReadyCondition) { + log.Info("KCP is not ready yet, requeing") return controller.ResultWithRequeue(30 * time.Second), nil } - log.Info("CAPI control plane is ready") + log.Info("KCP is ready") return controller.Result{}, nil } diff --git a/pkg/controller/clusters/clusterapi_test.go b/pkg/controller/clusters/clusterapi_test.go index f59d2c65bbd3a..ae5461dce9c26 100644 --- a/pkg/controller/clusters/clusterapi_test.go +++ b/pkg/controller/clusters/clusterapi_test.go @@ -2,14 +2,12 @@ package clusters_test import ( "context" - "os" "testing" "time" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1" controllerruntime "sigs.k8s.io/controller-runtime" @@ -22,74 +20,9 @@ import ( "github.com/aws/eks-anywhere/pkg/constants" "github.com/aws/eks-anywhere/pkg/controller" "github.com/aws/eks-anywhere/pkg/controller/clusters" - "github.com/aws/eks-anywhere/pkg/features" ) func TestCheckControlPlaneReadyItIsReady(t *testing.T) { - g := NewWithT(t) - ctx := context.Background() - eksaCluster := eksaCluster() - capiCluster := capiCluster(func(c *clusterv1.Cluster) { - c.Status.Conditions = clusterv1.Conditions{ - { - Type: clusterapi.ControlPlaneReadyCondition, - Status: corev1.ConditionTrue, - }, - } - }) - - client := fake.NewClientBuilder().WithObjects(eksaCluster, capiCluster).Build() - - result, err := clusters.CheckControlPlaneReady(ctx, client, test.NewNullLogger(), eksaCluster) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(result).To(Equal(controller.Result{})) -} - -func TestCheckControlPlaneReadyNoCluster(t *testing.T) { - g := NewWithT(t) - ctx := context.Background() - eksaCluster := eksaCluster() - - client := fake.NewClientBuilder().WithObjects(eksaCluster).Build() - - result, err := clusters.CheckControlPlaneReady(ctx, client, test.NewNullLogger(), eksaCluster) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(result).To(Equal( - controller.Result{Result: &controllerruntime.Result{RequeueAfter: 5 * time.Second}}), - ) -} - -func TestCheckControlPlaneReadyNotReady(t *testing.T) { - g := NewWithT(t) - ctx := context.Background() - eksaCluster := eksaCluster() - capiCluster := capiCluster() - - client := fake.NewClientBuilder().WithObjects(eksaCluster, capiCluster).Build() - - result, err := clusters.CheckControlPlaneReady(ctx, client, test.NewNullLogger(), eksaCluster) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(result).To(Equal( - controller.Result{Result: &controllerruntime.Result{RequeueAfter: 30 * time.Second}}), - ) -} - -func TestCheckControlPlaneReadyErrorReading(t *testing.T) { - g := NewWithT(t) - ctx := context.Background() - eksaCluster := eksaCluster() - - // This should make the client fail because CRDs are not registered - client := fake.NewClientBuilder().WithScheme(runtime.NewScheme()).Build() - - _, err := clusters.CheckControlPlaneReady(ctx, client, test.NewNullLogger(), eksaCluster) - g.Expect(err).To(MatchError(ContainSubstring("no kind is registered for the type"))) -} - -func TestCheckControlPlaneReadyItIsReadyWithKindlessUpgrade(t *testing.T) { - features.ClearCache() - os.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") - g := NewWithT(t) ctx := context.Background() eksaCluster := eksaCluster() @@ -109,10 +42,7 @@ func TestCheckControlPlaneReadyItIsReadyWithKindlessUpgrade(t *testing.T) { g.Expect(result).To(Equal(controller.Result{})) } -func TestCheckControlPlaneReadyNoKcpWithKindlessUpgrade(t *testing.T) { - features.ClearCache() - os.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") - +func TestCheckControlPlaneReadyNoKcp(t *testing.T) { g := NewWithT(t) ctx := context.Background() eksaCluster := eksaCluster() @@ -125,10 +55,7 @@ func TestCheckControlPlaneReadyNoKcpWithKindlessUpgrade(t *testing.T) { ) } -func TestCheckControlPlaneNotReadyWithKindlessUpgrade(t *testing.T) { - features.ClearCache() - os.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") - +func TestCheckControlPlaneNotReady(t *testing.T) { g := NewWithT(t) ctx := context.Background() eksaCluster := eksaCluster() @@ -147,10 +74,7 @@ func TestCheckControlPlaneNotReadyWithKindlessUpgrade(t *testing.T) { ) } -func TestCheckControlPlaneStatusNotReadyWithKindlessUpgrade(t *testing.T) { - features.ClearCache() - os.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") - +func TestCheckControlPlaneStatusNotReady(t *testing.T) { g := NewWithT(t) ctx := context.Background() eksaCluster := eksaCluster() @@ -184,26 +108,6 @@ func eksaCluster() *anywherev1.Cluster { } } -type capiClusterOpt func(*clusterv1.Cluster) - -func capiCluster(opts ...capiClusterOpt) *clusterv1.Cluster { - c := &clusterv1.Cluster{ - TypeMeta: metav1.TypeMeta{ - Kind: "Cluster", - APIVersion: clusterv1.GroupVersion.String(), - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "my-cluster", - Namespace: constants.EksaSystemNamespace, - }, - } - for _, opt := range opts { - opt(c) - } - - return c -} - type kcpObjectOpt func(*v1beta1.KubeadmControlPlane) func kcpObject(opts ...kcpObjectOpt) *v1beta1.KubeadmControlPlane { diff --git a/pkg/features/features.go b/pkg/features/features.go index ed47a79c6baeb..479ad7cf8b8f1 100644 --- a/pkg/features/features.go +++ b/pkg/features/features.go @@ -5,9 +5,6 @@ const ( CloudStackKubeVipDisabledEnvVar = "CLOUDSTACK_KUBE_VIP_DISABLED" CheckpointEnabledEnvVar = "CHECKPOINT_ENABLED" UseNewWorkflowsEnvVar = "USE_NEW_WORKFLOWS" - - ExperimentalSelfManagedClusterUpgradeEnvVar = "EXP_SELF_MANAGED_API_UPGRADE" - ExperimentalSelfManagedClusterUpgradeGate = "ExpSelfManagedAPIUpgrade" ) func FeedGates(featureGates []string) { @@ -28,17 +25,6 @@ func ClearCache() { globalFeatures.clearCache() } -// ExperimentalSelfManagedClusterUpgrade allows self managed cluster upgrades through the API. -func ExperimentalSelfManagedClusterUpgrade() Feature { - return Feature{ - Name: "[EXPERIMENTAL] Upgrade self-managed clusters through the API", - IsActive: globalFeatures.isActiveForEnvVarOrGate( - ExperimentalSelfManagedClusterUpgradeEnvVar, - ExperimentalSelfManagedClusterUpgradeGate, - ), - } -} - func CloudStackKubeVipDisabled() Feature { return Feature{ Name: "Kube-vip support disabled in CloudStack provider", diff --git a/pkg/providers/cloudstack/reconciler/reconciler_test.go b/pkg/providers/cloudstack/reconciler/reconciler_test.go index fd2eeb2124f6b..a3dc2de478ced 100644 --- a/pkg/providers/cloudstack/reconciler/reconciler_test.go +++ b/pkg/providers/cloudstack/reconciler/reconciler_test.go @@ -2,6 +2,7 @@ package reconciler_test import ( "context" + "fmt" "math" "testing" "time" @@ -44,10 +45,27 @@ func TestReconcilerReconcileSuccess(t *testing.T) { // We want to check that the cluster status is cleaned up if validations are passed tt.cluster.SetFailure(anywherev1.FailureReasonType("InvalidCluster"), "invalid cluster") - capiCluster := test.CAPICluster(func(c *clusterv1.Cluster) { - c.Name = tt.cluster.Name + kcp := test.KubeadmControlPlane(func(kcp *controlplanev1.KubeadmControlPlane) { + kcp.Name = tt.cluster.Name + kcp.Spec = controlplanev1.KubeadmControlPlaneSpec{ + MachineTemplate: controlplanev1.KubeadmControlPlaneMachineTemplate{ + InfrastructureRef: corev1.ObjectReference{ + Name: fmt.Sprintf("%s-control-plane-1", tt.cluster.Name), + }, + }, + } + kcp.Status = controlplanev1.KubeadmControlPlaneStatus{ + Conditions: clusterv1.Conditions{ + { + Type: clusterapi.ReadyCondition, + Status: corev1.ConditionTrue, + LastTransitionTime: metav1.NewTime(time.Now()), + }, + }, + ObservedGeneration: 2, + } }) - tt.eksaSupportObjs = append(tt.eksaSupportObjs, capiCluster, tt.secret) + tt.eksaSupportObjs = append(tt.eksaSupportObjs, tt.secret, kcp) tt.createAllObjs() logger := test.NewNullLogger() @@ -182,17 +200,27 @@ func TestReconcilerValidateMachineConfigFail(t *testing.T) { func TestReconcilerControlPlaneIsNotReady(t *testing.T) { tt := newReconcilerTest(t) - capiCluster := test.CAPICluster(func(c *clusterv1.Cluster) { - c.Name = tt.cluster.Name + kcp := test.KubeadmControlPlane(func(kcp *controlplanev1.KubeadmControlPlane) { + kcp.Name = tt.cluster.Name + kcp.Spec = controlplanev1.KubeadmControlPlaneSpec{ + MachineTemplate: controlplanev1.KubeadmControlPlaneMachineTemplate{ + InfrastructureRef: corev1.ObjectReference{ + Name: fmt.Sprintf("%s-control-plane-1", tt.cluster.Name), + }, + }, + } + kcp.Status = controlplanev1.KubeadmControlPlaneStatus{ + Conditions: clusterv1.Conditions{ + { + Type: clusterapi.ReadyCondition, + Status: corev1.ConditionFalse, + LastTransitionTime: metav1.NewTime(time.Now()), + }, + }, + ObservedGeneration: 2, + } }) - capiCluster.Status.Conditions = clusterv1.Conditions{ - { - Type: clusterapi.ControlPlaneReadyCondition, - Status: corev1.ConditionFalse, - LastTransitionTime: metav1.NewTime(time.Now()), - }, - } - tt.eksaSupportObjs = append(tt.eksaSupportObjs, capiCluster, tt.secret) + tt.eksaSupportObjs = append(tt.eksaSupportObjs, kcp, tt.secret) tt.createAllObjs() logger := test.NewNullLogger() diff --git a/pkg/providers/docker/reconciler/reconciler_test.go b/pkg/providers/docker/reconciler/reconciler_test.go index 9850c2c9a1fd2..f5f16a3ab93b8 100644 --- a/pkg/providers/docker/reconciler/reconciler_test.go +++ b/pkg/providers/docker/reconciler/reconciler_test.go @@ -3,12 +3,15 @@ package reconciler_test import ( "context" "errors" + "fmt" "strings" "testing" + "time" etcdv1 "github.com/aws/etcdadm-controller/api/v1beta1" "github.com/golang/mock/gomock" . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" @@ -22,6 +25,7 @@ import ( "github.com/aws/eks-anywhere/internal/test/envtest" anywherev1 "github.com/aws/eks-anywhere/pkg/api/v1alpha1" clusterspec "github.com/aws/eks-anywhere/pkg/cluster" + "github.com/aws/eks-anywhere/pkg/clusterapi" "github.com/aws/eks-anywhere/pkg/constants" "github.com/aws/eks-anywhere/pkg/controller" "github.com/aws/eks-anywhere/pkg/controller/clientutil" @@ -37,10 +41,27 @@ const ( func TestReconcilerReconcileSuccess(t *testing.T) { tt := newReconcilerTest(t) logger := test.NewNullLogger() - capiCluster := test.CAPICluster(func(c *clusterv1.Cluster) { - c.Name = tt.cluster.Name + kcp := test.KubeadmControlPlane(func(kcp *controlplanev1.KubeadmControlPlane) { + kcp.Name = tt.cluster.Name + kcp.Spec = controlplanev1.KubeadmControlPlaneSpec{ + MachineTemplate: controlplanev1.KubeadmControlPlaneMachineTemplate{ + InfrastructureRef: corev1.ObjectReference{ + Name: fmt.Sprintf("%s-control-plane-1", tt.cluster.Name), + }, + }, + } + kcp.Status = controlplanev1.KubeadmControlPlaneStatus{ + Conditions: clusterv1.Conditions{ + { + Type: clusterapi.ReadyCondition, + Status: corev1.ConditionTrue, + LastTransitionTime: metav1.NewTime(time.Now()), + }, + }, + ObservedGeneration: 2, + } }) - tt.eksaSupportObjs = append(tt.eksaSupportObjs, capiCluster) + tt.eksaSupportObjs = append(tt.eksaSupportObjs, kcp) tt.createAllObjs() remoteClient := fake.NewClientBuilder().Build() @@ -53,7 +74,7 @@ func TestReconcilerReconcileSuccess(t *testing.T) { tt.Expect(tt.cluster.Status.FailureMessage).To(BeZero()) tt.Expect(tt.cluster.Status.FailureReason).To(BeZero()) - tt.ShouldEventuallyExist(tt.ctx, capiCluster) + tt.ShouldEventuallyExist(tt.ctx, kcp) tt.ShouldEventuallyExist(tt.ctx, &controlplanev1.KubeadmControlPlane{ ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/providers/snow/reconciler/reconciler_test.go b/pkg/providers/snow/reconciler/reconciler_test.go index 082cfe60b858e..685f918bafb1b 100644 --- a/pkg/providers/snow/reconciler/reconciler_test.go +++ b/pkg/providers/snow/reconciler/reconciler_test.go @@ -2,7 +2,9 @@ package reconciler_test import ( "context" + "fmt" "testing" + "time" "github.com/golang/mock/gomock" . "github.com/onsi/gomega" @@ -20,6 +22,7 @@ import ( "github.com/aws/eks-anywhere/internal/test/envtest" anywherev1 "github.com/aws/eks-anywhere/pkg/api/v1alpha1" clusterspec "github.com/aws/eks-anywhere/pkg/cluster" + "github.com/aws/eks-anywhere/pkg/clusterapi" "github.com/aws/eks-anywhere/pkg/constants" "github.com/aws/eks-anywhere/pkg/controller" "github.com/aws/eks-anywhere/pkg/controller/clientutil" @@ -37,10 +40,27 @@ func TestReconcilerReconcileSuccess(t *testing.T) { tt := newReconcilerTest(t) // We want to check that the cluster status is cleaned up if validations are passed tt.cluster.SetFailure(anywherev1.FailureReasonType("InvalidCluster"), "invalid cluster") - capiCluster := test.CAPICluster(func(c *clusterv1.Cluster) { - c.Name = tt.cluster.Name + kcp := test.KubeadmControlPlane(func(kcp *controlplanev1.KubeadmControlPlane) { + kcp.Name = tt.cluster.Name + kcp.Spec = controlplanev1.KubeadmControlPlaneSpec{ + MachineTemplate: controlplanev1.KubeadmControlPlaneMachineTemplate{ + InfrastructureRef: corev1.ObjectReference{ + Name: fmt.Sprintf("%s-control-plane-1", tt.cluster.Name), + }, + }, + } + kcp.Status = controlplanev1.KubeadmControlPlaneStatus{ + Conditions: clusterv1.Conditions{ + { + Type: clusterapi.ReadyCondition, + Status: corev1.ConditionTrue, + LastTransitionTime: metav1.NewTime(time.Now()), + }, + }, + ObservedGeneration: 2, + } }) - tt.eksaSupportObjs = append(tt.eksaSupportObjs, capiCluster) + tt.eksaSupportObjs = append(tt.eksaSupportObjs, kcp) tt.createAllObjs() logger := test.NewNullLogger() diff --git a/pkg/providers/tinkerbell/reconciler/reconciler_test.go b/pkg/providers/tinkerbell/reconciler/reconciler_test.go index 6c6e94ac18d60..f605b5ff30d83 100644 --- a/pkg/providers/tinkerbell/reconciler/reconciler_test.go +++ b/pkg/providers/tinkerbell/reconciler/reconciler_test.go @@ -3,7 +3,9 @@ package reconciler_test import ( "context" "errors" + "fmt" "testing" + "time" "github.com/golang/mock/gomock" . "github.com/onsi/gomega" @@ -59,7 +61,29 @@ func TestReconcilerReconcileSuccess(t *testing.T) { capiCluster := test.CAPICluster(func(c *clusterv1.Cluster) { c.Name = tt.cluster.Name }) - tt.eksaSupportObjs = append(tt.eksaSupportObjs, capiCluster) + kcp := test.KubeadmControlPlane(func(kcp *controlplanev1.KubeadmControlPlane) { + kcp.Name = tt.cluster.Name + kcp.Spec = controlplanev1.KubeadmControlPlaneSpec{ + MachineTemplate: controlplanev1.KubeadmControlPlaneMachineTemplate{ + InfrastructureRef: corev1.ObjectReference{ + Name: fmt.Sprintf("%s-control-plane-1", tt.cluster.Name), + }, + }, + Version: "v1.19.8", + Replicas: ptr.Int32(1), + } + kcp.Status = controlplanev1.KubeadmControlPlaneStatus{ + Conditions: clusterv1.Conditions{ + { + Type: clusterapi.ReadyCondition, + Status: corev1.ConditionTrue, + LastTransitionTime: metav1.NewTime(time.Now()), + }, + }, + ObservedGeneration: 2, + } + }) + tt.eksaSupportObjs = append(tt.eksaSupportObjs, capiCluster, kcp) tt.eksaSupportObjs = append(tt.eksaSupportObjs, tinkHardware("hw1", "cp")) tt.eksaSupportObjs = append(tt.eksaSupportObjs, tinkHardware("hw2", "worker")) tt.createAllObjs() diff --git a/pkg/providers/vsphere/reconciler/reconciler_test.go b/pkg/providers/vsphere/reconciler/reconciler_test.go index ef97ac76c122a..35c9aa099d549 100644 --- a/pkg/providers/vsphere/reconciler/reconciler_test.go +++ b/pkg/providers/vsphere/reconciler/reconciler_test.go @@ -49,10 +49,27 @@ func TestReconcilerReconcileSuccess(t *testing.T) { // We want to check that the cluster status is cleaned up if validations are passed tt.cluster.SetFailure(anywherev1.FailureReasonType("InvalidCluster"), "invalid cluster") - capiCluster := test.CAPICluster(func(c *clusterv1.Cluster) { - c.Name = tt.cluster.Name + kcp := test.KubeadmControlPlane(func(kcp *controlplanev1.KubeadmControlPlane) { + kcp.Name = tt.cluster.Name + kcp.Spec = controlplanev1.KubeadmControlPlaneSpec{ + MachineTemplate: controlplanev1.KubeadmControlPlaneMachineTemplate{ + InfrastructureRef: corev1.ObjectReference{ + Name: fmt.Sprintf("%s-control-plane-1", tt.cluster.Name), + }, + }, + } + kcp.Status = controlplanev1.KubeadmControlPlaneStatus{ + Conditions: clusterv1.Conditions{ + { + Type: clusterapi.ReadyCondition, + Status: corev1.ConditionTrue, + LastTransitionTime: metav1.NewTime(time.Now()), + }, + }, + ObservedGeneration: 2, + } }) - tt.eksaSupportObjs = append(tt.eksaSupportObjs, capiCluster) + tt.eksaSupportObjs = append(tt.eksaSupportObjs, kcp) tt.createAllObjs() logger := test.NewNullLogger() diff --git a/pkg/workflows/management/upgrade_test.go b/pkg/workflows/management/upgrade_test.go index 1ef038b63d471..367c2409e0b88 100644 --- a/pkg/workflows/management/upgrade_test.go +++ b/pkg/workflows/management/upgrade_test.go @@ -278,7 +278,6 @@ func (c *upgradeManagementTestSetup) expectPreflightValidationsToPass() { func TestUpgradeManagementRunUpdateSetupFailed(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") test := newUpgradeManagementClusterTest(t) test.expectSetupToFail() test.expectWriteCheckpointFile() @@ -292,7 +291,6 @@ func TestUpgradeManagementRunUpdateSetupFailed(t *testing.T) { func TestUpgradeManagementRunUpdateSecretFailed(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") test := newUpgradeManagementClusterTest(t) test.expectSetup() test.expectPreflightValidationsToPass() @@ -309,7 +307,6 @@ func TestUpgradeManagementRunUpdateSecretFailed(t *testing.T) { func TestUpgradeManagementRunEnsureETCDFailed(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") test := newUpgradeManagementClusterTest(t) test.expectSetup() test.expectPreflightValidationsToPass() @@ -327,7 +324,6 @@ func TestUpgradeManagementRunEnsureETCDFailed(t *testing.T) { func TestUpgradeManagementRunPauseGitOpsReconcileUpgradeFailed(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") test := newUpgradeManagementClusterTest(t) test.expectSetup() test.expectPreflightValidationsToPass() @@ -346,7 +342,6 @@ func TestUpgradeManagementRunPauseGitOpsReconcileUpgradeFailed(t *testing.T) { func TestUpgradeManagementRunFailedBackup(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") test := newUpgradeManagementClusterTest(t) test.expectSetup() test.expectPreflightValidationsToPass() @@ -368,7 +363,6 @@ func TestUpgradeManagementRunFailedBackup(t *testing.T) { func TestUpgradeManagementRunPauseWorkloadCAPIFailed(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") test := newUpgradeManagementClusterTest(t) test.expectSetup() test.expectPreflightValidationsToPass() @@ -390,7 +384,6 @@ func TestUpgradeManagementRunPauseWorkloadCAPIFailed(t *testing.T) { func TestUpgradeManagementRunFailedUpgradeInstallEksd(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") test := newUpgradeManagementClusterTest(t) test.expectSetup() test.expectPreflightValidationsToPass() @@ -417,7 +410,6 @@ func TestUpgradeManagementRunFailedUpgradeInstallEksd(t *testing.T) { func TestUpgradeManagementRunFailedUpgradeApplyBundles(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") test := newUpgradeManagementClusterTest(t) test.expectSetup() test.expectPreflightValidationsToPass() @@ -442,7 +434,6 @@ func TestUpgradeManagementRunFailedUpgradeApplyBundles(t *testing.T) { func TestUpgradeManagementRunFailedUpgradeApplyReleases(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") test := newUpgradeManagementClusterTest(t) test.expectSetup() test.expectPreflightValidationsToPass() @@ -468,7 +459,6 @@ func TestUpgradeManagementRunFailedUpgradeApplyReleases(t *testing.T) { func TestUpgradeManagementRunFailedUpgrade(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") test := newUpgradeManagementClusterTest(t) test.expectSetup() test.expectPreflightValidationsToPass() @@ -496,7 +486,6 @@ func TestUpgradeManagementRunFailedUpgrade(t *testing.T) { func TestUpgradeManagementRunResumeCAPIWorkloadFailed(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") test := newUpgradeManagementClusterTest(t) test.expectSetup() test.expectPreflightValidationsToPass() @@ -529,7 +518,6 @@ func TestUpgradeManagementRunResumeCAPIWorkloadFailed(t *testing.T) { func TestUpgradeManagementRunUpdateGitEksaSpecFailed(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") test := newUpgradeManagementClusterTest(t) test.expectSetup() test.expectPreflightValidationsToPass() @@ -558,7 +546,6 @@ func TestUpgradeManagementRunUpdateGitEksaSpecFailed(t *testing.T) { func TestUpgradeManagementRunForceReconcileGitRepoFailed(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") test := newUpgradeManagementClusterTest(t) test.expectSetup() test.expectPreflightValidationsToPass() @@ -588,7 +575,6 @@ func TestUpgradeManagementRunForceReconcileGitRepoFailed(t *testing.T) { func TestUpgradeManagementRunResumeClusterResourcesReconcileFailed(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") test := newUpgradeManagementClusterTest(t) test.expectSetup() test.expectPreflightValidationsToPass() @@ -620,7 +606,6 @@ func TestUpgradeManagementRunResumeClusterResourcesReconcileFailed(t *testing.T) func TestUpgradeManagementRunSuccess(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() - t.Setenv(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true") test := newUpgradeManagementClusterTest(t) test.expectSetup() test.expectPreflightValidationsToPass() diff --git a/test/framework/cluster.go b/test/framework/cluster.go index b92f6d13e70a8..a590599ec784c 100644 --- a/test/framework/cluster.go +++ b/test/framework/cluster.go @@ -35,7 +35,6 @@ import ( "github.com/aws/eks-anywhere/pkg/cluster" "github.com/aws/eks-anywhere/pkg/constants" "github.com/aws/eks-anywhere/pkg/executables" - "github.com/aws/eks-anywhere/pkg/features" "github.com/aws/eks-anywhere/pkg/filewriter" "github.com/aws/eks-anywhere/pkg/git" "github.com/aws/eks-anywhere/pkg/providers/cloudstack/decoder" @@ -120,11 +119,6 @@ func NewClusterE2ETest(t T, provider Provider, opts ...ClusterE2ETestOpt) *Clust eksaBinaryLocation: defaultEksaBinaryLocation, } - // For kindless management upgrade task - // Remove this once we remove feature flag for ExpSelfManagedAPIUpgrade. - opts = append(opts, WithEnvVar(features.ExperimentalSelfManagedClusterUpgradeGate, "true")) - opts = append(opts, WithEnvVar(features.ExperimentalSelfManagedClusterUpgradeEnvVar, "true")) - for _, opt := range opts { opt(e) }