MigrationProfile/AWSMigrationProfile.psm1

Import-Module -Name @(Join-Path $PSScriptRoot .. | Join-Path -ChildPath Util | Join-Path -ChildPath Util)
function New-RMAWSMigrationProfile {
    param(
        [Parameter(Mandatory)]
        [System.Object] $CloudAccount,

        [Parameter(Mandatory)]
        [System.Object] $Entitlement,

        [Parameter(Mandatory)]
        [System.Object] $CloudAttributes,

        [Parameter(Mandatory)]
        [System.Object] $ScheduledAt,

        [Parameter(Mandatory)]
        [System.Object] $Source,

        [Parameter(Mandatory)]
        [string] $TargetVMName,

        [Parameter(Mandatory)]
        [System.Object[]] $SelectedMount,

        [Parameter(Mandatory)]
        [bool] $EncryptVolume,

        [Parameter(Mandatory)]
        [string] $VolumeType,

        [System.Object]  $ResizeMountPoint,

        [hashtable] $ConvertFileSystem,

        [string] $MigrationExtension,

        [string] $MigrationExtensionId,

        [string] $MigrationExtensionOSM,

        [string] $MigrationExtensionIdOSM,

        [string] $TransferMethod,

        [string] $IOPS,

        [Parameter(Mandatory)]
        [string] $Region,

        [Parameter(Mandatory)]
        [string] $VPCID,

        [Parameter(Mandatory)]
        [string] $SubnetID,

        [Parameter(Mandatory)]
        [bool] $AutoAssignPublicIP,

        [string] $StaticPrivateIP,

        [string] $Tenancy,

        [Parameter(Mandatory)]
        [string] $InstanceType,

        [bool] $EnforceTargetNetworkIsolation,

        [hashtable] $SecurityGroup,

        [string] $IAMRole,

        [Parameter(Mandatory)]
        [bool] $ShouldCreateAMI,

        [hashtable] $InstanceTag,

        [System.Object] $UpgradeOSVersion,

        [System.Object] $SQLServerUpgrade,

        [bool]  $InPlaceUpgrade,

        [bool] $DisableTargetDNSRegistration,

        [Parameter(Mandatory)]
        [bool] $ShutdownSource,

        [Parameter(Mandatory)]
        [bool] $ShutdownTarget,

        [Parameter(Mandatory)]
        [bool] $RemoveRMSAgent,

        [hashtable] $MigrationInstruction,

        [bool] $IgnoreValidationError,

        [string] $KMSKey,
        
        [bool] $EnableNetAppFileMigration,
        
        [string] $MTUSize,

        [string] $NetBIOSName,

        [System.Object] $KMSName,

        [bool] $GeneralizeSystem
    )

    $Subnet = Get-SubnetById -SubnetId $SubnetID -CloudAttributes $CloudAttributes
    if ($null -eq $Subnet) {
        throw "Subnet with ID '$SubnetID' does not exists"
    }

    if ($null -ieq $ConvertFileSystem) {
        $ConvertFileSystem = @{}
    }
    
    if ([string]::IsNullOrEmpty($UpgradeOSVersion)) {
        $UpgradeOSVersion = $null
    }

    if ("" -ieq  $ScheduledAt) {
          # To run "now", FE requires that the $ScheduledAt to be null
        $ScheduledAt = $null
    }

    if ($null -ieq $InstanceTag) {
        $InstanceTag = @{}
    }

    if ($null -ieq  $SecurityGroup) {
        $SecurityGroup = $null
    }

    $MigrationExtensionIdArray = @() 
    if (![string]::IsNullOrEmpty($MigrationExtensionId)) {
        $MigrationExtensionIdArray +=  $MigrationExtensionId
    }

    $MigrationExtensionArray = @()
    if (![string]::IsNullOrEmpty($MigrationExtension)) {
        $MigrationExtensionArray +=  $MigrationExtension
    }

    $MigrationExtensionIdOSMArray = @() 
    if (![string]::IsNullOrEmpty($MigrationExtensionIdOSM)) {
        $MigrationExtensionIdOSMArray +=  $MigrationExtensionIdOSM
    }

    $MigrationExtensionOSMArray = @()
    if (![string]::IsNullOrEmpty($MigrationExtensionOSM)) {
        $MigrationExtensionOSMArray +=  $MigrationExtensionOSM
    }


    $SQLServerUpgradeAsArray = @()
    if($null -ne $SQLServerUpgrade ) { 
        $SQLServerUpgradeAsArray += $SQLServerUpgrade
    } 

    $EnableNetAppFileMigrationValue = $null
    if ($EnableNetAppFileMigration) {
        $EnableNetAppFileMigrationValue = "netapp"
    }

    $CurrentTime = Get-Date -Format "yyyy/MM/dd HH:mm:ss"
    $MigrationProfile = @{
        "name"= "powershell-" + $Source.host + "-" + $CurrentTime
        "tags"= @()
        "entitlement"=$Entitlement.id
        "cloud_account"=$CloudAccount.id
        "is_data_only"= $false
        "is_vdi"= $false
        "appliance_id"=$CloudAccount.appliance.id
        "schedule"= $ScheduledAt
        "transfer_mode"="run-once"
        "sources"= @(
            @{
                "binary_asset_groups" = @(
                    @{
                        "binary_assets" = $MigrationExtensionIdArray
                    }
                    @{
                        "binary_asset_names" = $MigrationExtensionArray
                    }
                )
                "binary_asset_groups_osm"= @(
                    @{
                        "osm_assets" = $MigrationExtensionIdOSMArray
                    }

                    @{
                        "osm_asset_names" = $MigrationExtensionOSMArray
                    }
                )
                "source"= $Source.id
                "transfer_type" = $TransferMethod
                "target_config"= @{
                    "vm_details"= @{
                        "vm_name"= $TargetVMName
                        "vapp_name"= $TargetVMName
                        "tags"= $InstanceTag
                        "flavor"= @{
                            "flavor_type"= $InstanceType
                            "volume_type"= $VolumeType
                            "iops"= if ("" -eq $IOPS) { $null } else { $IOPS }
                        }
                        "kms_fqdn" = $KMSName
                        "security"= @{
                            "vpc_id"= $VPCID
                            "security_group_ids"= if ($EnforceTargetNetworkIsolation) { @() } else {$SecurityGroup.Keys}
                            "security_group_names"= $SecurityGroup.Values
                        }
                        "encrypt_volumes"= $EncryptVolume
                        "encrytion_key_arn" = $KMSKey
                        "capture_ami"= $ShouldCreateAMI
                        "iam_instance_profile"= $IAMRole
                    }
                    "properties"= @{
                        "network"= @{
                            "interfaces"= @{
                                "eth0"= @{
                                    "ip_type"= "dhcp"
                                    "mtu_size"= if ([string]::IsNullOrEmpty($MTUSize)) { $null } else { $MTUSize }
                                    "type"= "Ethernet"
                                    "network_name"= $SubnetID
                                    "assign_public_ip"= $AutoAssignPublicIP
                                    "ip_addr"= $StaticPrivateIP
                                }
                            }
                            "automatic_dns_registration"= !$DisableTargetDNSRegistration
                        }
                        "hostname" = $NetBIOSName
                        "selected_mounts"= $SelectedMount
                        "name"= $TargetVMName
                        "mounts_new_size"=  $ResizeMountPoint
                        "convert_filesystems"= $ConvertFileSystem
                    }
                    "options"= @{
                        "region"= $Region
                        "az"= $Subnet.availability_zone
                        "power_on"= $true
                        "tenancy"= "default"
                        "affinity"= $null
                        "host_id"= $null
                    }
                }
                "verify_ssl_certificates"= $false
                "publish_migration_hub"= $false
                "os_type"= $Source.os_type
                "name"= $Source.hostname
                "collection_type"= $null
                "generalize_system" = $GeneralizeSystem
                "product_upgrades" = $SQLServerUpgradeAsArray
                "shutdown_source"= $ShutdownSource
                "shutdown_target"= $ShutdownTarget
                "remove_target_agent"= $RemoveRMSAgent
                "in_place_upgrade"= $InPlaceUpgrade
                "upgrade_os_version"= $UpgradeOSVersion
                "migration_instructions"= $MigrationInstruction
                "data_transfer_port"= 5995
                "ignore_validation_errors"= $IgnoreValidationError
                "file_storage_mode"= $EnableNetAppFileMigrationValue
                "preflight_warning"= $false
            }
        )
    }

    # Giving max depth otherwise the cmdlet 'ConvertTo-Json' will truncate the JSON
    $MigrationProfileJson = $MigrationProfile |ConvertTo-Json -Depth 100

    $RMLoginResult = Get-Variable -Name "RMContext-UserLogin" -ValueOnly
    $Uri = Get-Variable -Name "RMContext-ReactorURI" -ValueOnly

    $Headers = @{
        Accept = "application/rm+json"
        "X-Auth-Token" = $RMLoginResult.token
    }

    $Params = @{
        Method = "Post"
        Uri = $Uri + "/migrationprofiles"
        Body = $MigrationProfileJson
        ContentType = "application/json"
        Headers = $Headers
    }

    return Invoke-RMRestMethod -Params $Params
}

