RiverMeadow.Migrate.psm1

Import-Module -Name $PSScriptRoot\Util\Util
Import-Module -Name $PSScriptRoot\Util\MigrationUtil
Import-Module -Name $PSScriptRoot\Common\Wrappers\Wrappers
function Start-RMAzureOSBasedMigration {
    param(
        [Alias("can")]
        [string] $CloudAccountName,

        [Alias("sip")]
        [string] $SourceIP,

        [Alias("rsa")]
        [bool] $RefreshSourceAttributes,

        [Alias("tvmname")]
        [string] $TargetVMName,

        [Alias("tm")]
        [ValidateSet("file-based", "block-based")]
        [string] $TransferMethod,

        [Alias("crg")]
        [bool] $CreateResourceGroup,

        [Alias("rg")]
        [string] $ResourceGroup,

        [Alias("rgr")]
        [string] $ResourceGroupRegion,

        [Alias("vmsn")]
        [string] $VMSizeName,

        [Alias("vt")]
        [ValidateSet("Standard_SSD", "Standard_HDD", "Premium_SSD")]
        [string] $VolumeType,

        [Alias("mp")]
        [string[]] $MountPoints,

        [Alias("rmp")]
        [string[]] $ResizeMountPoints,

        [Alias("vn")]
        [string] $VirtualNetwork,

        [Alias("sn")]
        [string] $Subnet,

        [Alias("apip")]
        [bool] $AssignPublicIP,

        [Alias("spip")]
        [string] $StaticPrivateIP,

        [Alias("etni")]
        [bool] $EnforceTargetNetworkIsolation,

        [Alias("sg")]
        [string] $SecurityGroup,

        [Alias("dtdnsr")]
        [bool] $DisableTargetDNSRegistration,

        [Alias("itags")]
        [string[]] $InstanceTags,

        #TODO: parameterset
        [Alias("ao")]
        [ValidateSet("None", "AvailabilityZone", "AvailabilitySet")]
        [string] $AvailabilityOptions,

        [Alias("az")]
        [ValidateSet(1, 2, 3)]
        [int] $AvailabilityZone,

        [Alias("cas")]
        [bool] $CreateAvailabilitySet,

        [Alias("as")]
        [string] $AvailabilitySet,

        [Alias("fd")]
        [int] $FaultDomains,

        [Alias("ud")]
        [int] $UpdateDomains,

        #TODO: parameterset
        [Alias("ebd")]
        [bool] $EnableBootDiagnostics,

        [Alias("sa")]
        [string] $StorageAccount,

        #TODO: parameterset
        [Alias("det")]
        [ValidateSet("platform-managed", "customer-managed")]
        [string] $DiskEncryptionType,

        [Alias("es")]
        [string] $EncryptionSet,

        [Alias("ehub")]
        [bool] $EnableHybridUseBenefit,

        [Alias("uosv")]
        [string] $UpgradeOSVersion,

        [Alias("ss")]
        [bool] $ShutdownSource,

        [Alias("st")]
        [bool] $ShutdownTarget,

        [Alias("rrmsa")]
        [bool] $RemoveRMSAgent,

        [Alias("mi")]
        [string[]] $MigrationInstructions
    )

    $UserLoginStatus = Test-UserLoggedIn
    if (!$UserLoginStatus) {
        return
    }

    Import-Module -Name $PSScriptRoot\Migration\AZURE\AZURE
    if (0 -eq $PSBoundParameters.Count) {
        Start-RMAzureOSBasedInteractiveMigration
    } else {
        Start-RMAzureOSBasedNonInteractiveMigration @PSBoundParameters
    }
}

