From 20d2a9f5f3d61a17298bbe3eda82f8a6a52a84dd Mon Sep 17 00:00:00 2001 From: ziyeqf Date: Mon, 27 Feb 2023 18:15:31 +0800 Subject: [PATCH 01/13] New Resource: `azurerm_site_recovery_hyperv_replicated_vm` --- .../recoveryservices/client/client.go | 6 + internal/services/recoveryservices/helpers.go | 26 + .../services/recoveryservices/registration.go | 1 + ..._recovery_hyperv_replicated_vm_resource.go | 948 ++++++++++++++++++ ...very_hyperv_replicated_vm_resource_test.go | 271 +++++ ...replication_policy_association_resource.go | 25 +- .../replicationprotectableitems/README.md | 53 + .../replicationprotectableitems/client.go | 18 + .../replicationprotectableitems/constants.go | 65 ++ .../id_replicationprotectableitem.go | 163 +++ .../id_replicationprotectioncontainer.go | 150 +++ .../method_get_autorest.go | 68 ++ ...eplicationprotectioncontainers_autorest.go | 220 ++++ .../model_configurationsettings.go | 64 ++ .../model_diskdetails.go | 11 + .../model_diskvolumedetails.go | 9 + .../model_healtherror.go | 40 + .../model_hypervvirtualmachinedetails.go | 48 + .../model_inmagediskdetails.go | 13 + .../model_innerhealtherror.go | 39 + .../model_osdetails.go | 13 + .../model_protectableitem.go | 12 + .../model_protectableitemproperties.go | 50 + .../model_replicationgroupdetails.go | 40 + .../model_vmmvirtualmachinedetails.go | 48 + .../model_vmwarevirtualmachinedetails.go | 50 + .../replicationprotectableitems/predicates.go | 29 + .../replicationprotectableitems/version.go | 12 + vendor/modules.txt | 1 + ...ecovery_hyperv_replicated_vm.html.markdown | 193 ++++ 30 files changed, 2662 insertions(+), 24 deletions(-) create mode 100644 internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go create mode 100644 internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/README.md create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/client.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/constants.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectableitem.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectioncontainer.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_get_autorest.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_listbyreplicationprotectioncontainers_autorest.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_configurationsettings.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_diskdetails.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_diskvolumedetails.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_healtherror.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_hypervvirtualmachinedetails.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_inmagediskdetails.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_innerhealtherror.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_osdetails.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_protectableitem.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_protectableitemproperties.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_replicationgroupdetails.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_vmmvirtualmachinedetails.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_vmwarevirtualmachinedetails.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/predicates.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/version.go create mode 100644 website/docs/r/site_recovery_hyperv_replicated_vm.html.markdown diff --git a/internal/services/recoveryservices/client/client.go b/internal/services/recoveryservices/client/client.go index ab87ef287ff3..fd25c6322aee 100644 --- a/internal/services/recoveryservices/client/client.go +++ b/internal/services/recoveryservices/client/client.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationfabrics" "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationnetworkmappings" "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationpolicies" + "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems" "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotecteditems" "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectioncontainermappings" "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectioncontainers" @@ -38,6 +39,7 @@ type Client struct { ReplicationPoliciesClient *replicationpolicies.ReplicationPoliciesClient ContainerMappingClient *replicationprotectioncontainermappings.ReplicationProtectionContainerMappingsClient NetworkMappingClient *replicationnetworkmappings.ReplicationNetworkMappingsClient + ReplicationProtectableItemsClient *replicationprotectableitems.ReplicationProtectableItemsClient ReplicationProtectedItemsClient *replicationprotecteditems.ReplicationProtectedItemsClient ReplicationRecoveryPlansClient *replicationrecoveryplans.ReplicationRecoveryPlansClient } @@ -97,6 +99,9 @@ func NewClient(o *common.ClientOptions) *Client { networkMappingClient := replicationnetworkmappings.NewReplicationNetworkMappingsClientWithBaseURI(o.ResourceManagerEndpoint) o.ConfigureClient(&networkMappingClient.Client, o.ResourceManagerAuthorizer) + replicationProtectableItemsCLient := replicationprotectableitems.NewReplicationProtectableItemsClientWithBaseURI(o.ResourceManagerEndpoint) + o.ConfigureClient(&replicationProtectableItemsCLient.Client, o.ResourceManagerAuthorizer) + replicationMigrationItemsClient := replicationprotecteditems.NewReplicationProtectedItemsClientWithBaseURI(o.ResourceManagerEndpoint) o.ConfigureClient(&replicationMigrationItemsClient.Client, o.ResourceManagerAuthorizer) @@ -122,6 +127,7 @@ func NewClient(o *common.ClientOptions) *Client { ReplicationPoliciesClient: &replicationPoliciesClient, ContainerMappingClient: &containerMappingClient, NetworkMappingClient: &networkMappingClient, + ReplicationProtectableItemsClient: &replicationProtectableItemsCLient, ReplicationProtectedItemsClient: &replicationMigrationItemsClient, ReplicationRecoveryPlansClient: &replicationRecoveryPlanClient, } diff --git a/internal/services/recoveryservices/helpers.go b/internal/services/recoveryservices/helpers.go index 63d53ac995a5..56f0248a5255 100644 --- a/internal/services/recoveryservices/helpers.go +++ b/internal/services/recoveryservices/helpers.go @@ -1,12 +1,16 @@ package recoveryservices import ( + "context" + "fmt" "net/http" "strings" "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/azure" "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationfabrics" + "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectioncontainers" ) // This code is a workaround for this bug https://github.com/Azure/azure-sdk-for-go/issues/2824 @@ -36,3 +40,25 @@ func wasBadRequestWithNotExist(resp *http.Response, err error) bool { return response.WasBadRequest(resp) && sc == "SubscriptionIdNotRegisteredWithSrs" } + +func fetchHyperVContainerIdByFabricId(ctx context.Context, containerClient *replicationprotectioncontainers.ReplicationProtectionContainersClient, fabricId replicationfabrics.ReplicationFabricId) (string, error) { + id, err := replicationprotectioncontainers.ParseReplicationFabricID(fabricId.ID()) + if err != nil { + return "", fmt.Errorf("parsing %s: %+v", fabricId.ID(), err) + } + + resp, err := containerClient.ListByReplicationFabricsComplete(ctx, *id) + if err != nil { + return "", fmt.Errorf("listing containers: %+v", err) + } + + if len(resp.Items) == 0 || len(resp.Items) > 1 { + return "", fmt.Errorf("expected one container but got %d", len(resp.Items)) + } + + if resp.Items[0].Id == nil { + return "", fmt.Errorf("container id is nil") + } + + return handleAzureSdkForGoBug2824(*resp.Items[0].Id), nil +} diff --git a/internal/services/recoveryservices/registration.go b/internal/services/recoveryservices/registration.go index 740d27571ce9..b455747b3545 100644 --- a/internal/services/recoveryservices/registration.go +++ b/internal/services/recoveryservices/registration.go @@ -29,6 +29,7 @@ func (r Registration) Resources() []sdk.Resource { ReplicationPolicyHyperVResource{}, HyperVSiteResource{}, HyperVReplicationPolicyAssociationResource{}, + SiteRecoveryHyperVReplicatedVMResource{}, } } diff --git a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go new file mode 100644 index 000000000000..3daac2f93302 --- /dev/null +++ b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go @@ -0,0 +1,948 @@ +package recoveryservices + +import ( + "context" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-sdk/resource-manager/compute/2021-11-01/availabilitysets" + "github.com/hashicorp/go-azure-sdk/resource-manager/compute/2022-03-01/proximityplacementgroups" + "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationfabrics" + "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationpolicies" + "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems" + "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotecteditems" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-azurerm/helpers/azure" + "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/compute/validate" + storageValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" + "github.com/hashicorp/terraform-provider-azurerm/internal/tags" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/suppress" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +const ( + // tracdked on https://github.com/Azure/azure-rest-api-specs/issues/22798 + enableRDPNever = "Never" + enableRdpOnlyOnTestFailOver = "OnlyOnTestFailover" + enableRdpAlways = "Always" +) + +type SiteRecoveryHyperVReplicatedVMModel struct { + Name string `tfschema:"name"` + HyperVSiteId string `tfschema:"hyperv_site_id"` + SourceVMName string `tfschema:"source_vm_name"` + TargetResourceGroupId string `tfschema:"target_resource_group_id"` + TargetVMName string `tfschema:"target_vm_name"` + PolicyId string `tfschema:"replication_policy_id"` + OsType string `tfschema:"os_type"` + OSDiskName string `tfschema:"os_disk_name"` + DiskNamesToInclude []string `tfschema:"disk_to_include"` + TargetStorageAccountId string `tfschema:"target_storage_account_id"` + TargetNetworkId string `tfschema:"target_network_id"` + TargetAvailabilityZone string `tfschema:"target_availability_zone"` + NetworkInterface []SiteRecoveryHyperVReplicatedVMNetworkInterfaceModel `tfschema:"network_interface"` + UseManagedDiskEnabled bool `tfschema:"use_managed_disk_enabled"` + ManagedDisks []SiteRecoveryHyperVReplicatedVMManagedDiskModel `tfschema:"managed_disk"` + EnableRdpOnTargetOption string `tfschema:"enable_rdp_or_ssh_on_target_option"` + LicenseType string `tfschema:"license_type"` + SqlServerLicenseType string `tfschema:"sql_server_license_type"` + TargetAvailabilitySetId string `tfschema:"target_availability_set_id"` + TargetManagedDiskTags map[string]string `tfschema:"target_disk_tags"` + TargetNicTags map[string]string `tfschema:"target_nic_tags"` + TargetProximityPlacementGroupId string `tfschema:"target_proximity_placement_group_id"` + TargetVMSize string `tfschema:"target_vm_size"` + TargetVMTags map[string]string `tfschema:"target_vm_tags"` + LogStorageAccountId string `tfschema:"log_storage_account_id"` +} + +type SiteRecoveryHyperVReplicatedVMNetworkInterfaceModel struct { + NetworkName string `tfschema:"network_name"` + TargetSubnetName string `tfschema:"target_subnet_name"` + TargetStaticIp string `tfschema:"target_static_ip"` + IsPrimary bool `tfschema:"is_primary"` + FailoverEnabled bool `tfschema:"failover_enabled"` +} + +type SiteRecoveryHyperVReplicatedVMManagedDiskModel struct { + DiskName string `tfschema:"disk_name"` + DiskEncryptionSetId string `tfschema:"target_disk_encryption_set_id"` + DiskType string `tfschema:"target_disk_type"` +} + +type SiteRecoveryHyperVReplicatedVMResource struct{} + +var _ sdk.Resource = SiteRecoveryHyperVReplicatedVMResource{} + +func (s SiteRecoveryHyperVReplicatedVMResource) Arguments() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "hyperv_site_id": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: replicationfabrics.ValidateReplicationFabricID, + }, + + "source_vm_name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "target_resource_group_id": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + DiffSuppressFunc: suppress.CaseDifference, + }, + + "target_vm_name": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "target_storage_account_id": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "replication_policy_id": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: replicationpolicies.ValidateReplicationPolicyID, + }, + + "os_type": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + "Linux", + "Windows", + }, false), + }, + + "os_disk_name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "disks_to_include": { + Type: pluginsdk.TypeList, + Optional: true, + ForceNew: true, + ConflictsWith: []string{"use_managed_disk_enabled", "managed_disk"}, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "use_managed_disk_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + ForceNew: true, + }, + + "managed_disk": { + Type: pluginsdk.TypeSet, + ConfigMode: pluginsdk.SchemaConfigModeAttr, + Optional: true, + ForceNew: true, + RequiredWith: []string{"use_managed_disk_enabled"}, + Set: resourceSiteRecoveryReplicatedVMDiskHash, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "disk_name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + "target_disk_encryption_set_id": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validate.DiskEncryptionSetID, + }, + "target_disk_type": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(replicationprotecteditems.DiskAccountTypePremiumLRS), + string(replicationprotecteditems.DiskAccountTypeStandardLRS), + string(replicationprotecteditems.DiskAccountTypeStandardSSDLRS), + }, false), + }, + }, + }, + }, + + "log_storage_account_id": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: storageValidate.StorageAccountID, + DiffSuppressFunc: suppress.CaseDifference, + }, + + "enable_rdp_or_ssh_on_target_option": { + Type: pluginsdk.TypeString, + Optional: true, + Default: enableRDPNever, + ValidateFunc: validation.StringInSlice([]string{ + enableRDPNever, + enableRdpOnlyOnTestFailOver, + enableRdpAlways}, + false), + }, + + "target_network_id": { + Type: pluginsdk.TypeString, + Required: true, // if no target_network_id interface set, the update request will fail. + ValidateFunc: azure.ValidateResourceID, + }, + + "network_interface": { + Type: pluginsdk.TypeSet, // use set to avoid diff caused by different orders. + ConfigMode: pluginsdk.SchemaConfigModeAttr, + Required: true, // if no network interface set, the update request will fail. + Elem: hyperVNetworkInterfaceResource(), + }, + + "target_vm_size": { + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + }, + + "target_availability_zone": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + ConflictsWith: []string{ + "target_availability_set_id", + }, + }, + + "license_type": { + Type: pluginsdk.TypeString, + Optional: true, + Default: replicationprotecteditems.LicenseTypeNotSpecified, + ValidateFunc: validation.StringInSlice([]string{ + string(replicationprotecteditems.LicenseTypeNotSpecified), + string(replicationprotecteditems.LicenseTypeNoLicenseType), + string(replicationprotecteditems.LicenseTypeWindowsServer), + }, false), + }, + + "sql_server_license_type": { + Type: pluginsdk.TypeString, + Optional: true, + Default: replicationprotecteditems.SqlServerLicenseTypeNotSpecified, + ValidateFunc: validation.StringInSlice([]string{ + string(replicationprotecteditems.SqlServerLicenseTypeNotSpecified), + string(replicationprotecteditems.SqlServerLicenseTypeNoLicenseType), + string(replicationprotecteditems.SqlServerLicenseTypePAYG), + string(replicationprotecteditems.SqlServerLicenseTypeAHUB), + }, false), + }, + + "target_availability_set_id": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: availabilitysets.ValidateAvailabilitySetID, + DiffSuppressFunc: suppress.CaseDifference, + ConflictsWith: []string{"target_availability_zone"}, + }, + + "target_proximity_placement_group_id": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: proximityplacementgroups.ValidateProximityPlacementGroupID, + }, + + "target_vm_tags": tags.Schema(), + + "target_disk_tags": { + Type: pluginsdk.TypeMap, + Optional: true, + ValidateFunc: tags.Validate, + RequiredWith: []string{"use_managed_disk_enabled"}, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "target_network_interface_tags": tags.Schema(), + } +} + +func hyperVNetworkInterfaceResource() *pluginsdk.Resource { + return &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "network_name": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "target_static_ip": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "target_subnet_name": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "is_primary": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, + }, + + "failover_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, + }, + }, + } +} + +func (s SiteRecoveryHyperVReplicatedVMResource) Attributes() map[string]*schema.Schema { + return map[string]*schema.Schema{} +} + +func (s SiteRecoveryHyperVReplicatedVMResource) ModelObject() interface{} { + return &SiteRecoveryHyperVReplicatedVMModel{} +} + +func (s SiteRecoveryHyperVReplicatedVMResource) ResourceType() string { + return "azurerm_site_recovery_hyperv_replicated_vm" +} + +func (s SiteRecoveryHyperVReplicatedVMResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return replicationprotecteditems.ValidateReplicationProtectedItemID +} + +func (s SiteRecoveryHyperVReplicatedVMResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 180 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + var plan SiteRecoveryHyperVReplicatedVMModel + if err := metadata.Decode(&plan); err != nil { + return fmt.Errorf("decoding %+v", err) + } + + client := metadata.Client.RecoveryServices.ReplicationProtectedItemsClient + + parsedFabricID, err := replicationfabrics.ParseReplicationFabricID(plan.HyperVSiteId) + if err != nil { + return fmt.Errorf("parsing %s: %+v", plan.HyperVSiteId, err) + } + containerId, err := fetchHyperVContainerIdByFabricId(ctx, metadata.Client.RecoveryServices.ProtectionContainerClient, *parsedFabricID) + if err != nil { + return fmt.Errorf("fetching HyperV Container Name by Fabric Id %s: %+v", plan.HyperVSiteId, err) + } + + parsedContainerId, err := replicationprotecteditems.ParseReplicationProtectionContainerID(containerId) + if err != nil { + return fmt.Errorf("parsing %s: %+v", containerId, err) + } + + id := replicationprotecteditems.NewReplicationProtectedItemID(parsedContainerId.SubscriptionId, parsedContainerId.ResourceGroupName, parsedContainerId.VaultName, parsedContainerId.ReplicationFabricName, parsedContainerId.ReplicationProtectionContainerName, plan.Name) + + protectableItem, err := fetchProtectableItemByVMName(ctx, metadata.Client.RecoveryServices.ReplicationProtectableItemsClient, containerId, plan.SourceVMName) + if err != nil { + return fmt.Errorf("fetching Protectable Item by VM Name %s: %+v", plan.SourceVMName, err) + } + + if protectableItem.Properties == nil { + return fmt.Errorf("retrieving properties for Protectable Item %q: Properties were nil", plan.SourceVMName) + } + + customDetail, ok := protectableItem.Properties.CustomDetails.(replicationprotectableitems.HyperVVirtualMachineDetails) + if !ok { + return fmt.Errorf("retrieving properties for Protectable Item %q: type mismatch", plan.SourceVMName) + } + + osVHDId := "" + diskIdsToInclude := make([]string, 0) + var diskToIncludeForManagedDisks []replicationprotecteditems.HyperVReplicaAzureDiskInputDetails + if plan.UseManagedDiskEnabled { + for _, disk := range plan.ManagedDisks { + diskId := "" + for _, d := range *customDetail.DiskDetails { + if *d.VhdName == disk.DiskName { + diskId = *d.VhdId + break + } + } + if diskId == "" { + return fmt.Errorf("disk %s not found in protectable item", disk.DiskName) + } + diskType := replicationprotecteditems.DiskAccountType(disk.DiskType) + diskToIncludeForManagedDisks = append(diskToIncludeForManagedDisks, replicationprotecteditems.HyperVReplicaAzureDiskInputDetails{ + DiskId: &diskId, + DiskEncryptionSetId: &disk.DiskEncryptionSetId, + DiskType: &diskType, + }) + } + } else { + for _, disk := range *customDetail.DiskDetails { + if *disk.VhdName == plan.OSDiskName { + osVHDId = *disk.VhdId + } + if utils.SliceContainsValue(plan.DiskNamesToInclude, *disk.VhdName) { + diskIdsToInclude = append(diskIdsToInclude, *disk.VhdId) + } + } + } + + licenseType := replicationprotecteditems.LicenseType(plan.LicenseType) + sqlLicenseType := replicationprotecteditems.SqlServerLicenseType(plan.SqlServerLicenseType) + input := replicationprotecteditems.EnableProtectionInput{ + Properties: &replicationprotecteditems.EnableProtectionInputProperties{ + PolicyId: &plan.PolicyId, + ProtectableItemId: protectableItem.Id, + ProviderSpecificDetails: &replicationprotecteditems.HyperVReplicaAzureEnableProtectionInput{ + OsType: &plan.OsType, + TargetAzureVMName: &plan.TargetVMName, + VhdId: &osVHDId, + DisksToInclude: &diskIdsToInclude, + TargetAzureV2ResourceGroupId: &plan.TargetResourceGroupId, + TargetAvailabilityZone: &plan.TargetAvailabilityZone, + TargetStorageAccountId: &plan.TargetStorageAccountId, + TargetAvailabilitySetId: &plan.TargetAvailabilitySetId, + UseManagedDisks: utils.String(strconv.FormatBool(plan.UseManagedDiskEnabled)), + TargetManagedDiskTags: &plan.TargetManagedDiskTags, + TargetVMTags: &plan.TargetVMTags, + TargetVMSize: &plan.TargetVMSize, + DisksToIncludeForManagedDisks: &diskToIncludeForManagedDisks, + EnableRdpOnTargetOption: &plan.EnableRdpOnTargetOption, + LicenseType: &licenseType, + SqlServerLicenseType: &sqlLicenseType, + LogStorageAccountId: &plan.LogStorageAccountId, + }, + }, + } + + err = client.CreateThenPoll(ctx, id, input) + if err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + metadata.SetID(id) + + err = hyperVReplicatedVMWaitForFullyProtected(ctx, metadata) + if err != nil { + return fmt.Errorf("waiting for %s to be fully protected: %+v", id, err) + } + + return HyperVReplicatedVMUpdateInternal(ctx, metadata) + }, + } +} + +func (s SiteRecoveryHyperVReplicatedVMResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.RecoveryServices.ReplicationProtectedItemsClient + + id, err := replicationprotecteditems.ParseReplicationProtectedItemID(metadata.ResourceData.Id()) + if err != nil { + return fmt.Errorf("parsing %s: %+v", metadata.ResourceData.Id(), err) + } + + resp, err := client.Get(ctx, *id) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { + return metadata.MarkAsGone(id) + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + + hyperVSiteId := replicationfabrics.NewReplicationFabricID(id.SubscriptionId, id.ResourceGroupName, id.VaultName, id.ReplicationFabricName) + + state := SiteRecoveryHyperVReplicatedVMModel{ + Name: id.ReplicationProtectedItemName, + HyperVSiteId: hyperVSiteId.ID(), + } + + if model := resp.Model; model != nil { + if prop := model.Properties; prop != nil { + if prop.ProtectableItemId != nil { + state.SourceVMName, err = fetchVMNameByProtectableItemId(ctx, metadata.Client.RecoveryServices.ReplicationProtectableItemsClient, *prop.ProtectableItemId) + if err != nil { + return fmt.Errorf("fetching VM Name by Protectable Item Id %s: %+v", *prop.ProtectableItemId, err) + } + } + + if prop.PolicyId != nil { + state.PolicyId = *prop.PolicyId + } + + if prop.ProviderSpecificDetails != nil { + if detail, ok := prop.ProviderSpecificDetails.(replicationprotecteditems.HyperVReplicaAzureReplicationDetails); ok { + if detail.RecoveryAzureResourceGroupId != nil { + state.TargetResourceGroupId = *detail.RecoveryAzureResourceGroupId + } + if detail.RecoveryAzureVMName != nil { + state.TargetVMName = *detail.RecoveryAzureVMName + } + if detail.SelectedRecoveryAzureNetworkId != nil { + state.TargetNetworkId = *detail.SelectedRecoveryAzureNetworkId + } + if detail.TargetAvailabilityZone != nil { + state.TargetAvailabilityZone = *detail.TargetAvailabilityZone + } + if detail.RecoveryAzureStorageAccount != nil { + state.TargetStorageAccountId = *detail.RecoveryAzureStorageAccount + } + if detail.OSDetails != nil && detail.OSDetails.OsType != nil { + state.OsType = *detail.OSDetails.OsType + } + if detail.AzureVMDiskDetails != nil { + var diskNames []string + for _, disk := range *detail.AzureVMDiskDetails { + if disk.VhdName != nil { + diskNames = append(diskNames, *disk.VhdName) + } + if disk.VhdType != nil && strings.EqualFold(*disk.VhdType, "OperatingSystem") { + state.OSDiskName = *disk.VhdName + } + } + + state.DiskNamesToInclude = diskNames + } + if detail.RecoveryAzureStorageAccount != nil { + state.TargetStorageAccountId = *detail.RecoveryAzureStorageAccount + } + if detail.SelectedRecoveryAzureNetworkId != nil { + state.TargetNetworkId = *detail.SelectedRecoveryAzureNetworkId + } + if detail.TargetAvailabilityZone != nil { + state.TargetAvailabilityZone = *detail.TargetAvailabilityZone + } + if detail.VMNics != nil { + var outputs []SiteRecoveryHyperVReplicatedVMNetworkInterfaceModel + primaryNicId := "" + if detail.SelectedSourceNicId != nil { + primaryNicId = *detail.SelectedSourceNicId + } + for _, nic := range *detail.VMNics { + o := SiteRecoveryHyperVReplicatedVMNetworkInterfaceModel{} + if nic.VMNetworkName != nil { + o.NetworkName = *nic.VMNetworkName + } + if nic.IPConfigs != nil && len(*nic.IPConfigs) == 1 { // it's only support to set one Ipconfig for now. + ip := (*nic.IPConfigs)[0] + if ip.RecoverySubnetName != nil { + o.TargetSubnetName = *ip.RecoverySubnetName + } + if ip.RecoveryStaticIPAddress != nil { + o.TargetStaticIp = *ip.RecoveryStaticIPAddress + } + } + if nic.SelectionType != nil { + o.FailoverEnabled = strings.EqualFold(*nic.SelectionType, "NotSelected") + } + if nic.NicId != nil && *nic.NicId == primaryNicId { + o.IsPrimary = true + } + outputs = append(outputs, o) + } + state.NetworkInterface = outputs + } + if detail.UseManagedDisks != nil { + state.UseManagedDiskEnabled, err = strconv.ParseBool(*detail.UseManagedDisks) + if err != nil { + return fmt.Errorf("parsing `use_managed_disk_enabled` %s: %+v", *detail.UseManagedDisks, err) + } + } + + if detail.ProtectedManagedDisks != nil { + diskIdToNameMap, _, err := fetchProtectableDiskNameIdMap(ctx, metadata.Client.RecoveryServices.ReplicationProtectableItemsClient, *prop.ProtectableItemId) + if err != nil { + return fmt.Errorf("fetching Disk Name to Id Map by Protectable Item Id %s: %+v", *prop.ProtectableItemId, err) + } + var outputs []SiteRecoveryHyperVReplicatedVMManagedDiskModel + for _, disk := range *detail.ProtectedManagedDisks { + o := SiteRecoveryHyperVReplicatedVMManagedDiskModel{} + if disk.DiskEncryptionSetId != nil { + o.DiskEncryptionSetId = *disk.DiskEncryptionSetId + } + if disk.ReplicaDiskType != nil { + o.DiskType = *disk.ReplicaDiskType + } + if v, existing := diskIdToNameMap[*disk.DiskId]; existing { + o.DiskName = v + } + } + state.ManagedDisks = outputs + } + if detail.EnableRdpOnTargetOption != nil { + state.EnableRdpOnTargetOption = *detail.EnableRdpOnTargetOption + } + if detail.LicenseType != nil { + state.LicenseType = *detail.LicenseType + } + if detail.SqlServerLicenseType != nil { + state.SqlServerLicenseType = *detail.SqlServerLicenseType + } + if detail.RecoveryAvailabilitySetId != nil { + state.TargetAvailabilitySetId = *detail.RecoveryAvailabilitySetId + } + if detail.TargetManagedDiskTags != nil { + state.TargetManagedDiskTags = *detail.TargetManagedDiskTags + } + if detail.TargetProximityPlacementGroupId != nil { + state.TargetProximityPlacementGroupId = *detail.TargetProximityPlacementGroupId + } + if detail.TargetVMTags != nil { + state.TargetVMTags = *detail.TargetVMTags + } + if detail.RecoveryAzureLogStorageAccountId != nil { + state.LogStorageAccountId = *detail.RecoveryAzureLogStorageAccountId + } + if detail.RecoveryAzureVMSize != nil { + state.TargetVMSize = *detail.RecoveryAzureVMSize + } + } + } + } + } + + return metadata.Encode(&state) + }, + } +} + +func (s SiteRecoveryHyperVReplicatedVMResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 80 * time.Minute, + Func: HyperVReplicatedVMUpdateInternal, + } +} + +func (s SiteRecoveryHyperVReplicatedVMResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 80 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.RecoveryServices.ReplicationProtectedItemsClient + + id, err := replicationprotecteditems.ParseReplicationProtectedItemID(metadata.ResourceData.Id()) + if err != nil { + return fmt.Errorf("parsing %s: %+v", metadata.ResourceData.Id(), err) + } + + err = client.DeleteThenPoll(ctx, *id, replicationprotecteditems.DisableProtectionInput{}) + if err != nil { + return fmt.Errorf("deleting %s: %+v", id, err) + } + + return nil + }, + } +} + +func fetchProtectableItemByVMName(ctx context.Context, client *replicationprotectableitems.ReplicationProtectableItemsClient, containerId string, vmName string) (*replicationprotectableitems.ProtectableItem, error) { + parsedContainerId, err := replicationprotectableitems.ParseReplicationProtectionContainerID(containerId) + if err != nil { + return nil, fmt.Errorf("parsing %s: %+v", containerId, err) + } + + protectableItems, err := client.ListByReplicationProtectionContainers(ctx, *parsedContainerId, replicationprotectableitems.DefaultListByReplicationProtectionContainersOperationOptions()) + if err != nil { + return nil, fmt.Errorf("listing protectable items by container %s: %+v", containerId, err) + } + + if protectableItems.Model == nil { + return nil, fmt.Errorf("listing protectable items by container: %s is nil", containerId) + } + + for _, v := range *protectableItems.Model { + if v.Properties != nil && v.Properties.FriendlyName != nil && *v.Properties.FriendlyName == vmName { + return &v, nil + } + } + + return nil, fmt.Errorf("protectable item with vm name %s not found", vmName) +} + +func fetchProtectableDiskNameIdMap(ctx context.Context, client *replicationprotectableitems.ReplicationProtectableItemsClient, protectableItemId string) (idToName map[string]string, nameToId map[string]string, err error) { + idToName = make(map[string]string) + nameToId = make(map[string]string) + protectableItem, err := fetchProtectableItemById(ctx, client, protectableItemId) + if err != nil { + return idToName, nameToId, fmt.Errorf("retrieving %s: %+v", protectableItemId, err) + } + + if protectableItem.Properties != nil && protectableItem.Properties.CustomDetails != nil { + if customDetail, ok := protectableItem.Properties.CustomDetails.(replicationprotectableitems.HyperVVirtualMachineDetails); ok { + if customDetail.DiskDetails != nil { + for _, disk := range *customDetail.DiskDetails { + if disk.VhdName != nil && disk.VhdId != nil { + nameToId[*disk.VhdName] = *disk.VhdId + idToName[*disk.VhdId] = *disk.VhdName + } + } + } + } + } + + return idToName, nameToId, nil +} + +func fetchVMNameByProtectableItemId(ctx context.Context, client *replicationprotectableitems.ReplicationProtectableItemsClient, protectableItemId string) (string, error) { + protectableItem, err := fetchProtectableItemById(ctx, client, protectableItemId) + if err != nil { + return "", fmt.Errorf("retrieving %s: %+v", protectableItemId, err) + } + + if protectableItem != nil && protectableItem.Properties != nil && protectableItem.Properties.FriendlyName != nil { + return *protectableItem.Properties.FriendlyName, nil + } + + return "", fmt.Errorf("retrieving %s: properties were nil", protectableItemId) +} + +func fetchProtectableItemById(ctx context.Context, client *replicationprotectableitems.ReplicationProtectableItemsClient, protectableItemId string) (*replicationprotectableitems.ProtectableItem, error) { + parsedProtectableItemId, err := replicationprotectableitems.ParseReplicationProtectableItemID(handleAzureSdkForGoBug2824(protectableItemId)) + if err != nil { + return nil, fmt.Errorf("parsing %s: %+v", protectableItemId, err) + } + + protectableItem, err := client.Get(ctx, *parsedProtectableItemId) + if err != nil { + return nil, fmt.Errorf("retrieving %s: %+v", protectableItemId, err) + } + + if protectableItem.Model != nil { + return protectableItem.Model, nil + } + + return nil, fmt.Errorf("retrieving %s: properties were nil", protectableItemId) +} + +func HyperVReplicatedVMUpdateInternal(ctx context.Context, metadata sdk.ResourceMetaData) error { + var plan SiteRecoveryHyperVReplicatedVMModel + if err := metadata.Decode(&plan); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + client := metadata.Client.RecoveryServices.ReplicationProtectedItemsClient + + id, err := replicationprotecteditems.ParseReplicationProtectedItemID(metadata.ResourceData.Id()) + if err != nil { + return fmt.Errorf("parsing %s: %+v", metadata.ResourceData.Id(), err) + } + + existing, err := client.Get(ctx, *id) + if err != nil { + if response.WasNotFound(existing.HttpResponse) { + return metadata.MarkAsGone(id) + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + if existing.Model == nil { + return fmt.Errorf("retrieving %s: Model was nil", id) + } + + if existing.Model.Properties == nil || existing.Model.Properties.ProviderSpecificDetails == nil { + return fmt.Errorf("retrieving %s: Properties or ProviderSpecificDetails was nil", id) + } + + detail, ok := existing.Model.Properties.ProviderSpecificDetails.(replicationprotecteditems.HyperVReplicaAzureReplicationDetails) + if !ok { + return fmt.Errorf("retrieving %s: ProviderSpecificDetails was not HyperVReplicaAzureReplicationDetails", id) + } + + if detail.SelectedSourceNicId == nil { + return fmt.Errorf("retrieving %s: SelectedSourceNicId was nil", id) + } + + primaryNicId := *detail.SelectedSourceNicId + vmNics := make([]replicationprotecteditems.VMNicInputDetails, 0) + for _, nic := range plan.NetworkInterface { + nicId, err := HyperVReplicatedVMFindNicId(*existing.Model, nic.NetworkName) + if err != nil { + return fmt.Errorf("finding nic id: %+v", err) + } + + if nic.IsPrimary { + if primaryNicId != "" { + return fmt.Errorf("only one nic can be primary") + } + primaryNicId = nicId + } + + selectType := "NotSelected" + if nic.FailoverEnabled { + selectType = "SelectedByUser" + } + + vmNics = append(vmNics, replicationprotecteditems.VMNicInputDetails{ + NicId: &nicId, + SelectionType: &selectType, + IPConfigs: &[]replicationprotecteditems.IPConfigInputDetails{ + { + RecoverySubnetName: &nic.TargetSubnetName, + RecoveryStaticIPAddress: &nic.TargetStaticIp, + // per Portal behaviour, these two property are always set to true. + // Primary Nic is selected by `selectedSourceNicId` parameter. + // Whether to create nic for failover is controled by `selectionType` + IsPrimary: utils.Bool(true), + IsSeletedForFailover: utils.Bool(true), + }, + }, + }) + } + + if existing.Model.Properties == nil || existing.Model.Properties.ProtectableItemId == nil { + return fmt.Errorf("retrieving %s: properties or protectableItemId was nil", id) + } + _, diskNameToIdMap, err := fetchProtectableDiskNameIdMap(ctx, metadata.Client.RecoveryServices.ReplicationProtectableItemsClient, *existing.Model.Properties.ProtectableItemId) + diskIdToDiskEncryptionMap := make(map[string]string, 0) + for _, disk := range plan.ManagedDisks { + vhdId := diskNameToIdMap[disk.DiskName] + diskIdToDiskEncryptionMap[vhdId] = disk.DiskEncryptionSetId + } + licenseType := replicationprotecteditems.LicenseType(plan.LicenseType) + sqlServerLicenseType := replicationprotecteditems.SqlServerLicenseType(plan.SqlServerLicenseType) + input := replicationprotecteditems.UpdateReplicationProtectedItemInput{ + Properties: &replicationprotecteditems.UpdateReplicationProtectedItemInputProperties{ + EnableRdpOnTargetOption: &plan.EnableRdpOnTargetOption, + LicenseType: &licenseType, + RecoveryAvailabilitySetId: &plan.TargetAvailabilitySetId, + RecoveryAzureVMName: &plan.TargetVMName, + SelectedRecoveryAzureNetworkId: &plan.TargetNetworkId, + VMNics: &vmNics, + SelectedSourceNicId: &primaryNicId, + ProviderSpecificDetails: replicationprotecteditems.HyperVReplicaAzureUpdateReplicationProtectedItemInput{ + RecoveryAzureV2ResourceGroupId: &plan.TargetResourceGroupId, + SqlServerLicenseType: &sqlServerLicenseType, + TargetAvailabilityZone: &plan.TargetAvailabilityZone, + TargetManagedDiskTags: &plan.TargetManagedDiskTags, + TargetNicTags: &plan.TargetNicTags, + TargetProximityPlacementGroupId: &plan.TargetProximityPlacementGroupId, + TargetVMTags: &plan.TargetVMTags, + DiskIdToDiskEncryptionMap: &diskIdToDiskEncryptionMap, + }, + }, + } + + if err := client.UpdateThenPoll(ctx, *id, input); err != nil { + return fmt.Errorf("updating %s: %+v", id, err) + } + + return nil +} + +func HyperVReplicatedVMFindNicId(protectedItem replicationprotecteditems.ReplicationProtectedItem, networkName string) (string, error) { + if protectedItem.Properties == nil { + return "", fmt.Errorf("properties were nil") + } + if protectedItem.Properties.ProviderSpecificDetails == nil { + return "", fmt.Errorf("provider specific details were nil") + } + detail, ok := protectedItem.Properties.ProviderSpecificDetails.(replicationprotecteditems.HyperVReplicaAzureReplicationDetails) + if !ok { + return "", fmt.Errorf("not a HyperVReplicaAzureReplicationDetails") + } + if detail.VMNics == nil { + return "", fmt.Errorf("vm nics were nil") + } + for _, nic := range *detail.VMNics { + if *nic.VMNetworkName == networkName { + return *nic.NicId, nil + } + } + return "", fmt.Errorf("nic with network name %s not found", networkName) +} + +func hyperVReplicatedVMWaitForFullyProtected(ctx context.Context, metadata sdk.ResourceMetaData) error { + stateConf := &pluginsdk.StateChangeConf{ + Target: []string{"Protected"}, + Refresh: hyperVWaitForReplicationToBeHealthyRefreshFunc(ctx, metadata), + PollInterval: time.Minute, + } + + deadline, ok := ctx.Deadline() + if !ok { + return fmt.Errorf("context had no deadline") + } + stateConf.Timeout = time.Until(deadline) + + _, err := stateConf.WaitForStateContext(ctx) + if err != nil { + return err + } + + return nil +} + +func hyperVWaitForReplicationToBeHealthyRefreshFunc(ctx context.Context, metadata sdk.ResourceMetaData) pluginsdk.StateRefreshFunc { + return func() (interface{}, string, error) { + id, err := replicationprotecteditems.ParseReplicationProtectedItemID(metadata.ResourceData.Id()) + if err != nil { + return nil, "", err + } + + client := metadata.Client.RecoveryServices.ReplicationProtectedItemsClient + + resp, err := client.Get(ctx, *id) + if err != nil { + return nil, "", fmt.Errorf("making Read request on site recovery replicated vm %s : %+v", id.String(), err) + } + + if resp.Model == nil { + return nil, "", fmt.Errorf("Missing Model in response when making Read request on site recovery replicated vm %s %+v", id.String(), err) + } + + if resp.Model.Properties == nil { + return nil, "", fmt.Errorf("Missing Properties in response when making Read request on site recovery replicated vm %s %+v", id.String(), err) + } + + if resp.Model.Properties.ProviderSpecificDetails == nil { + return nil, "", fmt.Errorf("Missing Properties.ProviderSpecificDetails in response when making Read request on site recovery replicated vm %s : %+v", id.String(), err) + } + + if detail, isH2A := resp.Model.Properties.ProviderSpecificDetails.(replicationprotecteditems.HyperVReplicaAzureReplicationDetails); isH2A { + if detail.VMProtectionState != nil { + return *resp.Model, *detail.VMProtectionState, nil + } + } + + if resp.Model.Properties.ReplicationHealth == nil { + return nil, "", fmt.Errorf("missing ReplicationHealth in response when making Read request on site recovery replicated vm %s : %+v", id.String(), err) + } + return *resp.Model, *resp.Model.Properties.ReplicationHealth, nil + } +} diff --git a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go new file mode 100644 index 000000000000..e0087fe558d5 --- /dev/null +++ b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go @@ -0,0 +1,271 @@ +package recoveryservices_test + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotecteditems" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +type SiteRecoveryHyperVReplicatedVMResource struct{} + +func TestAccSiteRecoveryHyperVReplicatedVM_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_site_recovery_hyperv_replicated_vm", "test") + r := SiteRecoveryHyperVReplicatedVMResource{} + hostResource := HyperVHostTestResource{} + adminPwd := GenerateRandomPassword(10) + + data.ResourceTest(t, r, append(hostResource.PrepareHostTestSteps(data, adminPwd), []acceptance.TestStep{ + { + PreConfig: func() { time.Sleep(5 * time.Minute) }, // sleep 5 minutes to wait for the host registration fully finished. + Config: r.basic(data, adminPwd), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }...)) +} + +func TestAccSiteRecoveryHyperVReplicatedVM_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_site_recovery_hyperv_replicated_vm", "test") + r := SiteRecoveryHyperVReplicatedVMResource{} + hostResource := HyperVHostTestResource{} + adminPwd := GenerateRandomPassword(10) + + data.ResourceTest(t, r, append(hostResource.PrepareHostTestSteps(data, adminPwd), []acceptance.TestStep{ + { + Config: r.complete(data, adminPwd), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }...)) +} + +func (SiteRecoveryHyperVReplicatedVMResource) basic(data acceptance.TestData, adminPwd string) string { + return fmt.Sprintf(` +%s + +resource "azurerm_resource_group" "target" { + name = "acctest-hyperv-target-%[2]d" + location = "%[3]s" +} + +resource "azurerm_storage_account" "target" { + name = "accttarget%[4]s" + resource_group_name = azurerm_resource_group.target.name + location = azurerm_resource_group.target.location + account_tier = "Standard" + account_kind = "StorageV2" + account_replication_type = "LRS" +} + +resource "azurerm_virtual_network" "target" { + name = "net-%[2]d" + resource_group_name = azurerm_resource_group.target.name + address_space = ["192.168.2.0/24"] + location = azurerm_resource_group.target.location +} + +resource "azurerm_subnet" "target" { + name = "snet-%[2]d" + resource_group_name = azurerm_resource_group.target.name + virtual_network_name = azurerm_virtual_network.target.name + address_prefixes = ["192.168.2.0/24"] +} + +resource "azurerm_site_recovery_hyperv_replicated_vm" "test" { + name = "acctest-vm-%[2]d" + hyperv_site_id = azurerm_site_recovery_services_vault_hyperv_site.test.id + source_vm_name = "VM1" + target_resource_group_id = azurerm_resource_group.target.id + target_vm_name = "target-vm" + target_storage_account_id = azurerm_storage_account.target.id + replication_policy_id = azurerm_site_recovery_hyperv_replication_policy.test.id + os_type = "Windows" + os_disk_name = "VM1" + target_network_id = azurerm_virtual_network.target.id + disks_to_include = ["VM1"] + + network_interface { + network_name = "HyperV-NAT" + target_subnet_name = azurerm_subnet.target.name + } +} +`, SiteRecoverHyperVReplicationPolicyAssociationResource{}.basic(data, adminPwd), data.RandomInteger, data.Locations.Primary, data.RandomString) +} + +func (SiteRecoveryHyperVReplicatedVMResource) complete(data acceptance.TestData, adminPwd string) string { + return fmt.Sprintf(` +%s + +resource "azurerm_resource_group" "target" { + name = "acctest-hyperv-target-%[2]d" + location = "%[3]s" +} + +resource "azurerm_storage_account" "target" { + name = "accttarget%[4]s" + resource_group_name = azurerm_resource_group.target.name + location = azurerm_resource_group.target.location + account_tier = "Standard" + account_kind = "StorageV2" + account_replication_type = "LRS" +} + +resource "azurerm_virtual_network" "target" { + name = "net-%[2]d" + resource_group_name = azurerm_resource_group.target.name + address_space = ["192.168.2.0/24"] + location = azurerm_resource_group.target.location +} + +resource "azurerm_subnet" "target" { + name = "snet-%[2]d" + resource_group_name = azurerm_resource_group.target.name + virtual_network_name = azurerm_virtual_network.target.name + address_prefixes = ["192.168.2.0/24"] +} + +resource "azurerm_key_vault" "target" { + name = "kv%[2]d" + location = azurerm_resource_group.target.location + resource_group_name = azurerm_resource_group.target.name + tenant_id = data.azurerm_client_config.current.tenant_id + sku_name = "standard" + enabled_for_disk_encryption = true + purge_protection_enabled = true +} + +resource "azurerm_key_vault_access_policy" "service-principal" { + key_vault_id = azurerm_key_vault.target.id + tenant_id = data.azurerm_client_config.current.tenant_id + object_id = data.azurerm_client_config.current.object_id + + key_permissions = [ + "Create", + "Delete", + "Get", + "Purge", + "Update", + ] + + secret_permissions = [ + "Get", + "Delete", + "Set", + ] +} + +resource "azurerm_key_vault_key" "target" { + name = "examplekey" + key_vault_id = azurerm_key_vault.target.id + key_type = "RSA" + key_size = 2048 + + key_opts = [ + "decrypt", + "encrypt", + "sign", + "unwrapKey", + "verify", + "wrapKey", + ] + + depends_on = ["azurerm_key_vault_access_policy.service-principal"] +} + +resource "azurerm_disk_encryption_set" "target" { + name = "acctestdes-%[2]d2" + resource_group_name = azurerm_resource_group.target.name + location = azurerm_resource_group.target.location + key_vault_key_id = azurerm_key_vault_key.target.id + + identity { + type = "SystemAssigned" + } +} + +resource "azurerm_key_vault_access_policy" "disk-encryption" { + key_vault_id = azurerm_key_vault.target.id + + key_permissions = [ + "Get", + "WrapKey", + "UnwrapKey", + ] + + tenant_id = azurerm_disk_encryption_set.target.identity.0.tenant_id + object_id = azurerm_disk_encryption_set.target.identity.0.principal_id +} + +resource "azurerm_proximity_placement_group" "target" { + name = "acctest-replication-%[2]d" + location = azurerm_resource_group.target.location + resource_group_name = azurerm_resource_group.target.name +} + +resource "azurerm_site_recovery_hyperv_replicated_vm" "test" { + name = "acctest-vm-%[2]d" + hyperv_site_id = azurerm_site_recovery_services_vault_hyperv_site.test.id + source_vm_name = "VM1" + target_resource_group_id = azurerm_resource_group.target.id + target_vm_name = "target-vm" + target_storage_account_id = azurerm_storage_account.target.id + replication_policy_id = azurerm_site_recovery_hyperv_replication_policy.test.id + os_type = "Windows" + os_disk_name = "VM1" + target_network_id = azurerm_virtual_network.target.id + use_managed_disk_enabled = true + managed_disk { + disk_name = "VM1" + target_disk_encryption_set_id = azurerm_disk_encryption_set.target.id + target_disk_type = "Standard_LRS" + } + log_storage_account_id = azurerm_storage_account.target.id + enable_rdp_or_ssh_on_target_option = "Always" + network_interface { + network_name = "HyperV-NAT" + target_static_ip = "10.0.10.5" + target_subnet_name = azurerm_subnet.target.name + is_primary = true + failover_enabled = true + } + license_type = "WindowsServer" + sql_server_license_type = "PAYG" + target_proximity_placement_group_id = azurerm_proximity_placement_group.target.id + target_vm_tags = { + tag = "foo" + } + target_disk_tags = { + tag = "foo" + } + target_network_interface_tags = { + tag = "foo" + } +} +`, SiteRecoverHyperVReplicationPolicyAssociationResource{}.basic(data, adminPwd), data.RandomInteger, data.Locations.Primary, data.RandomString) +} + +func (t SiteRecoveryHyperVReplicatedVMResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { + id, err := replicationprotecteditems.ParseReplicationProtectedItemID(state.ID) + if err != nil { + return nil, err + } + + resp, err := clients.RecoveryServices.ReplicationProtectedItemsClient.Get(ctx, *id) + if err != nil { + return nil, fmt.Errorf("reading site recovery replicated vm (%s): %+v", id.String(), err) + } + + return utils.Bool(resp.Model != nil), nil +} diff --git a/internal/services/recoveryservices/site_recovery_hyperv_replication_policy_association_resource.go b/internal/services/recoveryservices/site_recovery_hyperv_replication_policy_association_resource.go index 7ae2ab644f3e..70fb872c2d2b 100644 --- a/internal/services/recoveryservices/site_recovery_hyperv_replication_policy_association_resource.go +++ b/internal/services/recoveryservices/site_recovery_hyperv_replication_policy_association_resource.go @@ -9,7 +9,6 @@ import ( "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationfabrics" "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationpolicies" "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectioncontainermappings" - "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectioncontainers" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" @@ -88,7 +87,7 @@ func (h HyperVReplicationPolicyAssociationResource) Create() sdk.ResourceFunc { client := metadata.Client.RecoveryServices.ContainerMappingClient subscriptionId := metadata.Client.Account.SubscriptionId - containerId, err := fetchHyperVReplicationPolicyAssociationContainerNameByHostName(ctx, metadata.Client.RecoveryServices.ProtectionContainerClient, *parsedFabricId) + containerId, err := fetchHyperVContainerIdByFabricId(ctx, metadata.Client.RecoveryServices.ProtectionContainerClient, *parsedFabricId) if err != nil { return fmt.Errorf("fetching container id: %+v", err) } @@ -180,25 +179,3 @@ func (h HyperVReplicationPolicyAssociationResource) Delete() sdk.ResourceFunc { }, } } - -func fetchHyperVReplicationPolicyAssociationContainerNameByHostName(ctx context.Context, containerClient *replicationprotectioncontainers.ReplicationProtectionContainersClient, fabricId replicationfabrics.ReplicationFabricId) (string, error) { - id, err := replicationprotectioncontainers.ParseReplicationFabricID(fabricId.ID()) - if err != nil { - return "", fmt.Errorf("parsing %s: %+v", fabricId.ID(), err) - } - - resp, err := containerClient.ListByReplicationFabricsComplete(ctx, *id) - if err != nil { - return "", fmt.Errorf("listing containers: %+v", err) - } - - if len(resp.Items) == 0 || len(resp.Items) > 1 { - return "", fmt.Errorf("expected one container but got %d", len(resp.Items)) - } - - if resp.Items[0].Id == nil { - return "", fmt.Errorf("container id is nil") - } - - return handleAzureSdkForGoBug2824(*resp.Items[0].Id), nil -} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/README.md b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/README.md new file mode 100644 index 000000000000..cb5b55687b0b --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/README.md @@ -0,0 +1,53 @@ + +## `github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems` Documentation + +The `replicationprotectableitems` SDK allows for interaction with the Azure Resource Manager Service `recoveryservicessiterecovery` (API Version `2022-10-01`). + +This readme covers example usages, but further information on [using this SDK can be found in the project root](https://github.com/hashicorp/go-azure-sdk/tree/main/docs). + +### Import Path + +```go +import "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems" +``` + + +### Client Initialization + +```go +client := replicationprotectableitems.NewReplicationProtectableItemsClientWithBaseURI("https://management.azure.com") +client.Client.Authorizer = authorizer +``` + + +### Example Usage: `ReplicationProtectableItemsClient.Get` + +```go +ctx := context.TODO() +id := replicationprotectableitems.NewReplicationProtectableItemID("12345678-1234-9876-4563-123456789012", "example-resource-group", "vaultValue", "replicationFabricValue", "replicationProtectionContainerValue", "replicationProtectableItemValue") + +read, err := client.Get(ctx, id) +if err != nil { + // handle the error +} +if model := read.Model; model != nil { + // do something with the model/response object +} +``` + + +### Example Usage: `ReplicationProtectableItemsClient.ListByReplicationProtectionContainers` + +```go +ctx := context.TODO() +id := replicationprotectableitems.NewReplicationProtectionContainerID("12345678-1234-9876-4563-123456789012", "example-resource-group", "vaultValue", "replicationFabricValue", "replicationProtectionContainerValue") + +// alternatively `client.ListByReplicationProtectionContainers(ctx, id, replicationprotectableitems.DefaultListByReplicationProtectionContainersOperationOptions())` can be used to do batched pagination +items, err := client.ListByReplicationProtectionContainersComplete(ctx, id, replicationprotectableitems.DefaultListByReplicationProtectionContainersOperationOptions()) +if err != nil { + // handle the error +} +for _, item := range items { + // do something +} +``` diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/client.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/client.go new file mode 100644 index 000000000000..cd1356d41c0a --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/client.go @@ -0,0 +1,18 @@ +package replicationprotectableitems + +import "github.com/Azure/go-autorest/autorest" + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ReplicationProtectableItemsClient struct { + Client autorest.Client + baseUri string +} + +func NewReplicationProtectableItemsClientWithBaseURI(endpoint string) ReplicationProtectableItemsClient { + return ReplicationProtectableItemsClient{ + Client: autorest.NewClientWithUserAgent(userAgent()), + baseUri: endpoint, + } +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/constants.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/constants.go new file mode 100644 index 000000000000..7ae2eaa30c8b --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/constants.go @@ -0,0 +1,65 @@ +package replicationprotectableitems + +import "strings" + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type HealthErrorCustomerResolvability string + +const ( + HealthErrorCustomerResolvabilityAllowed HealthErrorCustomerResolvability = "Allowed" + HealthErrorCustomerResolvabilityNotAllowed HealthErrorCustomerResolvability = "NotAllowed" +) + +func PossibleValuesForHealthErrorCustomerResolvability() []string { + return []string{ + string(HealthErrorCustomerResolvabilityAllowed), + string(HealthErrorCustomerResolvabilityNotAllowed), + } +} + +func parseHealthErrorCustomerResolvability(input string) (*HealthErrorCustomerResolvability, error) { + vals := map[string]HealthErrorCustomerResolvability{ + "allowed": HealthErrorCustomerResolvabilityAllowed, + "notallowed": HealthErrorCustomerResolvabilityNotAllowed, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := HealthErrorCustomerResolvability(input) + return &out, nil +} + +type PresenceStatus string + +const ( + PresenceStatusNotPresent PresenceStatus = "NotPresent" + PresenceStatusPresent PresenceStatus = "Present" + PresenceStatusUnknown PresenceStatus = "Unknown" +) + +func PossibleValuesForPresenceStatus() []string { + return []string{ + string(PresenceStatusNotPresent), + string(PresenceStatusPresent), + string(PresenceStatusUnknown), + } +} + +func parsePresenceStatus(input string) (*PresenceStatus, error) { + vals := map[string]PresenceStatus{ + "notpresent": PresenceStatusNotPresent, + "present": PresenceStatusPresent, + "unknown": PresenceStatusUnknown, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := PresenceStatus(input) + return &out, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectableitem.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectableitem.go new file mode 100644 index 000000000000..f68e86b4ae67 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectableitem.go @@ -0,0 +1,163 @@ +package replicationprotectableitems + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +var _ resourceids.ResourceId = ReplicationProtectableItemId{} + +// ReplicationProtectableItemId is a struct representing the Resource ID for a Replication Protectable Item +type ReplicationProtectableItemId struct { + SubscriptionId string + ResourceGroupName string + VaultName string + ReplicationFabricName string + ReplicationProtectionContainerName string + ReplicationProtectableItemName string +} + +// NewReplicationProtectableItemID returns a new ReplicationProtectableItemId struct +func NewReplicationProtectableItemID(subscriptionId string, resourceGroupName string, vaultName string, replicationFabricName string, replicationProtectionContainerName string, replicationProtectableItemName string) ReplicationProtectableItemId { + return ReplicationProtectableItemId{ + SubscriptionId: subscriptionId, + ResourceGroupName: resourceGroupName, + VaultName: vaultName, + ReplicationFabricName: replicationFabricName, + ReplicationProtectionContainerName: replicationProtectionContainerName, + ReplicationProtectableItemName: replicationProtectableItemName, + } +} + +// ParseReplicationProtectableItemID parses 'input' into a ReplicationProtectableItemId +func ParseReplicationProtectableItemID(input string) (*ReplicationProtectableItemId, error) { + parser := resourceids.NewParserFromResourceIdType(ReplicationProtectableItemId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := ReplicationProtectableItemId{} + + if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { + return nil, fmt.Errorf("the segment 'subscriptionId' was not found in the resource id %q", input) + } + + if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { + return nil, fmt.Errorf("the segment 'resourceGroupName' was not found in the resource id %q", input) + } + + if id.VaultName, ok = parsed.Parsed["vaultName"]; !ok { + return nil, fmt.Errorf("the segment 'vaultName' was not found in the resource id %q", input) + } + + if id.ReplicationFabricName, ok = parsed.Parsed["replicationFabricName"]; !ok { + return nil, fmt.Errorf("the segment 'replicationFabricName' was not found in the resource id %q", input) + } + + if id.ReplicationProtectionContainerName, ok = parsed.Parsed["replicationProtectionContainerName"]; !ok { + return nil, fmt.Errorf("the segment 'replicationProtectionContainerName' was not found in the resource id %q", input) + } + + if id.ReplicationProtectableItemName, ok = parsed.Parsed["replicationProtectableItemName"]; !ok { + return nil, fmt.Errorf("the segment 'replicationProtectableItemName' was not found in the resource id %q", input) + } + + return &id, nil +} + +// ParseReplicationProtectableItemIDInsensitively parses 'input' case-insensitively into a ReplicationProtectableItemId +// note: this method should only be used for API response data and not user input +func ParseReplicationProtectableItemIDInsensitively(input string) (*ReplicationProtectableItemId, error) { + parser := resourceids.NewParserFromResourceIdType(ReplicationProtectableItemId{}) + parsed, err := parser.Parse(input, true) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := ReplicationProtectableItemId{} + + if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { + return nil, fmt.Errorf("the segment 'subscriptionId' was not found in the resource id %q", input) + } + + if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { + return nil, fmt.Errorf("the segment 'resourceGroupName' was not found in the resource id %q", input) + } + + if id.VaultName, ok = parsed.Parsed["vaultName"]; !ok { + return nil, fmt.Errorf("the segment 'vaultName' was not found in the resource id %q", input) + } + + if id.ReplicationFabricName, ok = parsed.Parsed["replicationFabricName"]; !ok { + return nil, fmt.Errorf("the segment 'replicationFabricName' was not found in the resource id %q", input) + } + + if id.ReplicationProtectionContainerName, ok = parsed.Parsed["replicationProtectionContainerName"]; !ok { + return nil, fmt.Errorf("the segment 'replicationProtectionContainerName' was not found in the resource id %q", input) + } + + if id.ReplicationProtectableItemName, ok = parsed.Parsed["replicationProtectableItemName"]; !ok { + return nil, fmt.Errorf("the segment 'replicationProtectableItemName' was not found in the resource id %q", input) + } + + return &id, nil +} + +// ValidateReplicationProtectableItemID checks that 'input' can be parsed as a Replication Protectable Item ID +func ValidateReplicationProtectableItemID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if _, err := ParseReplicationProtectableItemID(v); err != nil { + errors = append(errors, err) + } + + return +} + +// ID returns the formatted Replication Protectable Item ID +func (id ReplicationProtectableItemId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.RecoveryServices/vaults/%s/replicationFabrics/%s/replicationProtectionContainers/%s/replicationProtectableItems/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroupName, id.VaultName, id.ReplicationFabricName, id.ReplicationProtectionContainerName, id.ReplicationProtectableItemName) +} + +// Segments returns a slice of Resource ID Segments which comprise this Replication Protectable Item ID +func (id ReplicationProtectableItemId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("staticSubscriptions", "subscriptions", "subscriptions"), + resourceids.SubscriptionIdSegment("subscriptionId", "12345678-1234-9876-4563-123456789012"), + resourceids.StaticSegment("staticResourceGroups", "resourceGroups", "resourceGroups"), + resourceids.ResourceGroupSegment("resourceGroupName", "example-resource-group"), + resourceids.StaticSegment("staticProviders", "providers", "providers"), + resourceids.ResourceProviderSegment("staticMicrosoftRecoveryServices", "Microsoft.RecoveryServices", "Microsoft.RecoveryServices"), + resourceids.StaticSegment("staticVaults", "vaults", "vaults"), + resourceids.UserSpecifiedSegment("vaultName", "vaultValue"), + resourceids.StaticSegment("staticReplicationFabrics", "replicationFabrics", "replicationFabrics"), + resourceids.UserSpecifiedSegment("replicationFabricName", "replicationFabricValue"), + resourceids.StaticSegment("staticReplicationProtectionContainers", "replicationProtectionContainers", "replicationProtectionContainers"), + resourceids.UserSpecifiedSegment("replicationProtectionContainerName", "replicationProtectionContainerValue"), + resourceids.StaticSegment("staticReplicationProtectableItems", "replicationProtectableItems", "replicationProtectableItems"), + resourceids.UserSpecifiedSegment("replicationProtectableItemName", "replicationProtectableItemValue"), + } +} + +// String returns a human-readable description of this Replication Protectable Item ID +func (id ReplicationProtectableItemId) String() string { + components := []string{ + fmt.Sprintf("Subscription: %q", id.SubscriptionId), + fmt.Sprintf("Resource Group Name: %q", id.ResourceGroupName), + fmt.Sprintf("Vault Name: %q", id.VaultName), + fmt.Sprintf("Replication Fabric Name: %q", id.ReplicationFabricName), + fmt.Sprintf("Replication Protection Container Name: %q", id.ReplicationProtectionContainerName), + fmt.Sprintf("Replication Protectable Item Name: %q", id.ReplicationProtectableItemName), + } + return fmt.Sprintf("Replication Protectable Item (%s)", strings.Join(components, "\n")) +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectioncontainer.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectioncontainer.go new file mode 100644 index 000000000000..4f2ef2c7ef18 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectioncontainer.go @@ -0,0 +1,150 @@ +package replicationprotectableitems + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +var _ resourceids.ResourceId = ReplicationProtectionContainerId{} + +// ReplicationProtectionContainerId is a struct representing the Resource ID for a Replication Protection Container +type ReplicationProtectionContainerId struct { + SubscriptionId string + ResourceGroupName string + VaultName string + ReplicationFabricName string + ReplicationProtectionContainerName string +} + +// NewReplicationProtectionContainerID returns a new ReplicationProtectionContainerId struct +func NewReplicationProtectionContainerID(subscriptionId string, resourceGroupName string, vaultName string, replicationFabricName string, replicationProtectionContainerName string) ReplicationProtectionContainerId { + return ReplicationProtectionContainerId{ + SubscriptionId: subscriptionId, + ResourceGroupName: resourceGroupName, + VaultName: vaultName, + ReplicationFabricName: replicationFabricName, + ReplicationProtectionContainerName: replicationProtectionContainerName, + } +} + +// ParseReplicationProtectionContainerID parses 'input' into a ReplicationProtectionContainerId +func ParseReplicationProtectionContainerID(input string) (*ReplicationProtectionContainerId, error) { + parser := resourceids.NewParserFromResourceIdType(ReplicationProtectionContainerId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := ReplicationProtectionContainerId{} + + if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { + return nil, fmt.Errorf("the segment 'subscriptionId' was not found in the resource id %q", input) + } + + if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { + return nil, fmt.Errorf("the segment 'resourceGroupName' was not found in the resource id %q", input) + } + + if id.VaultName, ok = parsed.Parsed["vaultName"]; !ok { + return nil, fmt.Errorf("the segment 'vaultName' was not found in the resource id %q", input) + } + + if id.ReplicationFabricName, ok = parsed.Parsed["replicationFabricName"]; !ok { + return nil, fmt.Errorf("the segment 'replicationFabricName' was not found in the resource id %q", input) + } + + if id.ReplicationProtectionContainerName, ok = parsed.Parsed["replicationProtectionContainerName"]; !ok { + return nil, fmt.Errorf("the segment 'replicationProtectionContainerName' was not found in the resource id %q", input) + } + + return &id, nil +} + +// ParseReplicationProtectionContainerIDInsensitively parses 'input' case-insensitively into a ReplicationProtectionContainerId +// note: this method should only be used for API response data and not user input +func ParseReplicationProtectionContainerIDInsensitively(input string) (*ReplicationProtectionContainerId, error) { + parser := resourceids.NewParserFromResourceIdType(ReplicationProtectionContainerId{}) + parsed, err := parser.Parse(input, true) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := ReplicationProtectionContainerId{} + + if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { + return nil, fmt.Errorf("the segment 'subscriptionId' was not found in the resource id %q", input) + } + + if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { + return nil, fmt.Errorf("the segment 'resourceGroupName' was not found in the resource id %q", input) + } + + if id.VaultName, ok = parsed.Parsed["vaultName"]; !ok { + return nil, fmt.Errorf("the segment 'vaultName' was not found in the resource id %q", input) + } + + if id.ReplicationFabricName, ok = parsed.Parsed["replicationFabricName"]; !ok { + return nil, fmt.Errorf("the segment 'replicationFabricName' was not found in the resource id %q", input) + } + + if id.ReplicationProtectionContainerName, ok = parsed.Parsed["replicationProtectionContainerName"]; !ok { + return nil, fmt.Errorf("the segment 'replicationProtectionContainerName' was not found in the resource id %q", input) + } + + return &id, nil +} + +// ValidateReplicationProtectionContainerID checks that 'input' can be parsed as a Replication Protection Container ID +func ValidateReplicationProtectionContainerID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if _, err := ParseReplicationProtectionContainerID(v); err != nil { + errors = append(errors, err) + } + + return +} + +// ID returns the formatted Replication Protection Container ID +func (id ReplicationProtectionContainerId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.RecoveryServices/vaults/%s/replicationFabrics/%s/replicationProtectionContainers/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroupName, id.VaultName, id.ReplicationFabricName, id.ReplicationProtectionContainerName) +} + +// Segments returns a slice of Resource ID Segments which comprise this Replication Protection Container ID +func (id ReplicationProtectionContainerId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("staticSubscriptions", "subscriptions", "subscriptions"), + resourceids.SubscriptionIdSegment("subscriptionId", "12345678-1234-9876-4563-123456789012"), + resourceids.StaticSegment("staticResourceGroups", "resourceGroups", "resourceGroups"), + resourceids.ResourceGroupSegment("resourceGroupName", "example-resource-group"), + resourceids.StaticSegment("staticProviders", "providers", "providers"), + resourceids.ResourceProviderSegment("staticMicrosoftRecoveryServices", "Microsoft.RecoveryServices", "Microsoft.RecoveryServices"), + resourceids.StaticSegment("staticVaults", "vaults", "vaults"), + resourceids.UserSpecifiedSegment("vaultName", "vaultValue"), + resourceids.StaticSegment("staticReplicationFabrics", "replicationFabrics", "replicationFabrics"), + resourceids.UserSpecifiedSegment("replicationFabricName", "replicationFabricValue"), + resourceids.StaticSegment("staticReplicationProtectionContainers", "replicationProtectionContainers", "replicationProtectionContainers"), + resourceids.UserSpecifiedSegment("replicationProtectionContainerName", "replicationProtectionContainerValue"), + } +} + +// String returns a human-readable description of this Replication Protection Container ID +func (id ReplicationProtectionContainerId) String() string { + components := []string{ + fmt.Sprintf("Subscription: %q", id.SubscriptionId), + fmt.Sprintf("Resource Group Name: %q", id.ResourceGroupName), + fmt.Sprintf("Vault Name: %q", id.VaultName), + fmt.Sprintf("Replication Fabric Name: %q", id.ReplicationFabricName), + fmt.Sprintf("Replication Protection Container Name: %q", id.ReplicationProtectionContainerName), + } + return fmt.Sprintf("Replication Protection Container (%s)", strings.Join(components, "\n")) +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_get_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_get_autorest.go new file mode 100644 index 000000000000..5f174d7a1ccf --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_get_autorest.go @@ -0,0 +1,68 @@ +package replicationprotectableitems + +import ( + "context" + "net/http" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type GetOperationResponse struct { + HttpResponse *http.Response + Model *ProtectableItem +} + +// Get ... +func (c ReplicationProtectableItemsClient) Get(ctx context.Context, id ReplicationProtectableItemId) (result GetOperationResponse, err error) { + req, err := c.preparerForGet(ctx, id) + if err != nil { + err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "Get", nil, "Failure preparing request") + return + } + + result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "Get", result.HttpResponse, "Failure sending request") + return + } + + result, err = c.responderForGet(result.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "Get", result.HttpResponse, "Failure responding to request") + return + } + + return +} + +// preparerForGet prepares the Get request. +func (c ReplicationProtectableItemsClient) preparerForGet(ctx context.Context, id ReplicationProtectableItemId) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(id.ID()), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// responderForGet handles the response to the Get request. The method always +// closes the http.Response Body. +func (c ReplicationProtectableItemsClient) responderForGet(resp *http.Response) (result GetOperationResponse, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Model), + autorest.ByClosing()) + result.HttpResponse = resp + + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_listbyreplicationprotectioncontainers_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_listbyreplicationprotectioncontainers_autorest.go new file mode 100644 index 000000000000..5c77821d594b --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_listbyreplicationprotectioncontainers_autorest.go @@ -0,0 +1,220 @@ +package replicationprotectableitems + +import ( + "context" + "fmt" + "net/http" + "net/url" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ListByReplicationProtectionContainersOperationResponse struct { + HttpResponse *http.Response + Model *[]ProtectableItem + + nextLink *string + nextPageFunc func(ctx context.Context, nextLink string) (ListByReplicationProtectionContainersOperationResponse, error) +} + +type ListByReplicationProtectionContainersCompleteResult struct { + Items []ProtectableItem +} + +func (r ListByReplicationProtectionContainersOperationResponse) HasMore() bool { + return r.nextLink != nil +} + +func (r ListByReplicationProtectionContainersOperationResponse) LoadMore(ctx context.Context) (resp ListByReplicationProtectionContainersOperationResponse, err error) { + if !r.HasMore() { + err = fmt.Errorf("no more pages returned") + return + } + return r.nextPageFunc(ctx, *r.nextLink) +} + +type ListByReplicationProtectionContainersOperationOptions struct { + Filter *string + Take *string +} + +func DefaultListByReplicationProtectionContainersOperationOptions() ListByReplicationProtectionContainersOperationOptions { + return ListByReplicationProtectionContainersOperationOptions{} +} + +func (o ListByReplicationProtectionContainersOperationOptions) toHeaders() map[string]interface{} { + out := make(map[string]interface{}) + + return out +} + +func (o ListByReplicationProtectionContainersOperationOptions) toQueryString() map[string]interface{} { + out := make(map[string]interface{}) + + if o.Filter != nil { + out["$filter"] = *o.Filter + } + + if o.Take != nil { + out["$take"] = *o.Take + } + + return out +} + +// ListByReplicationProtectionContainers ... +func (c ReplicationProtectableItemsClient) ListByReplicationProtectionContainers(ctx context.Context, id ReplicationProtectionContainerId, options ListByReplicationProtectionContainersOperationOptions) (resp ListByReplicationProtectionContainersOperationResponse, err error) { + req, err := c.preparerForListByReplicationProtectionContainers(ctx, id, options) + if err != nil { + err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "ListByReplicationProtectionContainers", nil, "Failure preparing request") + return + } + + resp.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "ListByReplicationProtectionContainers", resp.HttpResponse, "Failure sending request") + return + } + + resp, err = c.responderForListByReplicationProtectionContainers(resp.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "ListByReplicationProtectionContainers", resp.HttpResponse, "Failure responding to request") + return + } + return +} + +// preparerForListByReplicationProtectionContainers prepares the ListByReplicationProtectionContainers request. +func (c ReplicationProtectableItemsClient) preparerForListByReplicationProtectionContainers(ctx context.Context, id ReplicationProtectionContainerId, options ListByReplicationProtectionContainersOperationOptions) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + for k, v := range options.toQueryString() { + queryParameters[k] = autorest.Encode("query", v) + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithHeaders(options.toHeaders()), + autorest.WithPath(fmt.Sprintf("%s/replicationProtectableItems", id.ID())), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// preparerForListByReplicationProtectionContainersWithNextLink prepares the ListByReplicationProtectionContainers request with the given nextLink token. +func (c ReplicationProtectableItemsClient) preparerForListByReplicationProtectionContainersWithNextLink(ctx context.Context, nextLink string) (*http.Request, error) { + uri, err := url.Parse(nextLink) + if err != nil { + return nil, fmt.Errorf("parsing nextLink %q: %+v", nextLink, err) + } + queryParameters := map[string]interface{}{} + for k, v := range uri.Query() { + if len(v) == 0 { + continue + } + val := v[0] + val = autorest.Encode("query", val) + queryParameters[k] = val + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(uri.Path), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// responderForListByReplicationProtectionContainers handles the response to the ListByReplicationProtectionContainers request. The method always +// closes the http.Response Body. +func (c ReplicationProtectableItemsClient) responderForListByReplicationProtectionContainers(resp *http.Response) (result ListByReplicationProtectionContainersOperationResponse, err error) { + type page struct { + Values []ProtectableItem `json:"value"` + NextLink *string `json:"nextLink"` + } + var respObj page + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&respObj), + autorest.ByClosing()) + result.HttpResponse = resp + result.Model = &respObj.Values + result.nextLink = respObj.NextLink + if respObj.NextLink != nil { + result.nextPageFunc = func(ctx context.Context, nextLink string) (result ListByReplicationProtectionContainersOperationResponse, err error) { + req, err := c.preparerForListByReplicationProtectionContainersWithNextLink(ctx, nextLink) + if err != nil { + err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "ListByReplicationProtectionContainers", nil, "Failure preparing request") + return + } + + result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "ListByReplicationProtectionContainers", result.HttpResponse, "Failure sending request") + return + } + + result, err = c.responderForListByReplicationProtectionContainers(result.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "ListByReplicationProtectionContainers", result.HttpResponse, "Failure responding to request") + return + } + + return + } + } + return +} + +// ListByReplicationProtectionContainersComplete retrieves all of the results into a single object +func (c ReplicationProtectableItemsClient) ListByReplicationProtectionContainersComplete(ctx context.Context, id ReplicationProtectionContainerId, options ListByReplicationProtectionContainersOperationOptions) (ListByReplicationProtectionContainersCompleteResult, error) { + return c.ListByReplicationProtectionContainersCompleteMatchingPredicate(ctx, id, options, ProtectableItemOperationPredicate{}) +} + +// ListByReplicationProtectionContainersCompleteMatchingPredicate retrieves all of the results and then applied the predicate +func (c ReplicationProtectableItemsClient) ListByReplicationProtectionContainersCompleteMatchingPredicate(ctx context.Context, id ReplicationProtectionContainerId, options ListByReplicationProtectionContainersOperationOptions, predicate ProtectableItemOperationPredicate) (resp ListByReplicationProtectionContainersCompleteResult, err error) { + items := make([]ProtectableItem, 0) + + page, err := c.ListByReplicationProtectionContainers(ctx, id, options) + if err != nil { + err = fmt.Errorf("loading the initial page: %+v", err) + return + } + if page.Model != nil { + for _, v := range *page.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + + for page.HasMore() { + page, err = page.LoadMore(ctx) + if err != nil { + err = fmt.Errorf("loading the next page: %+v", err) + return + } + + if page.Model != nil { + for _, v := range *page.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + } + + out := ListByReplicationProtectionContainersCompleteResult{ + Items: items, + } + return out, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_configurationsettings.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_configurationsettings.go new file mode 100644 index 000000000000..4d071558c6cb --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_configurationsettings.go @@ -0,0 +1,64 @@ +package replicationprotectableitems + +import ( + "encoding/json" + "fmt" + "strings" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ConfigurationSettings interface { +} + +func unmarshalConfigurationSettingsImplementation(input []byte) (ConfigurationSettings, error) { + if input == nil { + return nil, nil + } + + var temp map[string]interface{} + if err := json.Unmarshal(input, &temp); err != nil { + return nil, fmt.Errorf("unmarshaling ConfigurationSettings into map[string]interface: %+v", err) + } + + value, ok := temp["instanceType"].(string) + if !ok { + return nil, nil + } + + if strings.EqualFold(value, "HyperVVirtualMachine") { + var out HyperVVirtualMachineDetails + if err := json.Unmarshal(input, &out); err != nil { + return nil, fmt.Errorf("unmarshaling into HyperVVirtualMachineDetails: %+v", err) + } + return out, nil + } + + if strings.EqualFold(value, "ReplicationGroupDetails") { + var out ReplicationGroupDetails + if err := json.Unmarshal(input, &out); err != nil { + return nil, fmt.Errorf("unmarshaling into ReplicationGroupDetails: %+v", err) + } + return out, nil + } + + if strings.EqualFold(value, "VMwareVirtualMachine") { + var out VMwareVirtualMachineDetails + if err := json.Unmarshal(input, &out); err != nil { + return nil, fmt.Errorf("unmarshaling into VMwareVirtualMachineDetails: %+v", err) + } + return out, nil + } + + type RawConfigurationSettingsImpl struct { + Type string `json:"-"` + Values map[string]interface{} `json:"-"` + } + out := RawConfigurationSettingsImpl{ + Type: value, + Values: temp, + } + return out, nil + +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_diskdetails.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_diskdetails.go new file mode 100644 index 000000000000..f418a8a199ab --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_diskdetails.go @@ -0,0 +1,11 @@ +package replicationprotectableitems + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type DiskDetails struct { + MaxSizeMB *int64 `json:"maxSizeMB,omitempty"` + VhdId *string `json:"vhdId,omitempty"` + VhdName *string `json:"vhdName,omitempty"` + VhdType *string `json:"vhdType,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_diskvolumedetails.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_diskvolumedetails.go new file mode 100644 index 000000000000..a1807b2e5d90 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_diskvolumedetails.go @@ -0,0 +1,9 @@ +package replicationprotectableitems + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type DiskVolumeDetails struct { + Label *string `json:"label,omitempty"` + Name *string `json:"name,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_healtherror.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_healtherror.go new file mode 100644 index 000000000000..dd836fd7405e --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_healtherror.go @@ -0,0 +1,40 @@ +package replicationprotectableitems + +import ( + "time" + + "github.com/hashicorp/go-azure-helpers/lang/dates" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type HealthError struct { + CreationTimeUtc *string `json:"creationTimeUtc,omitempty"` + CustomerResolvability *HealthErrorCustomerResolvability `json:"customerResolvability,omitempty"` + EntityId *string `json:"entityId,omitempty"` + ErrorCategory *string `json:"errorCategory,omitempty"` + ErrorCode *string `json:"errorCode,omitempty"` + ErrorId *string `json:"errorId,omitempty"` + ErrorLevel *string `json:"errorLevel,omitempty"` + ErrorMessage *string `json:"errorMessage,omitempty"` + ErrorSource *string `json:"errorSource,omitempty"` + ErrorType *string `json:"errorType,omitempty"` + InnerHealthErrors *[]InnerHealthError `json:"innerHealthErrors,omitempty"` + PossibleCauses *string `json:"possibleCauses,omitempty"` + RecommendedAction *string `json:"recommendedAction,omitempty"` + RecoveryProviderErrorMessage *string `json:"recoveryProviderErrorMessage,omitempty"` + SummaryMessage *string `json:"summaryMessage,omitempty"` +} + +func (o *HealthError) GetCreationTimeUtcAsTime() (*time.Time, error) { + if o.CreationTimeUtc == nil { + return nil, nil + } + return dates.ParseAsFormat(o.CreationTimeUtc, "2006-01-02T15:04:05Z07:00") +} + +func (o *HealthError) SetCreationTimeUtcAsTime(input time.Time) { + formatted := input.Format("2006-01-02T15:04:05Z07:00") + o.CreationTimeUtc = &formatted +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_hypervvirtualmachinedetails.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_hypervvirtualmachinedetails.go new file mode 100644 index 000000000000..73a1c26e7088 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_hypervvirtualmachinedetails.go @@ -0,0 +1,48 @@ +package replicationprotectableitems + +import ( + "encoding/json" + "fmt" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +var _ ConfigurationSettings = HyperVVirtualMachineDetails{} + +type HyperVVirtualMachineDetails struct { + DiskDetails *[]DiskDetails `json:"diskDetails,omitempty"` + Generation *string `json:"generation,omitempty"` + HasFibreChannelAdapter *PresenceStatus `json:"hasFibreChannelAdapter,omitempty"` + HasPhysicalDisk *PresenceStatus `json:"hasPhysicalDisk,omitempty"` + HasSharedVhd *PresenceStatus `json:"hasSharedVhd,omitempty"` + HyperVHostId *string `json:"hyperVHostId,omitempty"` + OsDetails *OSDetails `json:"osDetails,omitempty"` + SourceItemId *string `json:"sourceItemId,omitempty"` + + // Fields inherited from ConfigurationSettings +} + +var _ json.Marshaler = HyperVVirtualMachineDetails{} + +func (s HyperVVirtualMachineDetails) MarshalJSON() ([]byte, error) { + type wrapper HyperVVirtualMachineDetails + wrapped := wrapper(s) + encoded, err := json.Marshal(wrapped) + if err != nil { + return nil, fmt.Errorf("marshaling HyperVVirtualMachineDetails: %+v", err) + } + + var decoded map[string]interface{} + if err := json.Unmarshal(encoded, &decoded); err != nil { + return nil, fmt.Errorf("unmarshaling HyperVVirtualMachineDetails: %+v", err) + } + decoded["instanceType"] = "HyperVVirtualMachine" + + encoded, err = json.Marshal(decoded) + if err != nil { + return nil, fmt.Errorf("re-marshaling HyperVVirtualMachineDetails: %+v", err) + } + + return encoded, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_inmagediskdetails.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_inmagediskdetails.go new file mode 100644 index 000000000000..a4233f281363 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_inmagediskdetails.go @@ -0,0 +1,13 @@ +package replicationprotectableitems + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type InMageDiskDetails struct { + DiskConfiguration *string `json:"diskConfiguration,omitempty"` + DiskId *string `json:"diskId,omitempty"` + DiskName *string `json:"diskName,omitempty"` + DiskSizeInMB *string `json:"diskSizeInMB,omitempty"` + DiskType *string `json:"diskType,omitempty"` + VolumeList *[]DiskVolumeDetails `json:"volumeList,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_innerhealtherror.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_innerhealtherror.go new file mode 100644 index 000000000000..ee306e7b2305 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_innerhealtherror.go @@ -0,0 +1,39 @@ +package replicationprotectableitems + +import ( + "time" + + "github.com/hashicorp/go-azure-helpers/lang/dates" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type InnerHealthError struct { + CreationTimeUtc *string `json:"creationTimeUtc,omitempty"` + CustomerResolvability *HealthErrorCustomerResolvability `json:"customerResolvability,omitempty"` + EntityId *string `json:"entityId,omitempty"` + ErrorCategory *string `json:"errorCategory,omitempty"` + ErrorCode *string `json:"errorCode,omitempty"` + ErrorId *string `json:"errorId,omitempty"` + ErrorLevel *string `json:"errorLevel,omitempty"` + ErrorMessage *string `json:"errorMessage,omitempty"` + ErrorSource *string `json:"errorSource,omitempty"` + ErrorType *string `json:"errorType,omitempty"` + PossibleCauses *string `json:"possibleCauses,omitempty"` + RecommendedAction *string `json:"recommendedAction,omitempty"` + RecoveryProviderErrorMessage *string `json:"recoveryProviderErrorMessage,omitempty"` + SummaryMessage *string `json:"summaryMessage,omitempty"` +} + +func (o *InnerHealthError) GetCreationTimeUtcAsTime() (*time.Time, error) { + if o.CreationTimeUtc == nil { + return nil, nil + } + return dates.ParseAsFormat(o.CreationTimeUtc, "2006-01-02T15:04:05Z07:00") +} + +func (o *InnerHealthError) SetCreationTimeUtcAsTime(input time.Time) { + formatted := input.Format("2006-01-02T15:04:05Z07:00") + o.CreationTimeUtc = &formatted +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_osdetails.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_osdetails.go new file mode 100644 index 000000000000..7b38e793990d --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_osdetails.go @@ -0,0 +1,13 @@ +package replicationprotectableitems + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type OSDetails struct { + OSMajorVersion *string `json:"oSMajorVersion,omitempty"` + OSMinorVersion *string `json:"oSMinorVersion,omitempty"` + OSVersion *string `json:"oSVersion,omitempty"` + OsEdition *string `json:"osEdition,omitempty"` + OsType *string `json:"osType,omitempty"` + ProductType *string `json:"productType,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_protectableitem.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_protectableitem.go new file mode 100644 index 000000000000..f2996c6b5147 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_protectableitem.go @@ -0,0 +1,12 @@ +package replicationprotectableitems + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ProtectableItem struct { + Id *string `json:"id,omitempty"` + Location *string `json:"location,omitempty"` + Name *string `json:"name,omitempty"` + Properties *ProtectableItemProperties `json:"properties,omitempty"` + Type *string `json:"type,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_protectableitemproperties.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_protectableitemproperties.go new file mode 100644 index 000000000000..5559fc9f13c4 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_protectableitemproperties.go @@ -0,0 +1,50 @@ +package replicationprotectableitems + +import ( + "encoding/json" + "fmt" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ProtectableItemProperties struct { + CustomDetails ConfigurationSettings `json:"customDetails"` + FriendlyName *string `json:"friendlyName,omitempty"` + ProtectionReadinessErrors *[]string `json:"protectionReadinessErrors,omitempty"` + ProtectionStatus *string `json:"protectionStatus,omitempty"` + RecoveryServicesProviderId *string `json:"recoveryServicesProviderId,omitempty"` + ReplicationProtectedItemId *string `json:"replicationProtectedItemId,omitempty"` + SupportedReplicationProviders *[]string `json:"supportedReplicationProviders,omitempty"` +} + +var _ json.Unmarshaler = &ProtectableItemProperties{} + +func (s *ProtectableItemProperties) UnmarshalJSON(bytes []byte) error { + type alias ProtectableItemProperties + var decoded alias + if err := json.Unmarshal(bytes, &decoded); err != nil { + return fmt.Errorf("unmarshaling into ProtectableItemProperties: %+v", err) + } + + s.FriendlyName = decoded.FriendlyName + s.ProtectionReadinessErrors = decoded.ProtectionReadinessErrors + s.ProtectionStatus = decoded.ProtectionStatus + s.RecoveryServicesProviderId = decoded.RecoveryServicesProviderId + s.ReplicationProtectedItemId = decoded.ReplicationProtectedItemId + s.SupportedReplicationProviders = decoded.SupportedReplicationProviders + + var temp map[string]json.RawMessage + if err := json.Unmarshal(bytes, &temp); err != nil { + return fmt.Errorf("unmarshaling ProtectableItemProperties into map[string]json.RawMessage: %+v", err) + } + + if v, ok := temp["customDetails"]; ok { + impl, err := unmarshalConfigurationSettingsImplementation(v) + if err != nil { + return fmt.Errorf("unmarshaling field 'CustomDetails' for 'ProtectableItemProperties': %+v", err) + } + s.CustomDetails = impl + } + return nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_replicationgroupdetails.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_replicationgroupdetails.go new file mode 100644 index 000000000000..2afdac69d0e6 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_replicationgroupdetails.go @@ -0,0 +1,40 @@ +package replicationprotectableitems + +import ( + "encoding/json" + "fmt" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +var _ ConfigurationSettings = ReplicationGroupDetails{} + +type ReplicationGroupDetails struct { + + // Fields inherited from ConfigurationSettings +} + +var _ json.Marshaler = ReplicationGroupDetails{} + +func (s ReplicationGroupDetails) MarshalJSON() ([]byte, error) { + type wrapper ReplicationGroupDetails + wrapped := wrapper(s) + encoded, err := json.Marshal(wrapped) + if err != nil { + return nil, fmt.Errorf("marshaling ReplicationGroupDetails: %+v", err) + } + + var decoded map[string]interface{} + if err := json.Unmarshal(encoded, &decoded); err != nil { + return nil, fmt.Errorf("unmarshaling ReplicationGroupDetails: %+v", err) + } + decoded["instanceType"] = "ReplicationGroupDetails" + + encoded, err = json.Marshal(decoded) + if err != nil { + return nil, fmt.Errorf("re-marshaling ReplicationGroupDetails: %+v", err) + } + + return encoded, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_vmmvirtualmachinedetails.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_vmmvirtualmachinedetails.go new file mode 100644 index 000000000000..1ae50cf4cc7d --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_vmmvirtualmachinedetails.go @@ -0,0 +1,48 @@ +package replicationprotectableitems + +import ( + "encoding/json" + "fmt" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +var _ ConfigurationSettings = VMmVirtualMachineDetails{} + +type VMmVirtualMachineDetails struct { + + // Fields inherited from HyperVVirtualMachineDetails + DiskDetails *[]DiskDetails `json:"diskDetails,omitempty"` + Generation *string `json:"generation,omitempty"` + HasFibreChannelAdapter *PresenceStatus `json:"hasFibreChannelAdapter,omitempty"` + HasPhysicalDisk *PresenceStatus `json:"hasPhysicalDisk,omitempty"` + HasSharedVhd *PresenceStatus `json:"hasSharedVhd,omitempty"` + HyperVHostId *string `json:"hyperVHostId,omitempty"` + OsDetails *OSDetails `json:"osDetails,omitempty"` + SourceItemId *string `json:"sourceItemId,omitempty"` +} + +var _ json.Marshaler = VMmVirtualMachineDetails{} + +func (s VMmVirtualMachineDetails) MarshalJSON() ([]byte, error) { + type wrapper VMmVirtualMachineDetails + wrapped := wrapper(s) + encoded, err := json.Marshal(wrapped) + if err != nil { + return nil, fmt.Errorf("marshaling VMmVirtualMachineDetails: %+v", err) + } + + var decoded map[string]interface{} + if err := json.Unmarshal(encoded, &decoded); err != nil { + return nil, fmt.Errorf("unmarshaling VMmVirtualMachineDetails: %+v", err) + } + decoded["instanceType"] = "VmmVirtualMachine" + + encoded, err = json.Marshal(decoded) + if err != nil { + return nil, fmt.Errorf("re-marshaling VMmVirtualMachineDetails: %+v", err) + } + + return encoded, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_vmwarevirtualmachinedetails.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_vmwarevirtualmachinedetails.go new file mode 100644 index 000000000000..8eb8ecdf063f --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_vmwarevirtualmachinedetails.go @@ -0,0 +1,50 @@ +package replicationprotectableitems + +import ( + "encoding/json" + "fmt" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +var _ ConfigurationSettings = VMwareVirtualMachineDetails{} + +type VMwareVirtualMachineDetails struct { + AgentGeneratedId *string `json:"agentGeneratedId,omitempty"` + AgentInstalled *string `json:"agentInstalled,omitempty"` + AgentVersion *string `json:"agentVersion,omitempty"` + DiscoveryType *string `json:"discoveryType,omitempty"` + DiskDetails *[]InMageDiskDetails `json:"diskDetails,omitempty"` + IPAddress *string `json:"ipAddress,omitempty"` + OsType *string `json:"osType,omitempty"` + PoweredOn *string `json:"poweredOn,omitempty"` + VCenterInfrastructureId *string `json:"vCenterInfrastructureId,omitempty"` + ValidationErrors *[]HealthError `json:"validationErrors,omitempty"` + + // Fields inherited from ConfigurationSettings +} + +var _ json.Marshaler = VMwareVirtualMachineDetails{} + +func (s VMwareVirtualMachineDetails) MarshalJSON() ([]byte, error) { + type wrapper VMwareVirtualMachineDetails + wrapped := wrapper(s) + encoded, err := json.Marshal(wrapped) + if err != nil { + return nil, fmt.Errorf("marshaling VMwareVirtualMachineDetails: %+v", err) + } + + var decoded map[string]interface{} + if err := json.Unmarshal(encoded, &decoded); err != nil { + return nil, fmt.Errorf("unmarshaling VMwareVirtualMachineDetails: %+v", err) + } + decoded["instanceType"] = "VMwareVirtualMachine" + + encoded, err = json.Marshal(decoded) + if err != nil { + return nil, fmt.Errorf("re-marshaling VMwareVirtualMachineDetails: %+v", err) + } + + return encoded, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/predicates.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/predicates.go new file mode 100644 index 000000000000..36eb2ae6240e --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/predicates.go @@ -0,0 +1,29 @@ +package replicationprotectableitems + +type ProtectableItemOperationPredicate struct { + Id *string + Location *string + Name *string + Type *string +} + +func (p ProtectableItemOperationPredicate) Matches(input ProtectableItem) bool { + + if p.Id != nil && (input.Id == nil && *p.Id != *input.Id) { + return false + } + + if p.Location != nil && (input.Location == nil && *p.Location != *input.Location) { + return false + } + + if p.Name != nil && (input.Name == nil && *p.Name != *input.Name) { + return false + } + + if p.Type != nil && (input.Type == nil && *p.Type != *input.Type) { + return false + } + + return true +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/version.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/version.go new file mode 100644 index 000000000000..80b6d6b46927 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/version.go @@ -0,0 +1,12 @@ +package replicationprotectableitems + +import "fmt" + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +const defaultApiVersion = "2022-10-01" + +func userAgent() string { + return fmt.Sprintf("hashicorp/go-azure-sdk/replicationprotectableitems/%s", defaultApiVersion) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index e6995e65d6f4..af842ebade8f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -462,6 +462,7 @@ github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicesbackup/2021-1 github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationfabrics github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationnetworkmappings github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationpolicies +github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotecteditems github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectioncontainermappings github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectioncontainers diff --git a/website/docs/r/site_recovery_hyperv_replicated_vm.html.markdown b/website/docs/r/site_recovery_hyperv_replicated_vm.html.markdown new file mode 100644 index 000000000000..2ca209b80296 --- /dev/null +++ b/website/docs/r/site_recovery_hyperv_replicated_vm.html.markdown @@ -0,0 +1,193 @@ +--- +subcategory: "Recovery Services" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_site_recovery_hyperv_replicated_vm" +description: |- + Manages a HyperV VM protected with Azure Site Recovery on Azure. +--- + +# azurerm_site_recovery_replicated_vm + +Manages a HyperV VM replicated using Azure Site Recovery (HyperV to Azure only). A replicated VM keeps a copiously updated image of the VM in Azure in order to be able to start the VM in Azure in case of a disaster. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-rg" + location = "West US" +} + +resource "azurerm_recovery_services_vault" "example" { + name = "example-recovery-vault" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + sku = "Standard" +} + +resource "azurerm_site_recovery_services_vault_hyperv_site" "example" { + name = "example-hyperv-site" + recovery_vault_id = azurerm_recovery_services_vault.example.id +} + +resource "azurerm_site_recovery_hyperv_replication_policy" "example" { + recovery_vault_id = azurerm_recovery_services_vault.example.id + name = "example-policy" + recovery_point_retention_in_hours = 2 + application_consistent_snapshot_frequency_in_hours = 1 + replication_interval_in_seconds = 300 +} + +resource "azurerm_site_recovery_hyperv_replication_policy_association" "example" { + name = "example-association" + hyperv_site_id = azurerm_site_recovery_services_vault_hyperv_site.example.id + policy_id = azurerm_site_recovery_hyperv_replication_policy.example.id +} + +resource "azurerm_storage_account" "example" { + name = "examplestorageacc" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_kind = "StorageV2" + account_replication_type = "LRS" +} + +resource "azurerm_virtual_network" "example" { + name = "example-net" + resource_group_name = azurerm_resource_group.example.name + address_space = ["192.168.2.0/24"] + location = azurerm_resource_group.example.location +} + + +resource "azurerm_subnet" "example" { + name = "example-subnet" + resource_group_name = azurerm_resource_group.primary.name + virtual_network_name = azurerm_virtual_network.primary.name + address_prefixes = ["192.168.2.0/24"] +} + +resource "azurerm_site_recovery_hyperv_replicated_vm" "example" { + name = "example-hyperv-vm" + hyperv_site_id = azurerm_site_recovery_services_vault_hyperv_site.example.id + source_vm_name = "VM1" + target_resource_group_id = azurerm_resource_group.example.id + target_vm_name = "target-vm" + target_storage_account_id = azurerm_storage_account.example.id + replication_policy_id = azurerm_site_recovery_hyperv_replication_policy.example.id + os_type = "Windows" + os_disk_name = "VM1" + target_network_id = azurerm_virtual_network.example.id + disks_to_include = ["VM1"] + + depends_on = [azurerm_site_recovery_hyperv_replication_policy_association.example] +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the replication for the replicated VM. Changing this forces a new resource to be created. + +* `hyperv_site_id` - (Required) ID of the HyperV Site or VMM Cloud in the Recovery Vault. Changing this forces a new resource to be created. + +* `source_vm_name` - (Required) The name of VM in HyperV. Changing this forces a new resource to be created. + +* `target_resource_group_id` - (Required) ID of resource group where the VM should be created when a failover is done. Changing this forces a new resource to be created. + +* `target_vm_name` - (Required) Name of the VM that should be created when a failover is done. Changing this forces a new resource to be created. + +* `target_storage_account_id` - (Required) ID of the storage account that should be used to replicate VM disks when a failover is done. Changing this forces a new resource to be created. + +* `replication_policy_id` - (Required) ID of the policy to use for this replicated VM. Changing this forces a new resource to be created. + +* `os_type` - (Required) OS type of the source VM. Possible values are `Linux` and `Windows`. Changing this forces a new resource to be created. + +* `os_disk_name` - (Required) Name of the OS disk of the source VM. Changing this forces a new resource to be created. + +* `target_network_id` - (Required) Network to use when a failover is done. + +* `network_interface` - (Required) One or more `network_interface` block as defined below. + +* `disks_to_include` - (Optional) A list of disk names to include from the source VM in the replication. Changing this forces a new resource to be created. + +* `use_managed_disk_enabled` - (Optional) Whether to use managed disks in replication. Changing this forces a new resource to be created. Defaults to `false`. + +* `managed_disk` - (Optional) One or more `managed_disk` block as defined below. Changing this forces a new resource to be created. + +-> **NOTE:** If `use_managed_disk_enabled` is set to `true`, then `managed_disk` block must be specified. If `use_managed_disk_enabled` is set to `false`, then `disks_to_include` block must be specified. + +* `log_storage_account_id` - (Optional) ID of the Storage Account to be used for logging during replication. Changing this forces a new resource to be created. + +* `enable_rdp_or_ssh_on_target_option` - (Optional) Options to enable RDP or SSH on replicated VM. Possible values are `Never`, `OnlyOnTestFailover` and `Always`. + +* `target_vm_size` - (Optional) Size of the VM that should be created when a failover is done, such as `Standard_F2`. If it's not specified, it will automatically be set by detecting the source VM size. + +* `target_availability_zone` - (Optional) The Availability Zone where the Failover VM should exist. + +* `target_availability_set_id` - (Optional) Id of availability set that the new VM should belong to when a failover is done. + +* `license_type` - (Optional) The License Type for this VM. Possible values are `NoLicenseType`, `NotSpecified` and `WindowsServer`. + +* `sql_server_license_type` - (Optional) The SQL Server License Type for this VM. Possible values are `NotSpecified`, `NoLicenseType`, `AHUB` and `PAYG`. + +* `target_proximity_placement_group_id` - (Optional) ID of Proximity Placement Group the new VM should belong to when a failover is done. + +* `target_vm_tags` - (Optional) A mapping of tags assigned to the replicated VM. + +* `target_disk_tags` - (Optional) A mapping of tags assigned to the disks of the replicated VM. + +* `target_network_interface_tags` - (Optional) A mapping of tags assigned to the Network Interfaces of the replicated VM. + +--- + +A `managed_disk` block supports the following: + +* `disk_name` - (Required) Name of the disks from the source VM. Changing this forces a new resource to be created. + +* `target_disk_type` - (Required) What type should the disk be when a failover is done. Possible values are `Standard_LRS`, `Premium_LRS`and `StandardSSD_LRS`. Changing this forces a new resource to be created. + +* `target_disk_encryption_set_id` - (Optional) The Disk Encryption Set that the Managed Disk will be associated with. + +-> **NOTE:** Creating replicated vm with `target_disk_encryption_set_id` wil take more time (up to 5 hours), please extend the `timeout` for `create`. + +--- + +A `network_interface` block supports the following: + +* `network_name` - (Required) Name of the Network in source VM. + +* `target_static_ip` - (Optional) Static IP to assign when a failover is done. + +* `target_subnet_name` - (Optional) Name of the subnet to use when a failover is done. + +* `is_primary` - (Optional) Whether this `network_interface` is primary for the replicated VM. Defaults to `true`. + +-> **NOTE:** Only allowed to set `is_primary` to `true` for one `network_interface`. + +* `failover_enabled` - (Optional) Whether this `network_interface` should be created when a failover is done. Defaults to `true`. + +## Attributes Reference + +In addition to the arguments above, the following attributes are exported: + +* `id` - The ID of the Site Recovery Replicated VM. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions: + +* `create` - (Defaults to 3 hours) Used when creating the Site Recovery HyperV Replicated VM. +* `update` - (Defaults to 80 minutes) Used when updating the Site Recovery HyperV Replicated VM. +* `read` - (Defaults to 5 minutes) Used when retrieving the Site Recovery HyperV Replicated VM. +* `delete` - (Defaults to 80 minutes) Used when deleting the Site Recovery HyperV Replicated VM. + +## Import + +Site Recovery Replicated VM's can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_site_recovery_hyperv_replicated_vm.vmreplication /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resource-group-name/providers/Microsoft.RecoveryServices/vaults/recovery-vault-name/replicationFabrics/fabric-name/replicationProtectionContainers/protection-container-name/replicationProtectedItems/vm-replication-name +``` From c0afd520d39c8f31f49d162a32f89eab108d5c13 Mon Sep 17 00:00:00 2001 From: ziyeqf Date: Tue, 7 Mar 2023 13:11:37 +0800 Subject: [PATCH 02/13] update code --- ...recovery_services_vault_hyperv_host_test.go | 9 ++++++--- ...e_recovery_hyperv_replicated_vm_resource.go | 18 +++++++++++------- ...overy_hyperv_replicated_vm_resource_test.go | 2 +- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/internal/services/recoveryservices/recovery_services_vault_hyperv_host_test.go b/internal/services/recoveryservices/recovery_services_vault_hyperv_host_test.go index 10db126cda33..a3cf7c6a29ba 100644 --- a/internal/services/recoveryservices/recovery_services_vault_hyperv_host_test.go +++ b/internal/services/recoveryservices/recovery_services_vault_hyperv_host_test.go @@ -14,7 +14,8 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/utils" ) -const LetterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +const LowerLetterBytes = "abcdefghijklmnopqrstuvwxyz" +const UpperLetterBytes = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" const NumberBytes = "1234567890" const SpecialBytes = "!@#$%^()" @@ -22,13 +23,15 @@ func GenerateRandomPassword(n int) string { b := make([]byte, n) for i := range b { r := rand.Int() - switch r % 3 { + switch r % 4 { case 0: - b[i] = LetterBytes[rand.Intn(len(LetterBytes))] + b[i] = LowerLetterBytes[rand.Intn(len(LowerLetterBytes))] case 1: b[i] = SpecialBytes[rand.Intn(len(SpecialBytes))] case 2: b[i] = NumberBytes[rand.Intn(len(NumberBytes))] + case 3: + b[i] = UpperLetterBytes[rand.Intn(len(UpperLetterBytes))] } } return string(b) diff --git a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go index 3daac2f93302..98f934fb233f 100644 --- a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go +++ b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go @@ -42,7 +42,7 @@ type SiteRecoveryHyperVReplicatedVMModel struct { PolicyId string `tfschema:"replication_policy_id"` OsType string `tfschema:"os_type"` OSDiskName string `tfschema:"os_disk_name"` - DiskNamesToInclude []string `tfschema:"disk_to_include"` + DiskNamesToInclude []string `tfschema:"disks_to_include"` TargetStorageAccountId string `tfschema:"target_storage_account_id"` TargetNetworkId string `tfschema:"target_network_id"` TargetAvailabilityZone string `tfschema:"target_availability_zone"` @@ -54,7 +54,7 @@ type SiteRecoveryHyperVReplicatedVMModel struct { SqlServerLicenseType string `tfschema:"sql_server_license_type"` TargetAvailabilitySetId string `tfschema:"target_availability_set_id"` TargetManagedDiskTags map[string]string `tfschema:"target_disk_tags"` - TargetNicTags map[string]string `tfschema:"target_nic_tags"` + TargetNicTags map[string]string `tfschema:"target_network_interface_tags"` TargetProximityPlacementGroupId string `tfschema:"target_proximity_placement_group_id"` TargetVMSize string `tfschema:"target_vm_size"` TargetVMTags map[string]string `tfschema:"target_vm_tags"` @@ -231,9 +231,10 @@ func (s SiteRecoveryHyperVReplicatedVMResource) Arguments() map[string]*schema.S }, "target_vm_size": { - Type: pluginsdk.TypeString, - Optional: true, - Computed: true, + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringIsNotEmpty, }, "target_availability_zone": { @@ -505,7 +506,7 @@ func (s SiteRecoveryHyperVReplicatedVMResource) Read() sdk.ResourceFunc { } if prop.PolicyId != nil { - state.PolicyId = *prop.PolicyId + state.PolicyId = handleAzureSdkForGoBug2824(*prop.PolicyId) } if prop.ProviderSpecificDetails != nil { @@ -662,7 +663,9 @@ func (s SiteRecoveryHyperVReplicatedVMResource) Delete() sdk.ResourceFunc { return fmt.Errorf("parsing %s: %+v", metadata.ResourceData.Id(), err) } - err = client.DeleteThenPoll(ctx, *id, replicationprotecteditems.DisableProtectionInput{}) + err = client.DeleteThenPoll(ctx, *id, replicationprotecteditems.DisableProtectionInput{ + Properties: replicationprotecteditems.DisableProtectionInputProperties{}, + }) if err != nil { return fmt.Errorf("deleting %s: %+v", id, err) } @@ -854,6 +857,7 @@ func HyperVReplicatedVMUpdateInternal(ctx context.Context, metadata sdk.Resource TargetProximityPlacementGroupId: &plan.TargetProximityPlacementGroupId, TargetVMTags: &plan.TargetVMTags, DiskIdToDiskEncryptionMap: &diskIdToDiskEncryptionMap, + UseManagedDisks: utils.String(strconv.FormatBool(plan.UseManagedDiskEnabled)), }, }, } diff --git a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go index e0087fe558d5..68fa31e5eee9 100644 --- a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go +++ b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go @@ -235,7 +235,7 @@ resource "azurerm_site_recovery_hyperv_replicated_vm" "test" { enable_rdp_or_ssh_on_target_option = "Always" network_interface { network_name = "HyperV-NAT" - target_static_ip = "10.0.10.5" + target_static_ip = "192.168.2.5" target_subnet_name = azurerm_subnet.target.name is_primary = true failover_enabled = true From b25df03dc1c8c9871100187ad8266346810e7711 Mon Sep 17 00:00:00 2001 From: ziyeqf Date: Tue, 7 Mar 2023 16:12:00 +0800 Subject: [PATCH 03/13] add azuresdkhacks for hyperv replicated vm --- .../azuresdkhacks/replicateditems_client.go | 18 +++++ .../replicateditems_method_delete.go | 77 +++++++++++++++++++ .../azuresdkhacks/replicateditems_model.go | 8 ++ .../recoveryservices/client/client.go | 5 ++ ..._recovery_hyperv_replicated_vm_resource.go | 46 ++++++----- ...very_hyperv_replicated_vm_resource_test.go | 7 +- 6 files changed, 142 insertions(+), 19 deletions(-) create mode 100644 internal/services/recoveryservices/azuresdkhacks/replicateditems_client.go create mode 100644 internal/services/recoveryservices/azuresdkhacks/replicateditems_method_delete.go create mode 100644 internal/services/recoveryservices/azuresdkhacks/replicateditems_model.go diff --git a/internal/services/recoveryservices/azuresdkhacks/replicateditems_client.go b/internal/services/recoveryservices/azuresdkhacks/replicateditems_client.go new file mode 100644 index 000000000000..e431e653ac9f --- /dev/null +++ b/internal/services/recoveryservices/azuresdkhacks/replicateditems_client.go @@ -0,0 +1,18 @@ +package azuresdkhacks + +import "github.com/Azure/go-autorest/autorest" + +// TODO 4.0: check if this is could be removed +// workaround for https://github.com/Azure/azure-rest-api-specs/issues/22947 + +type ReplicationProtectedItemsClient struct { + Client autorest.Client + BaseUri string +} + +func NewReplicationProtectedItemsClientWithBaseURI(endpoint string) ReplicationProtectedItemsClient { + return ReplicationProtectedItemsClient{ + Client: autorest.NewClientWithUserAgent(userAgent()), + BaseUri: endpoint, + } +} diff --git a/internal/services/recoveryservices/azuresdkhacks/replicateditems_method_delete.go b/internal/services/recoveryservices/azuresdkhacks/replicateditems_method_delete.go new file mode 100644 index 000000000000..e5e84345d186 --- /dev/null +++ b/internal/services/recoveryservices/azuresdkhacks/replicateditems_method_delete.go @@ -0,0 +1,77 @@ +package azuresdkhacks + +import ( + "context" + "fmt" + "net/http" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/hashicorp/go-azure-helpers/polling" + "github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotecteditems" +) + +type DeleteOperationResponse struct { + Poller polling.LongRunningPoller + HttpResponse *http.Response +} + +// Delete ... +func (c ReplicationProtectedItemsClient) Delete(ctx context.Context, id replicationprotecteditems.ReplicationProtectedItemId, input DisableProtectionInput) (result DeleteOperationResponse, err error) { + req, err := c.preparerForDelete(ctx, id, input) + if err != nil { + err = autorest.NewErrorWithError(err, "replicationprotecteditems.ReplicationProtectedItemsClient", "Delete", nil, "Failure preparing request") + return + } + + result, err = c.senderForDelete(ctx, req) + if err != nil { + err = autorest.NewErrorWithError(err, "replicationprotecteditems.ReplicationProtectedItemsClient", "Delete", result.HttpResponse, "Failure sending request") + return + } + + return +} + +// DeleteThenPoll performs Delete then polls until it's completed +func (c ReplicationProtectedItemsClient) DeleteThenPoll(ctx context.Context, id replicationprotecteditems.ReplicationProtectedItemId, input DisableProtectionInput) error { + result, err := c.Delete(ctx, id, input) + if err != nil { + return fmt.Errorf("performing Delete: %+v", err) + } + + if err := result.Poller.PollUntilDone(); err != nil { + return fmt.Errorf("polling after Delete: %+v", err) + } + + return nil +} + +// preparerForDelete prepares the Delete request. +func (c ReplicationProtectedItemsClient) preparerForDelete(ctx context.Context, id replicationprotecteditems.ReplicationProtectedItemId, input DisableProtectionInput) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPost(), + autorest.WithBaseURL(c.BaseUri), + autorest.WithPath(fmt.Sprintf("%s/remove", id.ID())), + autorest.WithJSON(input), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// senderForDelete sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (c ReplicationProtectedItemsClient) senderForDelete(ctx context.Context, req *http.Request) (future DeleteOperationResponse, err error) { + var resp *http.Response + resp, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + return + } + + future.Poller, err = polling.NewPollerFromResponse(ctx, resp, c.Client, req.Method) + return +} diff --git a/internal/services/recoveryservices/azuresdkhacks/replicateditems_model.go b/internal/services/recoveryservices/azuresdkhacks/replicateditems_model.go new file mode 100644 index 000000000000..af6fc667cfe0 --- /dev/null +++ b/internal/services/recoveryservices/azuresdkhacks/replicateditems_model.go @@ -0,0 +1,8 @@ +package azuresdkhacks + +type DisableProtectionInput struct { + Properties EmptyInput `json:"properties"` +} + +type EmptyInput struct { +} diff --git a/internal/services/recoveryservices/client/client.go b/internal/services/recoveryservices/client/client.go index fd25c6322aee..bd0005ad6c7a 100644 --- a/internal/services/recoveryservices/client/client.go +++ b/internal/services/recoveryservices/client/client.go @@ -41,6 +41,7 @@ type Client struct { NetworkMappingClient *replicationnetworkmappings.ReplicationNetworkMappingsClient ReplicationProtectableItemsClient *replicationprotectableitems.ReplicationProtectableItemsClient ReplicationProtectedItemsClient *replicationprotecteditems.ReplicationProtectedItemsClient + HackedReplicationProtectedItemsClient *azuresdkhacks.ReplicationProtectedItemsClient ReplicationRecoveryPlansClient *replicationrecoveryplans.ReplicationRecoveryPlansClient } @@ -108,6 +109,9 @@ func NewClient(o *common.ClientOptions) *Client { replicationRecoveryPlanClient := replicationrecoveryplans.NewReplicationRecoveryPlansClientWithBaseURI(o.ResourceManagerEndpoint) o.ConfigureClient(&replicationRecoveryPlanClient.Client, o.ResourceManagerAuthorizer) + hackedReplicationProtectedItemsClient := azuresdkhacks.NewReplicationProtectedItemsClientWithBaseURI(o.ResourceManagerEndpoint) + o.ConfigureClient(&hackedReplicationProtectedItemsClient.Client, o.ResourceManagerAuthorizer) + return &Client{ ProtectableItemsClient: &protectableItemsClient, ProtectedItemsClient: &protectedItemsClient, @@ -130,5 +134,6 @@ func NewClient(o *common.ClientOptions) *Client { ReplicationProtectableItemsClient: &replicationProtectableItemsCLient, ReplicationProtectedItemsClient: &replicationMigrationItemsClient, ReplicationRecoveryPlansClient: &replicationRecoveryPlanClient, + HackedReplicationProtectedItemsClient: &hackedReplicationProtectedItemsClient, } } diff --git a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go index 98f934fb233f..5ca18188bc78 100644 --- a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go +++ b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go @@ -18,6 +18,7 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/helpers/azure" "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" "github.com/hashicorp/terraform-provider-azurerm/internal/services/compute/validate" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/recoveryservices/azuresdkhacks" storageValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tags" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" @@ -403,6 +404,9 @@ func (s SiteRecoveryHyperVReplicatedVMResource) Create() sdk.ResourceFunc { diskId = *d.VhdId break } + if *d.VhdName == plan.OSDiskName { + osVHDId = *d.VhdId + } } if diskId == "" { return fmt.Errorf("disk %s not found in protectable item", disk.DiskName) @@ -443,6 +447,7 @@ func (s SiteRecoveryHyperVReplicatedVMResource) Create() sdk.ResourceFunc { UseManagedDisks: utils.String(strconv.FormatBool(plan.UseManagedDiskEnabled)), TargetManagedDiskTags: &plan.TargetManagedDiskTags, TargetVMTags: &plan.TargetVMTags, + TargetNicTags: &plan.TargetNicTags, TargetVMSize: &plan.TargetVMSize, DisksToIncludeForManagedDisks: &diskToIncludeForManagedDisks, EnableRdpOnTargetOption: &plan.EnableRdpOnTargetOption, @@ -529,19 +534,7 @@ func (s SiteRecoveryHyperVReplicatedVMResource) Read() sdk.ResourceFunc { if detail.OSDetails != nil && detail.OSDetails.OsType != nil { state.OsType = *detail.OSDetails.OsType } - if detail.AzureVMDiskDetails != nil { - var diskNames []string - for _, disk := range *detail.AzureVMDiskDetails { - if disk.VhdName != nil { - diskNames = append(diskNames, *disk.VhdName) - } - if disk.VhdType != nil && strings.EqualFold(*disk.VhdType, "OperatingSystem") { - state.OSDiskName = *disk.VhdName - } - } - state.DiskNamesToInclude = diskNames - } if detail.RecoveryAzureStorageAccount != nil { state.TargetStorageAccountId = *detail.RecoveryAzureStorageAccount } @@ -572,7 +565,7 @@ func (s SiteRecoveryHyperVReplicatedVMResource) Read() sdk.ResourceFunc { } } if nic.SelectionType != nil { - o.FailoverEnabled = strings.EqualFold(*nic.SelectionType, "NotSelected") + o.FailoverEnabled = !strings.EqualFold(*nic.SelectionType, "NotSelected") } if nic.NicId != nil && *nic.NicId == primaryNicId { o.IsPrimary = true @@ -588,6 +581,23 @@ func (s SiteRecoveryHyperVReplicatedVMResource) Read() sdk.ResourceFunc { } } + if detail.AzureVMDiskDetails != nil { + // no matter use managed disk or not, it will return in AzureVMDiskDetails + // but if it's not using managed disk, flatten it will cause force update. + var diskNames []string + for _, disk := range *detail.AzureVMDiskDetails { + if disk.VhdName != nil { + diskNames = append(diskNames, *disk.VhdName) + } + if disk.VhdType != nil && strings.EqualFold(*disk.VhdType, "OperatingSystem") { + state.OSDiskName = *disk.VhdName + } + } + if !state.UseManagedDiskEnabled { + state.DiskNamesToInclude = diskNames + } + } + if detail.ProtectedManagedDisks != nil { diskIdToNameMap, _, err := fetchProtectableDiskNameIdMap(ctx, metadata.Client.RecoveryServices.ReplicationProtectableItemsClient, *prop.ProtectableItemId) if err != nil { @@ -629,6 +639,9 @@ func (s SiteRecoveryHyperVReplicatedVMResource) Read() sdk.ResourceFunc { if detail.TargetVMTags != nil { state.TargetVMTags = *detail.TargetVMTags } + if detail.TargetNicTags != nil { + state.TargetNicTags = *detail.TargetNicTags + } if detail.RecoveryAzureLogStorageAccountId != nil { state.LogStorageAccountId = *detail.RecoveryAzureLogStorageAccountId } @@ -656,16 +669,13 @@ func (s SiteRecoveryHyperVReplicatedVMResource) Delete() sdk.ResourceFunc { return sdk.ResourceFunc{ Timeout: 80 * time.Minute, Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { - client := metadata.Client.RecoveryServices.ReplicationProtectedItemsClient - + client := metadata.Client.RecoveryServices.HackedReplicationProtectedItemsClient id, err := replicationprotecteditems.ParseReplicationProtectedItemID(metadata.ResourceData.Id()) if err != nil { return fmt.Errorf("parsing %s: %+v", metadata.ResourceData.Id(), err) } - err = client.DeleteThenPoll(ctx, *id, replicationprotecteditems.DisableProtectionInput{ - Properties: replicationprotecteditems.DisableProtectionInputProperties{}, - }) + err = client.DeleteThenPoll(ctx, *id, azuresdkhacks.DisableProtectionInput{}) if err != nil { return fmt.Errorf("deleting %s: %+v", id, err) } diff --git a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go index 68fa31e5eee9..4e3e99982c41 100644 --- a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go +++ b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go @@ -42,7 +42,8 @@ func TestAccSiteRecoveryHyperVReplicatedVM_complete(t *testing.T) { data.ResourceTest(t, r, append(hostResource.PrepareHostTestSteps(data, adminPwd), []acceptance.TestStep{ { - Config: r.complete(data, adminPwd), + PreConfig: func() { time.Sleep(5 * time.Minute) }, // sleep 5 minutes to wait for the host registration fully finished. + Config: r.complete(data, adminPwd), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), @@ -100,6 +101,8 @@ resource "azurerm_site_recovery_hyperv_replicated_vm" "test" { network_name = "HyperV-NAT" target_subnet_name = azurerm_subnet.target.name } + + depends_on = [azurerm_site_recovery_hyperv_replication_policy_association.test] } `, SiteRecoverHyperVReplicationPolicyAssociationResource{}.basic(data, adminPwd), data.RandomInteger, data.Locations.Primary, data.RandomString) } @@ -252,6 +255,8 @@ resource "azurerm_site_recovery_hyperv_replicated_vm" "test" { target_network_interface_tags = { tag = "foo" } + + depends_on = [azurerm_site_recovery_hyperv_replication_policy_association.test] } `, SiteRecoverHyperVReplicationPolicyAssociationResource{}.basic(data, adminPwd), data.RandomInteger, data.Locations.Primary, data.RandomString) } From ee9d7c48099ca9e744cd96fba1ac72c172777365 Mon Sep 17 00:00:00 2001 From: ziyeqf Date: Wed, 8 Mar 2023 12:05:57 +0800 Subject: [PATCH 04/13] remove `managed_disk` as it's not returned by service --- ..._recovery_hyperv_replicated_vm_resource.go | 175 +++--------------- ...very_hyperv_replicated_vm_resource_test.go | 6 +- 2 files changed, 28 insertions(+), 153 deletions(-) diff --git a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go index 5ca18188bc78..a9dea507887f 100644 --- a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go +++ b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go @@ -17,7 +17,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-azurerm/helpers/azure" "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/compute/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/services/recoveryservices/azuresdkhacks" storageValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tags" @@ -49,7 +48,6 @@ type SiteRecoveryHyperVReplicatedVMModel struct { TargetAvailabilityZone string `tfschema:"target_availability_zone"` NetworkInterface []SiteRecoveryHyperVReplicatedVMNetworkInterfaceModel `tfschema:"network_interface"` UseManagedDiskEnabled bool `tfschema:"use_managed_disk_enabled"` - ManagedDisks []SiteRecoveryHyperVReplicatedVMManagedDiskModel `tfschema:"managed_disk"` EnableRdpOnTargetOption string `tfschema:"enable_rdp_or_ssh_on_target_option"` LicenseType string `tfschema:"license_type"` SqlServerLicenseType string `tfschema:"sql_server_license_type"` @@ -70,12 +68,6 @@ type SiteRecoveryHyperVReplicatedVMNetworkInterfaceModel struct { FailoverEnabled bool `tfschema:"failover_enabled"` } -type SiteRecoveryHyperVReplicatedVMManagedDiskModel struct { - DiskName string `tfschema:"disk_name"` - DiskEncryptionSetId string `tfschema:"target_disk_encryption_set_id"` - DiskType string `tfschema:"target_disk_type"` -} - type SiteRecoveryHyperVReplicatedVMResource struct{} var _ sdk.Resource = SiteRecoveryHyperVReplicatedVMResource{} @@ -149,10 +141,9 @@ func (s SiteRecoveryHyperVReplicatedVMResource) Arguments() map[string]*schema.S }, "disks_to_include": { - Type: pluginsdk.TypeList, - Optional: true, - ForceNew: true, - ConflictsWith: []string{"use_managed_disk_enabled", "managed_disk"}, + Type: pluginsdk.TypeList, + Required: true, + ForceNew: true, Elem: &pluginsdk.Schema{ Type: pluginsdk.TypeString, }, @@ -165,40 +156,6 @@ func (s SiteRecoveryHyperVReplicatedVMResource) Arguments() map[string]*schema.S ForceNew: true, }, - "managed_disk": { - Type: pluginsdk.TypeSet, - ConfigMode: pluginsdk.SchemaConfigModeAttr, - Optional: true, - ForceNew: true, - RequiredWith: []string{"use_managed_disk_enabled"}, - Set: resourceSiteRecoveryReplicatedVMDiskHash, - Elem: &pluginsdk.Resource{ - Schema: map[string]*pluginsdk.Schema{ - "disk_name": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringIsNotEmpty, - }, - "target_disk_encryption_set_id": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: validate.DiskEncryptionSetID, - }, - "target_disk_type": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringInSlice([]string{ - string(replicationprotecteditems.DiskAccountTypePremiumLRS), - string(replicationprotecteditems.DiskAccountTypeStandardLRS), - string(replicationprotecteditems.DiskAccountTypeStandardSSDLRS), - }, false), - }, - }, - }, - }, - "log_storage_account_id": { Type: pluginsdk.TypeString, Optional: true, @@ -280,6 +237,7 @@ func (s SiteRecoveryHyperVReplicatedVMResource) Arguments() map[string]*schema.S "target_proximity_placement_group_id": { Type: pluginsdk.TypeString, + RequiredWith: []string{"use_managed_disk_enabled"}, Optional: true, ValidateFunc: proximityplacementgroups.ValidateProximityPlacementGroupID, }, @@ -395,37 +353,12 @@ func (s SiteRecoveryHyperVReplicatedVMResource) Create() sdk.ResourceFunc { osVHDId := "" diskIdsToInclude := make([]string, 0) - var diskToIncludeForManagedDisks []replicationprotecteditems.HyperVReplicaAzureDiskInputDetails - if plan.UseManagedDiskEnabled { - for _, disk := range plan.ManagedDisks { - diskId := "" - for _, d := range *customDetail.DiskDetails { - if *d.VhdName == disk.DiskName { - diskId = *d.VhdId - break - } - if *d.VhdName == plan.OSDiskName { - osVHDId = *d.VhdId - } - } - if diskId == "" { - return fmt.Errorf("disk %s not found in protectable item", disk.DiskName) - } - diskType := replicationprotecteditems.DiskAccountType(disk.DiskType) - diskToIncludeForManagedDisks = append(diskToIncludeForManagedDisks, replicationprotecteditems.HyperVReplicaAzureDiskInputDetails{ - DiskId: &diskId, - DiskEncryptionSetId: &disk.DiskEncryptionSetId, - DiskType: &diskType, - }) + for _, disk := range *customDetail.DiskDetails { + if *disk.VhdName == plan.OSDiskName { + osVHDId = *disk.VhdId } - } else { - for _, disk := range *customDetail.DiskDetails { - if *disk.VhdName == plan.OSDiskName { - osVHDId = *disk.VhdId - } - if utils.SliceContainsValue(plan.DiskNamesToInclude, *disk.VhdName) { - diskIdsToInclude = append(diskIdsToInclude, *disk.VhdId) - } + if utils.SliceContainsValue(plan.DiskNamesToInclude, *disk.VhdName) { + diskIdsToInclude = append(diskIdsToInclude, *disk.VhdId) } } @@ -436,24 +369,23 @@ func (s SiteRecoveryHyperVReplicatedVMResource) Create() sdk.ResourceFunc { PolicyId: &plan.PolicyId, ProtectableItemId: protectableItem.Id, ProviderSpecificDetails: &replicationprotecteditems.HyperVReplicaAzureEnableProtectionInput{ - OsType: &plan.OsType, - TargetAzureVMName: &plan.TargetVMName, - VhdId: &osVHDId, - DisksToInclude: &diskIdsToInclude, - TargetAzureV2ResourceGroupId: &plan.TargetResourceGroupId, - TargetAvailabilityZone: &plan.TargetAvailabilityZone, - TargetStorageAccountId: &plan.TargetStorageAccountId, - TargetAvailabilitySetId: &plan.TargetAvailabilitySetId, - UseManagedDisks: utils.String(strconv.FormatBool(plan.UseManagedDiskEnabled)), - TargetManagedDiskTags: &plan.TargetManagedDiskTags, - TargetVMTags: &plan.TargetVMTags, - TargetNicTags: &plan.TargetNicTags, - TargetVMSize: &plan.TargetVMSize, - DisksToIncludeForManagedDisks: &diskToIncludeForManagedDisks, - EnableRdpOnTargetOption: &plan.EnableRdpOnTargetOption, - LicenseType: &licenseType, - SqlServerLicenseType: &sqlLicenseType, - LogStorageAccountId: &plan.LogStorageAccountId, + OsType: &plan.OsType, + TargetAzureVMName: &plan.TargetVMName, + VhdId: &osVHDId, + DisksToInclude: &diskIdsToInclude, + TargetAzureV2ResourceGroupId: &plan.TargetResourceGroupId, + TargetAvailabilityZone: &plan.TargetAvailabilityZone, + TargetStorageAccountId: &plan.TargetStorageAccountId, + TargetAvailabilitySetId: &plan.TargetAvailabilitySetId, + UseManagedDisks: utils.String(strconv.FormatBool(plan.UseManagedDiskEnabled)), + TargetManagedDiskTags: &plan.TargetManagedDiskTags, + TargetVMTags: &plan.TargetVMTags, + TargetNicTags: &plan.TargetNicTags, + TargetVMSize: &plan.TargetVMSize, + EnableRdpOnTargetOption: &plan.EnableRdpOnTargetOption, + LicenseType: &licenseType, + SqlServerLicenseType: &sqlLicenseType, + LogStorageAccountId: &plan.LogStorageAccountId, }, }, } @@ -593,31 +525,9 @@ func (s SiteRecoveryHyperVReplicatedVMResource) Read() sdk.ResourceFunc { state.OSDiskName = *disk.VhdName } } - if !state.UseManagedDiskEnabled { - state.DiskNamesToInclude = diskNames - } + state.DiskNamesToInclude = diskNames } - if detail.ProtectedManagedDisks != nil { - diskIdToNameMap, _, err := fetchProtectableDiskNameIdMap(ctx, metadata.Client.RecoveryServices.ReplicationProtectableItemsClient, *prop.ProtectableItemId) - if err != nil { - return fmt.Errorf("fetching Disk Name to Id Map by Protectable Item Id %s: %+v", *prop.ProtectableItemId, err) - } - var outputs []SiteRecoveryHyperVReplicatedVMManagedDiskModel - for _, disk := range *detail.ProtectedManagedDisks { - o := SiteRecoveryHyperVReplicatedVMManagedDiskModel{} - if disk.DiskEncryptionSetId != nil { - o.DiskEncryptionSetId = *disk.DiskEncryptionSetId - } - if disk.ReplicaDiskType != nil { - o.DiskType = *disk.ReplicaDiskType - } - if v, existing := diskIdToNameMap[*disk.DiskId]; existing { - o.DiskName = v - } - } - state.ManagedDisks = outputs - } if detail.EnableRdpOnTargetOption != nil { state.EnableRdpOnTargetOption = *detail.EnableRdpOnTargetOption } @@ -709,30 +619,6 @@ func fetchProtectableItemByVMName(ctx context.Context, client *replicationprotec return nil, fmt.Errorf("protectable item with vm name %s not found", vmName) } -func fetchProtectableDiskNameIdMap(ctx context.Context, client *replicationprotectableitems.ReplicationProtectableItemsClient, protectableItemId string) (idToName map[string]string, nameToId map[string]string, err error) { - idToName = make(map[string]string) - nameToId = make(map[string]string) - protectableItem, err := fetchProtectableItemById(ctx, client, protectableItemId) - if err != nil { - return idToName, nameToId, fmt.Errorf("retrieving %s: %+v", protectableItemId, err) - } - - if protectableItem.Properties != nil && protectableItem.Properties.CustomDetails != nil { - if customDetail, ok := protectableItem.Properties.CustomDetails.(replicationprotectableitems.HyperVVirtualMachineDetails); ok { - if customDetail.DiskDetails != nil { - for _, disk := range *customDetail.DiskDetails { - if disk.VhdName != nil && disk.VhdId != nil { - nameToId[*disk.VhdName] = *disk.VhdId - idToName[*disk.VhdId] = *disk.VhdName - } - } - } - } - } - - return idToName, nameToId, nil -} - func fetchVMNameByProtectableItemId(ctx context.Context, client *replicationprotectableitems.ReplicationProtectableItemsClient, protectableItemId string) (string, error) { protectableItem, err := fetchProtectableItemById(ctx, client, protectableItemId) if err != nil { @@ -841,12 +727,6 @@ func HyperVReplicatedVMUpdateInternal(ctx context.Context, metadata sdk.Resource if existing.Model.Properties == nil || existing.Model.Properties.ProtectableItemId == nil { return fmt.Errorf("retrieving %s: properties or protectableItemId was nil", id) } - _, diskNameToIdMap, err := fetchProtectableDiskNameIdMap(ctx, metadata.Client.RecoveryServices.ReplicationProtectableItemsClient, *existing.Model.Properties.ProtectableItemId) - diskIdToDiskEncryptionMap := make(map[string]string, 0) - for _, disk := range plan.ManagedDisks { - vhdId := diskNameToIdMap[disk.DiskName] - diskIdToDiskEncryptionMap[vhdId] = disk.DiskEncryptionSetId - } licenseType := replicationprotecteditems.LicenseType(plan.LicenseType) sqlServerLicenseType := replicationprotecteditems.SqlServerLicenseType(plan.SqlServerLicenseType) input := replicationprotecteditems.UpdateReplicationProtectedItemInput{ @@ -866,7 +746,6 @@ func HyperVReplicatedVMUpdateInternal(ctx context.Context, metadata sdk.Resource TargetNicTags: &plan.TargetNicTags, TargetProximityPlacementGroupId: &plan.TargetProximityPlacementGroupId, TargetVMTags: &plan.TargetVMTags, - DiskIdToDiskEncryptionMap: &diskIdToDiskEncryptionMap, UseManagedDisks: utils.String(strconv.FormatBool(plan.UseManagedDiskEnabled)), }, }, diff --git a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go index 4e3e99982c41..bd80967bb568 100644 --- a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go +++ b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go @@ -229,11 +229,7 @@ resource "azurerm_site_recovery_hyperv_replicated_vm" "test" { os_disk_name = "VM1" target_network_id = azurerm_virtual_network.target.id use_managed_disk_enabled = true - managed_disk { - disk_name = "VM1" - target_disk_encryption_set_id = azurerm_disk_encryption_set.target.id - target_disk_type = "Standard_LRS" - } + disks_to_include = ["VM1"] log_storage_account_id = azurerm_storage_account.target.id enable_rdp_or_ssh_on_target_option = "Always" network_interface { From 84fdc6e5c1541817658761abba056b4943859ef3 Mon Sep 17 00:00:00 2001 From: ziyeqf Date: Wed, 8 Mar 2023 17:22:39 +0800 Subject: [PATCH 05/13] adjust test case to remove before destroy.. --- ...ecovery_services_vault_hyperv_host_test.go | 35 +++--- ...very_hyperv_replicated_vm_resource_test.go | 102 ++++-------------- ...cation_policy_association_resource_test.go | 27 +++-- 3 files changed, 57 insertions(+), 107 deletions(-) diff --git a/internal/services/recoveryservices/recovery_services_vault_hyperv_host_test.go b/internal/services/recoveryservices/recovery_services_vault_hyperv_host_test.go index a3cf7c6a29ba..b92d6b8ef508 100644 --- a/internal/services/recoveryservices/recovery_services_vault_hyperv_host_test.go +++ b/internal/services/recoveryservices/recovery_services_vault_hyperv_host_test.go @@ -103,7 +103,7 @@ func (HyperVHostTestResource) rebootVirtualMachine(ctx context.Context, clients func (r HyperVHostTestResource) PrepareHostTestSteps(data acceptance.TestData, adminPwd string) (steps []acceptance.TestStep) { return []acceptance.TestStep{ { - Config: r.recovery(data), + Config: r.recovery(data, true), Check: acceptance.ComposeTestCheckFunc( // set the registration key value to environment variable. data.CheckWithClientForResource(r.generateHyperVHostRegistrationCert(func(xmlContent string) error { @@ -112,14 +112,14 @@ func (r HyperVHostTestResource) PrepareHostTestSteps(data acceptance.TestData, a ), }, { - Config: r.hyperVTemplate(data, adminPwd), // split complete template into two parts to reboot the server. + Config: r.hyperVTemplate(data, adminPwd, true), // split complete template into two parts to reboot the server. Check: acceptance.ComposeTestCheckFunc( data.CheckWithClientForResource(r.virtualMachineExists, "azurerm_windows_virtual_machine.host"), data.CheckWithClientForResource(r.rebootVirtualMachine, "azurerm_windows_virtual_machine.host"), ), }, { - Config: r.template(data, adminPwd), + Config: r.template(data, adminPwd, true), }, } } @@ -307,7 +307,19 @@ resource "azurerm_network_interface_security_group_association" "hybrid" { ` } -func (r HyperVHostTestResource) recovery(data acceptance.TestData) string { +// in creating, it should create `hyperv_site` before connect host to it +// but it needs to remove the `hyperv_site` before deleting the host. +func (r HyperVHostTestResource) recovery(data acceptance.TestData, includeSite bool) string { + siteBlock := "" + if includeSite { + siteBlock = ` +resource "azurerm_site_recovery_services_vault_hyperv_site" "test" { + name = local.recovery_site_name + recovery_vault_id = azurerm_recovery_services_vault.test.id +} +` + } + return fmt.Sprintf(` %s @@ -320,14 +332,11 @@ resource "azurerm_recovery_services_vault" "test" { soft_delete_enabled = false } -resource "azurerm_site_recovery_services_vault_hyperv_site" "test" { - name = local.recovery_site_name - recovery_vault_id = azurerm_recovery_services_vault.test.id -} -`, r.base(data)) +%s +`, r.base(data), siteBlock) } -func (r HyperVHostTestResource) hyperVTemplate(data acceptance.TestData, adminPwd string) string { +func (r HyperVHostTestResource) hyperVTemplate(data acceptance.TestData, adminPwd string, includeSite bool) string { return fmt.Sprintf(` %[1]s @@ -458,10 +467,10 @@ resource "azurerm_windows_virtual_machine" "host" { %[3]s %[4]s -`, r.recovery(data), adminPwd, r.keyVault(), r.securityGroup()) +`, r.recovery(data, includeSite), adminPwd, r.keyVault(), r.securityGroup()) } -func (r HyperVHostTestResource) template(data acceptance.TestData, adminPwd string) string { +func (r HyperVHostTestResource) template(data acceptance.TestData, adminPwd string, includeSite bool) string { return fmt.Sprintf(` %s # register the server could only be done by CustomScriptExtension because it requires local admin to run. @@ -533,5 +542,5 @@ resource "azurerm_virtual_machine_extension" "script" { ] } -`, r.hyperVTemplate(data, adminPwd), HostName) +`, r.hyperVTemplate(data, adminPwd, includeSite), HostName) } diff --git a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go index bd80967bb568..3c37d899d02d 100644 --- a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go +++ b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource_test.go @@ -31,6 +31,9 @@ func TestAccSiteRecoveryHyperVReplicatedVM_basic(t *testing.T) { ), }, data.ImportStep(), + { + Config: hostResource.template(data, adminPwd, false), + }, }...)) } @@ -49,6 +52,9 @@ func TestAccSiteRecoveryHyperVReplicatedVM_complete(t *testing.T) { ), }, data.ImportStep(), + { + Config: hostResource.template(data, adminPwd, false), + }, }...)) } @@ -139,78 +145,6 @@ resource "azurerm_subnet" "target" { address_prefixes = ["192.168.2.0/24"] } -resource "azurerm_key_vault" "target" { - name = "kv%[2]d" - location = azurerm_resource_group.target.location - resource_group_name = azurerm_resource_group.target.name - tenant_id = data.azurerm_client_config.current.tenant_id - sku_name = "standard" - enabled_for_disk_encryption = true - purge_protection_enabled = true -} - -resource "azurerm_key_vault_access_policy" "service-principal" { - key_vault_id = azurerm_key_vault.target.id - tenant_id = data.azurerm_client_config.current.tenant_id - object_id = data.azurerm_client_config.current.object_id - - key_permissions = [ - "Create", - "Delete", - "Get", - "Purge", - "Update", - ] - - secret_permissions = [ - "Get", - "Delete", - "Set", - ] -} - -resource "azurerm_key_vault_key" "target" { - name = "examplekey" - key_vault_id = azurerm_key_vault.target.id - key_type = "RSA" - key_size = 2048 - - key_opts = [ - "decrypt", - "encrypt", - "sign", - "unwrapKey", - "verify", - "wrapKey", - ] - - depends_on = ["azurerm_key_vault_access_policy.service-principal"] -} - -resource "azurerm_disk_encryption_set" "target" { - name = "acctestdes-%[2]d2" - resource_group_name = azurerm_resource_group.target.name - location = azurerm_resource_group.target.location - key_vault_key_id = azurerm_key_vault_key.target.id - - identity { - type = "SystemAssigned" - } -} - -resource "azurerm_key_vault_access_policy" "disk-encryption" { - key_vault_id = azurerm_key_vault.target.id - - key_permissions = [ - "Get", - "WrapKey", - "UnwrapKey", - ] - - tenant_id = azurerm_disk_encryption_set.target.identity.0.tenant_id - object_id = azurerm_disk_encryption_set.target.identity.0.principal_id -} - resource "azurerm_proximity_placement_group" "target" { name = "acctest-replication-%[2]d" location = azurerm_resource_group.target.location @@ -218,18 +152,18 @@ resource "azurerm_proximity_placement_group" "target" { } resource "azurerm_site_recovery_hyperv_replicated_vm" "test" { - name = "acctest-vm-%[2]d" - hyperv_site_id = azurerm_site_recovery_services_vault_hyperv_site.test.id - source_vm_name = "VM1" - target_resource_group_id = azurerm_resource_group.target.id - target_vm_name = "target-vm" - target_storage_account_id = azurerm_storage_account.target.id - replication_policy_id = azurerm_site_recovery_hyperv_replication_policy.test.id - os_type = "Windows" - os_disk_name = "VM1" - target_network_id = azurerm_virtual_network.target.id - use_managed_disk_enabled = true - disks_to_include = ["VM1"] + name = "acctest-vm-%[2]d" + hyperv_site_id = azurerm_site_recovery_services_vault_hyperv_site.test.id + source_vm_name = "VM1" + target_resource_group_id = azurerm_resource_group.target.id + target_vm_name = "target-vm" + target_storage_account_id = azurerm_storage_account.target.id + replication_policy_id = azurerm_site_recovery_hyperv_replication_policy.test.id + os_type = "Windows" + os_disk_name = "VM1" + target_network_id = azurerm_virtual_network.target.id + use_managed_disk_enabled = true + disks_to_include = ["VM1"] log_storage_account_id = azurerm_storage_account.target.id enable_rdp_or_ssh_on_target_option = "Always" network_interface { diff --git a/internal/services/recoveryservices/site_recovery_hyperv_replication_policy_association_resource_test.go b/internal/services/recoveryservices/site_recovery_hyperv_replication_policy_association_resource_test.go index 5137fb8dedd6..859b1f79497f 100644 --- a/internal/services/recoveryservices/site_recovery_hyperv_replication_policy_association_resource_test.go +++ b/internal/services/recoveryservices/site_recovery_hyperv_replication_policy_association_resource_test.go @@ -21,15 +21,20 @@ func TestAccSiteRecoveryHyperVReplicationPolicyAssociation_basic(t *testing.T) { hostResource := HyperVHostTestResource{} adminPwd := GenerateRandomPassword(10) - data.ResourceTest(t, r, append(hostResource.PrepareHostTestSteps(data, adminPwd), []acceptance.TestStep{ - { - Config: r.basic(data, adminPwd), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - ), - }, - data.ImportStep(), - }...)) + data.ResourceTest(t, r, + append(hostResource.PrepareHostTestSteps(data, adminPwd), []acceptance.TestStep{ + { + Config: r.basic(data, adminPwd), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: hostResource.template(data, adminPwd, false), + }, + }...), + ) } func (SiteRecoverHyperVReplicationPolicyAssociationResource) basic(data acceptance.TestData, adminPwd string) string { @@ -48,8 +53,10 @@ resource "azurerm_site_recovery_hyperv_replication_policy_association" "test" { name = "test-association" hyperv_site_id = azurerm_site_recovery_services_vault_hyperv_site.test.id policy_id = azurerm_site_recovery_hyperv_replication_policy.test.id + + depends_on = [azurerm_windows_virtual_machine.host] } -`, HyperVHostTestResource{}.template(data, adminPwd), data.RandomInteger) +`, HyperVHostTestResource{}.template(data, adminPwd, true), data.RandomInteger) } func (t SiteRecoverHyperVReplicationPolicyAssociationResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { From 70270de84e43eb54dd4e19558790a394d3cc33e8 Mon Sep 17 00:00:00 2001 From: ziyeqf Date: Wed, 8 Mar 2023 17:36:30 +0800 Subject: [PATCH 06/13] update doc --- ...recovery_hyperv_replicated_vm.html.markdown | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/website/docs/r/site_recovery_hyperv_replicated_vm.html.markdown b/website/docs/r/site_recovery_hyperv_replicated_vm.html.markdown index 2ca209b80296..ac0b5463c005 100644 --- a/website/docs/r/site_recovery_hyperv_replicated_vm.html.markdown +++ b/website/docs/r/site_recovery_hyperv_replicated_vm.html.markdown @@ -115,10 +115,6 @@ The following arguments are supported: * `use_managed_disk_enabled` - (Optional) Whether to use managed disks in replication. Changing this forces a new resource to be created. Defaults to `false`. -* `managed_disk` - (Optional) One or more `managed_disk` block as defined below. Changing this forces a new resource to be created. - --> **NOTE:** If `use_managed_disk_enabled` is set to `true`, then `managed_disk` block must be specified. If `use_managed_disk_enabled` is set to `false`, then `disks_to_include` block must be specified. - * `log_storage_account_id` - (Optional) ID of the Storage Account to be used for logging during replication. Changing this forces a new resource to be created. * `enable_rdp_or_ssh_on_target_option` - (Optional) Options to enable RDP or SSH on replicated VM. Possible values are `Never`, `OnlyOnTestFailover` and `Always`. @@ -135,6 +131,8 @@ The following arguments are supported: * `target_proximity_placement_group_id` - (Optional) ID of Proximity Placement Group the new VM should belong to when a failover is done. +~> **NOTE:** When `target_proximity_placement_group_id` is specified, `use_managed_disk_enabled` must be set to `true`. + * `target_vm_tags` - (Optional) A mapping of tags assigned to the replicated VM. * `target_disk_tags` - (Optional) A mapping of tags assigned to the disks of the replicated VM. @@ -143,18 +141,6 @@ The following arguments are supported: --- -A `managed_disk` block supports the following: - -* `disk_name` - (Required) Name of the disks from the source VM. Changing this forces a new resource to be created. - -* `target_disk_type` - (Required) What type should the disk be when a failover is done. Possible values are `Standard_LRS`, `Premium_LRS`and `StandardSSD_LRS`. Changing this forces a new resource to be created. - -* `target_disk_encryption_set_id` - (Optional) The Disk Encryption Set that the Managed Disk will be associated with. - --> **NOTE:** Creating replicated vm with `target_disk_encryption_set_id` wil take more time (up to 5 hours), please extend the `timeout` for `create`. - ---- - A `network_interface` block supports the following: * `network_name` - (Required) Name of the Network in source VM. From eb684238239746b37e833cd3f7b3e9b211db303e Mon Sep 17 00:00:00 2001 From: ziyeqf Date: Wed, 8 Mar 2023 17:46:53 +0800 Subject: [PATCH 07/13] refresh vendor --- .../id_replicationprotectableitem.go | 3 +++ .../id_replicationprotectioncontainer.go | 3 +++ .../2022-10-01/replicationprotectableitems/predicates.go | 3 +++ 3 files changed, 9 insertions(+) diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectableitem.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectableitem.go index f68e86b4ae67..1b650ec79a41 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectableitem.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectableitem.go @@ -7,6 +7,9 @@ import ( "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" ) +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + var _ resourceids.ResourceId = ReplicationProtectableItemId{} // ReplicationProtectableItemId is a struct representing the Resource ID for a Replication Protectable Item diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectioncontainer.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectioncontainer.go index 4f2ef2c7ef18..70a56469f92e 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectioncontainer.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectioncontainer.go @@ -7,6 +7,9 @@ import ( "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" ) +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + var _ resourceids.ResourceId = ReplicationProtectionContainerId{} // ReplicationProtectionContainerId is a struct representing the Resource ID for a Replication Protection Container diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/predicates.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/predicates.go index 36eb2ae6240e..06bc4485e632 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/predicates.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/predicates.go @@ -1,5 +1,8 @@ package replicationprotectableitems +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + type ProtectableItemOperationPredicate struct { Id *string Location *string From b09c9a69a00b63176437dc04a676ff5ef2c47d69 Mon Sep 17 00:00:00 2001 From: ziyeqf Date: Wed, 8 Mar 2023 18:10:42 +0800 Subject: [PATCH 08/13] golint --- .../site_recovery_hyperv_replicated_vm_resource.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go index a9dea507887f..85c4845c61ea 100644 --- a/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go +++ b/internal/services/recoveryservices/site_recovery_hyperv_replicated_vm_resource.go @@ -716,7 +716,7 @@ func HyperVReplicatedVMUpdateInternal(ctx context.Context, metadata sdk.Resource RecoveryStaticIPAddress: &nic.TargetStaticIp, // per Portal behaviour, these two property are always set to true. // Primary Nic is selected by `selectedSourceNicId` parameter. - // Whether to create nic for failover is controled by `selectionType` + // Whether to create nic for failover is controlled by `selectionType` IsPrimary: utils.Bool(true), IsSeletedForFailover: utils.Bool(true), }, From e4bbcde2f99ee102d6df422e21c6209dc0ace1ee Mon Sep 17 00:00:00 2001 From: ziyeqf Date: Fri, 10 Mar 2023 10:54:52 +0800 Subject: [PATCH 09/13] add comment --- .../recoveryservices/recovery_services_vault_hyperv_host_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/services/recoveryservices/recovery_services_vault_hyperv_host_test.go b/internal/services/recoveryservices/recovery_services_vault_hyperv_host_test.go index b92d6b8ef508..8bc5131bff55 100644 --- a/internal/services/recoveryservices/recovery_services_vault_hyperv_host_test.go +++ b/internal/services/recoveryservices/recovery_services_vault_hyperv_host_test.go @@ -470,6 +470,7 @@ resource "azurerm_windows_virtual_machine" "host" { `, r.recovery(data, includeSite), adminPwd, r.keyVault(), r.securityGroup()) } +// for resources need a connected host, remove site and these resources and then remove the host, or it may fail. func (r HyperVHostTestResource) template(data acceptance.TestData, adminPwd string, includeSite bool) string { return fmt.Sprintf(` %s From c96e43b3b9fb8facf1a324278d23d3c0356af9bc Mon Sep 17 00:00:00 2001 From: ziyeqf <51212351+ziyeqf@users.noreply.github.com> Date: Tue, 30 May 2023 14:06:32 +0800 Subject: [PATCH 10/13] update doc Signed-off-by: ziyeqf <51212351+ziyeqf@users.noreply.github.com> --- .../docs/r/site_recovery_hyperv_replicated_vm.html.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/docs/r/site_recovery_hyperv_replicated_vm.html.markdown b/website/docs/r/site_recovery_hyperv_replicated_vm.html.markdown index ac0b5463c005..e1d406b46ea2 100644 --- a/website/docs/r/site_recovery_hyperv_replicated_vm.html.markdown +++ b/website/docs/r/site_recovery_hyperv_replicated_vm.html.markdown @@ -6,7 +6,7 @@ description: |- Manages a HyperV VM protected with Azure Site Recovery on Azure. --- -# azurerm_site_recovery_replicated_vm +# azurerm_site_recovery_hyperv_replicated_vm Manages a HyperV VM replicated using Azure Site Recovery (HyperV to Azure only). A replicated VM keeps a copiously updated image of the VM in Azure in order to be able to start the VM in Azure in case of a disaster. @@ -63,8 +63,8 @@ resource "azurerm_virtual_network" "example" { resource "azurerm_subnet" "example" { name = "example-subnet" - resource_group_name = azurerm_resource_group.primary.name - virtual_network_name = azurerm_virtual_network.primary.name + resource_group_name = azurerm_resource_group.example.name + virtual_network_name = azurerm_virtual_network.example.name address_prefixes = ["192.168.2.0/24"] } From 3827736463ef39034b86a80c2ccac29626deacae Mon Sep 17 00:00:00 2001 From: ziyeqf <51212351+ziyeqf@users.noreply.github.com> Date: Tue, 20 Jun 2023 15:44:54 +0800 Subject: [PATCH 11/13] refresh vendor Signed-off-by: ziyeqf <51212351+ziyeqf@users.noreply.github.com> --- .../id_replicationprotectableitem.go | 24 +++++++++---------- .../id_replicationprotectioncontainer.go | 20 ++++++++-------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectableitem.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectableitem.go index 1b650ec79a41..f7f0b3936cee 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectableitem.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectableitem.go @@ -46,27 +46,27 @@ func ParseReplicationProtectableItemID(input string) (*ReplicationProtectableIte id := ReplicationProtectableItemId{} if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { - return nil, fmt.Errorf("the segment 'subscriptionId' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", *parsed) } if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { - return nil, fmt.Errorf("the segment 'resourceGroupName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "resourceGroupName", *parsed) } if id.VaultName, ok = parsed.Parsed["vaultName"]; !ok { - return nil, fmt.Errorf("the segment 'vaultName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "vaultName", *parsed) } if id.ReplicationFabricName, ok = parsed.Parsed["replicationFabricName"]; !ok { - return nil, fmt.Errorf("the segment 'replicationFabricName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "replicationFabricName", *parsed) } if id.ReplicationProtectionContainerName, ok = parsed.Parsed["replicationProtectionContainerName"]; !ok { - return nil, fmt.Errorf("the segment 'replicationProtectionContainerName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "replicationProtectionContainerName", *parsed) } if id.ReplicationProtectableItemName, ok = parsed.Parsed["replicationProtectableItemName"]; !ok { - return nil, fmt.Errorf("the segment 'replicationProtectableItemName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "replicationProtectableItemName", *parsed) } return &id, nil @@ -85,27 +85,27 @@ func ParseReplicationProtectableItemIDInsensitively(input string) (*ReplicationP id := ReplicationProtectableItemId{} if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { - return nil, fmt.Errorf("the segment 'subscriptionId' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", *parsed) } if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { - return nil, fmt.Errorf("the segment 'resourceGroupName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "resourceGroupName", *parsed) } if id.VaultName, ok = parsed.Parsed["vaultName"]; !ok { - return nil, fmt.Errorf("the segment 'vaultName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "vaultName", *parsed) } if id.ReplicationFabricName, ok = parsed.Parsed["replicationFabricName"]; !ok { - return nil, fmt.Errorf("the segment 'replicationFabricName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "replicationFabricName", *parsed) } if id.ReplicationProtectionContainerName, ok = parsed.Parsed["replicationProtectionContainerName"]; !ok { - return nil, fmt.Errorf("the segment 'replicationProtectionContainerName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "replicationProtectionContainerName", *parsed) } if id.ReplicationProtectableItemName, ok = parsed.Parsed["replicationProtectableItemName"]; !ok { - return nil, fmt.Errorf("the segment 'replicationProtectableItemName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "replicationProtectableItemName", *parsed) } return &id, nil diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectioncontainer.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectioncontainer.go index 70a56469f92e..927a68eca8c3 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectioncontainer.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/id_replicationprotectioncontainer.go @@ -44,23 +44,23 @@ func ParseReplicationProtectionContainerID(input string) (*ReplicationProtection id := ReplicationProtectionContainerId{} if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { - return nil, fmt.Errorf("the segment 'subscriptionId' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", *parsed) } if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { - return nil, fmt.Errorf("the segment 'resourceGroupName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "resourceGroupName", *parsed) } if id.VaultName, ok = parsed.Parsed["vaultName"]; !ok { - return nil, fmt.Errorf("the segment 'vaultName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "vaultName", *parsed) } if id.ReplicationFabricName, ok = parsed.Parsed["replicationFabricName"]; !ok { - return nil, fmt.Errorf("the segment 'replicationFabricName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "replicationFabricName", *parsed) } if id.ReplicationProtectionContainerName, ok = parsed.Parsed["replicationProtectionContainerName"]; !ok { - return nil, fmt.Errorf("the segment 'replicationProtectionContainerName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "replicationProtectionContainerName", *parsed) } return &id, nil @@ -79,23 +79,23 @@ func ParseReplicationProtectionContainerIDInsensitively(input string) (*Replicat id := ReplicationProtectionContainerId{} if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { - return nil, fmt.Errorf("the segment 'subscriptionId' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", *parsed) } if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { - return nil, fmt.Errorf("the segment 'resourceGroupName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "resourceGroupName", *parsed) } if id.VaultName, ok = parsed.Parsed["vaultName"]; !ok { - return nil, fmt.Errorf("the segment 'vaultName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "vaultName", *parsed) } if id.ReplicationFabricName, ok = parsed.Parsed["replicationFabricName"]; !ok { - return nil, fmt.Errorf("the segment 'replicationFabricName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "replicationFabricName", *parsed) } if id.ReplicationProtectionContainerName, ok = parsed.Parsed["replicationProtectionContainerName"]; !ok { - return nil, fmt.Errorf("the segment 'replicationProtectionContainerName' was not found in the resource id %q", input) + return nil, resourceids.NewSegmentNotSpecifiedError(id, "replicationProtectionContainerName", *parsed) } return &id, nil From 7d90678483a8d2066cd5439396ce667dba75fc1b Mon Sep 17 00:00:00 2001 From: ziyeqf <51212351+ziyeqf@users.noreply.github.com> Date: Mon, 14 Aug 2023 14:57:36 +0800 Subject: [PATCH 12/13] update code Signed-off-by: ziyeqf <51212351+ziyeqf@users.noreply.github.com> --- .../services/recoveryservices/client/client.go | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/internal/services/recoveryservices/client/client.go b/internal/services/recoveryservices/client/client.go index 8c346a7635f6..5c61100ec61e 100644 --- a/internal/services/recoveryservices/client/client.go +++ b/internal/services/recoveryservices/client/client.go @@ -182,23 +182,10 @@ func NewClient(o *common.ClientOptions) (*Client, error) { VaultCertificatesClient: &vaultCertificatesClient, VaultsSettingsClient: vaultSettingsClient, StorageConfigsClient: &storageConfigsClient, - FabricClient: fabricClient, - ProtectionContainerClient: protectionContainerClient, - ReplicationPoliciesClient: replicationPoliciesClient, - ContainerMappingClient: containerMappingClient, - NetworkMappingClient: networkMappingClient, + ReplicationProtectableItemsClient: &replicationProtectableItemsCLient, ReplicationProtectedItemsClient: replicationMigrationItemsClient, ReplicationRecoveryPlansClient: replicationRecoveryPlanClient, ReplicationNetworksClient: replicationNetworksClient, - FabricClient: &fabricClient, - ProtectionContainerClient: &protectionContainerClient, - ReplicationPoliciesClient: &replicationPoliciesClient, - ContainerMappingClient: &containerMappingClient, - NetworkMappingClient: &networkMappingClient, - ReplicationProtectableItemsClient: &replicationProtectableItemsCLient, - ReplicationProtectedItemsClient: &replicationMigrationItemsClient, - ReplicationRecoveryPlansClient: &replicationRecoveryPlanClient, - ReplicationNetworksClient: &replicationNetworksClient, ResourceGuardProxyClient: &resourceGuardProxyClient, HackedReplicationProtectedItemsClient: &hackedReplicationProtectedItemsClient, }, nil From e186fa9acc62966688faab8cdda7b06a1a4614cf Mon Sep 17 00:00:00 2001 From: ziyeqf <51212351+ziyeqf@users.noreply.github.com> Date: Mon, 14 Aug 2023 15:01:36 +0800 Subject: [PATCH 13/13] update code Signed-off-by: ziyeqf <51212351+ziyeqf@users.noreply.github.com> --- .../recoveryservices/client/client.go | 9 +- .../replicationprotectableitems/client.go | 22 +- .../replicationprotectableitems/constants.go | 32 ++- .../replicationprotectableitems/method_get.go | 51 ++++ .../method_get_autorest.go | 68 ------ ...d_listbyreplicationprotectioncontainers.go | 121 ++++++++++ ...eplicationprotectioncontainers_autorest.go | 220 ------------------ .../model_configurationsettings.go | 13 +- .../replicationprotectableitems/predicates.go | 8 +- 9 files changed, 237 insertions(+), 307 deletions(-) create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_get.go delete mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_get_autorest.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_listbyreplicationprotectioncontainers.go delete mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_listbyreplicationprotectioncontainers_autorest.go diff --git a/internal/services/recoveryservices/client/client.go b/internal/services/recoveryservices/client/client.go index 5c61100ec61e..9886d9ba0113 100644 --- a/internal/services/recoveryservices/client/client.go +++ b/internal/services/recoveryservices/client/client.go @@ -146,8 +146,11 @@ func NewClient(o *common.ClientOptions) (*Client, error) { } o.Configure(replicationMigrationItemsClient.Client, o.Authorizers.ResourceManager) - replicationProtectableItemsCLient := replicationprotectableitems.NewReplicationProtectableItemsClientWithBaseURI(o.ResourceManagerEndpoint) - o.ConfigureClient(&replicationProtectableItemsCLient.Client, o.ResourceManagerAuthorizer) + replicationProtectableItemsCLient, err := replicationprotectableitems.NewReplicationProtectableItemsClientWithBaseURI(o.Environment.ResourceManager) + if err != nil { + return nil, fmt.Errorf("building replicationProtectableItems client: %+v", err) + } + o.Configure(replicationProtectableItemsCLient.Client, o.Authorizers.ResourceManager) replicationRecoveryPlanClient, err := replicationrecoveryplans.NewReplicationRecoveryPlansClientWithBaseURI(o.Environment.ResourceManager) if err != nil { @@ -182,7 +185,7 @@ func NewClient(o *common.ClientOptions) (*Client, error) { VaultCertificatesClient: &vaultCertificatesClient, VaultsSettingsClient: vaultSettingsClient, StorageConfigsClient: &storageConfigsClient, - ReplicationProtectableItemsClient: &replicationProtectableItemsCLient, + ReplicationProtectableItemsClient: replicationProtectableItemsCLient, ReplicationProtectedItemsClient: replicationMigrationItemsClient, ReplicationRecoveryPlansClient: replicationRecoveryPlanClient, ReplicationNetworksClient: replicationNetworksClient, diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/client.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/client.go index cd1356d41c0a..20a533cfe434 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/client.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/client.go @@ -1,18 +1,26 @@ package replicationprotectableitems -import "github.com/Azure/go-autorest/autorest" +import ( + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/client/resourcemanager" + sdkEnv "github.com/hashicorp/go-azure-sdk/sdk/environments" +) // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See NOTICE.txt in the project root for license information. type ReplicationProtectableItemsClient struct { - Client autorest.Client - baseUri string + Client *resourcemanager.Client } -func NewReplicationProtectableItemsClientWithBaseURI(endpoint string) ReplicationProtectableItemsClient { - return ReplicationProtectableItemsClient{ - Client: autorest.NewClientWithUserAgent(userAgent()), - baseUri: endpoint, +func NewReplicationProtectableItemsClientWithBaseURI(sdkApi sdkEnv.Api) (*ReplicationProtectableItemsClient, error) { + client, err := resourcemanager.NewResourceManagerClient(sdkApi, "replicationprotectableitems", defaultApiVersion) + if err != nil { + return nil, fmt.Errorf("instantiating ReplicationProtectableItemsClient: %+v", err) } + + return &ReplicationProtectableItemsClient{ + Client: client, + }, nil } diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/constants.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/constants.go index 7ae2eaa30c8b..ba651c886679 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/constants.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/constants.go @@ -1,6 +1,10 @@ package replicationprotectableitems -import "strings" +import ( + "encoding/json" + "fmt" + "strings" +) // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See NOTICE.txt in the project root for license information. @@ -19,6 +23,19 @@ func PossibleValuesForHealthErrorCustomerResolvability() []string { } } +func (s *HealthErrorCustomerResolvability) UnmarshalJSON(bytes []byte) error { + var decoded string + if err := json.Unmarshal(bytes, &decoded); err != nil { + return fmt.Errorf("unmarshaling: %+v", err) + } + out, err := parseHealthErrorCustomerResolvability(decoded) + if err != nil { + return fmt.Errorf("parsing %q: %+v", decoded, err) + } + *s = *out + return nil +} + func parseHealthErrorCustomerResolvability(input string) (*HealthErrorCustomerResolvability, error) { vals := map[string]HealthErrorCustomerResolvability{ "allowed": HealthErrorCustomerResolvabilityAllowed, @@ -49,6 +66,19 @@ func PossibleValuesForPresenceStatus() []string { } } +func (s *PresenceStatus) UnmarshalJSON(bytes []byte) error { + var decoded string + if err := json.Unmarshal(bytes, &decoded); err != nil { + return fmt.Errorf("unmarshaling: %+v", err) + } + out, err := parsePresenceStatus(decoded) + if err != nil { + return fmt.Errorf("parsing %q: %+v", decoded, err) + } + *s = *out + return nil +} + func parsePresenceStatus(input string) (*PresenceStatus, error) { vals := map[string]PresenceStatus{ "notpresent": PresenceStatusNotPresent, diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_get.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_get.go new file mode 100644 index 000000000000..c54f2d84c12e --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_get.go @@ -0,0 +1,51 @@ +package replicationprotectableitems + +import ( + "context" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type GetOperationResponse struct { + HttpResponse *http.Response + OData *odata.OData + Model *ProtectableItem +} + +// Get ... +func (c ReplicationProtectableItemsClient) Get(ctx context.Context, id ReplicationProtectableItemId) (result GetOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + Path: id.ID(), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + if err = resp.Unmarshal(&result.Model); err != nil { + return + } + + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_get_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_get_autorest.go deleted file mode 100644 index 5f174d7a1ccf..000000000000 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_get_autorest.go +++ /dev/null @@ -1,68 +0,0 @@ -package replicationprotectableitems - -import ( - "context" - "net/http" - - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" -) - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See NOTICE.txt in the project root for license information. - -type GetOperationResponse struct { - HttpResponse *http.Response - Model *ProtectableItem -} - -// Get ... -func (c ReplicationProtectableItemsClient) Get(ctx context.Context, id ReplicationProtectableItemId) (result GetOperationResponse, err error) { - req, err := c.preparerForGet(ctx, id) - if err != nil { - err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "Get", nil, "Failure preparing request") - return - } - - result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) - if err != nil { - err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "Get", result.HttpResponse, "Failure sending request") - return - } - - result, err = c.responderForGet(result.HttpResponse) - if err != nil { - err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "Get", result.HttpResponse, "Failure responding to request") - return - } - - return -} - -// preparerForGet prepares the Get request. -func (c ReplicationProtectableItemsClient) preparerForGet(ctx context.Context, id ReplicationProtectableItemId) (*http.Request, error) { - queryParameters := map[string]interface{}{ - "api-version": defaultApiVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(c.baseUri), - autorest.WithPath(id.ID()), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// responderForGet handles the response to the Get request. The method always -// closes the http.Response Body. -func (c ReplicationProtectableItemsClient) responderForGet(resp *http.Response) (result GetOperationResponse, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result.Model), - autorest.ByClosing()) - result.HttpResponse = resp - - return -} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_listbyreplicationprotectioncontainers.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_listbyreplicationprotectioncontainers.go new file mode 100644 index 000000000000..2164fcd89fe0 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_listbyreplicationprotectioncontainers.go @@ -0,0 +1,121 @@ +package replicationprotectableitems + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ListByReplicationProtectionContainersOperationResponse struct { + HttpResponse *http.Response + OData *odata.OData + Model *[]ProtectableItem +} + +type ListByReplicationProtectionContainersCompleteResult struct { + Items []ProtectableItem +} + +type ListByReplicationProtectionContainersOperationOptions struct { + Filter *string + Take *string +} + +func DefaultListByReplicationProtectionContainersOperationOptions() ListByReplicationProtectionContainersOperationOptions { + return ListByReplicationProtectionContainersOperationOptions{} +} + +func (o ListByReplicationProtectionContainersOperationOptions) ToHeaders() *client.Headers { + out := client.Headers{} + + return &out +} + +func (o ListByReplicationProtectionContainersOperationOptions) ToOData() *odata.Query { + out := odata.Query{} + return &out +} + +func (o ListByReplicationProtectionContainersOperationOptions) ToQuery() *client.QueryParams { + out := client.QueryParams{} + if o.Filter != nil { + out.Append("$filter", fmt.Sprintf("%v", *o.Filter)) + } + if o.Take != nil { + out.Append("$take", fmt.Sprintf("%v", *o.Take)) + } + return &out +} + +// ListByReplicationProtectionContainers ... +func (c ReplicationProtectableItemsClient) ListByReplicationProtectionContainers(ctx context.Context, id ReplicationProtectionContainerId, options ListByReplicationProtectionContainersOperationOptions) (result ListByReplicationProtectionContainersOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + Path: fmt.Sprintf("%s/replicationProtectableItems", id.ID()), + OptionsObject: options, + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + var resp *client.Response + resp, err = req.ExecutePaged(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + var values struct { + Values *[]ProtectableItem `json:"value"` + } + if err = resp.Unmarshal(&values); err != nil { + return + } + + result.Model = values.Values + + return +} + +// ListByReplicationProtectionContainersComplete retrieves all the results into a single object +func (c ReplicationProtectableItemsClient) ListByReplicationProtectionContainersComplete(ctx context.Context, id ReplicationProtectionContainerId, options ListByReplicationProtectionContainersOperationOptions) (ListByReplicationProtectionContainersCompleteResult, error) { + return c.ListByReplicationProtectionContainersCompleteMatchingPredicate(ctx, id, options, ProtectableItemOperationPredicate{}) +} + +// ListByReplicationProtectionContainersCompleteMatchingPredicate retrieves all the results and then applies the predicate +func (c ReplicationProtectableItemsClient) ListByReplicationProtectionContainersCompleteMatchingPredicate(ctx context.Context, id ReplicationProtectionContainerId, options ListByReplicationProtectionContainersOperationOptions, predicate ProtectableItemOperationPredicate) (result ListByReplicationProtectionContainersCompleteResult, err error) { + items := make([]ProtectableItem, 0) + + resp, err := c.ListByReplicationProtectionContainers(ctx, id, options) + if err != nil { + err = fmt.Errorf("loading results: %+v", err) + return + } + if resp.Model != nil { + for _, v := range *resp.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + + result = ListByReplicationProtectionContainersCompleteResult{ + Items: items, + } + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_listbyreplicationprotectioncontainers_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_listbyreplicationprotectioncontainers_autorest.go deleted file mode 100644 index 5c77821d594b..000000000000 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/method_listbyreplicationprotectioncontainers_autorest.go +++ /dev/null @@ -1,220 +0,0 @@ -package replicationprotectableitems - -import ( - "context" - "fmt" - "net/http" - "net/url" - - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" -) - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See NOTICE.txt in the project root for license information. - -type ListByReplicationProtectionContainersOperationResponse struct { - HttpResponse *http.Response - Model *[]ProtectableItem - - nextLink *string - nextPageFunc func(ctx context.Context, nextLink string) (ListByReplicationProtectionContainersOperationResponse, error) -} - -type ListByReplicationProtectionContainersCompleteResult struct { - Items []ProtectableItem -} - -func (r ListByReplicationProtectionContainersOperationResponse) HasMore() bool { - return r.nextLink != nil -} - -func (r ListByReplicationProtectionContainersOperationResponse) LoadMore(ctx context.Context) (resp ListByReplicationProtectionContainersOperationResponse, err error) { - if !r.HasMore() { - err = fmt.Errorf("no more pages returned") - return - } - return r.nextPageFunc(ctx, *r.nextLink) -} - -type ListByReplicationProtectionContainersOperationOptions struct { - Filter *string - Take *string -} - -func DefaultListByReplicationProtectionContainersOperationOptions() ListByReplicationProtectionContainersOperationOptions { - return ListByReplicationProtectionContainersOperationOptions{} -} - -func (o ListByReplicationProtectionContainersOperationOptions) toHeaders() map[string]interface{} { - out := make(map[string]interface{}) - - return out -} - -func (o ListByReplicationProtectionContainersOperationOptions) toQueryString() map[string]interface{} { - out := make(map[string]interface{}) - - if o.Filter != nil { - out["$filter"] = *o.Filter - } - - if o.Take != nil { - out["$take"] = *o.Take - } - - return out -} - -// ListByReplicationProtectionContainers ... -func (c ReplicationProtectableItemsClient) ListByReplicationProtectionContainers(ctx context.Context, id ReplicationProtectionContainerId, options ListByReplicationProtectionContainersOperationOptions) (resp ListByReplicationProtectionContainersOperationResponse, err error) { - req, err := c.preparerForListByReplicationProtectionContainers(ctx, id, options) - if err != nil { - err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "ListByReplicationProtectionContainers", nil, "Failure preparing request") - return - } - - resp.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) - if err != nil { - err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "ListByReplicationProtectionContainers", resp.HttpResponse, "Failure sending request") - return - } - - resp, err = c.responderForListByReplicationProtectionContainers(resp.HttpResponse) - if err != nil { - err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "ListByReplicationProtectionContainers", resp.HttpResponse, "Failure responding to request") - return - } - return -} - -// preparerForListByReplicationProtectionContainers prepares the ListByReplicationProtectionContainers request. -func (c ReplicationProtectableItemsClient) preparerForListByReplicationProtectionContainers(ctx context.Context, id ReplicationProtectionContainerId, options ListByReplicationProtectionContainersOperationOptions) (*http.Request, error) { - queryParameters := map[string]interface{}{ - "api-version": defaultApiVersion, - } - - for k, v := range options.toQueryString() { - queryParameters[k] = autorest.Encode("query", v) - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(c.baseUri), - autorest.WithHeaders(options.toHeaders()), - autorest.WithPath(fmt.Sprintf("%s/replicationProtectableItems", id.ID())), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// preparerForListByReplicationProtectionContainersWithNextLink prepares the ListByReplicationProtectionContainers request with the given nextLink token. -func (c ReplicationProtectableItemsClient) preparerForListByReplicationProtectionContainersWithNextLink(ctx context.Context, nextLink string) (*http.Request, error) { - uri, err := url.Parse(nextLink) - if err != nil { - return nil, fmt.Errorf("parsing nextLink %q: %+v", nextLink, err) - } - queryParameters := map[string]interface{}{} - for k, v := range uri.Query() { - if len(v) == 0 { - continue - } - val := v[0] - val = autorest.Encode("query", val) - queryParameters[k] = val - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(c.baseUri), - autorest.WithPath(uri.Path), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// responderForListByReplicationProtectionContainers handles the response to the ListByReplicationProtectionContainers request. The method always -// closes the http.Response Body. -func (c ReplicationProtectableItemsClient) responderForListByReplicationProtectionContainers(resp *http.Response) (result ListByReplicationProtectionContainersOperationResponse, err error) { - type page struct { - Values []ProtectableItem `json:"value"` - NextLink *string `json:"nextLink"` - } - var respObj page - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&respObj), - autorest.ByClosing()) - result.HttpResponse = resp - result.Model = &respObj.Values - result.nextLink = respObj.NextLink - if respObj.NextLink != nil { - result.nextPageFunc = func(ctx context.Context, nextLink string) (result ListByReplicationProtectionContainersOperationResponse, err error) { - req, err := c.preparerForListByReplicationProtectionContainersWithNextLink(ctx, nextLink) - if err != nil { - err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "ListByReplicationProtectionContainers", nil, "Failure preparing request") - return - } - - result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) - if err != nil { - err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "ListByReplicationProtectionContainers", result.HttpResponse, "Failure sending request") - return - } - - result, err = c.responderForListByReplicationProtectionContainers(result.HttpResponse) - if err != nil { - err = autorest.NewErrorWithError(err, "replicationprotectableitems.ReplicationProtectableItemsClient", "ListByReplicationProtectionContainers", result.HttpResponse, "Failure responding to request") - return - } - - return - } - } - return -} - -// ListByReplicationProtectionContainersComplete retrieves all of the results into a single object -func (c ReplicationProtectableItemsClient) ListByReplicationProtectionContainersComplete(ctx context.Context, id ReplicationProtectionContainerId, options ListByReplicationProtectionContainersOperationOptions) (ListByReplicationProtectionContainersCompleteResult, error) { - return c.ListByReplicationProtectionContainersCompleteMatchingPredicate(ctx, id, options, ProtectableItemOperationPredicate{}) -} - -// ListByReplicationProtectionContainersCompleteMatchingPredicate retrieves all of the results and then applied the predicate -func (c ReplicationProtectableItemsClient) ListByReplicationProtectionContainersCompleteMatchingPredicate(ctx context.Context, id ReplicationProtectionContainerId, options ListByReplicationProtectionContainersOperationOptions, predicate ProtectableItemOperationPredicate) (resp ListByReplicationProtectionContainersCompleteResult, err error) { - items := make([]ProtectableItem, 0) - - page, err := c.ListByReplicationProtectionContainers(ctx, id, options) - if err != nil { - err = fmt.Errorf("loading the initial page: %+v", err) - return - } - if page.Model != nil { - for _, v := range *page.Model { - if predicate.Matches(v) { - items = append(items, v) - } - } - } - - for page.HasMore() { - page, err = page.LoadMore(ctx) - if err != nil { - err = fmt.Errorf("loading the next page: %+v", err) - return - } - - if page.Model != nil { - for _, v := range *page.Model { - if predicate.Matches(v) { - items = append(items, v) - } - } - } - } - - out := ListByReplicationProtectionContainersCompleteResult{ - Items: items, - } - return out, nil -} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_configurationsettings.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_configurationsettings.go index 4d071558c6cb..c03a8b1acf1f 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_configurationsettings.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/model_configurationsettings.go @@ -12,6 +12,15 @@ import ( type ConfigurationSettings interface { } +// RawModeOfTransitImpl is returned when the Discriminated Value +// doesn't match any of the defined types +// NOTE: this should only be used when a type isn't defined for this type of Object (as a workaround) +// and is used only for Deserialization (e.g. this cannot be used as a Request Payload). +type RawConfigurationSettingsImpl struct { + Type string + Values map[string]interface{} +} + func unmarshalConfigurationSettingsImplementation(input []byte) (ConfigurationSettings, error) { if input == nil { return nil, nil @@ -51,10 +60,6 @@ func unmarshalConfigurationSettingsImplementation(input []byte) (ConfigurationSe return out, nil } - type RawConfigurationSettingsImpl struct { - Type string `json:"-"` - Values map[string]interface{} `json:"-"` - } out := RawConfigurationSettingsImpl{ Type: value, Values: temp, diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/predicates.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/predicates.go index 06bc4485e632..cd7684d64334 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/predicates.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservicessiterecovery/2022-10-01/replicationprotectableitems/predicates.go @@ -12,19 +12,19 @@ type ProtectableItemOperationPredicate struct { func (p ProtectableItemOperationPredicate) Matches(input ProtectableItem) bool { - if p.Id != nil && (input.Id == nil && *p.Id != *input.Id) { + if p.Id != nil && (input.Id == nil || *p.Id != *input.Id) { return false } - if p.Location != nil && (input.Location == nil && *p.Location != *input.Location) { + if p.Location != nil && (input.Location == nil || *p.Location != *input.Location) { return false } - if p.Name != nil && (input.Name == nil && *p.Name != *input.Name) { + if p.Name != nil && (input.Name == nil || *p.Name != *input.Name) { return false } - if p.Type != nil && (input.Type == nil && *p.Type != *input.Type) { + if p.Type != nil && (input.Type == nil || *p.Type != *input.Type) { return false }