diff --git a/test/e2e/data/infrastructure-vsphere-govmomi/main/ownerrefs-finalizers/kustomization.yaml b/test/e2e/data/infrastructure-vsphere-govmomi/main/ownerrefs-finalizers/kustomization.yaml index 93257b21a5..3da6575628 100644 --- a/test/e2e/data/infrastructure-vsphere-govmomi/main/ownerrefs-finalizers/kustomization.yaml +++ b/test/e2e/data/infrastructure-vsphere-govmomi/main/ownerrefs-finalizers/kustomization.yaml @@ -9,3 +9,4 @@ patchesStrategicMerge: - ../commons/cluster-network-CIDR.yaml - vsphereclusteridentity.yaml - drop-existing-identity-secret.yaml + - vspherecluster-failuredomainselector.yaml diff --git a/test/e2e/data/infrastructure-vsphere-govmomi/main/ownerrefs-finalizers/vspherecluster-failuredomainselector.yaml b/test/e2e/data/infrastructure-vsphere-govmomi/main/ownerrefs-finalizers/vspherecluster-failuredomainselector.yaml new file mode 100644 index 0000000000..e5e2072dc9 --- /dev/null +++ b/test/e2e/data/infrastructure-vsphere-govmomi/main/ownerrefs-finalizers/vspherecluster-failuredomainselector.yaml @@ -0,0 +1,7 @@ +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: VSphereCluster +metadata: + name: ${CLUSTER_NAME} + namespace: ${NAMESPACE} +spec: + failureDomainSelector: {} \ No newline at end of file diff --git a/test/e2e/ownerrefs_finalizers_test.go b/test/e2e/ownerrefs_finalizers_test.go index 2e10cd7fc5..81d7acbb0e 100644 --- a/test/e2e/ownerrefs_finalizers_test.go +++ b/test/e2e/ownerrefs_finalizers_test.go @@ -48,6 +48,7 @@ import ( infrav1 "sigs.k8s.io/cluster-api-provider-vsphere/apis/v1beta1" vmwarev1 "sigs.k8s.io/cluster-api-provider-vsphere/apis/vmware/v1beta1" + topologyv1 "sigs.k8s.io/cluster-api-provider-vsphere/internal/apis/topology/v1alpha1" vcsimv1 "sigs.k8s.io/cluster-api-provider-vsphere/test/infrastructure/vcsim/api/v1alpha1" ) @@ -85,6 +86,13 @@ var _ = Describe("Ensure OwnerReferences and Finalizers are resilient [vcsim] [s } }, PostMachinesProvisioned: func(proxy framework.ClusterProxy, namespace, clusterName string) { + By("Checking that failure domains got added to the Cluster") + if testMode == GovmomiTestMode { + checkGovmomiVSphereClusterFailureDomains(ctx, proxy, namespace, clusterName) + } else { + checkSupervisorVSphereClusterFailureDomains(ctx, proxy, namespace, clusterName) + } + forceCtx, forceCancelFunc := context.WithCancel(ctx) if testMode == GovmomiTestMode { // check the cluster identity secret has expected ownerReferences and finalizers, and they are resilient @@ -358,6 +366,44 @@ func createVsphereIdentitySecret(ctx context.Context, bootstrapClusterProxy fram })).To(Succeed()) } +func checkGovmomiVSphereClusterFailureDomains(ctx context.Context, proxy framework.ClusterProxy, namespace, clusterName string) { + vSphereCluster := &infrav1.VSphereCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: clusterName, + }, + } + Expect(proxy.GetClient().Get(ctx, ctrlclient.ObjectKeyFromObject(vSphereCluster), vSphereCluster)).To(Succeed()) + + Expect(vSphereCluster.Status.FailureDomains).To(BeEquivalentTo(clusterv1.FailureDomains{ + "ownerrefs-finalizers": clusterv1.FailureDomainSpec{ + ControlPlane: true, + }, + })) +} + +func checkSupervisorVSphereClusterFailureDomains(ctx context.Context, proxy framework.ClusterProxy, namespace, clusterName string) { + avalabilityZones := &topologyv1.AvailabilityZoneList{} + Expect(proxy.GetClient().List(ctx, avalabilityZones)).To(Succeed()) + + wantFailureDomains := clusterv1.FailureDomains{} + for _, zone := range avalabilityZones.Items { + wantFailureDomains[zone.Name] = clusterv1.FailureDomainSpec{ + ControlPlane: true, + } + } + + vSphereCluster := &vmwarev1.VSphereCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: clusterName, + }, + } + Expect(proxy.GetClient().Get(ctx, ctrlclient.ObjectKeyFromObject(vSphereCluster), vSphereCluster)).To(Succeed()) + + Expect(vSphereCluster.Status.FailureDomains).To(BeEquivalentTo(wantFailureDomains)) +} + func checkClusterIdentitySecretOwnerRefAndFinalizer(ctx context.Context, c ctrlclient.Client) { s := &corev1.Secret{} diff --git a/test/infrastructure/vcsim/controllers/envvar_controller.go b/test/infrastructure/vcsim/controllers/envvar_controller.go index cbba5645b3..205f443300 100644 --- a/test/infrastructure/vcsim/controllers/envvar_controller.go +++ b/test/infrastructure/vcsim/controllers/envvar_controller.go @@ -288,6 +288,7 @@ func clusterEnvVarSpecGovmomiVariables(c *vcsimv1.ClusterEnvVarSpec) map[string] // NOTE: omitting cluster Name intentionally because E2E tests provide this value in other ways vars["VSPHERE_DATACENTER"] = vcsimhelpers.DatacenterName(datacenter) + vars["VSPHERE_COMPUTE_CLUSTER"] = vcsimhelpers.ClusterName(datacenter, cluster) vars["VSPHERE_DATASTORE"] = vcsimhelpers.DatastoreName(datastore) vars["VSPHERE_FOLDER"] = vcsimhelpers.VMFolderName(datacenter) vars["VSPHERE_NETWORK"] = vcsimhelpers.NetworkPath(datacenter, vcsimhelpers.DefaultNetworkName) diff --git a/test/infrastructure/vcsim/controllers/vcsim_controller.go b/test/infrastructure/vcsim/controllers/vcsim_controller.go index 34d80b95c6..db77df16d6 100644 --- a/test/infrastructure/vcsim/controllers/vcsim_controller.go +++ b/test/infrastructure/vcsim/controllers/vcsim_controller.go @@ -30,10 +30,14 @@ import ( _ "github.com/dougm/pretty" // NOTE: this is required to add commands vm.* to cli.Run "github.com/pkg/errors" "github.com/vmware/govmomi/govc/cli" - _ "github.com/vmware/govmomi/govc/vm" // NOTE: this is required to add commands vm.* to cli.Run + _ "github.com/vmware/govmomi/govc/tags" // NOTE: this is required to add commands tags.* to cli.Run + _ "github.com/vmware/govmomi/govc/tags/association" // NOTE: this is required to add commands tags.attach.* to cli.Run + _ "github.com/vmware/govmomi/govc/tags/category" // NOTE: this is required to add commands tags.category.* to cli.Run + _ "github.com/vmware/govmomi/govc/vm" // NOTE: this is required to add commands vm.* to cli.Run pbmsimulator "github.com/vmware/govmomi/pbm/simulator" "github.com/vmware/govmomi/simulator" _ "github.com/vmware/govmomi/vapi/simulator" // NOTE: this is required to content library & other vapi methods to the simulator + _ "github.com/vmware/govmomi/vapi/tags" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -189,6 +193,13 @@ func (r *VCenterSimulatorReconciler) reconcileNormal(ctx context.Context, vCente if err := createVMTemplates(ctx, vCenterSimulator); err != nil { return err } + + if !r.SupervisorMode { + // Create and attach tags for failure domain tests. + if err := createGovmomiFailureDomainTags(vCenterSimulator); err != nil { + return err + } + } } if vCenterSimulator.Status.Thumbprint == "" { @@ -256,6 +267,30 @@ func createVMTemplates(ctx context.Context, vCenterSimulator *vcsimv1.VCenterSim return nil } +func createGovmomiFailureDomainTags(vCenterSimulator *vcsimv1.VCenterSimulator) error { + govcURLArg := fmt.Sprintf("-u=https://%s:%s@%s/sdk", vCenterSimulator.Status.Username, vCenterSimulator.Status.Password, vCenterSimulator.Status.Host) + + datacenterName := vcsimhelpers.DatacenterName(0) + computeClusterName := vcsimhelpers.ClusterName(0, 0) + commands := [][]string{ + {"tags.category.create", "-k=true", govcURLArg, "-t=Datacenter", "k8s-region"}, + {"tags.category.create", "-k=true", govcURLArg, "k8s-zone"}, + {"tags.create", "-k=true", govcURLArg, "-c", "k8s-region", datacenterName}, + {"tags.create", "-k=true", govcURLArg, "-c", "k8s-zone", computeClusterName}, + {"tags.attach", "-k=true", govcURLArg, "-c", "k8s-region", datacenterName, "/" + datacenterName}, + {"tags.attach", "-k=true", govcURLArg, "-c", "k8s-zone", computeClusterName, "/" + datacenterName + "/host/" + computeClusterName}, + } + + for _, command := range commands { + exit := cli.Run(command) + if exit != 0 { + return fmt.Errorf("failed to run command: %s", strings.Join(command, " ")) + } + } + + return nil +} + func (r *VCenterSimulatorReconciler) reconcileDelete(ctx context.Context, vCenterSimulator *vcsimv1.VCenterSimulator) { log := ctrl.LoggerFrom(ctx) log.Info("Reconciling delete VCenter server")