function New-RMAWSVMBasedMigrationProfile {
    param(
        [System.Object] $CloudAccount,
        [System.Object] $CloudAttributes,
        [System.Object] $Entitlement,
        [System.Object] $Source,
        [string] $SourceVMName,
        [string] $ScheduledAt,
        [string] $TargetVMName,
        [System.Object[]] $SelectedDisk,
        [bool] $EncryptAllVolume,
        [string] $KMSKey,
        [string] $MigrationExtension,
        [string] $MigrationExtensionId,
        [string] $VolumeType,
        [string] $IOPS,
        [string] $Region,
        [string] $VPCID,
        [string] $SubnetID,
        [bool] $AutoAssignPublicIP,
        [string] $StaticPrivateIP,
        [string] $InstanceType,
        [bool] $EnforceTargetNetworkIsolation,
        [hashtable] $SecurityGroup,
        [string] $AddIAMRole,
        [bool] $CreateAMI,
        [hashtable] $InstanceTag,
        [bool] $ShutdownSource,
        [bool] $ShutdownTarget,
        [bool] $FinalizeMigration,
        [hashtable] $MigrationInstruction,
        [bool] $IgnoreValidationError,
        [bool] $OverrideExistingMigration,
        [string] $MTUSize
    )

    $CurrentTime = Get-Date -Format "yyyy/MM/dd HH:mm:ss"

    $PowerOn = $false
    if ($Source.power_state -ieq "poweredOn") {
        $PowerOn = $true
    }

    if ("" -ieq $ScheduledAt) {
        $ScheduledAt = $null
    }

    $Subnet = Get-SubnetById -SubnetId $SubnetID -CloudAttributes $CloudAttributes

    $MigrationExtensionIdArray = @() 
    if (![string]::IsNullOrEmpty($MigrationExtensionId)) {
        $MigrationExtensionIdArray +=  $MigrationExtensionId
    }

    $MigrationExtensionArray = @()
    if (![string]::IsNullOrEmpty($MigrationExtension)) {
        $MigrationExtensionArray +=  $MigrationExtension
    }
    
    $MigrationProfile = @{
        "name" = "powershell-" + $Source.host + "-" + $CurrentTime
        "tags" = @()
        "entitlement" = $Entitlement.id
        "cloud_account" = $CloudAccount.id
        "is_data_only" = $false
        "is_vdi" = $false
        "appliance_id" = $CloudAccount.appliance.id
        "schedule" = $ScheduledAt
        "schedule_delta" = 0
        "transfer_mode" =  "run-once"
        "sources" =  @(@{
             "binary_asset_groups" = @(
                    @{
                        "binary_assets" = $MigrationExtensionIdArray
                    }
                    @{
                        "binary_asset_names" = $MigrationExtensionArray
                    }
                )
                "source" = $Source.id
                "target_config" = @{
                    "vm_details" = @{
                        "vm_name" = $TargetVMName
                        "vapp_name" = $TargetVMName
                        "tags" = $InstanceTag
                        "flavor" = @{
                            "flavor_type" = $InstanceType
                            "volume_type" = $VolumeType
                            "iops" = if ("" -eq $IOPS) { $null } else { $IOPS }
                        }
                        "security" = @{
                            "vpc_id" = $VPCID
                            "security_group_ids" = if ($EnforceTargetNetworkIsolation) { @() } else {$SecurityGroup.Keys}
                            "security_group_names" = $SecurityGroup.Values
                        }
                        "encrypt_volumes" = $EncryptAllVolume
                        "capture_ami" = $CreateAMI
                        "encryption_key_arn" = $KMSKey
                        "iam_instance_profile" = $AddIAMRole
                    }
                    "properties" = @{
                        "network" = @{
                            "interfaces" = @{
                                "eth0" = @{
                                    "ip_type" = "dhcp"
                                    "type" = "Ethernet"
                                    "mtu" = $MTUSize
                                    "network_name" = $SubnetID
                                    "assign_public_ip" = $AutoAssignPublicIP
                                    "ip_addr" = $StaticPrivateIP
                                }
                            }
                        }
                        "convert_filesystems" = @{}
                        "selected_mounts" = $SelectedDisk
                        "name" = $TargetVMName
                        "mounts_new_size" = @{} #Always empty for VM based
                    }
                    "options" = @{
                        "region" = $Region
                        "az" = $Subnet.availability_zone
                        "power_on" = $PowerOn
                        "tenancy" = "default" #TODO - Dedicated host is currently not supported in PS
                        "affinity" = $null #TODO - Dedicated host is currently not supported in PS
                        "host_id" = $null #TODO - Dedicated host is currently not supported in PS
                    }
                }
                "verify_ssl_certificates" = $false
                "drive_mapping" = @()
                "os_type" = $Source.os_type
                "name" = $Source.host
                "collection_type" = "vm"
                "shutdown_source" = $ShutdownSource
                "shutdown_target" = $ShutdownTarget
                "finalize_target" = $FinalizeMigration
                "in_place_upgrade" = $false # always false for VM based
                "upgrade_os_version" = $null # always null for VM based
                "migration_instructions" = $MigrationInstruction
                "ignore_validation_errors" = $IgnoreValidationError
                "preflight_warning" = $false
            }
        )
    }

    return Invoke-RMMigrationProfilePost -MigrationProfile $MigrationProfile
}
function Get-SubnetById {
    param(
        [string] $SubnetId,
        [System.Object] $CloudAttributes
    )

    $VPCS = $CloudAttributes.properties.regions[0].vpcs
    foreach ($VPC in $VPCS) {
        foreach ($Subnet in $VPC.subnets) {
            if ($SubnetId -eq $Subnet.id) {
                return $Subnet
            }
        }
    }

    return $null
}

Export-ModuleMember -Function New-RMAWSMigrationProfile, New-RMAWSVMBasedMigrationProfile