MigrationProfile/HPEVMEMigrationProfile.psm1

Import-Module -Name @(Join-Path $PSScriptRoot .. | Join-Path -ChildPath Util | Join-Path -ChildPath Util)

function New-RMHPEVMEMigrationProfile {
    param(
        [Parameter(Mandatory)]
        [System.Object] $CloudAccount,

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

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

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

        [string] $TransferMethod,

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

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

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

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

        [string] $HostName,

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

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

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

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

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

        [string[]] $IpAddresses,

        [System.Object] $ResizeMountPoint,

        [string] $NetBIOSName,

        [bool] $Sysprep,

        [hashtable] $ConvertFileSystem,

        [string] $MigrationExtension,

        [string] $MigrationExtensionId,

        [string] $MigrationExtensionOSM,
        
        [string] $MigrationExtensionIdOSM,

        [string] $UpgradeOSVersion,

        [bool] $InPlaceUpgrade,

        [hashtable] $OSHardening,

        [bool] $InstallAzureARC,

        [bool] $ConnectARCAgent,

        [System.Object] $InstallAzureARCParameter,

        [bool] $RemoveRMSAgent,

        [bool] $IgnoreValidationError,

        [bool] $InstallAWSSSMAgent,

        [bool] $InstallAWSCloudWatchAgent,

        [bool] $DisableTargetDNSRegistration,

        [bool] $ShutdownSource,

        [bool] $ShutdownTarget,

        [hashtable] $MigrationInstruction,

        [bool] $EnableCloudFilesMigration,

        [string[]] $Datastore,

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

        [Parameter(Mandatory)]
        [System.Object] $TargetInventory
    )

    $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
    }
    $InstallApplication = @()
    if ($InstallAzureARC) {
        $InstallApplication += @{
            "name" = "AZURE_ARC"
            "parameters" = $InstallAzureARCParameter
        }
    }

    if ($InstallAWSCloudWatchAgent) {
        $InstallApplication += @{
            "name" = "AWS_CLOUDWATCH"
            "parameters" = $null
        }
    }

    $NetworkInterfaces = @{}
    for ($i = 0; $i -lt $DestinationNetworkName.Count; $i++) {
        $interfaceName = "eth$i"
        $NetworkInterfaces[$interfaceName] = @{
            "ip_type" = $AssignmentType[$i].ToLower()
            "type" = "Ethernet"
            "network_name" = $DestinationNetworkName[$i]
        }
        if ($AssignmentType[$i].ToLower() -eq "static" -and $IpAddresses -and $i -lt $IpAddresses.Count) {
            $NetworkInterfaces[$interfaceName]["ip_address"] = $IpAddresses[$i]
        }
    }
    
    $SelectedGroup = $TargetInventory.attributes.hpe_vme.groups | Where-Object { $_.name -eq $Group }
    $SelectedCloud = $SelectedGroup.clouds | Where-Object { $_.name -eq $Cloud }
    $SelectedCluster = $SelectedCloud.clusters | Where-Object { $_.name -eq $Cluster }
    $SelectedDatastore = @()
    foreach ($Store in $Datastore) {
        $SelectedDatastore +=   $SelectedCluster.datastores | Where-Object { $_.name -eq $Store } 
    }
    $SelectedHost = if ($HostName) { $SelectedCluster.hosts | Where-Object { $_.name -eq $HostName } } else { $null }
    $SelectedLayout = $TargetInventory.attributes.hpe_vme.instance_type_layouts | Where-Object { $_.name -eq $Layout }
    $SelectedPlan = $TargetInventory.attributes.hpe_vme.plans | Where-Object { $_.name -eq $Plan }
    $SelectedResourcePool = $SelectedLayout.resource_pools  | Where-Object { $_.name -eq $ResourcePool }

    $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" = if("" -eq $ScheduledAt) { $null } else { $ScheduledAt }
        "transfer_mode" = "run-once"
        "sources" = @(
            @{
                "desc" = "Basic Migration"
                "source" = $Source.id
                "boot_mode_conversion" = $null
                "generalize_system" = $Sysprep
                "transfer_type" = $TransferMethod
                "target_config" = @{
                    "vm_details" = @{
                        "vm_name" = $TargetVMName
                        "flavor" = @{
                            "plan" = $SelectedPlan.identifier
                            "plan_display_name" = $SelectedPlan.name
                        }
                        "datastores" = @($SelectedDatastore.identifier)
                        "group" = $SelectedGroup.identifier
                        "group_display_name" = $SelectedGroup.name
                        "cloud" = $SelectedCloud.identifier
                        "cloud_display_name" = $SelectedCloud.name
                        "cluster" = $SelectedCluster.identifier
                        "cluster_display_name" = $SelectedCluster.name
                        "host" = $SelectedHost.identifier
                        "host_display_name" = if ($SelectedHost) { $SelectedHost.name } else { "" }
                        "instance_type" = $SelectedLayout.instance_type_identifier
                        "instance_type_layout" = $SelectedLayout.identifier
                        "instance_type_layout_display_name" = $SelectedLayout.name
                        "resource_pool" = $SelectedResourcePool.identifier
                        "resource_pool_display_name" = $ResourcePool
                        "install_ssm_agent" = $InstallAWSSSMAgent
                    }
                    "options" = @{}
                    "properties" = @{
                        "network" = @{
                            "interfaces" = $NetworkInterfaces
                            "automatic_dns_registration" = !$DisableTargetDNSRegistration
                        }
                        "mounts_new_size" = $ResizeMountPoint
                        "selected_mounts" = $SelectedMount
                        "convert_filesystems" = $ConvertFileSystem
                        "name" = $TargetVMName
                        "connect_azure_arc_agent" = $ConnectARCAgent
                        "install_applications" = $InstallApplication
                        "hostname" = $TargetVMName
                    }
                }
                "harden_os" = if ($null -ieq $OSHardening) { $false } else { $true }
                "os_hardening" = $OSHardening
                "os_type" = $Source.os_type
                "name" = $TargetVMName
                "collection_type" = $null
                "shutdown_target" = $ShutdownTarget
                "in_place_upgrade" = $InPlaceUpgrade
                "upgrade_os_version" = if( "" -ieq $UpgradeOSVersion) { $null } else { $UpgradeOSVersion }
                "remove_target_agent" = $RemoveRMSAgent
                "migration_instructions" = $MigrationInstruction
                "ignore_validation_errors" = $IgnoreValidationError
                "file_storage_mode" = "netapp"
                "preflight_warning" = $false
                "binary_asset_groups" = @(
                    @{
                        "binary_assets" = $MigrationExtensionIdArray
                    }
                    @{
                        "binary_asset_names" = $MigrationExtensionArray
                    }
                )
                "binary_asset_groups_osm" = @(
                    @{
                        "osm_assets" = $MigrationExtensionIdOSMArray
                    }
                    @{
                        "osm_asset_names" = $MigrationExtensionOSMArray
                    }
                )
            }
        )
    }

   
    $MigrationProfileJson = $MigrationProfile | ConvertTo-Json -Depth 100

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

    $Headers = @{
        Accept = "application/json"
        Cookie = $RMLoginResult
    }

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

    return Invoke-RMRestMethod -Params $Params
}

