From 94c69358d0384e48dc7a7034268eeadb2ea2fa4d Mon Sep 17 00:00:00 2001 From: Taylor Neyland Date: Fri, 10 Sep 2021 09:14:30 -0500 Subject: [PATCH 1/5] Make namespace configurable for anywhere resources --- controllers/controllers/resource/fetcher.go | 5 + pkg/api/v1alpha1/dockerdatacenterconfig.go | 4 + pkg/api/v1alpha1/gitopsconfig.go | 10 +- pkg/api/v1alpha1/gitopsconfig_test.go | 12 +- pkg/api/v1alpha1/object_meta.go | 3 +- pkg/api/v1alpha1/oidcconfig.go | 9 +- pkg/api/v1alpha1/oidcconfig_test.go | 3 +- pkg/api/v1alpha1/vspheredatacenterconfig.go | 4 + pkg/api/v1alpha1/vspheremachineconfig.go | 4 + pkg/bootstrapper/bootstrapper.go | 8 +- pkg/bootstrapper/bootstrapper_test.go | 4 +- pkg/bootstrapper/mocks/client.go | 14 ++ pkg/cluster/spec.go | 4 +- pkg/clustermanager/cluster_manager.go | 42 +++--- pkg/clustermanager/cluster_manager_test.go | 24 ++-- .../mocks/client_and_networking.go | 44 ++++-- pkg/executables/kubectl.go | 29 ++-- pkg/executables/kubectl_test.go | 24 +++- pkg/providers/aws/aws.go | 6 +- pkg/providers/aws/aws_test.go | 3 +- pkg/providers/aws/mocks/client.go | 8 +- pkg/providers/docker/docker.go | 2 +- pkg/providers/mocks/providers.go | 8 +- pkg/providers/provider.go | 2 +- pkg/providers/vsphere/mocks/client.go | 16 +-- .../cluster_bottlerocket_external_etcd.yaml | 6 + .../vsphere/testdata/cluster_full_oidc.yaml | 5 + .../vsphere/testdata/cluster_main.yaml | 5 + .../vsphere/testdata/cluster_main_121.yaml | 5 + .../vsphere/testdata/cluster_minimal.yaml | 3 + .../testdata/cluster_minimal_oidc.yaml | 5 + pkg/providers/vsphere/vsphere.go | 39 ++++-- pkg/providers/vsphere/vsphere_test.go | 126 ++++++++++++------ .../upgradevalidations/immutableFields.go | 10 +- .../mocks/upgradevalidations.go | 24 ++-- .../preflightvalidations_test.go | 8 +- .../upgradevalidations/upgradevalidations.go | 6 +- test/framework/e2e.go | 2 +- 38 files changed, 373 insertions(+), 163 deletions(-) diff --git a/controllers/controllers/resource/fetcher.go b/controllers/controllers/resource/fetcher.go index 3e99a93fc43f..777a60485817 100644 --- a/controllers/controllers/resource/fetcher.go +++ b/controllers/controllers/resource/fetcher.go @@ -138,6 +138,11 @@ func (r *capiResourceFetcher) fetchClusterForRef(ctx context.Context, refId type return &c, nil } } + if c.Spec.ExternalEtcdConfiguration.MachineGroupRef != nil && c.Spec.ExternalEtcdConfiguration.MachineGroupRef.Name == refId.Name { + if _, err := r.clusterByName(ctx, constants.EksaSystemNamespace, c.Name); err == nil { // further validates a capi cluster exists + return &c, nil + } + } } } return nil, fmt.Errorf("eksa cluster not found for datacenterRef %v", refId) diff --git a/pkg/api/v1alpha1/dockerdatacenterconfig.go b/pkg/api/v1alpha1/dockerdatacenterconfig.go index 871fa14d1374..78583ae21ed8 100644 --- a/pkg/api/v1alpha1/dockerdatacenterconfig.go +++ b/pkg/api/v1alpha1/dockerdatacenterconfig.go @@ -32,6 +32,10 @@ func (c *DockerDatacenterConfigGenerate) Name() string { return c.ObjectMeta.Name } +func (c *DockerDatacenterConfigGenerate) Namespace() string { + return c.ObjectMeta.Namespace +} + func GetDockerDatacenterConfig(fileName string) (*DockerDatacenterConfig, error) { var clusterConfig DockerDatacenterConfig err := ParseClusterConfig(fileName, &clusterConfig) diff --git a/pkg/api/v1alpha1/gitopsconfig.go b/pkg/api/v1alpha1/gitopsconfig.go index 88babe455ad7..857c27b02261 100644 --- a/pkg/api/v1alpha1/gitopsconfig.go +++ b/pkg/api/v1alpha1/gitopsconfig.go @@ -8,12 +8,12 @@ import ( const GitOpsConfigKind = "GitOpsConfig" -func GetAndValidateGitOpsConfig(fileName string, refName string) (*GitOpsConfig, error) { +func GetAndValidateGitOpsConfig(fileName string, refName string, clusterConfig *Cluster) (*GitOpsConfig, error) { config, err := getGitOpsConfig(fileName) if err != nil { return nil, err } - err = validateGitOpsConfig(config, refName) + err = validateGitOpsConfig(config, refName, clusterConfig) if err != nil { return nil, err } @@ -29,7 +29,7 @@ func getGitOpsConfig(fileName string) (*GitOpsConfig, error) { return &config, nil } -func validateGitOpsConfig(config *GitOpsConfig, refName string) error { +func validateGitOpsConfig(config *GitOpsConfig, refName string, clusterConfig *Cluster) error { if config == nil { return errors.New("gitOpsRef is specified but GitOpsConfig is not specified") } @@ -37,6 +37,10 @@ func validateGitOpsConfig(config *GitOpsConfig, refName string) error { return fmt.Errorf("GitOpsConfig retrieved with name %s does not match name (%s) specified in "+ "gitOpsRef", config.Name, refName) } + if config.Namespace != clusterConfig.Namespace { + return errors.New("GitOpsConfig and Cluster objects must have the same namespace specified") + } + flux := config.Spec.Flux if len(flux.Github.Owner) <= 0 { diff --git a/pkg/api/v1alpha1/gitopsconfig_test.go b/pkg/api/v1alpha1/gitopsconfig_test.go index fb686f13e7fe..d7523b8de4d7 100644 --- a/pkg/api/v1alpha1/gitopsconfig_test.go +++ b/pkg/api/v1alpha1/gitopsconfig_test.go @@ -13,6 +13,7 @@ func TestGetAndValidateGitOpsConfig(t *testing.T) { fileName string refName string wantGitOpsConfig *GitOpsConfig + clusterConfig *Cluster wantErr bool }{ { @@ -49,6 +50,15 @@ func TestGetAndValidateGitOpsConfig(t *testing.T) { }, }, }, + clusterConfig: &Cluster{ + TypeMeta: metav1.TypeMeta{ + Kind: ClusterKind, + APIVersion: SchemeBuilder.GroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + }, + }, wantErr: false, }, { @@ -67,7 +77,7 @@ func TestGetAndValidateGitOpsConfig(t *testing.T) { for _, tt := range tests { t.Run(tt.testName, func(t *testing.T) { - got, err := GetAndValidateGitOpsConfig(tt.fileName, tt.refName) + got, err := GetAndValidateGitOpsConfig(tt.fileName, tt.refName, tt.clusterConfig) if (err != nil) != tt.wantErr { t.Fatalf("GetAndValidateGitOpsConfig() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/pkg/api/v1alpha1/object_meta.go b/pkg/api/v1alpha1/object_meta.go index b1728d80af9b..f4e8d50cac49 100644 --- a/pkg/api/v1alpha1/object_meta.go +++ b/pkg/api/v1alpha1/object_meta.go @@ -6,5 +6,6 @@ package v1alpha1 // and https://github.com/kubernetes-sigs/cluster-api/blob/bf790fc2a53614ff5d3405c83c0de0dd3303bb1f/api/v1alpha2/common_types.go#L67-L128 // as needed. type ObjectMeta struct { - Name string `json:"name,omitempty"` + Name string `json:"name,omitempty"` + Namespace string `json:"namespace,omitempty"` } diff --git a/pkg/api/v1alpha1/oidcconfig.go b/pkg/api/v1alpha1/oidcconfig.go index 7cc16a6e1fee..e7c610f9110c 100644 --- a/pkg/api/v1alpha1/oidcconfig.go +++ b/pkg/api/v1alpha1/oidcconfig.go @@ -7,12 +7,12 @@ import ( const OIDCConfigKind = "OIDCConfig" -func GetAndValidateOIDCConfig(fileName string, refName string) (*OIDCConfig, error) { +func GetAndValidateOIDCConfig(fileName string, refName string, clusterConfig *Cluster) (*OIDCConfig, error) { config, err := getOIDCConfig(fileName) if err != nil { return nil, err } - err = validateOIDCConfig(config, refName) + err = validateOIDCConfig(config, refName, clusterConfig) if err != nil { return nil, err } @@ -32,7 +32,7 @@ func getOIDCConfig(fileName string) (*OIDCConfig, error) { return &config, nil } -func validateOIDCConfig(config *OIDCConfig, refName string) error { +func validateOIDCConfig(config *OIDCConfig, refName string, clusterConfig *Cluster) error { if config == nil { return nil } @@ -40,6 +40,9 @@ func validateOIDCConfig(config *OIDCConfig, refName string) error { return fmt.Errorf("OIDCConfig retrieved with name %v does not match name (%v) specified in "+ "identityProviderRefs", config.Name, refName) } + if config.Namespace != clusterConfig.Namespace { + return fmt.Errorf("OIDCConfig and Cluster objects must have the same namespace specified") + } if config.Spec.ClientId == "" { return fmt.Errorf("OIDCConfig clientId is required") } diff --git a/pkg/api/v1alpha1/oidcconfig_test.go b/pkg/api/v1alpha1/oidcconfig_test.go index 28f2e3b8ad88..4bab68f5f481 100644 --- a/pkg/api/v1alpha1/oidcconfig_test.go +++ b/pkg/api/v1alpha1/oidcconfig_test.go @@ -95,7 +95,8 @@ func TestGetAndValidateOIDCConfig(t *testing.T) { } for _, tt := range tests { t.Run(tt.testName, func(t *testing.T) { - got, err := GetAndValidateOIDCConfig(tt.fileName, tt.refName) + c := &Cluster{} + got, err := GetAndValidateOIDCConfig(tt.fileName, tt.refName, c) if (err != nil) != tt.wantErr { t.Fatalf("GetAndValidateOIDCConfig() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/pkg/api/v1alpha1/vspheredatacenterconfig.go b/pkg/api/v1alpha1/vspheredatacenterconfig.go index 773344d6664f..435d56267507 100644 --- a/pkg/api/v1alpha1/vspheredatacenterconfig.go +++ b/pkg/api/v1alpha1/vspheredatacenterconfig.go @@ -32,6 +32,10 @@ func (c *VSphereDatacenterConfigGenerate) Name() string { return c.ObjectMeta.Name } +func (c *VSphereDatacenterConfigGenerate) Namespace() string { + return c.ObjectMeta.Namespace +} + func GetVSphereDatacenterConfig(fileName string) (*VSphereDatacenterConfig, error) { var clusterConfig VSphereDatacenterConfig err := ParseClusterConfig(fileName, &clusterConfig) diff --git a/pkg/api/v1alpha1/vspheremachineconfig.go b/pkg/api/v1alpha1/vspheremachineconfig.go index 3340e0db4c4c..232965f42e68 100644 --- a/pkg/api/v1alpha1/vspheremachineconfig.go +++ b/pkg/api/v1alpha1/vspheremachineconfig.go @@ -46,6 +46,10 @@ func (c *VSphereMachineConfigGenerate) Name() string { return c.ObjectMeta.Name } +func (c *VSphereMachineConfigGenerate) Namespace() string { + return c.ObjectMeta.Namespace +} + func GetVSphereMachineConfigs(fileName string) (map[string]*VSphereMachineConfig, error) { configs := make(map[string]*VSphereMachineConfig) content, err := ioutil.ReadFile(fileName) diff --git a/pkg/bootstrapper/bootstrapper.go b/pkg/bootstrapper/bootstrapper.go index 1e425bcaa9c1..71ae40686304 100644 --- a/pkg/bootstrapper/bootstrapper.go +++ b/pkg/bootstrapper/bootstrapper.go @@ -27,6 +27,7 @@ type ClusterClient interface { ClusterExists(ctx context.Context, clusterName string) (bool, error) ValidateClustersCRD(ctx context.Context, cluster *types.Cluster) error CreateNamespace(ctx context.Context, kubeconfig string, namespace string) error + GetNamespace(ctx context.Context, kubeconfig string, namespace string) error } type ( @@ -51,8 +52,11 @@ func (b *Bootstrapper) CreateBootstrapCluster(ctx context.Context, clusterSpec * KubeconfigFile: kubeconfigFile, } - if err := b.clusterClient.CreateNamespace(ctx, c.KubeconfigFile, constants.EksaSystemNamespace); err != nil { - return nil, err + err = b.clusterClient.GetNamespace(ctx, c.KubeconfigFile, constants.EksaSystemNamespace) + if err != nil { + if err := b.clusterClient.CreateNamespace(ctx, c.KubeconfigFile, constants.EksaSystemNamespace); err != nil { + return nil, err + } } err = cluster.ApplyExtraObjects(ctx, b.clusterClient, c, clusterSpec) diff --git a/pkg/bootstrapper/bootstrapper_test.go b/pkg/bootstrapper/bootstrapper_test.go index 2affa7ea200f..612752095e05 100644 --- a/pkg/bootstrapper/bootstrapper_test.go +++ b/pkg/bootstrapper/bootstrapper_test.go @@ -36,7 +36,7 @@ func TestBootstrapperCreateBootstrapClusterSuccessNoExtraObjects(t *testing.T) { ctx := context.Background() b, client := newBootstrapper(t) client.EXPECT().CreateBootstrapCluster(ctx, clusterSpec).Return(kubeconfigFile, nil) - client.EXPECT().CreateNamespace(ctx, kubeconfigFile, constants.EksaSystemNamespace) + client.EXPECT().GetNamespace(ctx, kubeconfigFile, constants.EksaSystemNamespace) got, err := b.CreateBootstrapCluster(ctx, clusterSpec, tt.opts...) if err != nil { @@ -60,7 +60,7 @@ func TestBootstrapperCreateBootstrapClusterSuccessExtraObjects(t *testing.T) { ctx := context.Background() b, client := newBootstrapper(t) client.EXPECT().CreateBootstrapCluster(ctx, clusterSpec).Return(kubeconfigFile, nil) - client.EXPECT().CreateNamespace(ctx, kubeconfigFile, constants.EksaSystemNamespace) + client.EXPECT().GetNamespace(ctx, kubeconfigFile, constants.EksaSystemNamespace) client.EXPECT().ApplyKubeSpecFromBytes(ctx, wantCluster, gomock.Any()) got, err := b.CreateBootstrapCluster(ctx, clusterSpec) diff --git a/pkg/bootstrapper/mocks/client.go b/pkg/bootstrapper/mocks/client.go index d5e614095498..dc712c61b4a1 100644 --- a/pkg/bootstrapper/mocks/client.go +++ b/pkg/bootstrapper/mocks/client.go @@ -144,6 +144,20 @@ func (mr *MockClusterClientMockRecorder) GetKubeconfig(arg0, arg1 interface{}) * return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKubeconfig", reflect.TypeOf((*MockClusterClient)(nil).GetKubeconfig), arg0, arg1) } +// GetNamespace mocks base method. +func (m *MockClusterClient) GetNamespace(arg0 context.Context, arg1, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNamespace", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// GetNamespace indicates an expected call of GetNamespace. +func (mr *MockClusterClientMockRecorder) GetNamespace(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNamespace", reflect.TypeOf((*MockClusterClient)(nil).GetNamespace), arg0, arg1, arg2) +} + // ValidateClustersCRD mocks base method. func (m *MockClusterClient) ValidateClustersCRD(arg0 context.Context, arg1 *types.Cluster) error { m.ctrl.T.Helper() diff --git a/pkg/cluster/spec.go b/pkg/cluster/spec.go index 3895f83c19bc..c04d0d2edfe7 100644 --- a/pkg/cluster/spec.go +++ b/pkg/cluster/spec.go @@ -139,7 +139,7 @@ func NewSpec(clusterConfigPath string, cliVersion version.Info, opts ...SpecOpt) if len(s.Cluster.Spec.IdentityProviderRefs) != 0 { // Since we only support one configuration, and only OIDCConfig, for identityProviderRefs, it is safe to assume that // it is the only element that exists in the array - oidcConfig, err := eksav1alpha1.GetAndValidateOIDCConfig(clusterConfigPath, s.Cluster.Spec.IdentityProviderRefs[0].Name) + oidcConfig, err := eksav1alpha1.GetAndValidateOIDCConfig(clusterConfigPath, s.Cluster.Spec.IdentityProviderRefs[0].Name, clusterConfig) if err != nil { return nil, err } @@ -147,7 +147,7 @@ func NewSpec(clusterConfigPath string, cliVersion version.Info, opts ...SpecOpt) } if s.Cluster.Spec.GitOpsRef != nil { - gitOpsConfig, err := eksav1alpha1.GetAndValidateGitOpsConfig(clusterConfigPath, s.Cluster.Spec.GitOpsRef.Name) + gitOpsConfig, err := eksav1alpha1.GetAndValidateGitOpsConfig(clusterConfigPath, s.Cluster.Spec.GitOpsRef.Name, clusterConfig) if err != nil { return nil, err } diff --git a/pkg/clustermanager/cluster_manager.go b/pkg/clustermanager/cluster_manager.go index 3f0f565943f0..9e3797677829 100644 --- a/pkg/clustermanager/cluster_manager.go +++ b/pkg/clustermanager/cluster_manager.go @@ -63,10 +63,12 @@ type ClusterClient interface { GetMachines(ctx context.Context, cluster *types.Cluster) ([]types.Machine, error) GetClusters(ctx context.Context, cluster *types.Cluster) ([]types.CAPICluster, error) GetEksaCluster(ctx context.Context, cluster *types.Cluster) (*v1alpha1.Cluster, error) - GetEksaVSphereDatacenterConfig(ctx context.Context, VSphereDatacenterName string, kubeconfigFile string) (*v1alpha1.VSphereDatacenterConfig, error) + GetEksaVSphereDatacenterConfig(ctx context.Context, VSphereDatacenterName string, kubeconfigFile string, namespace string) (*v1alpha1.VSphereDatacenterConfig, error) UpdateAnnotationInNamespace(ctx context.Context, resourceType, objectName string, annotations map[string]string, cluster *types.Cluster, namespace string) error RemoveAnnotationInNamespace(ctx context.Context, resourceType, objectName, key string, cluster *types.Cluster, namespace string) error - GetEksaVSphereMachineConfig(ctx context.Context, VSphereDatacenterName string, kubeconfigFile string) (*v1alpha1.VSphereMachineConfig, error) + GetEksaVSphereMachineConfig(ctx context.Context, VSphereDatacenterName string, kubeconfigFile string, namespace string) (*v1alpha1.VSphereMachineConfig, error) + CreateNamespace(ctx context.Context, kubeconfig string, namespace string) error + GetNamespace(ctx context.Context, kubeconfig string, namespace string) error ValidateControlPlaneNodes(ctx context.Context, cluster *types.Cluster) error ValidateWorkerNodes(ctx context.Context, cluster *types.Cluster) error } @@ -236,7 +238,7 @@ func (c *ClusterManager) EKSAClusterSpecChanged(ctx context.Context, cluster *ty case v1alpha1.VSphereDatacenterKind: machineConfigMap := make(map[string]*v1alpha1.VSphereMachineConfig) - existingVdc, err := c.clusterClient.GetEksaVSphereDatacenterConfig(ctx, cc.Spec.DatacenterRef.Name, cluster.KubeconfigFile) + existingVdc, err := c.clusterClient.GetEksaVSphereDatacenterConfig(ctx, cc.Spec.DatacenterRef.Name, cluster.KubeconfigFile, clusterSpec.Namespace) if err != nil { return false, err } @@ -250,7 +252,7 @@ func (c *ClusterManager) EKSAClusterSpecChanged(ctx context.Context, cluster *ty mc := config.(*v1alpha1.VSphereMachineConfig) machineConfigMap[mc.Name] = mc } - existingCpVmc, err := c.clusterClient.GetEksaVSphereMachineConfig(ctx, cc.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, cluster.KubeconfigFile) + existingCpVmc, err := c.clusterClient.GetEksaVSphereMachineConfig(ctx, cc.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, cluster.KubeconfigFile, clusterSpec.Namespace) if err != nil { return false, err } @@ -259,7 +261,7 @@ func (c *ClusterManager) EKSAClusterSpecChanged(ctx context.Context, cluster *ty logger.V(3).Info("New control plane machine config spec is different from the existing spec") return true, nil } - existingWnVmc, err := c.clusterClient.GetEksaVSphereMachineConfig(ctx, cc.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, cluster.KubeconfigFile) + existingWnVmc, err := c.clusterClient.GetEksaVSphereMachineConfig(ctx, cc.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, cluster.KubeconfigFile, clusterSpec.Namespace) if err != nil { return false, err } @@ -269,7 +271,7 @@ func (c *ClusterManager) EKSAClusterSpecChanged(ctx context.Context, cluster *ty return true, nil } if cc.Spec.ExternalEtcdConfiguration != nil { - existingEtcdVmc, err := c.clusterClient.GetEksaVSphereMachineConfig(ctx, cc.Spec.ExternalEtcdConfiguration.MachineGroupRef.Name, cluster.KubeconfigFile) + existingEtcdVmc, err := c.clusterClient.GetEksaVSphereMachineConfig(ctx, cc.Spec.ExternalEtcdConfiguration.MachineGroupRef.Name, cluster.KubeconfigFile, clusterSpec.Namespace) if err != nil { return false, err } @@ -629,6 +631,13 @@ func (c *ClusterManager) InstallCustomComponents(ctx context.Context, clusterSpe func (c *ClusterManager) CreateEKSAResources(ctx context.Context, cluster *types.Cluster, clusterSpec *cluster.Spec, datacenterConfig providers.DatacenterConfig, machineConfigs []providers.MachineConfig) error { + if clusterSpec.Namespace != "" { + if err := c.clusterClient.GetNamespace(ctx, cluster.KubeconfigFile, clusterSpec.Namespace); err != nil { + if err := c.clusterClient.CreateNamespace(ctx, cluster.KubeconfigFile, clusterSpec.Namespace); err != nil { + return err + } + } + } resourcesSpec, err := clustermarshaller.MarshalClusterSpec(clusterSpec, datacenterConfig, machineConfigs) if err != nil { return err @@ -644,6 +653,7 @@ func (c *ClusterManager) CreateEKSAResources(ctx context.Context, cluster *types func (c *ClusterManager) applyVersionBundle(ctx context.Context, clusterSpec *cluster.Spec, cluster *types.Cluster) error { clusterSpec.Bundles.Name = clusterSpec.Name + clusterSpec.Bundles.Namespace = clusterSpec.Namespace bundleObj, err := yaml.Marshal(clusterSpec.Bundles) if err != nil { return fmt.Errorf("error outputting bundle yaml: %v", err) @@ -663,7 +673,7 @@ func (c *ClusterManager) PauseEKSAControllerReconcile(ctx context.Context, clust pausedAnnotation := map[string]string{clusterSpec.PausedAnnotation(): "true"} err := c.Retrier.Retry( func() error { - return c.clusterClient.UpdateAnnotationInNamespace(ctx, provider.DatacenterResourceType(), clusterSpec.Spec.DatacenterRef.Name, pausedAnnotation, cluster, "") + return c.clusterClient.UpdateAnnotationInNamespace(ctx, provider.DatacenterResourceType(), clusterSpec.Spec.DatacenterRef.Name, pausedAnnotation, cluster, clusterSpec.Namespace) }, ) if err != nil { @@ -681,7 +691,7 @@ func (c *ClusterManager) PauseEKSAControllerReconcile(ctx context.Context, clust } err := c.Retrier.Retry( func() error { - return c.clusterClient.UpdateAnnotationInNamespace(ctx, provider.MachineResourceType(), clusterSpec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, pausedAnnotation, cluster, "") + return c.clusterClient.UpdateAnnotationInNamespace(ctx, provider.MachineResourceType(), clusterSpec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, pausedAnnotation, cluster, clusterSpec.Namespace) }, ) if err != nil { @@ -690,7 +700,7 @@ func (c *ClusterManager) PauseEKSAControllerReconcile(ctx context.Context, clust if clusterSpec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name != clusterSpec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name { err := c.Retrier.Retry( func() error { - return c.clusterClient.UpdateAnnotationInNamespace(ctx, provider.MachineResourceType(), clusterSpec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, pausedAnnotation, cluster, "") + return c.clusterClient.UpdateAnnotationInNamespace(ctx, provider.MachineResourceType(), clusterSpec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, pausedAnnotation, cluster, clusterSpec.Namespace) }, ) if err != nil { @@ -702,7 +712,7 @@ func (c *ClusterManager) PauseEKSAControllerReconcile(ctx context.Context, clust // etcd machines have a separate machineGroupRef which hasn't been paused yet, so apply pause annotation err := c.Retrier.Retry( func() error { - return c.clusterClient.UpdateAnnotationInNamespace(ctx, provider.MachineResourceType(), clusterSpec.Spec.ExternalEtcdConfiguration.MachineGroupRef.Name, pausedAnnotation, cluster, "") + return c.clusterClient.UpdateAnnotationInNamespace(ctx, provider.MachineResourceType(), clusterSpec.Spec.ExternalEtcdConfiguration.MachineGroupRef.Name, pausedAnnotation, cluster, clusterSpec.Namespace) }, ) if err != nil { @@ -714,7 +724,7 @@ func (c *ClusterManager) PauseEKSAControllerReconcile(ctx context.Context, clust err = c.Retrier.Retry( func() error { - return c.clusterClient.UpdateAnnotationInNamespace(ctx, clusterSpec.ResourceType(), cluster.Name, pausedAnnotation, cluster, "") + return c.clusterClient.UpdateAnnotationInNamespace(ctx, clusterSpec.ResourceType(), cluster.Name, pausedAnnotation, cluster, clusterSpec.Namespace) }, ) if err != nil { @@ -727,7 +737,7 @@ func (c *ClusterManager) ResumeEKSAControllerReconcile(ctx context.Context, clus pausedAnnotation := clusterSpec.PausedAnnotation() err := c.Retrier.Retry( func() error { - return c.clusterClient.RemoveAnnotationInNamespace(ctx, provider.DatacenterResourceType(), clusterSpec.Spec.DatacenterRef.Name, pausedAnnotation, cluster, "") + return c.clusterClient.RemoveAnnotationInNamespace(ctx, provider.DatacenterResourceType(), clusterSpec.Spec.DatacenterRef.Name, pausedAnnotation, cluster, clusterSpec.Namespace) }, ) if err != nil { @@ -745,7 +755,7 @@ func (c *ClusterManager) ResumeEKSAControllerReconcile(ctx context.Context, clus } err := c.Retrier.Retry( func() error { - return c.clusterClient.RemoveAnnotationInNamespace(ctx, provider.MachineResourceType(), clusterSpec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, pausedAnnotation, cluster, "") + return c.clusterClient.RemoveAnnotationInNamespace(ctx, provider.MachineResourceType(), clusterSpec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, pausedAnnotation, cluster, clusterSpec.Namespace) }, ) if err != nil { @@ -754,7 +764,7 @@ func (c *ClusterManager) ResumeEKSAControllerReconcile(ctx context.Context, clus if clusterSpec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name != clusterSpec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name { err := c.Retrier.Retry( func() error { - return c.clusterClient.RemoveAnnotationInNamespace(ctx, provider.MachineResourceType(), clusterSpec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, pausedAnnotation, cluster, "") + return c.clusterClient.RemoveAnnotationInNamespace(ctx, provider.MachineResourceType(), clusterSpec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, pausedAnnotation, cluster, clusterSpec.Namespace) }, ) if err != nil { @@ -766,7 +776,7 @@ func (c *ClusterManager) ResumeEKSAControllerReconcile(ctx context.Context, clus // etcd machines have a separate machineGroupRef which hasn't been resumed yet, so apply pause annotation with false value err := c.Retrier.Retry( func() error { - return c.clusterClient.RemoveAnnotationInNamespace(ctx, provider.MachineResourceType(), clusterSpec.Spec.ExternalEtcdConfiguration.MachineGroupRef.Name, pausedAnnotation, cluster, "") + return c.clusterClient.RemoveAnnotationInNamespace(ctx, provider.MachineResourceType(), clusterSpec.Spec.ExternalEtcdConfiguration.MachineGroupRef.Name, pausedAnnotation, cluster, clusterSpec.Namespace) }, ) if err != nil { @@ -778,7 +788,7 @@ func (c *ClusterManager) ResumeEKSAControllerReconcile(ctx context.Context, clus err = c.Retrier.Retry( func() error { - return c.clusterClient.RemoveAnnotationInNamespace(ctx, clusterSpec.ResourceType(), cluster.Name, pausedAnnotation, cluster, "") + return c.clusterClient.RemoveAnnotationInNamespace(ctx, clusterSpec.ResourceType(), cluster.Name, pausedAnnotation, cluster, clusterSpec.Namespace) }, ) if err != nil { diff --git a/pkg/clustermanager/cluster_manager_test.go b/pkg/clustermanager/cluster_manager_test.go index a20d17b45f6d..bef3c5461646 100644 --- a/pkg/clustermanager/cluster_manager_test.go +++ b/pkg/clustermanager/cluster_manager_test.go @@ -957,9 +957,9 @@ func TestClusterManagerClusterSpecChangedNoChanges(t *testing.T) { Spec: clusterSpec, }, nil, ) - m.client.EXPECT().GetEksaVSphereDatacenterConfig(ctx, spec.Spec.DatacenterRef.Name, gomock.Any()).Return(datacenterConfig, nil) - m.client.EXPECT().GetEksaVSphereMachineConfig(ctx, spec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, gomock.Any()).Return(machineConfig, nil) - m.client.EXPECT().GetEksaVSphereMachineConfig(ctx, spec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, gomock.Any()).Return(machineConfig, nil) + m.client.EXPECT().GetEksaVSphereDatacenterConfig(ctx, spec.Spec.DatacenterRef.Name, gomock.Any(), gomock.Any()).Return(datacenterConfig, nil) + m.client.EXPECT().GetEksaVSphereMachineConfig(ctx, spec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, gomock.Any(), gomock.Any()).Return(machineConfig, nil) + m.client.EXPECT().GetEksaVSphereMachineConfig(ctx, spec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, gomock.Any(), gomock.Any()).Return(machineConfig, nil) diff, err := c.EKSAClusterSpecChanged(ctx, cl, &spec, datacenterConfig, []providers.MachineConfig{machineConfig}) assert.Nil(t, err, "Error should be nil") assert.False(t, diff, "No changes should have been detected") @@ -1097,7 +1097,7 @@ func TestClusterManagerClusterSpecChangedNoChangesDatacenterSpecChanged(t *testi Spec: clusterSpec, }, nil, ) - m.client.EXPECT().GetEksaVSphereDatacenterConfig(ctx, spec.Spec.DatacenterRef.Name, gomock.Any()).Return(datacenterConfig, nil) + m.client.EXPECT().GetEksaVSphereDatacenterConfig(ctx, spec.Spec.DatacenterRef.Name, gomock.Any(), gomock.Any()).Return(datacenterConfig, nil) diff, err := c.EKSAClusterSpecChanged(ctx, cl, &spec, &modifiedDatacenterSpec, []providers.MachineConfig{machineConfig}) assert.Nil(t, err, "Error should be nil") assert.True(t, diff, "Changes should have been detected") @@ -1166,8 +1166,8 @@ func TestClusterManagerClusterSpecChangedNoChangesControlPlaneMachineConfigSpecC Spec: clusterSpec, }, nil, ) - m.client.EXPECT().GetEksaVSphereDatacenterConfig(ctx, spec.Spec.DatacenterRef.Name, gomock.Any()).Return(datacenterConfig, nil) - m.client.EXPECT().GetEksaVSphereMachineConfig(ctx, spec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, gomock.Any()).Return(machineConfig, nil) + m.client.EXPECT().GetEksaVSphereDatacenterConfig(ctx, spec.Spec.DatacenterRef.Name, gomock.Any(), gomock.Any()).Return(datacenterConfig, nil) + m.client.EXPECT().GetEksaVSphereMachineConfig(ctx, spec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, gomock.Any(), gomock.Any()).Return(machineConfig, nil) diff, err := c.EKSAClusterSpecChanged(ctx, cl, &spec, datacenterConfig, []providers.MachineConfig{&modifiedMachineConfigSpec}) assert.Nil(t, err, "Error should be nil") assert.True(t, diff, "Changes should have been detected") @@ -1248,9 +1248,9 @@ func TestClusterManagerClusterSpecChangedNoChangesWorkerNodeMachineConfigSpecCha Spec: clusterSpec, }, nil, ) - m.client.EXPECT().GetEksaVSphereDatacenterConfig(ctx, spec.Spec.DatacenterRef.Name, gomock.Any()).Return(datacenterConfig, nil) - m.client.EXPECT().GetEksaVSphereMachineConfig(ctx, spec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, gomock.Any()).Return(controlPlaneMachineConfig, nil) - m.client.EXPECT().GetEksaVSphereMachineConfig(ctx, spec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, gomock.Any()).Return(workerNodeMachineConfig, nil) + m.client.EXPECT().GetEksaVSphereDatacenterConfig(ctx, spec.Spec.DatacenterRef.Name, gomock.Any(), gomock.Any()).Return(datacenterConfig, nil) + m.client.EXPECT().GetEksaVSphereMachineConfig(ctx, spec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, gomock.Any(), gomock.Any()).Return(controlPlaneMachineConfig, nil) + m.client.EXPECT().GetEksaVSphereMachineConfig(ctx, spec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, gomock.Any(), gomock.Any()).Return(workerNodeMachineConfig, nil) diff, err := c.EKSAClusterSpecChanged(ctx, cl, &spec, datacenterConfig, []providers.MachineConfig{controlPlaneMachineConfig, &modifiedMachineConfigSpec}) assert.Nil(t, err, "Error should be nil") assert.True(t, diff, "Changes should have been detected") @@ -1349,9 +1349,9 @@ func TestClusterManagerClusterSpecChangedGitOpsDefault(t *testing.T) { }, }, nil, ) - m.client.EXPECT().GetEksaVSphereDatacenterConfig(ctx, spec.Spec.DatacenterRef.Name, gomock.Any()).Return(datacenterConfig, nil) - m.client.EXPECT().GetEksaVSphereMachineConfig(ctx, spec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, gomock.Any()).Return(machineConfig, nil) - m.client.EXPECT().GetEksaVSphereMachineConfig(ctx, spec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, gomock.Any()).Return(machineConfig, nil) + m.client.EXPECT().GetEksaVSphereDatacenterConfig(ctx, spec.Spec.DatacenterRef.Name, gomock.Any(), gomock.Any()).Return(datacenterConfig, nil) + m.client.EXPECT().GetEksaVSphereMachineConfig(ctx, spec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, gomock.Any(), gomock.Any()).Return(machineConfig, nil) + m.client.EXPECT().GetEksaVSphereMachineConfig(ctx, spec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, gomock.Any(), gomock.Any()).Return(machineConfig, nil) diff, err := c.EKSAClusterSpecChanged(ctx, cl, &spec, datacenterConfig, []providers.MachineConfig{machineConfig}) assert.Nil(t, err, "Error should be nil") assert.False(t, diff, "No changes should have not been detected") diff --git a/pkg/clustermanager/mocks/client_and_networking.go b/pkg/clustermanager/mocks/client_and_networking.go index 6b49bfa8c319..303b81489a75 100644 --- a/pkg/clustermanager/mocks/client_and_networking.go +++ b/pkg/clustermanager/mocks/client_and_networking.go @@ -95,6 +95,20 @@ func (mr *MockClusterClientMockRecorder) ApplyKubeSpecWithNamespace(arg0, arg1, return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyKubeSpecWithNamespace", reflect.TypeOf((*MockClusterClient)(nil).ApplyKubeSpecWithNamespace), arg0, arg1, arg2, arg3) } +// CreateNamespace mocks base method. +func (m *MockClusterClient) CreateNamespace(arg0 context.Context, arg1, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateNamespace", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateNamespace indicates an expected call of CreateNamespace. +func (mr *MockClusterClientMockRecorder) CreateNamespace(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateNamespace", reflect.TypeOf((*MockClusterClient)(nil).CreateNamespace), arg0, arg1, arg2) +} + // DeleteCluster mocks base method. func (m *MockClusterClient) DeleteCluster(arg0 context.Context, arg1, arg2 *types.Cluster) error { m.ctrl.T.Helper() @@ -140,33 +154,33 @@ func (mr *MockClusterClientMockRecorder) GetEksaCluster(arg0, arg1 interface{}) } // GetEksaVSphereDatacenterConfig mocks base method. -func (m *MockClusterClient) GetEksaVSphereDatacenterConfig(arg0 context.Context, arg1, arg2 string) (*v1alpha1.VSphereDatacenterConfig, error) { +func (m *MockClusterClient) GetEksaVSphereDatacenterConfig(arg0 context.Context, arg1, arg2, arg3 string) (*v1alpha1.VSphereDatacenterConfig, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetEksaVSphereDatacenterConfig", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "GetEksaVSphereDatacenterConfig", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(*v1alpha1.VSphereDatacenterConfig) ret1, _ := ret[1].(error) return ret0, ret1 } // GetEksaVSphereDatacenterConfig indicates an expected call of GetEksaVSphereDatacenterConfig. -func (mr *MockClusterClientMockRecorder) GetEksaVSphereDatacenterConfig(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockClusterClientMockRecorder) GetEksaVSphereDatacenterConfig(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEksaVSphereDatacenterConfig", reflect.TypeOf((*MockClusterClient)(nil).GetEksaVSphereDatacenterConfig), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEksaVSphereDatacenterConfig", reflect.TypeOf((*MockClusterClient)(nil).GetEksaVSphereDatacenterConfig), arg0, arg1, arg2, arg3) } // GetEksaVSphereMachineConfig mocks base method. -func (m *MockClusterClient) GetEksaVSphereMachineConfig(arg0 context.Context, arg1, arg2 string) (*v1alpha1.VSphereMachineConfig, error) { +func (m *MockClusterClient) GetEksaVSphereMachineConfig(arg0 context.Context, arg1, arg2, arg3 string) (*v1alpha1.VSphereMachineConfig, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetEksaVSphereMachineConfig", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "GetEksaVSphereMachineConfig", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(*v1alpha1.VSphereMachineConfig) ret1, _ := ret[1].(error) return ret0, ret1 } // GetEksaVSphereMachineConfig indicates an expected call of GetEksaVSphereMachineConfig. -func (mr *MockClusterClientMockRecorder) GetEksaVSphereMachineConfig(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockClusterClientMockRecorder) GetEksaVSphereMachineConfig(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEksaVSphereMachineConfig", reflect.TypeOf((*MockClusterClient)(nil).GetEksaVSphereMachineConfig), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEksaVSphereMachineConfig", reflect.TypeOf((*MockClusterClient)(nil).GetEksaVSphereMachineConfig), arg0, arg1, arg2, arg3) } // GetMachines mocks base method. @@ -184,6 +198,20 @@ func (mr *MockClusterClientMockRecorder) GetMachines(arg0, arg1 interface{}) *go return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMachines", reflect.TypeOf((*MockClusterClient)(nil).GetMachines), arg0, arg1) } +// GetNamespace mocks base method. +func (m *MockClusterClient) GetNamespace(arg0 context.Context, arg1, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNamespace", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// GetNamespace indicates an expected call of GetNamespace. +func (mr *MockClusterClientMockRecorder) GetNamespace(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNamespace", reflect.TypeOf((*MockClusterClient)(nil).GetNamespace), arg0, arg1, arg2) +} + // GetWorkloadKubeconfig mocks base method. func (m *MockClusterClient) GetWorkloadKubeconfig(arg0 context.Context, arg1 string, arg2 *types.Cluster) ([]byte, error) { m.ctrl.T.Helper() diff --git a/pkg/executables/kubectl.go b/pkg/executables/kubectl.go index 35cf60e50d56..69c032bfdf70 100644 --- a/pkg/executables/kubectl.go +++ b/pkg/executables/kubectl.go @@ -31,7 +31,6 @@ const ( var ( capiClustersResourceType = fmt.Sprintf("clusters.%s", v1alpha3.GroupVersion.Group) - eksaClustersResourceType = fmt.Sprintf("clusters.%s", v1alpha1.GroupVersion.Group) eksaVSphereDatacenterResourceType = fmt.Sprintf("vspheredatacenterconfigs.%s", v1alpha1.GroupVersion.Group) eksaVSphereMachineResourceType = fmt.Sprintf("vspheremachineconfigs.%s", v1alpha1.GroupVersion.Group) eksaAwsResourceType = fmt.Sprintf("awsdatacenterconfigs.%s", v1alpha1.GroupVersion.Group) @@ -55,6 +54,12 @@ func NewKubectl(executable Executable) *Kubectl { } } +func (k *Kubectl) GetNamespace(ctx context.Context, kubeconfig string, namespace string) error { + params := []string{"get", "namespace", namespace, "--kubeconfig", kubeconfig} + _, err := k.executable.Execute(ctx, params...) + return err +} + func (k *Kubectl) CreateNamespace(ctx context.Context, kubeconfig string, namespace string) error { params := []string{"create", "namespace", namespace, "--kubeconfig", kubeconfig} _, err := k.executable.Execute(ctx, params...) @@ -578,7 +583,7 @@ func (k *Kubectl) RemoveAnnotationInNamespace(ctx context.Context, resourceType, } func (k *Kubectl) GetEksaCluster(ctx context.Context, cluster *types.Cluster) (*v1alpha1.Cluster, error) { - params := []string{"get", eksaClustersResourceType, cluster.Name, "-o", "json", "--kubeconfig", cluster.KubeconfigFile} + params := []string{"get", "clusters", "-A", "--kubeconfig", cluster.KubeconfigFile, "--field-selector=metadata.name=" + cluster.Name} stdOut, err := k.executable.Execute(ctx, params...) if err != nil { return nil, fmt.Errorf("error getting eksa cluster: %v", err) @@ -593,8 +598,8 @@ func (k *Kubectl) GetEksaCluster(ctx context.Context, cluster *types.Cluster) (* return response, nil } -func (k *Kubectl) GetEksaGitOpsConfig(ctx context.Context, gitOpsConfigName string, kubeconfigFile string) (*v1alpha1.GitOpsConfig, error) { - params := []string{"get", eksaGitOpsResourceType, gitOpsConfigName, "-o", "json", "--kubeconfig", kubeconfigFile} +func (k *Kubectl) GetEksaGitOpsConfig(ctx context.Context, gitOpsConfigName string, kubeconfigFile string, namespace string) (*v1alpha1.GitOpsConfig, error) { + params := []string{"get", eksaGitOpsResourceType, gitOpsConfigName, "-o", "json", "--kubeconfig", kubeconfigFile, "--namespace", namespace} stdOut, err := k.executable.Execute(ctx, params...) if err != nil { return nil, fmt.Errorf("error getting eksa GitOpsConfig: %v", err) @@ -609,8 +614,8 @@ func (k *Kubectl) GetEksaGitOpsConfig(ctx context.Context, gitOpsConfigName stri return response, nil } -func (k *Kubectl) GetEksaOIDCConfig(ctx context.Context, oidcConfigName string, kubeconfigFile string) (*v1alpha1.OIDCConfig, error) { - params := []string{"get", eksaOIDCResourceType, oidcConfigName, "-o", "json", "--kubeconfig", kubeconfigFile} +func (k *Kubectl) GetEksaOIDCConfig(ctx context.Context, oidcConfigName string, kubeconfigFile string, namespace string) (*v1alpha1.OIDCConfig, error) { + params := []string{"get", eksaOIDCResourceType, oidcConfigName, "-o", "json", "--kubeconfig", kubeconfigFile, "--namespace", namespace} stdOut, err := k.executable.Execute(ctx, params...) if err != nil { return nil, fmt.Errorf("error getting eksa OIDCConfig: %v", err) @@ -625,8 +630,8 @@ func (k *Kubectl) GetEksaOIDCConfig(ctx context.Context, oidcConfigName string, return response, nil } -func (k *Kubectl) GetEksaVSphereDatacenterConfig(ctx context.Context, vsphereDatacenterConfigName string, kubeconfigFile string) (*v1alpha1.VSphereDatacenterConfig, error) { - params := []string{"get", eksaVSphereDatacenterResourceType, vsphereDatacenterConfigName, "-o", "json", "--kubeconfig", kubeconfigFile} +func (k *Kubectl) GetEksaVSphereDatacenterConfig(ctx context.Context, vsphereDatacenterConfigName string, kubeconfigFile string, namespace string) (*v1alpha1.VSphereDatacenterConfig, error) { + params := []string{"get", eksaVSphereDatacenterResourceType, vsphereDatacenterConfigName, "-o", "json", "--kubeconfig", kubeconfigFile, "--namespace", namespace} stdOut, err := k.executable.Execute(ctx, params...) if err != nil { return nil, fmt.Errorf("error getting eksa vsphere cluster %v", err) @@ -641,8 +646,8 @@ func (k *Kubectl) GetEksaVSphereDatacenterConfig(ctx context.Context, vsphereDat return response, nil } -func (k *Kubectl) GetEksaVSphereMachineConfig(ctx context.Context, vsphereMachineConfigName string, kubeconfigFile string) (*v1alpha1.VSphereMachineConfig, error) { - params := []string{"get", eksaVSphereMachineResourceType, vsphereMachineConfigName, "-o", "json", "--kubeconfig", kubeconfigFile} +func (k *Kubectl) GetEksaVSphereMachineConfig(ctx context.Context, vsphereMachineConfigName string, kubeconfigFile string, namespace string) (*v1alpha1.VSphereMachineConfig, error) { + params := []string{"get", eksaVSphereMachineResourceType, vsphereMachineConfigName, "-o", "json", "--kubeconfig", kubeconfigFile, "--namespace", namespace} stdOut, err := k.executable.Execute(ctx, params...) if err != nil { return nil, fmt.Errorf("error getting eksa vsphere cluster %v", err) @@ -657,8 +662,8 @@ func (k *Kubectl) GetEksaVSphereMachineConfig(ctx context.Context, vsphereMachin return response, nil } -func (k *Kubectl) GetEksaAWSDatacenterConfig(ctx context.Context, awsDatacenterConfigName string, kubeconfigFile string) (*v1alpha1.AWSDatacenterConfig, error) { - params := []string{"get", eksaAwsResourceType, awsDatacenterConfigName, "-o", "json", "--kubeconfig", kubeconfigFile} +func (k *Kubectl) GetEksaAWSDatacenterConfig(ctx context.Context, awsDatacenterConfigName string, kubeconfigFile string, namespace string) (*v1alpha1.AWSDatacenterConfig, error) { + params := []string{"get", eksaAwsResourceType, awsDatacenterConfigName, "-o", "json", "--kubeconfig", kubeconfigFile, "--namespace", namespace} stdOut, err := k.executable.Execute(ctx, params...) if err != nil { return nil, fmt.Errorf("error getting eksa aws cluster %v", err) diff --git a/pkg/executables/kubectl_test.go b/pkg/executables/kubectl_test.go index a130c6d72ac4..de00424a5d5a 100644 --- a/pkg/executables/kubectl_test.go +++ b/pkg/executables/kubectl_test.go @@ -93,6 +93,28 @@ func TestKubectlCreateNamespaceError(t *testing.T) { } } +func TestKubectlGetNamespaceSuccess(t *testing.T) { + var kubeconfig, namespace string + + k, ctx, _, e := newKubectl(t) + expectedParam := []string{"get", "namespace", namespace, "--kubeconfig", kubeconfig} + e.EXPECT().Execute(ctx, gomock.Eq(expectedParam)).Return(bytes.Buffer{}, nil) + if err := k.GetNamespace(ctx, kubeconfig, namespace); err != nil { + t.Errorf("Kubectl.GetNamespace() error = %v, want nil", err) + } +} + +func TestKubectlGetNamespaceError(t *testing.T) { + var kubeconfig, namespace string + + k, ctx, _, e := newKubectl(t) + expectedParam := []string{"get", "namespace", namespace, "--kubeconfig", kubeconfig} + e.EXPECT().Execute(ctx, gomock.Eq(expectedParam)).Return(bytes.Buffer{}, errors.New("error from execute")) + if err := k.GetNamespace(ctx, kubeconfig, namespace); err == nil { + t.Errorf("Kubectl.GetNamespace() error = nil, want not nil") + } +} + func TestKubectlWaitSuccess(t *testing.T) { var timeout, kubeconfig, forCondition, property, namespace string @@ -602,7 +624,7 @@ func TestKubectlGetEKSAClusters(t *testing.T) { t.Run(tt.testName, func(t *testing.T) { fileContent := test.ReadFile(t, tt.jsonResponseFile) k, ctx, cluster, e := newKubectl(t) - e.EXPECT().Execute(ctx, []string{"get", "clusters.anywhere.eks.amazonaws.com", tt.clusterName, "-o", "json", "--kubeconfig", cluster.KubeconfigFile}).Return(*bytes.NewBufferString(fileContent), nil) + e.EXPECT().Execute(ctx, []string{"get", "clusters", "-A", "--kubeconfig", cluster.KubeconfigFile, "--field-selector=metadata.name=" + tt.clusterName}).Return(*bytes.NewBufferString(fileContent), nil) gotCluster, err := k.GetEksaCluster(ctx, cluster) if err != nil { diff --git a/pkg/providers/aws/aws.go b/pkg/providers/aws/aws.go index 610ec212a256..df68f2061c8a 100644 --- a/pkg/providers/aws/aws.go +++ b/pkg/providers/aws/aws.go @@ -57,7 +57,7 @@ type ProviderClient interface { type ProviderKubectlClient interface { GetEksaCluster(ctx context.Context, cluster *types.Cluster) (*v1alpha1.Cluster, error) - GetEksaAWSDatacenterConfig(ctx context.Context, awsDatacenterConfigName string, kubeconfigFile string) (*v1alpha1.AWSDatacenterConfig, error) + GetEksaAWSDatacenterConfig(ctx context.Context, awsDatacenterConfigName string, kubeconfigFile string, namespace string) (*v1alpha1.AWSDatacenterConfig, error) GetKubeadmControlPlane(ctx context.Context, cluster *types.Cluster, opts ...executables.KubectlOpt) (*kubeadmnv1alpha3.KubeadmControlPlane, error) GetMachineDeployment(ctx context.Context, cluster *types.Cluster, opts ...executables.KubectlOpt) (*v1alpha3.MachineDeployment, error) } @@ -241,7 +241,7 @@ func (p *provider) generateTemplateValuesForUpgrade(ctx context.Context, bootstr if err != nil { return nil, err } - ac, err := p.providerKubectlClient.GetEksaAWSDatacenterConfig(ctx, p.datacenterConfig.Name, workloadCluster.KubeconfigFile) + ac, err := p.providerKubectlClient.GetEksaAWSDatacenterConfig(ctx, p.datacenterConfig.Name, workloadCluster.KubeconfigFile, clusterSpec.Namespace) if err != nil { return nil, err } @@ -376,6 +376,6 @@ func (p *provider) MachineConfigs() []providers.MachineConfig { return nil } -func (p *provider) ValidateNewSpec(_ context.Context, _ *types.Cluster) error { +func (p *provider) ValidateNewSpec(_ context.Context, _ *types.Cluster, _ *cluster.Spec) error { return nil } diff --git a/pkg/providers/aws/aws_test.go b/pkg/providers/aws/aws_test.go index d24c434afd12..3e46bffa58db 100644 --- a/pkg/providers/aws/aws_test.go +++ b/pkg/providers/aws/aws_test.go @@ -32,6 +32,7 @@ func TestProviderGenerateDeploymentFileSuccess(t *testing.T) { testName: "no AWS options", clusterSpec: test.NewClusterSpec(func(s *cluster.Spec) { s.Name = "test-cluster" + s.Namespace = "test-namespace" s.Spec.KubernetesVersion = "1.19" s.Spec.ControlPlaneConfiguration.Count = 3 s.Spec.WorkerNodeGroupConfigurations[0].Count = 3 @@ -129,7 +130,7 @@ func TestProviderGenerateDeploymentFileSuccess(t *testing.T) { }, } kubectl.EXPECT().GetEksaCluster(ctx, cluster).Return(oriCluster, nil) - kubectl.EXPECT().GetEksaAWSDatacenterConfig(ctx, tt.providerConfig.Name, cluster.KubeconfigFile).Return(&tt.providerConfig, nil) + kubectl.EXPECT().GetEksaAWSDatacenterConfig(ctx, tt.providerConfig.Name, cluster.KubeconfigFile, tt.clusterSpec.Namespace).Return(&tt.providerConfig, nil) got, err := p.GenerateDeploymentFileForUpgrade(ctx, bootstrapCluster, cluster, tt.clusterSpec, fileName) if err != nil { t.Fatalf("provider.GenerateDeploymentFile() error = %v, wantErr nil", err) diff --git a/pkg/providers/aws/mocks/client.go b/pkg/providers/aws/mocks/client.go index faa6a462a4a5..54da4326c0ee 100644 --- a/pkg/providers/aws/mocks/client.go +++ b/pkg/providers/aws/mocks/client.go @@ -106,18 +106,18 @@ func (m *MockProviderKubectlClient) EXPECT() *MockProviderKubectlClientMockRecor } // GetEksaAWSDatacenterConfig mocks base method. -func (m *MockProviderKubectlClient) GetEksaAWSDatacenterConfig(arg0 context.Context, arg1, arg2 string) (*v1alpha1.AWSDatacenterConfig, error) { +func (m *MockProviderKubectlClient) GetEksaAWSDatacenterConfig(arg0 context.Context, arg1, arg2, arg3 string) (*v1alpha1.AWSDatacenterConfig, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetEksaAWSDatacenterConfig", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "GetEksaAWSDatacenterConfig", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(*v1alpha1.AWSDatacenterConfig) ret1, _ := ret[1].(error) return ret0, ret1 } // GetEksaAWSDatacenterConfig indicates an expected call of GetEksaAWSDatacenterConfig. -func (mr *MockProviderKubectlClientMockRecorder) GetEksaAWSDatacenterConfig(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockProviderKubectlClientMockRecorder) GetEksaAWSDatacenterConfig(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEksaAWSDatacenterConfig", reflect.TypeOf((*MockProviderKubectlClient)(nil).GetEksaAWSDatacenterConfig), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEksaAWSDatacenterConfig", reflect.TypeOf((*MockProviderKubectlClient)(nil).GetEksaAWSDatacenterConfig), arg0, arg1, arg2, arg3) } // GetEksaCluster mocks base method. diff --git a/pkg/providers/docker/docker.go b/pkg/providers/docker/docker.go index 6e6a5f5ab339..4470229af887 100644 --- a/pkg/providers/docker/docker.go +++ b/pkg/providers/docker/docker.go @@ -370,6 +370,6 @@ func (p *provider) MachineConfigs() []providers.MachineConfig { return nil } -func (p *provider) ValidateNewSpec(_ context.Context, _ *types.Cluster) error { +func (p *provider) ValidateNewSpec(_ context.Context, _ *types.Cluster, _ *cluster.Spec) error { return nil } diff --git a/pkg/providers/mocks/providers.go b/pkg/providers/mocks/providers.go index a5e4851a6c48..c8470f8d3303 100644 --- a/pkg/providers/mocks/providers.go +++ b/pkg/providers/mocks/providers.go @@ -325,17 +325,17 @@ func (mr *MockProviderMockRecorder) UpdateSecrets(arg0, arg1 interface{}) *gomoc } // ValidateNewSpec mocks base method. -func (m *MockProvider) ValidateNewSpec(arg0 context.Context, arg1 *types.Cluster) error { +func (m *MockProvider) ValidateNewSpec(arg0 context.Context, arg1 *types.Cluster, arg2 *cluster.Spec) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ValidateNewSpec", arg0, arg1) + ret := m.ctrl.Call(m, "ValidateNewSpec", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // ValidateNewSpec indicates an expected call of ValidateNewSpec. -func (mr *MockProviderMockRecorder) ValidateNewSpec(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockProviderMockRecorder) ValidateNewSpec(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateNewSpec", reflect.TypeOf((*MockProvider)(nil).ValidateNewSpec), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateNewSpec", reflect.TypeOf((*MockProvider)(nil).ValidateNewSpec), arg0, arg1, arg2) } // Version mocks base method. diff --git a/pkg/providers/provider.go b/pkg/providers/provider.go index 44398975e373..5783f8ef1d90 100644 --- a/pkg/providers/provider.go +++ b/pkg/providers/provider.go @@ -30,7 +30,7 @@ type Provider interface { DatacenterResourceType() string MachineResourceType() string MachineConfigs() []MachineConfig - ValidateNewSpec(ctx context.Context, cluster *types.Cluster) error + ValidateNewSpec(ctx context.Context, cluster *types.Cluster, clusterSpec *cluster.Spec) error GenerateMHC() ([]byte, error) } diff --git a/pkg/providers/vsphere/mocks/client.go b/pkg/providers/vsphere/mocks/client.go index 4055a05c3a38..22881dc43229 100644 --- a/pkg/providers/vsphere/mocks/client.go +++ b/pkg/providers/vsphere/mocks/client.go @@ -325,33 +325,33 @@ func (mr *MockProviderKubectlClientMockRecorder) GetEksaCluster(arg0, arg1 inter } // GetEksaVSphereDatacenterConfig mocks base method. -func (m *MockProviderKubectlClient) GetEksaVSphereDatacenterConfig(arg0 context.Context, arg1, arg2 string) (*v1alpha1.VSphereDatacenterConfig, error) { +func (m *MockProviderKubectlClient) GetEksaVSphereDatacenterConfig(arg0 context.Context, arg1, arg2, arg3 string) (*v1alpha1.VSphereDatacenterConfig, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetEksaVSphereDatacenterConfig", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "GetEksaVSphereDatacenterConfig", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(*v1alpha1.VSphereDatacenterConfig) ret1, _ := ret[1].(error) return ret0, ret1 } // GetEksaVSphereDatacenterConfig indicates an expected call of GetEksaVSphereDatacenterConfig. -func (mr *MockProviderKubectlClientMockRecorder) GetEksaVSphereDatacenterConfig(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockProviderKubectlClientMockRecorder) GetEksaVSphereDatacenterConfig(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEksaVSphereDatacenterConfig", reflect.TypeOf((*MockProviderKubectlClient)(nil).GetEksaVSphereDatacenterConfig), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEksaVSphereDatacenterConfig", reflect.TypeOf((*MockProviderKubectlClient)(nil).GetEksaVSphereDatacenterConfig), arg0, arg1, arg2, arg3) } // GetEksaVSphereMachineConfig mocks base method. -func (m *MockProviderKubectlClient) GetEksaVSphereMachineConfig(arg0 context.Context, arg1, arg2 string) (*v1alpha1.VSphereMachineConfig, error) { +func (m *MockProviderKubectlClient) GetEksaVSphereMachineConfig(arg0 context.Context, arg1, arg2, arg3 string) (*v1alpha1.VSphereMachineConfig, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetEksaVSphereMachineConfig", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "GetEksaVSphereMachineConfig", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(*v1alpha1.VSphereMachineConfig) ret1, _ := ret[1].(error) return ret0, ret1 } // GetEksaVSphereMachineConfig indicates an expected call of GetEksaVSphereMachineConfig. -func (mr *MockProviderKubectlClientMockRecorder) GetEksaVSphereMachineConfig(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockProviderKubectlClientMockRecorder) GetEksaVSphereMachineConfig(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEksaVSphereMachineConfig", reflect.TypeOf((*MockProviderKubectlClient)(nil).GetEksaVSphereMachineConfig), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEksaVSphereMachineConfig", reflect.TypeOf((*MockProviderKubectlClient)(nil).GetEksaVSphereMachineConfig), arg0, arg1, arg2, arg3) } // GetEtcdadmCluster mocks base method. diff --git a/pkg/providers/vsphere/testdata/cluster_bottlerocket_external_etcd.yaml b/pkg/providers/vsphere/testdata/cluster_bottlerocket_external_etcd.yaml index 4bbccacbc1b9..1222105325d9 100644 --- a/pkg/providers/vsphere/testdata/cluster_bottlerocket_external_etcd.yaml +++ b/pkg/providers/vsphere/testdata/cluster_bottlerocket_external_etcd.yaml @@ -2,6 +2,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: Cluster metadata: name: test + namespace: test-namespace spec: controlPlaneConfiguration: count: 3 @@ -40,6 +41,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereMachineConfig metadata: name: test-cp + namespace: test-namespace spec: diskGiB: 25 datastore: "/SDDC-Datacenter/datastore/WorkloadDatastore" @@ -57,6 +59,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereMachineConfig metadata: name: test-wn + namespace: test-namespace spec: diskGiB: 25 datastore: "/SDDC-Datacenter/datastore/WorkloadDatastore" @@ -74,6 +77,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereMachineConfig metadata: name: test-etcd + namespace: test-namespace spec: diskGiB: 25 datastore: "/SDDC-Datacenter/datastore/WorkloadDatastore" @@ -91,6 +95,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereDatacenterConfig metadata: name: test + namespace: test-namespace spec: datacenter: "SDDC-Datacenter" network: "/SDDC-Datacenter/network/sddc-cgw-network-1" @@ -102,6 +107,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: OIDCConfig metadata: name: test + namespace: test-namespace spec: clientId: my-client-id groupsClaim: claim1 diff --git a/pkg/providers/vsphere/testdata/cluster_full_oidc.yaml b/pkg/providers/vsphere/testdata/cluster_full_oidc.yaml index de71150bf7f3..6dfcb63870a9 100644 --- a/pkg/providers/vsphere/testdata/cluster_full_oidc.yaml +++ b/pkg/providers/vsphere/testdata/cluster_full_oidc.yaml @@ -2,6 +2,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: Cluster metadata: name: test + namespace: test-namespace spec: controlPlaneConfiguration: count: 3 @@ -35,6 +36,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereMachineConfig metadata: name: test-cp + namespace: test-namespace spec: diskGiB: 25 datastore: "/SDDC-Datacenter/datastore/WorkloadDatastore" @@ -52,6 +54,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereMachineConfig metadata: name: test-wn + namespace: test-namespace spec: diskGiB: 25 datastore: "/SDDC-Datacenter/datastore/WorkloadDatastore" @@ -69,6 +72,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereDatacenterConfig metadata: name: test + namespace: test-namespace spec: datacenter: "SDDC-Datacenter" network: "/SDDC-Datacenter/network/sddc-cgw-network-1" @@ -80,6 +84,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: OIDCConfig metadata: name: test + namespace: test-namespace spec: clientId: my-client-id groupsClaim: claim1 diff --git a/pkg/providers/vsphere/testdata/cluster_main.yaml b/pkg/providers/vsphere/testdata/cluster_main.yaml index 55d8be3b1617..8ce841054af0 100644 --- a/pkg/providers/vsphere/testdata/cluster_main.yaml +++ b/pkg/providers/vsphere/testdata/cluster_main.yaml @@ -2,6 +2,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: Cluster metadata: name: test + namespace: test-namespace spec: controlPlaneConfiguration: count: 3 @@ -37,6 +38,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereMachineConfig metadata: name: test-cp + namespace: test-namespace spec: diskGiB: 25 datastore: "/SDDC-Datacenter/datastore/WorkloadDatastore" @@ -56,6 +58,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereMachineConfig metadata: name: test-wn + namespace: test-namespace spec: diskGiB: 25 datastore: "/SDDC-Datacenter/datastore/WorkloadDatastore" @@ -75,6 +78,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereMachineConfig metadata: name: test-etcd + namespace: test-namespace spec: diskGiB: 25 datastore: "/SDDC-Datacenter/datastore/WorkloadDatastore" @@ -94,6 +98,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereDatacenterConfig metadata: name: test + namespace: test-namespace spec: datacenter: "SDDC-Datacenter" network: "/SDDC-Datacenter/network/sddc-cgw-network-1" diff --git a/pkg/providers/vsphere/testdata/cluster_main_121.yaml b/pkg/providers/vsphere/testdata/cluster_main_121.yaml index 3dc6cc0b1833..6589006ad94d 100644 --- a/pkg/providers/vsphere/testdata/cluster_main_121.yaml +++ b/pkg/providers/vsphere/testdata/cluster_main_121.yaml @@ -2,6 +2,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: Cluster metadata: name: test + namespace: test-namespace spec: controlPlaneConfiguration: count: 3 @@ -37,6 +38,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereMachineConfig metadata: name: test-cp + namespace: test-namespace spec: diskGiB: 25 datastore: "/SDDC-Datacenter/datastore/WorkloadDatastore" @@ -56,6 +58,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereMachineConfig metadata: name: test-wn + namespace: test-namespace spec: diskGiB: 25 datastore: "/SDDC-Datacenter/datastore/WorkloadDatastore" @@ -75,6 +78,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereMachineConfig metadata: name: test-etcd + namespace: test-namespace spec: diskGiB: 25 datastore: "/SDDC-Datacenter/datastore/WorkloadDatastore" @@ -94,6 +98,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereDatacenterConfig metadata: name: test + namespace: test-namespace spec: datacenter: "SDDC-Datacenter" network: "/SDDC-Datacenter/network/sddc-cgw-network-1" diff --git a/pkg/providers/vsphere/testdata/cluster_minimal.yaml b/pkg/providers/vsphere/testdata/cluster_minimal.yaml index fbb398658514..a8f2eb345ff7 100644 --- a/pkg/providers/vsphere/testdata/cluster_minimal.yaml +++ b/pkg/providers/vsphere/testdata/cluster_minimal.yaml @@ -2,6 +2,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: Cluster metadata: name: test + namespace: test-namespace spec: controlPlaneConfiguration: count: 3 @@ -32,6 +33,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereMachineConfig metadata: name: test + namespace: test-namespace spec: diskGiB: 25 datastore: "/SDDC-Datacenter/datastore/WorkloadDatastore" @@ -50,6 +52,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereDatacenterConfig metadata: name: test + namespace: test-namespace spec: datacenter: "SDDC-Datacenter" network: "/SDDC-Datacenter/network/sddc-cgw-network-1" diff --git a/pkg/providers/vsphere/testdata/cluster_minimal_oidc.yaml b/pkg/providers/vsphere/testdata/cluster_minimal_oidc.yaml index b782204bfe69..39c5d01332bd 100644 --- a/pkg/providers/vsphere/testdata/cluster_minimal_oidc.yaml +++ b/pkg/providers/vsphere/testdata/cluster_minimal_oidc.yaml @@ -2,6 +2,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: Cluster metadata: name: test + namespace: test-namespace spec: controlPlaneConfiguration: count: 3 @@ -35,6 +36,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereMachineConfig metadata: name: test-cp + namespace: test-namespace spec: diskGiB: 25 datastore: "/SDDC-Datacenter/datastore/WorkloadDatastore" @@ -52,6 +54,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereMachineConfig metadata: name: test-wn + namespace: test-namespace spec: diskGiB: 25 datastore: "/SDDC-Datacenter/datastore/WorkloadDatastore" @@ -69,6 +72,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: VSphereDatacenterConfig metadata: name: test + namespace: test-namespace spec: datacenter: "SDDC-Datacenter" network: "/SDDC-Datacenter/network/sddc-cgw-network-1" @@ -80,6 +84,7 @@ apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: OIDCConfig metadata: name: test + namespace: test-namespace spec: issuerUrl: https://mydomain.com/issuer clientId: my-client-id diff --git a/pkg/providers/vsphere/vsphere.go b/pkg/providers/vsphere/vsphere.go index 1170f368cf50..8c1396a5a6b0 100644 --- a/pkg/providers/vsphere/vsphere.go +++ b/pkg/providers/vsphere/vsphere.go @@ -121,8 +121,8 @@ type ProviderKubectlClient interface { CreateNamespace(ctx context.Context, kubeconfig string, namespace string) error LoadSecret(ctx context.Context, secretObject string, secretObjType string, secretObjectName string, kubeConfFile string) error GetEksaCluster(ctx context.Context, cluster *types.Cluster) (*v1alpha1.Cluster, error) - GetEksaVSphereDatacenterConfig(ctx context.Context, vsphereDatacenterConfigName string, kubeconfigFile string) (*v1alpha1.VSphereDatacenterConfig, error) - GetEksaVSphereMachineConfig(ctx context.Context, vsphereMachineConfigName string, kubeconfigFile string) (*v1alpha1.VSphereMachineConfig, error) + GetEksaVSphereDatacenterConfig(ctx context.Context, vsphereDatacenterConfigName string, kubeconfigFile string, namespace string) (*v1alpha1.VSphereDatacenterConfig, error) + GetEksaVSphereMachineConfig(ctx context.Context, vsphereMachineConfigName string, kubeconfigFile string, namespace string) (*v1alpha1.VSphereMachineConfig, error) GetKubeadmControlPlane(ctx context.Context, cluster *types.Cluster, opts ...executables.KubectlOpt) (*kubeadmnv1alpha3.KubeadmControlPlane, error) GetMachineDeployment(ctx context.Context, cluster *types.Cluster, opts ...executables.KubectlOpt) (*v1alpha3.MachineDeployment, error) GetEtcdadmCluster(ctx context.Context, cluster *types.Cluster, opts ...executables.KubectlOpt) (*etcdv1alpha3.EtcdadmCluster, error) @@ -589,6 +589,15 @@ func (p *vsphereProvider) setupAndValidateCluster(ctx context.Context, clusterSp return fmt.Errorf("error validating SSHUsername for control plane VSphereMachineConfig %v: %v", controlPlaneMachineConfig.Name, err) } + for _, machineConfig := range p.machineConfigs { + if machineConfig.Namespace != clusterSpec.Namespace { + return errors.New("VSphereMachineConfig and Cluster objects must have the same namespace specified") + } + } + if p.datacenterConfig.Namespace != clusterSpec.Namespace { + return errors.New("VSphereDatacenterConfig and Cluster objects must have the same namespace specified") + } + if controlPlaneMachineConfig.Spec.Template == "" { logger.V(1).Info("Control plane VSphereMachineConfig template is not set. Using default template.") err := p.setupDefaultTemplate(ctx, clusterSpec, controlPlaneMachineConfig, p.controlPlaneTemplateFactory) @@ -1125,17 +1134,17 @@ func (p *vsphereProvider) generateTemplateValuesForUpgrade(ctx context.Context, if err != nil { return nil, err } - vdc, err := p.providerKubectlClient.GetEksaVSphereDatacenterConfig(ctx, p.datacenterConfig.Name, workloadCluster.KubeconfigFile) + vdc, err := p.providerKubectlClient.GetEksaVSphereDatacenterConfig(ctx, p.datacenterConfig.Name, workloadCluster.KubeconfigFile, clusterSpec.Namespace) if err != nil { return nil, err } controlPlaneMachineConfig := p.machineConfigs[clusterSpec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name] - controlPlaneVmc, err := p.providerKubectlClient.GetEksaVSphereMachineConfig(ctx, c.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, workloadCluster.KubeconfigFile) + controlPlaneVmc, err := p.providerKubectlClient.GetEksaVSphereMachineConfig(ctx, c.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, workloadCluster.KubeconfigFile, clusterSpec.Namespace) if err != nil { return nil, err } workerMachineConfig := p.machineConfigs[clusterSpec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name] - workerVmc, err := p.providerKubectlClient.GetEksaVSphereMachineConfig(ctx, c.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, workloadCluster.KubeconfigFile) + workerVmc, err := p.providerKubectlClient.GetEksaVSphereMachineConfig(ctx, c.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, workloadCluster.KubeconfigFile, clusterSpec.Namespace) if err != nil { return nil, err } @@ -1164,7 +1173,7 @@ func (p *vsphereProvider) generateTemplateValuesForUpgrade(ctx context.Context, if clusterSpec.Spec.ExternalEtcdConfiguration != nil { etcdMachineConfig := p.machineConfigs[clusterSpec.Spec.ExternalEtcdConfiguration.MachineGroupRef.Name] - etcdMachineVmc, err := p.providerKubectlClient.GetEksaVSphereMachineConfig(ctx, c.Spec.ExternalEtcdConfiguration.MachineGroupRef.Name, workloadCluster.KubeconfigFile) + etcdMachineVmc, err := p.providerKubectlClient.GetEksaVSphereMachineConfig(ctx, c.Spec.ExternalEtcdConfiguration.MachineGroupRef.Name, workloadCluster.KubeconfigFile, clusterSpec.Namespace) if err != nil { return nil, err } @@ -1378,13 +1387,13 @@ func (p *vsphereProvider) MachineConfigs() []providers.MachineConfig { return configs } -func (p *vsphereProvider) ValidateNewSpec(ctx context.Context, cluster *types.Cluster) error { +func (p *vsphereProvider) ValidateNewSpec(ctx context.Context, cluster *types.Cluster, clusterSpec *cluster.Spec) error { prevSpec, err := p.providerKubectlClient.GetEksaCluster(ctx, cluster) if err != nil { return err } - prevDatacenter, err := p.providerKubectlClient.GetEksaVSphereDatacenterConfig(ctx, prevSpec.Spec.DatacenterRef.Name, cluster.KubeconfigFile) + prevDatacenter, err := p.providerKubectlClient.GetEksaVSphereDatacenterConfig(ctx, prevSpec.Spec.DatacenterRef.Name, cluster.KubeconfigFile, prevSpec.Namespace) if err != nil { return err } @@ -1396,12 +1405,16 @@ func (p *vsphereProvider) ValidateNewSpec(ctx context.Context, cluster *types.Cl nSpec := datacenter.Spec for _, machineConfig := range p.machineConfigs { - err := p.validateMachineConfigImmutability(ctx, cluster, machineConfig) + err := p.validateMachineConfigImmutability(ctx, cluster, machineConfig, clusterSpec) if err != nil { return err } } + if datacenter.Namespace != prevDatacenter.Namespace { + return fmt.Errorf("namespace is immutable. Previous value %s, new value %s", prevDatacenter.Namespace, datacenter.Namespace) + } + if nSpec.Server != oSpec.Server { return fmt.Errorf("spec.server is immutable. Previous value %s, new value %s", oSpec.Server, nSpec.Server) } @@ -1432,8 +1445,8 @@ func (p *vsphereProvider) ValidateNewSpec(ctx context.Context, cluster *types.Cl return nil } -func (p *vsphereProvider) validateMachineConfigImmutability(ctx context.Context, cluster *types.Cluster, newConfig *v1alpha1.VSphereMachineConfig) error { - prevMachineConfig, err := p.providerKubectlClient.GetEksaVSphereMachineConfig(ctx, newConfig.Name, cluster.KubeconfigFile) +func (p *vsphereProvider) validateMachineConfigImmutability(ctx context.Context, cluster *types.Cluster, newConfig *v1alpha1.VSphereMachineConfig, clusterSpec *cluster.Spec) error { + prevMachineConfig, err := p.providerKubectlClient.GetEksaVSphereMachineConfig(ctx, newConfig.Name, cluster.KubeconfigFile, clusterSpec.Namespace) if err != nil { return err } @@ -1442,6 +1455,10 @@ func (p *vsphereProvider) validateMachineConfigImmutability(ctx context.Context, return fmt.Errorf("spec.storagePolicyName is immutable. Previous value %s, new value %s", prevMachineConfig.Spec.StoragePolicyName, newConfig.Spec.StoragePolicyName) } + if newConfig.Namespace != prevMachineConfig.Namespace { + return fmt.Errorf("namespace is immutable. Previous value %s, new value %s", prevMachineConfig.Namespace, newConfig.Namespace) + } + if !reflect.DeepEqual(newConfig.Spec.Users, prevMachineConfig.Spec.Users) { return fmt.Errorf("vsphereMachineConfig %s users are immutable; new user: %v; old user: %v", newConfig.Name, newConfig.Spec.Users, prevMachineConfig.Spec.Users) } diff --git a/pkg/providers/vsphere/vsphere_test.go b/pkg/providers/vsphere/vsphere_test.go index 6c0703c542a3..b63ca4bf6e65 100644 --- a/pkg/providers/vsphere/vsphere_test.go +++ b/pkg/providers/vsphere/vsphere_test.go @@ -146,6 +146,7 @@ func givenEmptyClusterSpec() *cluster.Spec { return test.NewClusterSpec(func(s *cluster.Spec) { s.VersionsBundle.KubeVersion = "1.19" s.VersionsBundle.EksD.Name = eksd119Release + s.Namespace = "test-namespace" }) } @@ -290,9 +291,9 @@ func TestProviderGenerateDeploymentFileUpgradeCmdUpdateMachineTemplate(t *testin } kubectl.EXPECT().GetEksaCluster(ctx, cluster).Return(clusterSpec.Cluster, nil) - kubectl.EXPECT().GetEksaVSphereDatacenterConfig(ctx, cluster.Name, cluster.KubeconfigFile).Return(vsphereDatacenter, nil) - kubectl.EXPECT().GetEksaVSphereMachineConfig(ctx, clusterSpec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, cluster.KubeconfigFile).Return(vsphereMachineConfig, nil) - kubectl.EXPECT().GetEksaVSphereMachineConfig(ctx, clusterSpec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, cluster.KubeconfigFile).Return(vsphereMachineConfig, nil) + kubectl.EXPECT().GetEksaVSphereDatacenterConfig(ctx, cluster.Name, cluster.KubeconfigFile, clusterSpec.Namespace).Return(vsphereDatacenter, nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(ctx, clusterSpec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, cluster.KubeconfigFile, clusterSpec.Namespace).Return(vsphereMachineConfig, nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(ctx, clusterSpec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, cluster.KubeconfigFile, clusterSpec.Namespace).Return(vsphereMachineConfig, nil) datacenterConfig := givenDatacenterConfig(t, tt.clusterconfigFile) machineConfigs := givenMachineConfigs(t, tt.clusterconfigFile) _, writer := test.NewWriter(t) @@ -354,10 +355,10 @@ func TestProviderGenerateDeploymentFileUpgradeCmdUpdateMachineTemplateExternalEt } kubectl.EXPECT().GetEksaCluster(ctx, cluster).Return(clusterSpec.Cluster, nil) - kubectl.EXPECT().GetEksaVSphereDatacenterConfig(ctx, cluster.Name, cluster.KubeconfigFile).Return(vsphereDatacenter, nil) - kubectl.EXPECT().GetEksaVSphereMachineConfig(ctx, clusterSpec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, cluster.KubeconfigFile).Return(vsphereMachineConfig, nil) - kubectl.EXPECT().GetEksaVSphereMachineConfig(ctx, clusterSpec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, cluster.KubeconfigFile).Return(vsphereMachineConfig, nil) - kubectl.EXPECT().GetEksaVSphereMachineConfig(ctx, clusterSpec.Spec.ExternalEtcdConfiguration.MachineGroupRef.Name, cluster.KubeconfigFile).Return(vsphereMachineConfig, nil) + kubectl.EXPECT().GetEksaVSphereDatacenterConfig(ctx, cluster.Name, cluster.KubeconfigFile, clusterSpec.Namespace).Return(vsphereDatacenter, nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(ctx, clusterSpec.Spec.ControlPlaneConfiguration.MachineGroupRef.Name, cluster.KubeconfigFile, clusterSpec.Namespace).Return(vsphereMachineConfig, nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(ctx, clusterSpec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name, cluster.KubeconfigFile, clusterSpec.Namespace).Return(vsphereMachineConfig, nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(ctx, clusterSpec.Spec.ExternalEtcdConfiguration.MachineGroupRef.Name, cluster.KubeconfigFile, clusterSpec.Namespace).Return(vsphereMachineConfig, nil) kubectl.EXPECT().UpdateAnnotation(ctx, "etcdadmcluster", fmt.Sprintf("%s-etcd", cluster.Name), map[string]string{etcdv1alpha3.UpgradeInProgressAnnotation: "true"}, gomock.AssignableToTypeOf(executables.WithCluster(bootstrapCluster))) datacenterConfig := givenDatacenterConfig(t, tt.clusterconfigFile) machineConfigs := givenMachineConfigs(t, tt.clusterconfigFile) @@ -494,10 +495,10 @@ func TestProviderGenerateDeploymentFileUpgradeCmdNotUpdateMachineTemplate(t *tes workerNodeMachineConfigName := clusterSpec.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name etcdMachineConfigName := clusterSpec.Spec.ExternalEtcdConfiguration.MachineGroupRef.Name kubectl.EXPECT().GetEksaCluster(ctx, cluster).Return(clusterSpec.Cluster, nil) - kubectl.EXPECT().GetEksaVSphereDatacenterConfig(ctx, cluster.Name, cluster.KubeconfigFile).Return(datacenterConfig, nil) - kubectl.EXPECT().GetEksaVSphereMachineConfig(ctx, controlPlaneMachineConfigName, cluster.KubeconfigFile).Return(machineConfigs[controlPlaneMachineConfigName], nil) - kubectl.EXPECT().GetEksaVSphereMachineConfig(ctx, workerNodeMachineConfigName, cluster.KubeconfigFile).Return(machineConfigs[workerNodeMachineConfigName], nil) - kubectl.EXPECT().GetEksaVSphereMachineConfig(ctx, etcdMachineConfigName, cluster.KubeconfigFile).Return(machineConfigs[etcdMachineConfigName], nil) + kubectl.EXPECT().GetEksaVSphereDatacenterConfig(ctx, cluster.Name, cluster.KubeconfigFile, clusterSpec.Namespace).Return(datacenterConfig, nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(ctx, controlPlaneMachineConfigName, cluster.KubeconfigFile, clusterSpec.Namespace).Return(machineConfigs[controlPlaneMachineConfigName], nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(ctx, workerNodeMachineConfigName, cluster.KubeconfigFile, clusterSpec.Namespace).Return(machineConfigs[workerNodeMachineConfigName], nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(ctx, etcdMachineConfigName, cluster.KubeconfigFile, clusterSpec.Namespace).Return(machineConfigs[etcdMachineConfigName], nil) kubectl.EXPECT().GetKubeadmControlPlane(ctx, cluster, gomock.AssignableToTypeOf(executables.WithCluster(bootstrapCluster))).Return(cp, nil) kubectl.EXPECT().GetMachineDeployment(ctx, cluster, gomock.AssignableToTypeOf(executables.WithCluster(bootstrapCluster))).Return(md, nil) kubectl.EXPECT().GetEtcdadmCluster(ctx, cluster, gomock.AssignableToTypeOf(executables.WithCluster(bootstrapCluster))).Return(etcdadmCluster, nil) @@ -1727,6 +1728,7 @@ func TestSetupAndValidateCreateClusterDefaultTemplate(t *testing.T) { s.VersionsBundle.EksD.Name = eksd119Release s.VersionsBundle.EksD.KubeVersion = "v1.19.8" s.VersionsBundle.KubeVersion = "1.19" + s.Namespace = "test-namespace" }) fillClusterSpecWithClusterConfig(clusterSpec, givenClusterConfig(t, testClusterConfigMainFilename)) provider := givenProvider(t) @@ -1840,17 +1842,19 @@ func TestValidateNewSpecSuccess(t *testing.T) { "password": []byte("vsphere_password"), }, } - + clusterSpec := test.NewClusterSpec(func(s *cluster.Spec) { + s.Namespace = "test-namespace" + }) c := &types.Cluster{} kubectl.EXPECT().GetEksaCluster(context.TODO(), gomock.Any()).Return(clusterConfig, nil) - kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any()).Return(newProviderConfig, nil) + kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any(), clusterConfig.Namespace).Return(newProviderConfig, nil) for _, config := range newMachineConfigs { - kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any()).Return(config, nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any(), clusterConfig.Namespace).Return(config, nil) } kubectl.EXPECT().GetSecret(gomock.Any(), credentialsObjectName, gomock.Any()).Return(clusterVsphereSecret, nil) - err := provider.ValidateNewSpec(context.TODO(), c) + err := provider.ValidateNewSpec(context.TODO(), c, clusterSpec) assert.NoError(t, err, "No error should be returned when previous spec == new spec") } @@ -1879,14 +1883,18 @@ func TestValidateNewSpecMutableFields(t *testing.T) { }, } + clusterSpec := test.NewClusterSpec(func(s *cluster.Spec) { + s.Namespace = "test-namespace" + }) + kubectl.EXPECT().GetEksaCluster(context.TODO(), gomock.Any()).Return(clusterConfig, nil) - kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any()).Return(newDatacenterConfig, nil) + kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any(), gomock.Any()).Return(newDatacenterConfig, nil) for _, config := range newMachineConfigs { - kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any()).Return(config, nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any(), clusterConfig.Namespace).Return(config, nil) } - kubectl.EXPECT().GetSecret(gomock.Any(), credentialsObjectName, gomock.Any()).Return(clusterVsphereSecret, nil) + kubectl.EXPECT().GetSecret(gomock.Any(), credentialsObjectName, gomock.Any(), gomock.Any()).Return(clusterVsphereSecret, nil) - err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}) + err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}, clusterSpec) assert.NoError(t, err, "No error should be returned when modifying mutable fields") } @@ -1903,13 +1911,17 @@ func TestValidateNewSpecDatacenterImmutable(t *testing.T) { newMachineConfigs := givenMachineConfigs(t, testClusterConfigMainFilename) + clusterSpec := test.NewClusterSpec(func(s *cluster.Spec) { + s.Namespace = "test-namespace" + }) + kubectl.EXPECT().GetEksaCluster(context.TODO(), gomock.Any()).Return(clusterConfig, nil) - kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any()).Return(newProviderConfig, nil) + kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any(), clusterConfig.Namespace).Return(newProviderConfig, nil) for _, config := range newMachineConfigs { - kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any()).Return(config, nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any(), clusterConfig.Namespace).Return(config, nil) } - err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}) + err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}, clusterSpec) assert.Error(t, err, "Datacenter should be immutable") } @@ -1926,13 +1938,17 @@ func TestValidateNewSpecServerImmutable(t *testing.T) { newMachineConfigs := givenMachineConfigs(t, testClusterConfigMainFilename) + clusterSpec := test.NewClusterSpec(func(s *cluster.Spec) { + s.Namespace = "test-namespace" + }) + kubectl.EXPECT().GetEksaCluster(context.TODO(), gomock.Any()).Return(clusterConfig, nil) - kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any()).Return(newProviderConfig, nil) + kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any(), clusterConfig.Namespace).Return(newProviderConfig, nil) for _, config := range newMachineConfigs { - kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any()).Return(config, nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any(), clusterConfig.Namespace).Return(config, nil) } - err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}) + err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}, clusterSpec) assert.Error(t, err, "Server should be immutable") } @@ -1950,11 +1966,15 @@ func TestValidateNewSpecStoragePolicyNameImmutableControlPlane(t *testing.T) { controlPlaneMachineConfigName := clusterConfig.Spec.ControlPlaneConfiguration.MachineGroupRef.Name newMachineConfigs[controlPlaneMachineConfigName].Spec.StoragePolicyName = "new-" + newMachineConfigs[controlPlaneMachineConfigName].Spec.StoragePolicyName + clusterSpec := test.NewClusterSpec(func(s *cluster.Spec) { + s.Namespace = "test-namespace" + }) + kubectl.EXPECT().GetEksaCluster(context.TODO(), gomock.Any()).Return(clusterConfig, nil) - kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any()).Return(newProviderConfig, nil) - kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any()).Return(newMachineConfigs[controlPlaneMachineConfigName], nil) + kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any(), clusterConfig.Namespace).Return(newProviderConfig, nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any(), clusterConfig.Namespace).Return(newMachineConfigs[controlPlaneMachineConfigName], nil) - err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}) + err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}, clusterSpec) assert.Error(t, err, "StoragePolicyName should be immutable") } @@ -1972,11 +1992,15 @@ func TestValidateNewSpecStoragePolicyNameImmutableWorker(t *testing.T) { workerMachineConfigName := clusterConfig.Spec.WorkerNodeGroupConfigurations[0].MachineGroupRef.Name newMachineConfigs[workerMachineConfigName].Spec.StoragePolicyName = "new-" + newMachineConfigs[workerMachineConfigName].Spec.StoragePolicyName + clusterSpec := test.NewClusterSpec(func(s *cluster.Spec) { + s.Namespace = "test-namespace" + }) + kubectl.EXPECT().GetEksaCluster(context.TODO(), gomock.Any()).Return(clusterConfig, nil) - kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any()).Return(newProviderConfig, nil) - kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any()).Return(newMachineConfigs[workerMachineConfigName], nil) + kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any(), clusterConfig.Namespace).Return(newProviderConfig, nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any(), clusterConfig.Namespace).Return(newMachineConfigs[workerMachineConfigName], nil) - err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}) + err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}, clusterSpec) assert.Error(t, err, "StoragePolicyName should be immutable") } @@ -1993,12 +2017,16 @@ func TestValidateNewSpecTLSInsecureImmutable(t *testing.T) { newMachineConfigs := givenMachineConfigs(t, testClusterConfigMainFilename) + clusterSpec := test.NewClusterSpec(func(s *cluster.Spec) { + s.Namespace = "test-namespace" + }) + kubectl.EXPECT().GetEksaCluster(context.TODO(), gomock.Any()).Return(clusterConfig, nil) - kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any()).Return(newProviderConfig, nil) + kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any(), clusterConfig.Namespace).Return(newProviderConfig, nil) for _, config := range newMachineConfigs { - kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any()).Return(config, nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any(), clusterConfig.Namespace).Return(config, nil) } - err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}) + err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}, clusterSpec) assert.Error(t, err, "Insecure should be immutable") } @@ -2015,12 +2043,16 @@ func TestValidateNewSpecTLSThumbprintImmutable(t *testing.T) { newMachineConfigs := givenMachineConfigs(t, testClusterConfigMainFilename) + clusterSpec := test.NewClusterSpec(func(s *cluster.Spec) { + s.Namespace = "test-namespace" + }) + kubectl.EXPECT().GetEksaCluster(context.TODO(), gomock.Any()).Return(clusterConfig, nil) - kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any()).Return(newProviderConfig, nil) + kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any(), clusterConfig.Namespace).Return(newProviderConfig, nil) for _, config := range newMachineConfigs { - kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any()).Return(config, nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any(), clusterConfig.Namespace).Return(config, nil) } - err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}) + err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}, clusterSpec) assert.Error(t, err, "Thumbprint should be immutable") } @@ -2037,13 +2069,17 @@ func TestValidateNewSpecMachineConfigSshUsersImmutable(t *testing.T) { newMachineConfigs := givenMachineConfigs(t, testClusterConfigMainFilename) + clusterSpec := test.NewClusterSpec(func(s *cluster.Spec) { + s.Namespace = "test-namespace" + }) + kubectl.EXPECT().GetEksaCluster(context.TODO(), gomock.Any()).Return(clusterConfig, nil) - kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any()).Return(newProviderConfig, nil) - kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any()).Return(newMachineConfigs["test-cp"], nil) + kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any(), clusterConfig.Namespace).Return(newProviderConfig, nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any(), clusterConfig.Namespace).Return(newMachineConfigs["test-cp"], nil) newMachineConfigs["test-cp"].Spec.Users[0].Name = "newNameShouldNotBeAllowed" - err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}) + err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}, clusterSpec) assert.Error(t, err, "User should be immutable") } @@ -2060,11 +2096,15 @@ func TestValidateNewSpecMachineConfigSshAuthKeysImmutable(t *testing.T) { newMachineConfigs := givenMachineConfigs(t, testClusterConfigMainFilename) + clusterSpec := test.NewClusterSpec(func(s *cluster.Spec) { + s.Namespace = "test-namespace" + }) + kubectl.EXPECT().GetEksaCluster(context.TODO(), gomock.Any()).Return(clusterConfig, nil) - kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any()).Return(newProviderConfig, nil) - kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any()).Return(newMachineConfigs["test-cp"], nil) + kubectl.EXPECT().GetEksaVSphereDatacenterConfig(context.TODO(), clusterConfig.Spec.DatacenterRef.Name, gomock.Any(), clusterConfig.Namespace).Return(newProviderConfig, nil) + kubectl.EXPECT().GetEksaVSphereMachineConfig(context.TODO(), gomock.Any(), gomock.Any(), clusterConfig.Namespace).Return(newMachineConfigs["test-cp"], nil) newMachineConfigs["test-cp"].Spec.Users[0].SshAuthorizedKeys = []string{"rsa ssh-asd;lfajsfl;asjdfl;asjdlfajsdlfjasl;djf"} - err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}) + err := provider.ValidateNewSpec(context.TODO(), &types.Cluster{}, clusterSpec) assert.Error(t, err, "SSH Authorized Keys should be immutable") } diff --git a/pkg/validations/upgradevalidations/immutableFields.go b/pkg/validations/upgradevalidations/immutableFields.go index bca22360d92b..5446a50338fc 100644 --- a/pkg/validations/upgradevalidations/immutableFields.go +++ b/pkg/validations/upgradevalidations/immutableFields.go @@ -20,6 +20,10 @@ func ValidateImmutableFields(ctx context.Context, k ValidationsKubectlClient, cl return fmt.Errorf("cluster name is immutable") } + if prevSpec.Namespace != spec.Namespace { + return fmt.Errorf("cluster namespace is immutable") + } + oSpec := prevSpec.Spec nSpec := spec.Spec @@ -32,7 +36,7 @@ func ValidateImmutableFields(ctx context.Context, k ValidationsKubectlClient, cl } if nSpec.GitOpsRef != nil { - prevGitOps, err := k.GetEksaGitOpsConfig(ctx, nSpec.GitOpsRef.Name, cluster.KubeconfigFile) + prevGitOps, err := k.GetEksaGitOpsConfig(ctx, nSpec.GitOpsRef.Name, cluster.KubeconfigFile, spec.Namespace) if err != nil { return err } @@ -69,7 +73,7 @@ func ValidateImmutableFields(ctx context.Context, k ValidationsKubectlClient, cl if len(nSpec.IdentityProviderRefs) > 0 { // if it got here, it means we already validated for IdentityProviderRefs to ensure it only has one and is // of type OIDCConfig - prevOIDC, err := k.GetEksaOIDCConfig(ctx, nSpec.IdentityProviderRefs[0].Name, cluster.KubeconfigFile) + prevOIDC, err := k.GetEksaOIDCConfig(ctx, nSpec.IdentityProviderRefs[0].Name, cluster.KubeconfigFile, spec.Namespace) if err != nil { return err } @@ -78,5 +82,5 @@ func ValidateImmutableFields(ctx context.Context, k ValidationsKubectlClient, cl } } - return provider.ValidateNewSpec(ctx, cluster) + return provider.ValidateNewSpec(ctx, cluster, spec) } diff --git a/pkg/validations/upgradevalidations/mocks/upgradevalidations.go b/pkg/validations/upgradevalidations/mocks/upgradevalidations.go index d5362e62d572..4e06cb368522 100644 --- a/pkg/validations/upgradevalidations/mocks/upgradevalidations.go +++ b/pkg/validations/upgradevalidations/mocks/upgradevalidations.go @@ -68,48 +68,48 @@ func (mr *MockValidationsKubectlClientMockRecorder) GetEksaCluster(ctx, cluster } // GetEksaGitOpsConfig mocks base method. -func (m *MockValidationsKubectlClient) GetEksaGitOpsConfig(ctx context.Context, gitOpsConfigName, kubeconfigFile string) (*v1alpha1.GitOpsConfig, error) { +func (m *MockValidationsKubectlClient) GetEksaGitOpsConfig(ctx context.Context, gitOpsConfigName, kubeconfigFile, namespace string) (*v1alpha1.GitOpsConfig, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetEksaGitOpsConfig", ctx, gitOpsConfigName, kubeconfigFile) + ret := m.ctrl.Call(m, "GetEksaGitOpsConfig", ctx, gitOpsConfigName, kubeconfigFile, namespace) ret0, _ := ret[0].(*v1alpha1.GitOpsConfig) ret1, _ := ret[1].(error) return ret0, ret1 } // GetEksaGitOpsConfig indicates an expected call of GetEksaGitOpsConfig. -func (mr *MockValidationsKubectlClientMockRecorder) GetEksaGitOpsConfig(ctx, gitOpsConfigName, kubeconfigFile interface{}) *gomock.Call { +func (mr *MockValidationsKubectlClientMockRecorder) GetEksaGitOpsConfig(ctx, gitOpsConfigName, kubeconfigFile, namespace interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEksaGitOpsConfig", reflect.TypeOf((*MockValidationsKubectlClient)(nil).GetEksaGitOpsConfig), ctx, gitOpsConfigName, kubeconfigFile) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEksaGitOpsConfig", reflect.TypeOf((*MockValidationsKubectlClient)(nil).GetEksaGitOpsConfig), ctx, gitOpsConfigName, kubeconfigFile, namespace) } // GetEksaOIDCConfig mocks base method. -func (m *MockValidationsKubectlClient) GetEksaOIDCConfig(ctx context.Context, oidcConfigName, kubeconfigFile string) (*v1alpha1.OIDCConfig, error) { +func (m *MockValidationsKubectlClient) GetEksaOIDCConfig(ctx context.Context, oidcConfigName, kubeconfigFile, namespace string) (*v1alpha1.OIDCConfig, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetEksaOIDCConfig", ctx, oidcConfigName, kubeconfigFile) + ret := m.ctrl.Call(m, "GetEksaOIDCConfig", ctx, oidcConfigName, kubeconfigFile, namespace) ret0, _ := ret[0].(*v1alpha1.OIDCConfig) ret1, _ := ret[1].(error) return ret0, ret1 } // GetEksaOIDCConfig indicates an expected call of GetEksaOIDCConfig. -func (mr *MockValidationsKubectlClientMockRecorder) GetEksaOIDCConfig(ctx, oidcConfigName, kubeconfigFile interface{}) *gomock.Call { +func (mr *MockValidationsKubectlClientMockRecorder) GetEksaOIDCConfig(ctx, oidcConfigName, kubeconfigFile, namespace interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEksaOIDCConfig", reflect.TypeOf((*MockValidationsKubectlClient)(nil).GetEksaOIDCConfig), ctx, oidcConfigName, kubeconfigFile) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEksaOIDCConfig", reflect.TypeOf((*MockValidationsKubectlClient)(nil).GetEksaOIDCConfig), ctx, oidcConfigName, kubeconfigFile, namespace) } // GetEksaVSphereDatacenterConfig mocks base method. -func (m *MockValidationsKubectlClient) GetEksaVSphereDatacenterConfig(ctx context.Context, vsphereDatacenterConfigName, kubeconfigFile string) (*v1alpha1.VSphereDatacenterConfig, error) { +func (m *MockValidationsKubectlClient) GetEksaVSphereDatacenterConfig(ctx context.Context, vsphereDatacenterConfigName, kubeconfigFile, namespace string) (*v1alpha1.VSphereDatacenterConfig, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetEksaVSphereDatacenterConfig", ctx, vsphereDatacenterConfigName, kubeconfigFile) + ret := m.ctrl.Call(m, "GetEksaVSphereDatacenterConfig", ctx, vsphereDatacenterConfigName, kubeconfigFile, namespace) ret0, _ := ret[0].(*v1alpha1.VSphereDatacenterConfig) ret1, _ := ret[1].(error) return ret0, ret1 } // GetEksaVSphereDatacenterConfig indicates an expected call of GetEksaVSphereDatacenterConfig. -func (mr *MockValidationsKubectlClientMockRecorder) GetEksaVSphereDatacenterConfig(ctx, vsphereDatacenterConfigName, kubeconfigFile interface{}) *gomock.Call { +func (mr *MockValidationsKubectlClientMockRecorder) GetEksaVSphereDatacenterConfig(ctx, vsphereDatacenterConfigName, kubeconfigFile, namespace interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEksaVSphereDatacenterConfig", reflect.TypeOf((*MockValidationsKubectlClient)(nil).GetEksaVSphereDatacenterConfig), ctx, vsphereDatacenterConfigName, kubeconfigFile) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEksaVSphereDatacenterConfig", reflect.TypeOf((*MockValidationsKubectlClient)(nil).GetEksaVSphereDatacenterConfig), ctx, vsphereDatacenterConfigName, kubeconfigFile, namespace) } // ValidateClustersCRD mocks base method. diff --git a/pkg/validations/upgradevalidations/preflightvalidations_test.go b/pkg/validations/upgradevalidations/preflightvalidations_test.go index 7d24d12efe0b..ecec5ea0a2b9 100644 --- a/pkg/validations/upgradevalidations/preflightvalidations_test.go +++ b/pkg/validations/upgradevalidations/preflightvalidations_test.go @@ -581,16 +581,16 @@ func TestPreflightValidations(t *testing.T) { } provider.EXPECT().DatacenterConfig().Return(existingProviderSpec).MaxTimes(1) - provider.EXPECT().ValidateNewSpec(ctx, workloadCluster).Return(nil).MaxTimes(1) - k.EXPECT().GetEksaVSphereDatacenterConfig(ctx, clusterSpec.Spec.DatacenterRef.Name, gomock.Any()).Return(existingProviderSpec, nil).MaxTimes(1) + provider.EXPECT().ValidateNewSpec(ctx, workloadCluster, clusterSpec).Return(nil).MaxTimes(1) + k.EXPECT().GetEksaVSphereDatacenterConfig(ctx, clusterSpec.Spec.DatacenterRef.Name, gomock.Any(), gomock.Any()).Return(existingProviderSpec, nil).MaxTimes(1) k.EXPECT().ValidateControlPlaneNodes(ctx, workloadCluster).Return(tc.cpResponse) k.EXPECT().ValidateWorkerNodes(ctx, workloadCluster).Return(tc.workerResponse) k.EXPECT().ValidateNodes(ctx, kubeconfigFilePath).Return(tc.nodeResponse) k.EXPECT().ValidateClustersCRD(ctx, workloadCluster).Return(tc.crdResponse) k.EXPECT().GetClusters(ctx, workloadCluster).Return(tc.getClusterResponse, nil) k.EXPECT().GetEksaCluster(ctx, workloadCluster).Return(existingClusterSpec.Cluster, nil) - k.EXPECT().GetEksaGitOpsConfig(ctx, clusterSpec.Spec.GitOpsRef.Name, gomock.Any()).Return(existingClusterSpec.GitOpsConfig, nil).MaxTimes(1) - k.EXPECT().GetEksaOIDCConfig(ctx, clusterSpec.Spec.IdentityProviderRefs[0].Name, gomock.Any()).Return(existingClusterSpec.OIDCConfig, nil).MaxTimes(1) + k.EXPECT().GetEksaGitOpsConfig(ctx, clusterSpec.Spec.GitOpsRef.Name, gomock.Any(), gomock.Any()).Return(existingClusterSpec.GitOpsConfig, nil).MaxTimes(1) + k.EXPECT().GetEksaOIDCConfig(ctx, clusterSpec.Spec.IdentityProviderRefs[0].Name, gomock.Any(), gomock.Any()).Return(existingClusterSpec.OIDCConfig, nil).MaxTimes(1) k.EXPECT().Version(ctx, workloadCluster).Return(versionResponse, nil) upgradeValidations := upgradevalidations.New(opts) err := upgradeValidations.PreflightValidations(ctx) diff --git a/pkg/validations/upgradevalidations/upgradevalidations.go b/pkg/validations/upgradevalidations/upgradevalidations.go index f74826daea9d..98a4c998f255 100644 --- a/pkg/validations/upgradevalidations/upgradevalidations.go +++ b/pkg/validations/upgradevalidations/upgradevalidations.go @@ -18,9 +18,9 @@ type ValidationsKubectlClient interface { Version(ctx context.Context, cluster *types.Cluster) (*executables.VersionResponse, error) GetClusters(ctx context.Context, cluster *types.Cluster) ([]types.CAPICluster, error) GetEksaCluster(ctx context.Context, cluster *types.Cluster) (*v1alpha1.Cluster, error) - GetEksaGitOpsConfig(ctx context.Context, gitOpsConfigName string, kubeconfigFile string) (*v1alpha1.GitOpsConfig, error) - GetEksaOIDCConfig(ctx context.Context, oidcConfigName string, kubeconfigFile string) (*v1alpha1.OIDCConfig, error) - GetEksaVSphereDatacenterConfig(ctx context.Context, vsphereDatacenterConfigName string, kubeconfigFile string) (*v1alpha1.VSphereDatacenterConfig, error) + GetEksaGitOpsConfig(ctx context.Context, gitOpsConfigName string, kubeconfigFile string, namespace string) (*v1alpha1.GitOpsConfig, error) + GetEksaOIDCConfig(ctx context.Context, oidcConfigName string, kubeconfigFile string, namespace string) (*v1alpha1.OIDCConfig, error) + GetEksaVSphereDatacenterConfig(ctx context.Context, vsphereDatacenterConfigName string, kubeconfigFile string, namespace string) (*v1alpha1.VSphereDatacenterConfig, error) } func New(opts *UpgradeValidationOpts) *UpgradeValidations { diff --git a/test/framework/e2e.go b/test/framework/e2e.go index da60e315cb8c..bd609b07b54a 100644 --- a/test/framework/e2e.go +++ b/test/framework/e2e.go @@ -260,7 +260,7 @@ func (e *E2ETest) GetEksaVSphereMachineConfigs() []v1alpha1.VSphereMachineConfig machineConfigs := make([]v1alpha1.VSphereMachineConfig, 0, len(machineConfigNames)) for _, name := range machineConfigNames { - m, err := e.KubectlClient.GetEksaVSphereMachineConfig(ctx, name, kubeconfig) + m, err := e.KubectlClient.GetEksaVSphereMachineConfig(ctx, name, kubeconfig, clusterConfig.Namespace) if err != nil { e.T.Fatalf("Failed getting VSphereMachineConfig: %v", err) } From 49d3862fc112118c9940279a6ed3599840e0f227 Mon Sep 17 00:00:00 2001 From: Taylor Neyland Date: Fri, 10 Sep 2021 10:42:46 -0500 Subject: [PATCH 2/5] Look at first item when getting clusters --- pkg/executables/kubectl.go | 2 +- pkg/executables/kubectl_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/executables/kubectl.go b/pkg/executables/kubectl.go index 69c032bfdf70..cfe6c7e3e2f8 100644 --- a/pkg/executables/kubectl.go +++ b/pkg/executables/kubectl.go @@ -583,7 +583,7 @@ func (k *Kubectl) RemoveAnnotationInNamespace(ctx context.Context, resourceType, } func (k *Kubectl) GetEksaCluster(ctx context.Context, cluster *types.Cluster) (*v1alpha1.Cluster, error) { - params := []string{"get", "clusters", "-A", "--kubeconfig", cluster.KubeconfigFile, "--field-selector=metadata.name=" + cluster.Name} + params := []string{"get", "clusters", "-A", "-o", "jsonpath={.items[0]}", "--kubeconfig", cluster.KubeconfigFile, "--field-selector=metadata.name=" + cluster.Name} stdOut, err := k.executable.Execute(ctx, params...) if err != nil { return nil, fmt.Errorf("error getting eksa cluster: %v", err) diff --git a/pkg/executables/kubectl_test.go b/pkg/executables/kubectl_test.go index de00424a5d5a..c457006099a9 100644 --- a/pkg/executables/kubectl_test.go +++ b/pkg/executables/kubectl_test.go @@ -624,7 +624,7 @@ func TestKubectlGetEKSAClusters(t *testing.T) { t.Run(tt.testName, func(t *testing.T) { fileContent := test.ReadFile(t, tt.jsonResponseFile) k, ctx, cluster, e := newKubectl(t) - e.EXPECT().Execute(ctx, []string{"get", "clusters", "-A", "--kubeconfig", cluster.KubeconfigFile, "--field-selector=metadata.name=" + tt.clusterName}).Return(*bytes.NewBufferString(fileContent), nil) + e.EXPECT().Execute(ctx, []string{"get", "clusters", "-A", "-o", "jsonpath={.items[0]}", "--kubeconfig", cluster.KubeconfigFile, "--field-selector=metadata.name=" + tt.clusterName}).Return(*bytes.NewBufferString(fileContent), nil) gotCluster, err := k.GetEksaCluster(ctx, cluster) if err != nil { From b02be752ff047763773e4d8890e75674822f5dc8 Mon Sep 17 00:00:00 2001 From: Taylor Neyland Date: Mon, 13 Sep 2021 10:36:37 -0500 Subject: [PATCH 3/5] Remove unnecessary use of namespace for generate cmd --- pkg/api/v1alpha1/dockerdatacenterconfig.go | 4 ---- pkg/api/v1alpha1/object_meta.go | 3 +-- pkg/api/v1alpha1/vspheredatacenterconfig.go | 4 ---- pkg/api/v1alpha1/vspheremachineconfig.go | 4 ---- 4 files changed, 1 insertion(+), 14 deletions(-) diff --git a/pkg/api/v1alpha1/dockerdatacenterconfig.go b/pkg/api/v1alpha1/dockerdatacenterconfig.go index 78583ae21ed8..871fa14d1374 100644 --- a/pkg/api/v1alpha1/dockerdatacenterconfig.go +++ b/pkg/api/v1alpha1/dockerdatacenterconfig.go @@ -32,10 +32,6 @@ func (c *DockerDatacenterConfigGenerate) Name() string { return c.ObjectMeta.Name } -func (c *DockerDatacenterConfigGenerate) Namespace() string { - return c.ObjectMeta.Namespace -} - func GetDockerDatacenterConfig(fileName string) (*DockerDatacenterConfig, error) { var clusterConfig DockerDatacenterConfig err := ParseClusterConfig(fileName, &clusterConfig) diff --git a/pkg/api/v1alpha1/object_meta.go b/pkg/api/v1alpha1/object_meta.go index f4e8d50cac49..b1728d80af9b 100644 --- a/pkg/api/v1alpha1/object_meta.go +++ b/pkg/api/v1alpha1/object_meta.go @@ -6,6 +6,5 @@ package v1alpha1 // and https://github.com/kubernetes-sigs/cluster-api/blob/bf790fc2a53614ff5d3405c83c0de0dd3303bb1f/api/v1alpha2/common_types.go#L67-L128 // as needed. type ObjectMeta struct { - Name string `json:"name,omitempty"` - Namespace string `json:"namespace,omitempty"` + Name string `json:"name,omitempty"` } diff --git a/pkg/api/v1alpha1/vspheredatacenterconfig.go b/pkg/api/v1alpha1/vspheredatacenterconfig.go index 435d56267507..773344d6664f 100644 --- a/pkg/api/v1alpha1/vspheredatacenterconfig.go +++ b/pkg/api/v1alpha1/vspheredatacenterconfig.go @@ -32,10 +32,6 @@ func (c *VSphereDatacenterConfigGenerate) Name() string { return c.ObjectMeta.Name } -func (c *VSphereDatacenterConfigGenerate) Namespace() string { - return c.ObjectMeta.Namespace -} - func GetVSphereDatacenterConfig(fileName string) (*VSphereDatacenterConfig, error) { var clusterConfig VSphereDatacenterConfig err := ParseClusterConfig(fileName, &clusterConfig) diff --git a/pkg/api/v1alpha1/vspheremachineconfig.go b/pkg/api/v1alpha1/vspheremachineconfig.go index 232965f42e68..3340e0db4c4c 100644 --- a/pkg/api/v1alpha1/vspheremachineconfig.go +++ b/pkg/api/v1alpha1/vspheremachineconfig.go @@ -46,10 +46,6 @@ func (c *VSphereMachineConfigGenerate) Name() string { return c.ObjectMeta.Name } -func (c *VSphereMachineConfigGenerate) Namespace() string { - return c.ObjectMeta.Namespace -} - func GetVSphereMachineConfigs(fileName string) (map[string]*VSphereMachineConfig, error) { configs := make(map[string]*VSphereMachineConfig) content, err := ioutil.ReadFile(fileName) From ac1c4bfb603a9e02b07f1892f678da0832e28463 Mon Sep 17 00:00:00 2001 From: Taylor Neyland Date: Tue, 14 Sep 2021 15:12:45 -0500 Subject: [PATCH 4/5] Add e2e tests --- internal/pkg/api/cluster.go | 6 ++++ internal/pkg/api/gitops.go | 6 ++++ internal/pkg/api/vsphere.go | 11 +++++++ pkg/providers/vsphere/vsphere.go | 8 +++-- .../upgradevalidations/immutableFields.go | 4 ++- test/e2e/simpleflow_test.go | 20 +++++++++++ test/e2e/upgrade_test.go | 33 +++++++++++++++++++ 7 files changed, 85 insertions(+), 3 deletions(-) diff --git a/internal/pkg/api/cluster.go b/internal/pkg/api/cluster.go index bd8836933890..abe4bbb58b61 100644 --- a/internal/pkg/api/cluster.go +++ b/internal/pkg/api/cluster.go @@ -34,6 +34,12 @@ func WithKubernetesVersion(v v1alpha1.KubernetesVersion) ClusterFiller { } } +func WithClusterNamespace(ns string) ClusterFiller { + return func(c *v1alpha1.Cluster) { + c.Namespace = ns + } +} + func WithControlPlaneCount(r int) ClusterFiller { return func(c *v1alpha1.Cluster) { c.Spec.ControlPlaneConfiguration.Count = r diff --git a/internal/pkg/api/gitops.go b/internal/pkg/api/gitops.go index 85d7eb296a94..f0a0f54ffafb 100644 --- a/internal/pkg/api/gitops.go +++ b/internal/pkg/api/gitops.go @@ -27,6 +27,12 @@ func NewGitOpsConfig(name string, opts ...GitOpsConfigOpt) *v1alpha1.GitOpsConfi return config } +func WithGitOpsNamespace(ns string) GitOpsConfigOpt { + return func(c *v1alpha1.GitOpsConfig) { + c.Namespace = ns + } +} + func WithFluxOwner(username string) GitOpsConfigOpt { return func(c *v1alpha1.GitOpsConfig) { c.Spec.Flux.Github.Owner = username diff --git a/internal/pkg/api/vsphere.go b/internal/pkg/api/vsphere.go index 4ed85a3bf677..188a60b2f2b7 100644 --- a/internal/pkg/api/vsphere.go +++ b/internal/pkg/api/vsphere.go @@ -172,6 +172,17 @@ func WithStoragePolicyName(value string) VSphereFiller { } } +func WithVSphereConfigNamespace(ns string) VSphereFiller { + return func(config VSphereConfig) { + config.datacenterConfig.Namespace = ns + config.workerMachineConfig.Namespace = ns + config.cpMachineConfig.Namespace = ns + if config.etcdMachineConfig != nil { + config.etcdMachineConfig.Namespace = ns + } + } +} + func WithSSHUsernameAndAuthorizedKey(username string, key string) VSphereFiller { return func(config VSphereConfig) { if len(config.cpMachineConfig.Spec.Users) == 0 { diff --git a/pkg/providers/vsphere/vsphere.go b/pkg/providers/vsphere/vsphere.go index 8c1396a5a6b0..a2d8f7eb12db 100644 --- a/pkg/providers/vsphere/vsphere.go +++ b/pkg/providers/vsphere/vsphere.go @@ -1412,7 +1412,9 @@ func (p *vsphereProvider) ValidateNewSpec(ctx context.Context, cluster *types.Cl } if datacenter.Namespace != prevDatacenter.Namespace { - return fmt.Errorf("namespace is immutable. Previous value %s, new value %s", prevDatacenter.Namespace, datacenter.Namespace) + if !(prevDatacenter.Namespace == "default" && datacenter.Namespace == "") { + return fmt.Errorf("namespace is immutable. Previous value %s, new value %s", prevDatacenter.Namespace, datacenter.Namespace) + } } if nSpec.Server != oSpec.Server { @@ -1456,7 +1458,9 @@ func (p *vsphereProvider) validateMachineConfigImmutability(ctx context.Context, } if newConfig.Namespace != prevMachineConfig.Namespace { - return fmt.Errorf("namespace is immutable. Previous value %s, new value %s", prevMachineConfig.Namespace, newConfig.Namespace) + if !(prevMachineConfig.Namespace == "default" && newConfig.Namespace == "") { + return fmt.Errorf("namespace is immutable. Previous value %s, new value %s", prevMachineConfig.Namespace, newConfig.Namespace) + } } if !reflect.DeepEqual(newConfig.Spec.Users, prevMachineConfig.Spec.Users) { diff --git a/pkg/validations/upgradevalidations/immutableFields.go b/pkg/validations/upgradevalidations/immutableFields.go index 5446a50338fc..5faf026ec696 100644 --- a/pkg/validations/upgradevalidations/immutableFields.go +++ b/pkg/validations/upgradevalidations/immutableFields.go @@ -21,7 +21,9 @@ func ValidateImmutableFields(ctx context.Context, k ValidationsKubectlClient, cl } if prevSpec.Namespace != spec.Namespace { - return fmt.Errorf("cluster namespace is immutable") + if !(prevSpec.Namespace == "default" && spec.Namespace == "") { + return fmt.Errorf("cluster namespace is immutable") + } } oSpec := prevSpec.Spec diff --git a/test/e2e/simpleflow_test.go b/test/e2e/simpleflow_test.go index 6580affebb05..52b3c0b8f734 100644 --- a/test/e2e/simpleflow_test.go +++ b/test/e2e/simpleflow_test.go @@ -72,6 +72,16 @@ func TestVSphereKubernetes121ThreeReplicasFiveWorkersSimpleFlow(t *testing.T) { runSimpleFlow(test) } +func TestVsphereKubernetes121DifferentNamespaceSimpleFlow(t *testing.T) { + test := framework.NewE2ETest( + t, + framework.NewVSphere(t, framework.WithUbuntu121(), framework.WithVSphereFillers(api.WithVSphereConfigNamespace(clusterNamespace))), + framework.WithClusterFiller(api.WithKubernetesVersion(v1alpha1.Kube121)), + framework.WithClusterFiller(api.WithClusterNamespace(clusterNamespace)), + ) + runSimpleFlow(test) +} + func TestVSphereKubernetes120BottleRocketSimpleFlow(t *testing.T) { test := framework.NewE2ETest( t, @@ -91,3 +101,13 @@ func TestVSphereKubernetes120BottleRocketThreeReplicasFiveWorkersSimpleFlow(t *t ) runSimpleFlow(test) } + +func TestVSphereKubernetes120BottleRocketDifferentNamespaceSimpleFlow(t *testing.T) { + test := framework.NewE2ETest( + t, + framework.NewVSphere(t, framework.WithBottleRocket120(), framework.WithVSphereFillers(api.WithVSphereConfigNamespace(clusterNamespace))), + framework.WithClusterFiller(api.WithKubernetesVersion(v1alpha1.Kube120)), + framework.WithClusterFiller(api.WithClusterNamespace(clusterNamespace)), + ) + runSimpleFlow(test) +} diff --git a/test/e2e/upgrade_test.go b/test/e2e/upgrade_test.go index 73f5d2ea8f96..c4908d176759 100644 --- a/test/e2e/upgrade_test.go +++ b/test/e2e/upgrade_test.go @@ -20,6 +20,7 @@ const ( vsphereFolderUpdateVar = "/SDDC-Datacenter/vm/capv/e2eUpdate" vsphereNetwork2UpdateVar = "/SDDC-Datacenter/network/sddc-cgw-network-2" vsphereNetwork3UpdateVar = "/SDDC-Datacenter/network/sddc-cgw-network-3" + clusterNamespace = "test-namespace" ) func runSimpleUpgradeFlow(test *framework.E2ETest, updateVersion v1alpha1.KubernetesVersion, opts ...framework.E2ETestOpt) { @@ -88,6 +89,22 @@ func TestVSphereKubernetes120UbuntuTo121WithFluxUpgrade(t *testing.T) { ) } +func TestVSphereKubernetes120UbuntuTo121DifferentNamespaceWithFluxUpgrade(t *testing.T) { + provider := framework.NewVSphere(t, framework.WithUbuntu120(), framework.WithVSphereFillers(api.WithVSphereConfigNamespace(clusterNamespace))) + test := framework.NewE2ETest(t, + provider, + framework.WithFlux(api.WithGitOpsNamespace(clusterNamespace)), + framework.WithClusterFiller(api.WithKubernetesVersion(v1alpha1.Kube120)), + framework.WithClusterFiller(api.WithClusterNamespace(clusterNamespace)), + ) + runUpgradeFlowWithFlux( + test, + v1alpha1.Kube121, + framework.WithClusterUpgrade(api.WithKubernetesVersion(v1alpha1.Kube121)), + provider.WithProviderUpgrade(framework.UpdateUbuntuTemplate121Var()), + ) +} + func TestVSphereKubernetes120UbuntuControlPlaneNodeUpgrade(t *testing.T) { provider := framework.NewVSphere(t, framework.WithUbuntu120()) test := framework.NewE2ETest( @@ -177,6 +194,22 @@ func TestVSphereKubernetes120BottlerocketTo121WithFluxUpgrade(t *testing.T) { ) } +func TestVSphereKubernetes120BottlerocketTo121DifferentNamespaceWithFluxUpgrade(t *testing.T) { + provider := framework.NewVSphere(t, framework.WithBottleRocket120(), framework.WithVSphereFillers(api.WithVSphereConfigNamespace(clusterNamespace))) + test := framework.NewE2ETest(t, + provider, + framework.WithFlux(api.WithGitOpsNamespace(clusterNamespace)), + framework.WithClusterFiller(api.WithKubernetesVersion(v1alpha1.Kube120)), + framework.WithClusterFiller(api.WithClusterNamespace(clusterNamespace)), + ) + runUpgradeFlowWithFlux( + test, + v1alpha1.Kube121, + framework.WithClusterUpgrade(api.WithKubernetesVersion(v1alpha1.Kube121)), + provider.WithProviderUpgrade(framework.UpdateBottlerocketTemplate121()), + ) +} + func TestVSphereKubernetes120BottlerocketControlPlaneNodeUpgrade(t *testing.T) { provider := framework.NewVSphere(t, framework.WithBottleRocket120()) test := framework.NewE2ETest( From 79969009ecf017119866df94b6292f4bd5c15edc Mon Sep 17 00:00:00 2001 From: Taylor Neyland Date: Tue, 14 Sep 2021 21:18:48 -0500 Subject: [PATCH 5/5] Remove unnecessary validations in vsphere configs --- pkg/providers/vsphere/vsphere.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/pkg/providers/vsphere/vsphere.go b/pkg/providers/vsphere/vsphere.go index a2d8f7eb12db..c4349f441839 100644 --- a/pkg/providers/vsphere/vsphere.go +++ b/pkg/providers/vsphere/vsphere.go @@ -1411,12 +1411,6 @@ func (p *vsphereProvider) ValidateNewSpec(ctx context.Context, cluster *types.Cl } } - if datacenter.Namespace != prevDatacenter.Namespace { - if !(prevDatacenter.Namespace == "default" && datacenter.Namespace == "") { - return fmt.Errorf("namespace is immutable. Previous value %s, new value %s", prevDatacenter.Namespace, datacenter.Namespace) - } - } - if nSpec.Server != oSpec.Server { return fmt.Errorf("spec.server is immutable. Previous value %s, new value %s", oSpec.Server, nSpec.Server) } @@ -1457,12 +1451,6 @@ func (p *vsphereProvider) validateMachineConfigImmutability(ctx context.Context, return fmt.Errorf("spec.storagePolicyName is immutable. Previous value %s, new value %s", prevMachineConfig.Spec.StoragePolicyName, newConfig.Spec.StoragePolicyName) } - if newConfig.Namespace != prevMachineConfig.Namespace { - if !(prevMachineConfig.Namespace == "default" && newConfig.Namespace == "") { - return fmt.Errorf("namespace is immutable. Previous value %s, new value %s", prevMachineConfig.Namespace, newConfig.Namespace) - } - } - if !reflect.DeepEqual(newConfig.Spec.Users, prevMachineConfig.Spec.Users) { return fmt.Errorf("vsphereMachineConfig %s users are immutable; new user: %v; old user: %v", newConfig.Name, newConfig.Spec.Users, prevMachineConfig.Spec.Users) }