Validate/Validate.psm1

Import-Module -Name @(Join-Path $PSScriptRoot .. | Join-Path -ChildPath Util | Join-Path -ChildPath Util)
function Confirm-RMVSphereValidateOSBasedMigrationProfile {
    param(
        [System.Object] $Entitlement,
        [System.Object] $Source,
        [System.Object] $CloudAccount,
        [string] $TargetVMName,
        [string] $TransferType,
        [string] $CoresPerSocket,
        [string] $MemorySize,
        [int] $TargetVMVCPUCount,
        [int] $TargetVMMemorySize,
        [string] $DatacenterName,
        [string] $ClusterName,
        [string] $ResourcePoolName,
        [string] $FolderName,
        [string] $HardwareVersion,
        [string[]] $DatastoreLocations,
        [string[]] $DisksProvisioningType,
        [string] $DataTransferPort,
        [bool] $EnableDestinationNetworkIsolation,
        [RMVSphereMigrationNetworkConfiguration] $MigrationNetworkConfig,
        [RMVSphereIsolatedNetworkConfiguration] $IsolatedNetworkConfig,
        [RMVSphereDestinationNetworkConfiguration[]] $DestinationNICConfig,
        [string] $DisableAutomaticDNSRegistrationOnTheTarget,
        [string] $ShutdownSource,
        [string] $ShutdownTarget,
        [string] $RemoveRMSAgentFromSource,
        [string] $RemoveRMSAgentFromTarget,
        [hashtable]  $MigrationInstructions,
        [System.Object[]] $SelectedMounts
    )

    $OverrideCPU = $false
    $Cpus = $Source.attributes.cpu.processors.Count
    if ($Cpus -ne $TargetVMVCPUCount) {
        $OverrideCPU = $true
    }
   
    $Partitions = Get-RMPartition  -SelectedMounts $SelectedMounts

    $MigrationInstructionsList = @()
    if ($null -ne $MigrationInstructions) {
        $MigrationInstructionsList =  $MigrationInstructions.Keys | foreach-object { "$_/$($MigrationInstructions[$_])"}
    }

    $OverrideMemory = $false
    if (0 -ne $TargetVMMemorySize) {
        $OverrideMemory = $true
    }

    $NetworkConfig = @()
    if ($EnableDestinationNetworkIsolation) {
        $NetworkConfig = $MigrationNetworkConfig.IPType, $MigrationNetworkConfig.MigrationNetworkName, `
            $MigrationNetworkConfig.IPAddress, $MigrationNetworkConfig.Netmask, $MigrationNetworkConfig.DefaultGateway, `
            $MigrationNetworkConfig.PrimaryDNS, $MigrationNetworkConfig.SecondaryDNS
    } else {
        # Looks like, CSV migrations support only a single NIC hence we can validate only the first NIC
        $NetworkConfig = $DestinationNICConfig[0].IPType, $DestinationNICConfig[0].DestinationNetworkName, `
            $DestinationNICConfig[0].IPAddress, $DestinationNICConfig[0].Netmask, $DestinationNICConfig[0].DefaultGateway, `
            $DestinationNICConfig[0].PrimaryDNS, $DestinationNICConfig[0].SecondaryDNS
    }

    $ValidateData = @{
        "source_ip" = $Source.host
        "migration_method" = "OS-based"
        "source_hostname" = $Source.hostname
        "os_type" = $Source.os_type
        "migration_type" = "full"
        "scheduled_at" = ""
        "target_vm_name" = "$TargetVMName"
        "transfer_method" = "$TransferType"
        "cpus" = "$Cpus"
        "override_cpu_count" = "$TargetVMVCPUCount"
        "cores_per_socket" = "$CoresPerSocket"
        "memory" =  "$MemorySize"
        "override_memory" = "$OverrideMemory"
        "override_memory_size" = "$TargetVMMemorySize"
        "override_cpus" = "$OverrideCPU"
        "datacenter" = "$DatacenterName"
        "cluster" = "$ClusterName"
        "resource_pool" = "$ResourcePoolName"
        "vm_folder" =  "$FolderName"
        "vm_hardware_version" = "$HardwareVersion"
        "disk_datastores" =  $DatastoreLocations
        "disks_provisioning_type" =  $DisksProvisioningType
        "data_transfer_port" = "$DataTransferPort"
        "ip_type" = $NetworkConfig[0]
        "destination_network_name"= $NetworkConfig[1]
        "ip_address" = $NetworkConfig[2]
        "netmask" = $NetworkConfig[3]
        "default_gateway" = $NetworkConfig[4]
        "primary_dns" = $NetworkConfig[5]
        "secondary_dns" = $NetworkConfig[6]
        "enable_destination_network_isolation" = "$EnableDestinationNetworkIsolation"
        "network_isolation_ip_type" = $IsolatedNetworkConfig.IPType
        "network_isolation_network_name" = $IsolatedNetworkConfig.IsolatedNetworkName
        "network_isolation_ip_address" = $IsolatedNetworkConfig.IPAddress
        "network_isolation_netmask" = $IsolatedNetworkConfig.Netmask
        "network_isolation_default_gateway" = $IsolatedNetworkConfig.DefaultGateway
        "network_isolation_primary_dns" = $IsolatedNetworkConfig.PrimaryDNS
        "network_isolation_secondary_dns" = $IsolatedNetworkConfig.SecondaryDNS
        "disable_automatic_dns_registration_on_target" = "$DisableAutomaticDNSRegistrationOnTheTarget"
        "source_shutdown" = "$ShutdownSource"
        "target_shutdown" = "$ShutdownTarget"
        "remove_rms_agent_from_source_post_migration" = "$RemoveRMSAgentFromSource"
        "remove_rms_agent_from_target_post_migration" = "$RemoveRMSAgentFromTarget"
        "override_source_migration" = "$false"
        "migration_instructions" = @($MigrationInstructionsList)
        "ignore_validation_errors" =  "$true"
        "target_cloud" = $CloudAccount.name
        "source_id" =  $Source.id
        "create_resource_pool" = "$false"
        "create_vm_folder" = "$false"
        "partitions" = @($Partitions)
    }

    return Invoke-RMValidateDataPost -ValidateData $ValidateData -Entitlement $Entitlement -MigrationMethod "OS-based"
}