function Start-RMVSphereOSBasedMigration {
    param(
        [Alias('can')]
        [string] $CloudAccountName,

        [Alias("sip")]
        [string] $SourceIP,

        [Alias("rsa")]
        [bool] $RefreshSourceAttributes,

        [Alias("tvmname")]
        [string] $TargetVMName,

        [Alias("mp")]
        [string[]] $MountPoints,

        [Alias("rmp")]
        [string[]] $ResizeMountPoints,

        [Alias("tm")]
        [ValidateSet("file-based", "block-based")]
        [string] $TransferMethod,

        [Alias("cps")]
        [ValidateSet("1", "2")]
        [int] $CoresPerSocket,

        [Alias("om")]
        [bool] $OverrideMemory,

        [Alias("oms")]
        [int] $OverrideMemorySize,

        [Alias("dcn")]
        [string] $DatacenterName,

        [Alias("edni")]
        [bool] $EnableDestinationNetworkIsolation,

        [Alias("dnn")]
        [string] $DestinationNetworkName,

        [Alias("ipt")]
        [ValidateSet("static", "DHCP")]
        [string] $IpType,

        [Alias("ipa")]
        [string] $IpAddress,

        [Alias("nm")]
        [string] $Netmask,

        [Alias("dg")]
        [string] $DefaultGateway,

        [Alias("pdns")]
        [string] $PrimaryDNS,

        [Alias("sdns")]
        [string] $SecondaryDNS,

        [Alias("inn")]
        [string] $IsolatedNetworkName,

        [Alias("iipt")]
        [ValidateSet("static", "DHCP")]
        [string] $IsolatedIpType,

        [Alias("iipa")]
        [string] $IsolatedIpAddress,

        [Alias("in")]
        [string] $IsolatedNetmask,

        [Alias("idg")]
        [string] $IsolatedDefaultGateway,

        [Alias("ipdns")]
        [string] $IsolatedPrimaryDNS,

        [Alias("isdns")]
        [string] $IsolatedSecondaryDNS,

        [Alias("dadnsrot")]
        [bool] $DisableAuthomaticDNSRegistrationOnTheTarget,

        [Alias("cl")]
        [string] $Cluster,

        [Alias("rp")]
        [string] $ResourcePool,

        [Alias("fn")]
        [string] $FolderName,

        [Alias("dc")]
        [string] $DatastoreCluster,

        [Alias("dn")]
        [string[]] $DatastoreNames,

        [Alias("dpt")]
        [ValidateSet("thick-lazy-zeroed", "thick-eager-zeroed", "thin")]
        [string[]] $DiskProvisioningTypes,

        [Alias("hv")]
        [int] $HardwareVersion,

        [Alias("ss")]
        [bool] $ShutdownSource,

        [Alias("st")]
        [bool] $ShutdownTarget,

        [Alias("rrmsa")]
        [bool] $RemoveRMSAgent,

        [Alias("mi")]
        [hashtable] $MigrationInstructions,

        [Alias("uosv")]
        [string]  $UpgradeOSVersion
    )

    $UserLoginStatus = Test-UserLoggedIn
    if (!$UserLoginStatus) {
        return
    }

    Import-Module -Name $PSScriptRoot\Migration\vSphere\vSphere -Force

    if (0 -eq $PSBoundPArameters.Count) {
        return Start-RMInteractiveVSphereOSBasedMigration
    } else {
        return Start-RMNonInteractiveVsphereOsBasedMigration  @PSBoundParameters
    }
}

function Start-RMVSphereDifferentialMigration {
    param(
        [Alias("mid")]
        [System.Guid] $MigrationId
    )

    $UserLoginStatus = Test-UserLoggedIn
    if (!$UserLoginStatus) {
        return
    }

    Import-Module -Name $PSScriptRoot\Migration\vSphere\vSphere -Force

    $InvalidUUID = $null
    if (0 -eq $PSBoundPArameters.Count) {
        $UserMigrationId = @()
        $UserMigrationId, $InvalidUUID = Read-UUID -UserMessage "Enter the full migration ID" -ErrorMessage "Full migration ID is required"
        if ($InvalidUUID.Count -gt 0) {
            Throw "Invalid full migration ID: $InvalidUUID"
        }
        $MigrationId = $UserMigrationId[0]
    }

    return Start-RMVSphereOsBasedDifferentialMigration -MigrationId $MigrationId
}