function New-RMHPEVMEVMBasedMigrationProfile {
    param(
        [Parameter(Mandatory)]
        [System.Object] $CloudAccount,

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

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

        [System.Object] $ScheduledAt,

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

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

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

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

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

        [string] $HostName,

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

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

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

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

        [string] $CoresPerSocket,

        [string] $Memory,

        [string] $Cores,

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

        [bool] $UseCustomNetworkConfig,

        [string] $DefaultGateway,

        [string] $PrimaryDNS,

        [string] $SecondaryDNS,

        [string] $MigrationExtension,

        [string] $MigrationExtensionId,

        [bool] $FinalizeMigration,

        [bool] $ShutdownSource,

        [bool] $ShutdownTarget,

        [hashtable] $MigrationInstruction,

        [bool] $IgnoreValidationError,

        [bool] $InstallAWSSSMAgent,

        [bool] $InstallAWSCloudWatchAgent,

        [Parameter(Mandatory)]
        [System.Object] $TargetInventory
    )

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

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

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

    $InstallApplication = @()
    if ($InstallAWSCloudWatchAgent) {
        $InstallApplication += @{
            "name" = "AWS_CLOUDWATCH"
            "parameters" = $null
        }
    }

    $SelectedGroup = $TargetInventory.attributes.hpe_vme.groups | Where-Object { $_.name -eq $Group }
    $SelectedCloud = $SelectedGroup.clouds | Where-Object { $_.name -eq $Cloud }

    $NetworkInterfaces = @{}
    for ($i = 0; $i -lt $DestinationNICConfig.Count; $i++) {
        $interfaceName = "eth$i"
        $config = $DestinationNICConfig[$i]

        $DvSwitchName = ""
        $DestinationNetworkName = $config.DestinationNetworkName 
        [string[]] $networkNamesArray = $config.DestinationNetworkName -split "/"
        if ($networkNamesArray.Count -eq 2) {
            $DestinationNetworkName = $networkNamesArray[1]
            $DvSwitchName = $networkNamesArray[0]
        }

        $IpType = $config.IPType.ToLower()
        $NetworkPool = $null
        if ($IpType -ne "static" -and $IpType -ne "dhcp") {
            $SelectedNetwork = $SelectedCloud.networks | Where-Object { $_.name -eq $config.DestinationNetworkName }
            if ($SelectedNetwork -and -not [string]::IsNullOrEmpty($SelectedNetwork.pool_id)) {
                $NetworkPool = $SelectedNetwork.pool_id
            }
            $IpType = "dhcp"
        }

        $NetworkInterfaces[$interfaceName] = @{
            "ip_type" = $IpType
            "type" = "Ethernet"
            "network_name" = $DestinationNetworkName
            "dv_switch_name" = $DvSwitchName 
        }
        if (-not [string]::IsNullOrEmpty($NetworkPool)) {
            $NetworkInterfaces[$interfaceName]["network_pool"] = $NetworkPool
        }
        if ($config.IPType.ToLower() -eq "static" -and ![string]::IsNullOrEmpty($config.IPAddress)) {
            $NetworkInterfaces[$interfaceName]["ip_addr"] = $config.IPAddress
        }
        if ($UseCustomNetworkConfig -and ![string]::IsNullOrEmpty($config.Netmask)) {
            $NetworkInterfaces[$interfaceName]["netmask"] = $config.Netmask
        }
    }
    $SelectedCluster = $SelectedCloud.clusters | Where-Object { $_.name -eq $Cluster }
    $SelectedDatastore = @()
    foreach ($Store in $Datastore) {
        $SelectedDatastore += $SelectedCluster.datastores | Where-Object { $_.name -eq $Store } 
    }
    $SelectedHost = if ($HostName) { $SelectedCluster.hosts | Where-Object { $_.name -eq $HostName } } else { $null }
    $SelectedLayout = $TargetInventory.attributes.hpe_vme.instance_type_layouts | Where-Object { $_.name -eq $Layout }
    $SelectedPlan = $TargetInventory.attributes.hpe_vme.plans | Where-Object { $_.name -eq $Plan }
    $SelectedResourcePool = $SelectedLayout.resource_pools | Where-Object { $_.name -eq $ResourcePool }

    $EffectiveCoresPerSocket = if (-not [string]::IsNullOrEmpty($CoresPerSocket)) { [int]$CoresPerSocket } else { $SelectedPlan.cores_per_socket }
    $EffectiveMemory = $null
    if ($SelectedPlan.custom_memory) {
        if (-not [string]::IsNullOrEmpty($Memory)) {
            $EffectiveMemory = [int]$Memory * 1024
        } else {
            $EffectiveMemory = $SelectedPlan.memory_kb
        }
    }
    $EffectiveCores = $null
    if ($SelectedPlan.custom_cpus) {
        if (-not [string]::IsNullOrEmpty($Cores)) {
            $EffectiveCores = [int]$Cores
        } else {
            $EffectiveCores = $SelectedPlan.cpus
        }
    }

    $CurrentTime = Get-Date -Format "yyyy/MM/dd HH:mm:ss"
    $MigrationProfile = @{
        "name" = "powershell-" + $Source.host + "-" + $CurrentTime
        "tags" = @()
        "entitlement" = $false
        "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
                    }
                )
                "desc" = "Basic Migration"
                "source" = $Source.id
                "boot_mode_conversion" = $null
                "generalize_system" = $false
                "target_config" = @{
                    "vm_details" = @{
                        "vm_name" = $TargetVMName
                        "flavor" = @{
                            "cores_per_socket" = "$EffectiveCoresPerSocket"
                            "plan" = $SelectedPlan.identifier
                            "plan_display_name" = $SelectedPlan.name
                            "ram_kb" = $EffectiveMemory
                            "cpu" =  if ($null -ne $EffectiveCores) {"$EffectiveCores" } else {$null}
                        }
                        "datastores" = @($SelectedDatastore.identifier)
                        "group" = $SelectedGroup.identifier
                        "group_display_name" = $SelectedGroup.name
                        "cloud" = $SelectedCloud.identifier
                        "cloud_display_name" = $SelectedCloud.name
                        "cluster" = $SelectedCluster.identifier
                        "cluster_display_name" = $SelectedCluster.name
                        "host" = $SelectedHost.identifier
                        "host_display_name" = if ($SelectedHost) { $SelectedHost.name } else { "" }
                        "instance_type" = $SelectedLayout.instance_type_identifier
                        "instance_type_layout" = $SelectedLayout.identifier
                        "instance_type_layout_display_name" = $SelectedLayout.name
                        "resource_pool" = $SelectedResourcePool.identifier
                        "resource_pool_display_name" = $ResourcePool
                        "install_ssm_agent" = $InstallAWSSSMAgent
                        "install_cloudwatch_agent" = $InstallAWSCloudWatchAgent
                    }
                    "options" = @{}
                    "properties" = @{
                        "network" = @{
                            "dns" = @{
                                "primary" = $PrimaryDNS
                                "secondary" = $SecondaryDNS
                            }
                            "force_provided_network_config" = $UseCustomNetworkConfig
                            "interfaces" = $NetworkInterfaces
                            "routes" = @{
                                "default_gateway" = $DefaultGateway
                            }
                        }
                        "selected_mounts" = $SelectedDisk
                        "install_applications" = $InstallApplication
                        "name" = $TargetVMName
                        "mounts_new_size" = @{}
                        "convert_filesystems" = @{}
                    }
                }
                "os_type" = $Source.os_type
                "name" = $Source.host
                "collection_type" = "vm"
                "finalize_target" = $FinalizeMigration
                "shutdown_source" = $ShutdownSource
                "shutdown_target" = $ShutdownTarget
                "in_place_upgrade" = $false
                "upgrade_os_version" = $null
                "transfer_technology" = "bbt"
                "transfer_type" = "block-based"
                "migration_instructions" = $MigrationInstruction
                "ignore_validation_errors" = $IgnoreValidationError
                "preflight_warning" = $false
            }
        )
    }

    return Invoke-RMMigrationProfilePost -MigrationProfile $MigrationProfile
}