diff --git a/api/v1alpha3/virtualmachine_types.go b/api/v1alpha3/virtualmachine_types.go index e6cd59ed9..c4aaa72d6 100644 --- a/api/v1alpha3/virtualmachine_types.go +++ b/api/v1alpha3/virtualmachine_types.go @@ -198,17 +198,25 @@ const ( // VMware vCenter (VC) that is managing this virtual machine. ManagerID = GroupName + "/manager-id" - // RegisteredVMAnnotation on a VirtualMachine represents that a virtual machine has - // been registered using the RegisterVM API after a restore, or a fail-over operation by - // a vendor. The presence of this annotation is used to bypass some validation checks - // that are otherwise applicable to all VirtualMachine create/update requests. - RegisteredVMAnnotation = GroupName + "/registered-vm" + // RestoredVMAnnotation on a VirtualMachine represents that a virtual + // machine has been restored using the RegisterVM API, typically by a + // VADP based data protection vendor. The presence of this annotation is + // used to bypass some validation checks that are otherwise + // applicable to all VirtualMachine create/update requests. + RestoredVMAnnotation = GroupName + "/restored-vm" // ImportedVMAnnotation on a VirtualMachine represents that a traditional virtual // machine has been imported into Supervisor using the ImportVM API. The presence of this // annotation is used to bypass some validation checks that are otherwise applicable // to all VirtualMachine create/update requests. ImportedVMAnnotation = GroupName + "/imported-vm" + + // FailedOverVMAnnotation on a VirtualMachine resource represents that a virtual + // machine has been failed over from one site to the other, typically as part of a + // disaster recovery workflow. The presence of this annotation is used to bypass + // some validation checks that are otherwise applicable to all VirtualMachine + // create/update requests. + FailedOverVMAnnotation = GroupName + "/failed-over-vm" ) const ( diff --git a/pkg/backup/api/backup_types.go b/pkg/backup/api/backup_types.go index 8e87dbf9f..19fe25672 100644 --- a/pkg/backup/api/backup_types.go +++ b/pkg/backup/api/backup_types.go @@ -108,20 +108,4 @@ const ( // specifying this key, backup/restore and/or disaster recovery solutions are // responsible to register the VM with Supervisor. DisableAutoRegistrationExtraConfigKey = "vmservice.virtualmachine.disableAutomaticRegistration" - - // TestFailoverLabelKey label signifies that a VirtualMachine is going through - // a test recovery plan scenario. Typically, this involves failing over a VM - // to a dedicated temporary network so as to not exhaust, and cause IP address - // collisions with the production network. This label on a VirtualMachine - // custom resource allows vendors to change the VM's network interface to - // connect to the test network after the VM is registered post a failover. - // - // VM operator does not support mutable networks, so this label allows only - // select vendors (e.g., SRM) to support recovery plan test workflows while we - // build support for true network mutability. - // - // The value of this label does not matter. Its presence is considered a - // sufficient evidence to indicate that the virtual machine is going through - // test fail-over. - TestFailoverLabelKey = "virtualmachine." + GroupName + "/test-failover" ) diff --git a/pkg/util/annotations/helpers.go b/pkg/util/annotations/helpers.go index 4079170dd..a03360850 100644 --- a/pkg/util/annotations/helpers.go +++ b/pkg/util/annotations/helpers.go @@ -9,8 +9,12 @@ import ( vmopv1 "github.com/vmware-tanzu/vm-operator/api/v1alpha3" ) -func HasRegisterVM(o metav1.Object) bool { - return hasAnnotation(o, vmopv1.RegisteredVMAnnotation) +func HasRestoredVM(o metav1.Object) bool { + return hasAnnotation(o, vmopv1.RestoredVMAnnotation) +} + +func HasFailOverVM(o metav1.Object) bool { + return hasAnnotation(o, vmopv1.FailedOverVMAnnotation) } func HasImportVM(o metav1.Object) bool { diff --git a/pkg/util/annotations/helpers_test.go b/pkg/util/annotations/helpers_test.go index 7ffe2ba8d..6c6565ddd 100644 --- a/pkg/util/annotations/helpers_test.go +++ b/pkg/util/annotations/helpers_test.go @@ -48,20 +48,20 @@ var _ = DescribeTable( ) var _ = DescribeTable( - "HasRegisterVM", + "HasRestoredVM", func(in map[string]string, out bool) { vm := &vmopv1.VirtualMachine{ ObjectMeta: metav1.ObjectMeta{ Annotations: in, }, } - actual := annotations.HasRegisterVM(vm) + actual := annotations.HasRestoredVM(vm) Expect(actual).To(Equal(out)) }, Entry("nil", nil, false), Entry("not present", map[string]string{"foo": "bar"}, false), - Entry("present but empty ", map[string]string{vmopv1.RegisteredVMAnnotation: ""}, true), - Entry("present and not empty ", map[string]string{vmopv1.RegisteredVMAnnotation: "true"}, true), + Entry("present but empty ", map[string]string{vmopv1.RestoredVMAnnotation: ""}, true), + Entry("present and not empty ", map[string]string{vmopv1.RestoredVMAnnotation: "true"}, true), ) var _ = DescribeTable( @@ -80,3 +80,20 @@ var _ = DescribeTable( Entry("present but empty ", map[string]string{vmopv1.ImportedVMAnnotation: ""}, true), Entry("present and not empty ", map[string]string{vmopv1.ImportedVMAnnotation: "true"}, true), ) + +var _ = DescribeTable( + "HasFailOverVM", + func(in map[string]string, out bool) { + vm := &vmopv1.VirtualMachine{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: in, + }, + } + actual := annotations.HasFailOverVM(vm) + Expect(actual).To(Equal(out)) + }, + Entry("nil", nil, false), + Entry("not present", map[string]string{"foo": "bar"}, false), + Entry("present but empty ", map[string]string{vmopv1.FailedOverVMAnnotation: ""}, true), + Entry("present and not empty ", map[string]string{vmopv1.FailedOverVMAnnotation: "true"}, true), +) diff --git a/webhooks/virtualmachine/validation/virtualmachine_validator.go b/webhooks/virtualmachine/validation/virtualmachine_validator.go index 7a6543d56..7610a75dd 100644 --- a/webhooks/virtualmachine/validation/virtualmachine_validator.go +++ b/webhooks/virtualmachine/validation/virtualmachine_validator.go @@ -33,7 +33,6 @@ import ( vmopv1 "github.com/vmware-tanzu/vm-operator/api/v1alpha3" "github.com/vmware-tanzu/vm-operator/api/v1alpha3/sysprep" - backupapi "github.com/vmware-tanzu/vm-operator/pkg/backup/api" "github.com/vmware-tanzu/vm-operator/pkg/builder" pkgcfg "github.com/vmware-tanzu/vm-operator/pkg/config" "github.com/vmware-tanzu/vm-operator/pkg/constants" @@ -154,13 +153,13 @@ func (v validator) ValidateDelete(*pkgctx.WebhookRequestContext) admission.Respo return admission.Allowed("") } -// Updates to VM's image are only allowed if it is a Registered VM (used for failover -// in disaster recovery). +// Updates to VM's image are only allowed if it is a failed over VM. func (v validator) validateImageOnUpdate(ctx *pkgctx.WebhookRequestContext, vm, oldVM *vmopv1.VirtualMachine) field.ErrorList { var allErrs field.ErrorList + // Allow resetting of image if this is a failover operation. if vmopv1util.IsImagelessVM(*vm) && pkgcfg.FromContext(ctx).Features.VMIncrementalRestore { - if annotations.HasRegisterVM(vm) { + if annotations.HasFailOverVM(vm) { if !vmopv1util.ImageRefsEqual(vm.Spec.Image, oldVM.Spec.Image) { if !ctx.IsPrivilegedAccount { allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "image"), restrictedToPrivUsers)) @@ -402,8 +401,8 @@ func (v validator) validateImageOnCreate(ctx *pkgctx.WebhookRequestContext, vm * (pkgcfg.FromContext(ctx).Features.VMImportNewNet || pkgcfg.FromContext(ctx).Features.VMIncrementalRestore): // TODO: Simplify this once mobility operator starts creating VMs with correct annotation. - // Skip validations on images if it is a VM created using ImportVM, or RegisterVM. - if annotations.HasImportVM(vm) || annotations.HasRegisterVM(vm) { + // Skip validations on images if it is a VM that is imported, registered, or failed over. + if annotations.HasImportVM(vm) || annotations.HasRestoredVM(vm) || annotations.HasFailOverVM(vm) { // Restrict creating imageless VM resources to privileged users. if !ctx.IsPrivilegedAccount { allErrs = append(allErrs, field.Forbidden(f, restrictedToPrivUsers)) @@ -1237,9 +1236,9 @@ func (v validator) validateImmutableNetwork(ctx *pkgctx.WebhookRequestContext, v return append(allErrs, field.Forbidden(p.Child("interfaces"), "network interfaces cannot be added or removed")) } - // Skip comparing interfaces if this is a test fail-over to allow vendors to - // connect network each interface to test network. - if _, ok := vm.Labels[backupapi.TestFailoverLabelKey]; ok { + // Skip comparing interfaces if this is a fail-over to allow vendors to + // connect network each interface to the test, or the production network. + if _, ok := vm.Annotations[vmopv1.FailedOverVMAnnotation]; ok { return allErrs } @@ -1337,8 +1336,12 @@ func (v validator) validateAnnotation(ctx *pkgctx.WebhookRequestContext, vm, old allErrs = append(allErrs, field.Forbidden(annotationPath.Key(vmopv1.FirstBootDoneAnnotation), modifyAnnotationNotAllowedForNonAdmin)) } - if vm.Annotations[vmopv1.RegisteredVMAnnotation] != oldVM.Annotations[vmopv1.RegisteredVMAnnotation] { - allErrs = append(allErrs, field.Forbidden(annotationPath.Key(vmopv1.RegisteredVMAnnotation), modifyAnnotationNotAllowedForNonAdmin)) + if vm.Annotations[vmopv1.RestoredVMAnnotation] != oldVM.Annotations[vmopv1.RestoredVMAnnotation] { + allErrs = append(allErrs, field.Forbidden(annotationPath.Key(vmopv1.RestoredVMAnnotation), modifyAnnotationNotAllowedForNonAdmin)) + } + + if vm.Annotations[vmopv1.FailedOverVMAnnotation] != oldVM.Annotations[vmopv1.FailedOverVMAnnotation] { + allErrs = append(allErrs, field.Forbidden(annotationPath.Key(vmopv1.FailedOverVMAnnotation), modifyAnnotationNotAllowedForNonAdmin)) } if vm.Annotations[vmopv1.ImportedVMAnnotation] != oldVM.Annotations[vmopv1.ImportedVMAnnotation] { diff --git a/webhooks/virtualmachine/validation/virtualmachine_validator_unit_test.go b/webhooks/virtualmachine/validation/virtualmachine_validator_unit_test.go index 4c8f9996f..570249c72 100644 --- a/webhooks/virtualmachine/validation/virtualmachine_validator_unit_test.go +++ b/webhooks/virtualmachine/validation/virtualmachine_validator_unit_test.go @@ -27,7 +27,6 @@ import ( "github.com/vmware-tanzu/vm-operator/api/v1alpha3/common" "github.com/vmware-tanzu/vm-operator/api/v1alpha3/sysprep" topologyv1 "github.com/vmware-tanzu/vm-operator/external/tanzu-topology/api/v1alpha1" - backupapi "github.com/vmware-tanzu/vm-operator/pkg/backup/api" pkgbuilder "github.com/vmware-tanzu/vm-operator/pkg/builder" pkgcfg "github.com/vmware-tanzu/vm-operator/pkg/config" "github.com/vmware-tanzu/vm-operator/pkg/constants" @@ -50,6 +49,7 @@ const ( dummyCreatedAtSchemaVersionVal = "dummy-created-at-schema-version" dummyRegisteredAnnVal = "dummy-registered-annotation" dummyImportedAnnVal = "dummy-imported-annotation" + dummyFailedOverAnnVal = "dummy-failedover-annotation" dummyPausedVMLabelVal = "dummy-devops" dummyVmiName = "vmi-dummy" dummyNamespaceName = "dummy-vm-namespace-for-webhook-validation" @@ -588,7 +588,7 @@ func unitTestsValidateCreate() { ctx.vm.Spec.ImageName = "" ctx.IsPrivilegedAccount = true ctx.vm.Annotations = map[string]string{ - vmopv1.RegisteredVMAnnotation: "", + vmopv1.RestoredVMAnnotation: "", } pkgcfg.SetContext(ctx, func(config *pkgcfg.Config) { config.Features.VMIncrementalRestore = true @@ -647,7 +647,7 @@ func unitTestsValidateCreate() { ctx.vm.Spec.ImageName = "" ctx.IsPrivilegedAccount = false ctx.vm.Annotations = map[string]string{ - vmopv1.RegisteredVMAnnotation: "", + vmopv1.RestoredVMAnnotation: "", } pkgcfg.SetContext(ctx, func(config *pkgcfg.Config) { config.Features.VMIncrementalRestore = true @@ -987,12 +987,14 @@ func unitTestsValidateCreate() { setup: func(ctx *unitValidatingWebhookContext) { ctx.vm.Annotations[vmopv1.InstanceIDAnnotation] = dummyInstanceIDVal ctx.vm.Annotations[vmopv1.FirstBootDoneAnnotation] = dummyFirstBootDoneVal - ctx.vm.Annotations[vmopv1.RegisteredVMAnnotation] = dummyFirstBootDoneVal - ctx.vm.Annotations[vmopv1.ImportedVMAnnotation] = dummyFirstBootDoneVal + ctx.vm.Annotations[vmopv1.RestoredVMAnnotation] = dummyRegisteredAnnVal + ctx.vm.Annotations[vmopv1.ImportedVMAnnotation] = dummyImportedAnnVal + ctx.vm.Annotations[vmopv1.FailedOverVMAnnotation] = dummyFailedOverAnnVal }, validate: doValidateWithMsg( - field.Forbidden(annotationPath.Key(vmopv1.RegisteredVMAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), + field.Forbidden(annotationPath.Key(vmopv1.RestoredVMAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), field.Forbidden(annotationPath.Key(vmopv1.ImportedVMAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), + field.Forbidden(annotationPath.Key(vmopv1.FailedOverVMAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), field.Forbidden(annotationPath.Key(vmopv1.InstanceIDAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), field.Forbidden(annotationPath.Key(vmopv1.FirstBootDoneAnnotation), "modifying this annotation is not allowed for non-admin users").Error()), }, @@ -1004,8 +1006,9 @@ func unitTestsValidateCreate() { ctx.vm.Annotations[vmopv1.InstanceIDAnnotation] = dummyInstanceIDVal ctx.vm.Annotations[vmopv1.FirstBootDoneAnnotation] = dummyFirstBootDoneVal - ctx.vm.Annotations[vmopv1.RegisteredVMAnnotation] = dummyFirstBootDoneVal - ctx.vm.Annotations[vmopv1.ImportedVMAnnotation] = dummyFirstBootDoneVal + ctx.vm.Annotations[vmopv1.RestoredVMAnnotation] = dummyRegisteredAnnVal + ctx.vm.Annotations[vmopv1.ImportedVMAnnotation] = dummyImportedAnnVal + ctx.vm.Annotations[vmopv1.FailedOverVMAnnotation] = dummyFailedOverAnnVal }, expectAllowed: true, }, @@ -1023,8 +1026,9 @@ func unitTestsValidateCreate() { ctx.vm.Annotations[vmopv1.InstanceIDAnnotation] = dummyInstanceIDVal ctx.vm.Annotations[vmopv1.FirstBootDoneAnnotation] = dummyFirstBootDoneVal - ctx.vm.Annotations[vmopv1.RegisteredVMAnnotation] = dummyFirstBootDoneVal - ctx.vm.Annotations[vmopv1.ImportedVMAnnotation] = dummyFirstBootDoneVal + ctx.vm.Annotations[vmopv1.RestoredVMAnnotation] = dummyRegisteredAnnVal + ctx.vm.Annotations[vmopv1.ImportedVMAnnotation] = dummyImportedAnnVal + ctx.vm.Annotations[vmopv1.FailedOverVMAnnotation] = dummyFailedOverAnnVal }, expectAllowed: true, }, @@ -2787,23 +2791,26 @@ func unitTestsValidateUpdate() { ctx.oldVM.Annotations[vmopv1.FirstBootDoneAnnotation] = dummyFirstBootDoneVal ctx.oldVM.Annotations[constants.CreatedAtBuildVersionAnnotationKey] = dummyCreatedAtBuildVersionVal ctx.oldVM.Annotations[constants.CreatedAtSchemaVersionAnnotationKey] = dummyCreatedAtSchemaVersionVal - ctx.oldVM.Annotations[vmopv1.RegisteredVMAnnotation] = dummyRegisteredAnnVal + ctx.oldVM.Annotations[vmopv1.RestoredVMAnnotation] = dummyRegisteredAnnVal ctx.oldVM.Annotations[vmopv1.ImportedVMAnnotation] = dummyImportedAnnVal + ctx.oldVM.Annotations[vmopv1.FailedOverVMAnnotation] = dummyFailedOverAnnVal ctx.vm.Annotations[vmopv1.InstanceIDAnnotation] = dummyInstanceIDVal + updateSuffix ctx.vm.Annotations[vmopv1.FirstBootDoneAnnotation] = dummyFirstBootDoneVal + updateSuffix ctx.vm.Annotations[constants.CreatedAtBuildVersionAnnotationKey] = dummyCreatedAtBuildVersionVal + updateSuffix ctx.vm.Annotations[constants.CreatedAtSchemaVersionAnnotationKey] = dummyCreatedAtSchemaVersionVal + updateSuffix - ctx.vm.Annotations[vmopv1.RegisteredVMAnnotation] = dummyRegisteredAnnVal + updateSuffix + ctx.vm.Annotations[vmopv1.RestoredVMAnnotation] = dummyRegisteredAnnVal + updateSuffix ctx.vm.Annotations[vmopv1.ImportedVMAnnotation] = dummyImportedAnnVal + updateSuffix + ctx.vm.Annotations[vmopv1.FailedOverVMAnnotation] = dummyFailedOverAnnVal + updateSuffix }, validate: doValidateWithMsg( field.Forbidden(annotationPath.Key(vmopv1.InstanceIDAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), field.Forbidden(annotationPath.Key(vmopv1.FirstBootDoneAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), field.Forbidden(annotationPath.Key(constants.CreatedAtBuildVersionAnnotationKey), "modifying this annotation is not allowed for non-admin users").Error(), field.Forbidden(annotationPath.Key(constants.CreatedAtSchemaVersionAnnotationKey), "modifying this annotation is not allowed for non-admin users").Error(), - field.Forbidden(annotationPath.Key(vmopv1.RegisteredVMAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), + field.Forbidden(annotationPath.Key(vmopv1.RestoredVMAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), field.Forbidden(annotationPath.Key(vmopv1.ImportedVMAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), + field.Forbidden(annotationPath.Key(vmopv1.FailedOverVMAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), ), }, ), @@ -2814,16 +2821,18 @@ func unitTestsValidateUpdate() { ctx.oldVM.Annotations[vmopv1.FirstBootDoneAnnotation] = dummyFirstBootDoneVal ctx.oldVM.Annotations[constants.CreatedAtBuildVersionAnnotationKey] = dummyCreatedAtBuildVersionVal ctx.oldVM.Annotations[constants.CreatedAtSchemaVersionAnnotationKey] = dummyCreatedAtSchemaVersionVal - ctx.oldVM.Annotations[vmopv1.RegisteredVMAnnotation] = dummyRegisteredAnnVal + ctx.oldVM.Annotations[vmopv1.RestoredVMAnnotation] = dummyRegisteredAnnVal ctx.oldVM.Annotations[vmopv1.ImportedVMAnnotation] = dummyImportedAnnVal + ctx.oldVM.Annotations[vmopv1.FailedOverVMAnnotation] = dummyFailedOverAnnVal }, validate: doValidateWithMsg( field.Forbidden(annotationPath.Key(vmopv1.InstanceIDAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), field.Forbidden(annotationPath.Key(vmopv1.FirstBootDoneAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), field.Forbidden(annotationPath.Key(constants.CreatedAtBuildVersionAnnotationKey), "modifying this annotation is not allowed for non-admin users").Error(), field.Forbidden(annotationPath.Key(constants.CreatedAtSchemaVersionAnnotationKey), "modifying this annotation is not allowed for non-admin users").Error(), - field.Forbidden(annotationPath.Key(vmopv1.RegisteredVMAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), + field.Forbidden(annotationPath.Key(vmopv1.RestoredVMAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), field.Forbidden(annotationPath.Key(vmopv1.ImportedVMAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), + field.Forbidden(annotationPath.Key(vmopv1.FailedOverVMAnnotation), "modifying this annotation is not allowed for non-admin users").Error(), ), }, ), @@ -2836,15 +2845,17 @@ func unitTestsValidateUpdate() { ctx.oldVM.Annotations[vmopv1.FirstBootDoneAnnotation] = dummyFirstBootDoneVal ctx.oldVM.Annotations[constants.CreatedAtBuildVersionAnnotationKey] = dummyCreatedAtBuildVersionVal ctx.oldVM.Annotations[constants.CreatedAtSchemaVersionAnnotationKey] = dummyCreatedAtSchemaVersionVal - ctx.oldVM.Annotations[vmopv1.RegisteredVMAnnotation] = dummyRegisteredAnnVal + ctx.oldVM.Annotations[vmopv1.RestoredVMAnnotation] = dummyRegisteredAnnVal ctx.oldVM.Annotations[vmopv1.ImportedVMAnnotation] = dummyImportedAnnVal + ctx.oldVM.Annotations[vmopv1.FailedOverVMAnnotation] = dummyFailedOverAnnVal ctx.vm.Annotations[vmopv1.InstanceIDAnnotation] = dummyInstanceIDVal + updateSuffix ctx.vm.Annotations[vmopv1.FirstBootDoneAnnotation] = dummyFirstBootDoneVal + updateSuffix ctx.vm.Annotations[constants.CreatedAtBuildVersionAnnotationKey] = dummyCreatedAtBuildVersionVal + updateSuffix ctx.vm.Annotations[constants.CreatedAtSchemaVersionAnnotationKey] = dummyCreatedAtSchemaVersionVal + updateSuffix - ctx.vm.Annotations[vmopv1.RegisteredVMAnnotation] = dummyRegisteredAnnVal + updateSuffix + ctx.vm.Annotations[vmopv1.RestoredVMAnnotation] = dummyRegisteredAnnVal + updateSuffix ctx.vm.Annotations[vmopv1.ImportedVMAnnotation] = dummyImportedAnnVal + updateSuffix + ctx.vm.Annotations[vmopv1.FailedOverVMAnnotation] = dummyFailedOverAnnVal + updateSuffix }, expectAllowed: true, }, @@ -2858,8 +2869,9 @@ func unitTestsValidateUpdate() { ctx.oldVM.Annotations[vmopv1.FirstBootDoneAnnotation] = dummyFirstBootDoneVal ctx.oldVM.Annotations[constants.CreatedAtBuildVersionAnnotationKey] = dummyCreatedAtBuildVersionVal ctx.oldVM.Annotations[constants.CreatedAtSchemaVersionAnnotationKey] = dummyCreatedAtSchemaVersionVal - ctx.oldVM.Annotations[vmopv1.RegisteredVMAnnotation] = dummyRegisteredAnnVal + ctx.oldVM.Annotations[vmopv1.RestoredVMAnnotation] = dummyRegisteredAnnVal ctx.oldVM.Annotations[vmopv1.ImportedVMAnnotation] = dummyImportedAnnVal + ctx.oldVM.Annotations[vmopv1.FailedOverVMAnnotation] = dummyFailedOverAnnVal }, expectAllowed: true, }, @@ -2881,15 +2893,17 @@ func unitTestsValidateUpdate() { ctx.oldVM.Annotations[vmopv1.FirstBootDoneAnnotation] = dummyFirstBootDoneVal ctx.oldVM.Annotations[constants.CreatedAtBuildVersionAnnotationKey] = dummyCreatedAtBuildVersionVal ctx.oldVM.Annotations[constants.CreatedAtSchemaVersionAnnotationKey] = dummyCreatedAtSchemaVersionVal - ctx.oldVM.Annotations[vmopv1.RegisteredVMAnnotation] = dummyRegisteredAnnVal + ctx.oldVM.Annotations[vmopv1.RestoredVMAnnotation] = dummyRegisteredAnnVal ctx.oldVM.Annotations[vmopv1.ImportedVMAnnotation] = dummyImportedAnnVal + ctx.oldVM.Annotations[vmopv1.FailedOverVMAnnotation] = dummyFailedOverAnnVal ctx.vm.Annotations[vmopv1.InstanceIDAnnotation] = dummyInstanceIDVal + updateSuffix ctx.vm.Annotations[vmopv1.FirstBootDoneAnnotation] = dummyFirstBootDoneVal + updateSuffix ctx.vm.Annotations[constants.CreatedAtBuildVersionAnnotationKey] = dummyCreatedAtBuildVersionVal + updateSuffix ctx.vm.Annotations[constants.CreatedAtSchemaVersionAnnotationKey] = dummyCreatedAtSchemaVersionVal + updateSuffix - ctx.vm.Annotations[vmopv1.RegisteredVMAnnotation] = dummyRegisteredAnnVal + updateSuffix + ctx.vm.Annotations[vmopv1.RestoredVMAnnotation] = dummyRegisteredAnnVal + updateSuffix ctx.vm.Annotations[vmopv1.ImportedVMAnnotation] = dummyImportedAnnVal + updateSuffix + ctx.vm.Annotations[vmopv1.FailedOverVMAnnotation] = dummyFailedOverAnnVal + updateSuffix }, expectAllowed: true, }, @@ -2911,8 +2925,9 @@ func unitTestsValidateUpdate() { ctx.oldVM.Annotations[vmopv1.FirstBootDoneAnnotation] = dummyFirstBootDoneVal ctx.oldVM.Annotations[constants.CreatedAtBuildVersionAnnotationKey] = dummyCreatedAtBuildVersionVal ctx.oldVM.Annotations[constants.CreatedAtSchemaVersionAnnotationKey] = dummyCreatedAtSchemaVersionVal - ctx.oldVM.Annotations[vmopv1.RegisteredVMAnnotation] = dummyRegisteredAnnVal + ctx.oldVM.Annotations[vmopv1.RestoredVMAnnotation] = dummyRegisteredAnnVal ctx.oldVM.Annotations[vmopv1.ImportedVMAnnotation] = dummyImportedAnnVal + ctx.oldVM.Annotations[vmopv1.FailedOverVMAnnotation] = dummyFailedOverAnnVal }, expectAllowed: true, }, @@ -3012,7 +3027,7 @@ func unitTestsValidateUpdate() { }, ), - Entry("forbid unset of imageName by unprivileged users if FSS_WCP_VMSERVICE_INCREMENTAL_RESTORE is enabled and registered annotation is present", + Entry("forbid unset of imageName by unprivileged users if FSS_WCP_VMSERVICE_INCREMENTAL_RESTORE is enabled and failover annotation is present", testParams{ setup: func(ctx *unitValidatingWebhookContext) { pkgcfg.SetContext(ctx, func(config *pkgcfg.Config) { @@ -3020,7 +3035,7 @@ func unitTestsValidateUpdate() { }) ctx.IsPrivilegedAccount = false ctx.oldVM.Annotations = map[string]string{ - vmopv1.RegisteredVMAnnotation: "foo", + vmopv1.FailedOverVMAnnotation: "foo", } ctx.oldVM.Spec.ImageName = dummyVmiName @@ -3033,7 +3048,7 @@ func unitTestsValidateUpdate() { }, ), - Entry("allow unset of imageName for privileged users when FSS_WCP_VMSERVICE_INCREMENTAL_RESTORE is enabled, and registered annotation is present", + Entry("allow unset of imageName for privileged users when FSS_WCP_VMSERVICE_INCREMENTAL_RESTORE is enabled, and failover annotation is present", testParams{ setup: func(ctx *unitValidatingWebhookContext) { pkgcfg.SetContext(ctx, func(config *pkgcfg.Config) { @@ -3044,7 +3059,7 @@ func unitTestsValidateUpdate() { ctx.oldVM.Spec.ImageName = dummyVmiName ctx.oldVM.Annotations = map[string]string{ - vmopv1.RegisteredVMAnnotation: "foo", + vmopv1.FailedOverVMAnnotation: "foo", } ctx.vm = ctx.oldVM.DeepCopy() ctx.vm.Spec.ImageName = "" @@ -3103,7 +3118,7 @@ func unitTestsValidateUpdate() { }, ), - Entry("forbid unset of image for privileged users when FSS_WCP_VMSERVICE_INCREMENTAL_RESTORE is enabled, but Registered annotation is not present", + Entry("forbid unset of image for privileged users when FSS_WCP_VMSERVICE_INCREMENTAL_RESTORE is enabled, but failover annotation is not present", testParams{ setup: func(ctx *unitValidatingWebhookContext) { pkgcfg.SetContext(ctx, func(config *pkgcfg.Config) { @@ -3124,7 +3139,7 @@ func unitTestsValidateUpdate() { }, ), - Entry("forbid unset of image by unprivileged users when FSS_WCP_VMSERVICE_INCREMENTAL_RESTORE is enabled and the Registered annotation is present", + Entry("forbid unset of image by unprivileged users when FSS_WCP_VMSERVICE_INCREMENTAL_RESTORE is enabled and the failover annotation is present", testParams{ setup: func(ctx *unitValidatingWebhookContext) { pkgcfg.SetContext(ctx, func(config *pkgcfg.Config) { @@ -3133,7 +3148,7 @@ func unitTestsValidateUpdate() { ctx.IsPrivilegedAccount = false ctx.oldVM.Annotations = map[string]string{ - vmopv1.RegisteredVMAnnotation: "bar", + vmopv1.FailedOverVMAnnotation: "bar", } ctx.oldVM.Spec.Image = &vmopv1.VirtualMachineImageRef{ @@ -3148,7 +3163,7 @@ func unitTestsValidateUpdate() { }, ), - Entry("alow changing image for privileged users when FSS_WCP_VMSERVICE_INCREMENTAL_RESTORE is enabled, and Registered annotation is present", + Entry("alow changing image for privileged users when FSS_WCP_VMSERVICE_INCREMENTAL_RESTORE is enabled, and failover annotation is present", testParams{ setup: func(ctx *unitValidatingWebhookContext) { pkgcfg.SetContext(ctx, func(config *pkgcfg.Config) { @@ -3157,7 +3172,7 @@ func unitTestsValidateUpdate() { ctx.IsPrivilegedAccount = true ctx.oldVM.Annotations = map[string]string{ - vmopv1.RegisteredVMAnnotation: "bar", + vmopv1.FailedOverVMAnnotation: "bar", } ctx.oldVM.Spec.Image = &vmopv1.VirtualMachineImageRef{ @@ -3329,13 +3344,13 @@ func unitTestsValidateUpdate() { }, ), - Entry("allow interface name change if VM has test failover label", + Entry("allow interface name change if VM has failover label", testParams{ setup: func(ctx *unitValidatingWebhookContext) { if ctx.oldVM.Labels == nil { ctx.oldVM.Labels = make(map[string]string) } - ctx.oldVM.Labels[backupapi.TestFailoverLabelKey] = "foo" + ctx.oldVM.Annotations[vmopv1.FailedOverVMAnnotation] = "foo" ctx.oldVM.Spec.Network = &vmopv1.VirtualMachineNetworkSpec{ Interfaces: []vmopv1.VirtualMachineNetworkInterfaceSpec{ @@ -3351,13 +3366,13 @@ func unitTestsValidateUpdate() { expectAllowed: true, }, ), - Entry("allow changing network interface network if VM has test failover label", + Entry("allow changing network interface network if VM has failover label", testParams{ setup: func(ctx *unitValidatingWebhookContext) { if ctx.oldVM.Labels == nil { ctx.oldVM.Labels = make(map[string]string) } - ctx.oldVM.Labels[backupapi.TestFailoverLabelKey] = "foo" + ctx.oldVM.Annotations[vmopv1.FailedOverVMAnnotation] = "foo" ctx.oldVM.Spec.Network = &vmopv1.VirtualMachineNetworkSpec{ Interfaces: []vmopv1.VirtualMachineNetworkInterfaceSpec{