function Stop-RMMigration {
    param (
        [Alias("mid")]
        [System.Guid] $MigrationId
    )

    $UserLoginStatus = Test-UserLoggedIn
    if (!$UserLoginStatus) {
        return
    }

    $InvalidUUID = @()
    if (0 -eq $PSBoundParameters.Count) {
        $UserMigrationId = @()
        $UserMigrationId, $InvalidUUID = Read-UUID -UserMessage "Enter the ID of the migration that you want to stop" -ErrorMessage "Migration ID is required"
        if ($InvalidUUID.Count -gt 0) {
            Throw "Invalid migration ID: $InvalidUUID"
        }
        $MigrationId = $UserMigrationId[0]
    }

    $Migration = Get-RMMigrationByIdAndStatus -MigrationId $MigrationId -StatusOnly $true

    if("error" -ne $Migration.state -and "success" -ne $Migration.state -and "cancelled" -ne $Migration.state) {

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

        $Headers = @{
            Accept = "application/rm+json"
            "X-Auth-Token" = $RMLoginResult.Value.token
        }
    
        $Params = @{
            Method = "Post"
            Uri = $Uri.Value + "/migrations/" + $MigrationId + "/cancel"
            Headers = $Headers
            ContentType = "application/json"
        }

        $Response = Invoke-RMRestMethod -Params $Params
        return "Migration " + $Response.id + " is cancelled."
    }
    throw "Migration is in final state " +  $Migration.state + ", cannot be cancelled."
}

function Get-RMMigrations {
    param (
        # ID's of the migrations that needs to be fetched
        [Alias("mid")]
        [System.Guid[]] $MigrationIds
    )

    $UserLoginStatus = Test-UserLoggedIn
    if (!$UserLoginStatus) {
        return
    }

    $InvalidUUIDs = @()
    if (0 -eq $PSBoundParameters.Count) {
        $MigrationIds, $InvalidUUIDs = Read-UUID -UserMessage "Enter one or more migration IDs, separated by commas" -ErrorMessage "At least one migration ID is required."
    }

    if ($MigrationIds.Count -eq 0 -and $InvalidUUIDs.Count -gt 0) {
        $InvalidUUIDsAsString = $InvalidUUIDs -join ", "
        Throw "Invalid migration IDs: $InvalidUUIDsAsString"
    }

    $Migrations = Get-RMMigrationsByIds -MigrationIds $MigrationIds
    $Result = @()
    $ReceivedMigrationIds = @()
    foreach ($Migration in $Migrations.content) {
        switch ($Migration.state) {
            "success" {
                $MigrationStatus = [MigrationStatus]::new($Migration.id, $Migration.state, "100%")
            }
            "running" {
                $Progress = [string] (Get-RMMigrationProgress -Migration $Migration)
                $IsStalled = Test-RMMigrationStalled -Migration $Migration
                if ($IsStalled) {
                    $MigrationStatus = [MigrationStatus]::new($Migration.id, "stalled", "N/A")
                } else {
                    $MigrationStatus = [MigrationStatus]::new($Migration.id, $Migration.state, $Progress+"%")
                }
            }
            default {
                $MigrationStatus = [MigrationStatus]::new($Migration.id, $Migration.state, "N/A")
            }
        }
        $Result += $MigrationStatus 
        $ReceivedMigrationIds += $Migration.id
    }

    if ($Migrations.content.Count -ne $MigrationIds.Count) {
        $MigrationsNotFound = Get-RMMigrationsNotFound -ReceivedMigrationIds $ReceivedMigrationIds -UserInputMigrationIds $MigrationIds
        $MigrationsNotFoundAsString = $MigrationsNotFound -join ", "
        Write-RMError -Message "Could not find migrations with IDs: $MigrationsNotFoundAsString"
    }

    if ($InvalidUUIDs.Count -gt 0) {
        $InvalidUUIDsAsString = $InvalidUUIDs -join ", "
        Write-RMError -Message "Invalid migration IDs: $InvalidUUIDsAsString"
    }
    return $Result 
}

Export-ModuleMember -Function Start-RMVSphereOSBasedMigration, Start-RMAzureOSBasedMigration, Get-RMMigrations, Start-RMVSphereDifferentialMigration, Stop-RMMigration