function Get-RMValidationErrors {
    param (
        [System.Object] $ErrorObj
    )
    $Errors = @()
    $ErrorString = $ErrorObj.ToString()
    $ErrorString = $ErrorString | ConvertFrom-Json
    foreach($Message in $ErrorString.validation_errors.errors) {
        if ($null -eq $Message.message) {
            $Errors += $ErrorObj.ToString()
            break
        } else {
            $Errors += $Message.message
        }
    }
    return $Errors
}

function Confirm-RMVSphereValidateVMBasedMigrationProfile {
    param(
        [System.Object] $Entitlement,
        [System.Object] $CloudAccount,
        [System.Object] $Source,
        [System.Object] $ScheduledAt,
        [string] $TargetVMName,
        [string[]] $SelectedDiskLabel,
        [System.Object[]] $SelectedDisk,
        [string[]] $SelectedDiskIndex,
        [string] $TargetVMVCPUCount,
        [string] $CoresPerSocket,
        [int] $TargetVMMemorySize,
        [string] $DatacenterName,
        [bool] $PreserveIPAddress,
        [RMVSphereDestinationNetworkConfiguration[]] $DestinationNICConfig,
        [bool] $PreserveMACAddress,
        [hashtable] $VMTag,
        [string] $ClusterName,
        [string] $ResourcePoolName,
        [string] $FolderName,
        [string] $DatastoreClusterName,
        [string[]] $DatastoreLocation,
        [hashtable] $StorageProfileId,
        [hashtable] $StorageProfileName,
        [System.Object[]] $DiskProvisioningType,
        [bool] $UpgradeTool,
        [string] $HardwareVersion,
        [string] $ToolsPackage,
        [bool] $ShutdownSource,
        [bool] $ShutdownTarget,
        [bool] $FinalizeMigration,
        [hashtable] $MigrationInstruction,
        [bool] $IgnoreValidationErrors
    )

    $OverrideCPU = $false
    $SourceCpuCnt = $Source.attributes.cpu.processors.Count
    if (0 -ne $TargetVMVCPUCount) {
        $OverrideCPU = $true
    }

    $MigrationInstructionsList = @()
    if ($null -ne $MigrationInstructions) {
        $MigrationInstructionsList =  $MigrationInstructions.Keys | foreach-object { "$_/$($MigrationInstructions[$_])"}
    }

    $OverrideMemory = $false
    if (0 -ne $TargetVMMemorySize) {
        $OverrideMemory = $true
    }

    $StoragePolicyNames = @()
    $PopulateDefaultPolicyCnt = 0
    if ($null -eq $StorageProfileName) {
        $PopulateDefaultPolicyCnt = $SelectedDiskLabel.Count
    } else {
        $StoragePolicyNames = $StorageProfileName.Values
        $PopulateDefaultPolicyCnt = $SelectedDiskLabel.Count - $StorageProfileName.Keys.Count
    }

    for ($Index = 0; $Index -lt $PopulateDefaultPolicyCnt; $Index++) {
        $StoragePolicyNames += "Datastore Default"
    }
    
    $ValidateData = @{
        "target_cloud" = $CloudAccount.name
        "source_vm_name" = $Source.host
        "os_type" = $Source.os_type
        "migration_type" = "full"
        "migration_method" = "VM-based"
        "scheduled_at" = ""
        "target_vm_name" = $TargetVMName
        "cpus" = $SourceCpuCnt
        "override_cpus" = $OverrideCPU
        "override_cpu_count" = $TargetVMVCPUCount
        "cores_per_socket" = $CoresPerSocket
        "memory" = [math]::Round($Source.attributes.memory.total_kb/(1024 * 1024))
        "override_memory" = $OverrideMemory
        "override_memory_size" = $TargetVMMemorySize
        "datacenter" = $DatacenterName
        "cluster" = $ClusterName
        "resource_pool" = $ResourcePoolName
        "create_resource_pool" = $false
        "vm_folder" = $FolderName
        "create_vm_folder" = $false
        "vm_hardware_version" = $HardwareVersion
        "disks" = $SelectedDiskLabel
        "disk_datastores" = $DatastoreLocation
        "storage_policies" = $StoragePolicyNames
        "disks_provisioning_type" = $DiskProvisioningType
        "preserve_ip" = $PreserveIPAddress
        "preserve_mac_address" = $PreserveMACAddress
        "ip_type" = $DestinationNICConfig[0].IPType
        "destination_network_name" = $DestinationNICConfig[0].DestinationNetworkName
        "ip_address" = $DestinationNICConfig[0].IPAddress
        "netmask" = $DestinationNICConfig[0].Netmask
        "default_gateway" = $DestinationNICConfig[0].DefaultGateway
        "primary_dns" = $DestinationNICConfig[0].PrimaryDNS
        "secondary_dns" = $DestinationNICConfig[0].SecondaryDNS
        "upgrade_tools" = $UpgradeTool
        "source_shutdown" = $ShutdownSource
        "target_shutdown" = $ShutdownTarget
        "finalize_migration" = $FinalizeMigration
        "override_source_migration" = "FALSE"
        "migration_instructions" = $MigrationInstructionsList
        "ignore_validation_errors" = $IgnoreValidationErrors
        "source_id" = $Source.id
    }

    return Invoke-RMValidateDataPost -ValidateData $ValidateData -Entitlement $Entitlement -MigrationMethod "vm-based"
}

function Invoke-RMValidateDataPost {
    param(
        [hashtable] $ValidateData,
        [System.Object] $Entitlement,
        [string] $MigrationMethod
    )

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

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

    $Body = @{
        "entitlement_id" = $Entitlement.id
        "timezone" = "test"
        "csv_migration_data" = @($ValidateData)
        "migration_method" = $MigrationMethod

    } | ConvertTo-Json -Depth 100

    $Params = @{
        Method = "Post"
        Uri = $Uri.Value + "/csvmigrations/validate"
        Headers = $Headers
        ContentType = "application/json"
        Body =$Body
    }

    try {
        Invoke-RMRestMethod -Params $Params | Out-Null
    } catch [System.Exception] {
        Show-RMError -ErrorObj $PSItem
        return Get-RMValidationErrors -ErrorObj $PSItem
    }
}