Migration/GCP/GCPUtil.psm1

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

function Get-RMProjectIDToNameMapping {
    param(
        [System.Object] $CloudAttribute
    )
    $ProjectMapping = @{}
    foreach ($Project in $CloudAttribute.properties.projects) {
        $ProjectMapping.Add($Project.identifier, $Project.name)
    }

    return $ProjectMapping
}

function Get-RMRegionToZonesMapping {
    param(
        [System.Object] $RegionAndZone
    )

    $RegionZoneMapping = @{}
    foreach ($Region in $RegionAndZone) {
        $RegionZoneMapping.Add($Region.name, $Region.zones.name)
    }

    return $RegionZoneMapping
}

function Read-RMMachineType {
    param (
        [System.Object] $CloudAttribute
    )
    while ($true) {
        $ReadValue = Read-RMString -UserMessage "Enter machine type, e.g. c2-standard-16" `
            -ParameterName "Machine Type" -IsRequired $true

        if ($CloudAttribute.properties.projects[0].regions[0].zones[0].machine_types.name -notcontains $ReadValue) {
            Write-RMError -Message "Machine type '$ReadValue' does not exists."
            continue
        }

        return $ReadValue
    }
}

function Get-RMDiskTypeBySource {
    param(
        [System.Object] $Source,
        [bool] $IsInteractive,
        [bool] $IsVM,
        [string[]] $DiskTypeName,
        [string[]] $SelectedDiskLabel 
    )

    $DiskTypes = @()
    if (!$IsVM) {
        $SortedDisks =  $Source.attributes.storage.disks.psobject.Properties.Value | Sort-Object -Property device
    } else {
        $SortedDisks = $Source.attributes.storage.vm_disks
    }
    
    $DiskTypeCount = 0;
    foreach ($Disk in  $SortedDisks) {
        if ($IsInteractive) {
            $Size = $Disk.size_kb/(1024*1024)
            $Size = [math]::round($Size, 2)
            $Type = Read-RMString -UserMessage "Enter the disk type for disk with size $Size GiB" `
                -Options "Standard_Persistent", "Balanced_Persistent", "SSD_Persistent" -ParameterName "Disk Type" `
                -DefaultValue "SSD_Persistent" -IsRequired $false
            $DiskTypes += Get-RMDiskTypeByUserInput -UserInput $Type
        } else {
            if ($IsVM) {
                if ($SelectedDiskLabel -contains $Disk.label -and $DiskTypeCount -lt $DiskTypeName.Count) {
                    $DiskTypes += Get-RMDiskTypeByUserInput -UserInput $DiskTypeName[$DiskTypeCount]
                }
            } elseif ($DiskTypeCount -lt $DiskTypeName.Count) {
                $DiskTypes += Get-RMDiskTypeByUserInput -UserInput $DiskTypeName[$DiskTypeCount]
            }
            $DiskTypeCount ++
        }
    }
    return $DiskTypes
}

function Get-RMDiskTypeByUserInput {
    param (
        [string] $UserInput
    )
    $DiskTypes = @{
        "Standard_Persistent" = "pd-standard"
        "Balanced_Persistent" = "pd-balanced"
        "SSD_Persistent" = "pd-ssd"
    }

    return $DiskTypes[$UserInput]
}

function Get-RMNetworkToSubnetMapping {
    param(
        [System.Object] $CloudAttribute
    )

    if ($null -eq $CloudAttribute.properties.projects[0].regions[0].networks -or `
            $CloudAttribute.properties.projects[0].regions[0].networks.Count -eq 0) {
        return $null
    }

    $NetworkToSubnetMapping = @{}
    foreach ($Network in $CloudAttribute.properties.projects[0].regions[0].networks) {
        $NetworkName = $Network.name
        if (![string]::IsNullOrWhiteSpace($Network.from_project)) {
            $NetworkName += "-from_project:" + $Network.from_project
        }
        $NetworkToSubnetMapping.Add($NetworkName, $Network.subnets)
    }

    return $NetworkToSubnetMapping
}

function Get-RMSubnetNameByNetworkName {
    param(
        [string] $NetworkName,
        [System.Object] $NetworkToSubnetMapping
    )

    $Subnets = $NetworkToSubnetMapping[$NetworkName]
    $SubnetNames = @()
    foreach ($Subnet in $Subnets) {
        $SubnetNames += $Subnet.name
    }

    return $SubnetNames
}

function Get-RMNetworkNameToNetworkTagsMapping {
    param(
        [System.Object] $CloudAttribute
    )
    if ($null -eq $CloudAttribute.properties.projects[0].regions[0].networks -or `
            $CloudAttribute.properties.projects[0].regions[0].networks.Count -eq 0) {
        return $null
    }

    $NetworkNameToNetworkTagsMapping = @{}
    foreach ($Network in $CloudAttribute.properties.projects[0].regions[0].networks) {
        $NetworkName = $Network.name
        if (![string]::IsNullOrWhiteSpace($Network.from_project)) {
            $NetworkName += "-from_project:" + $Network.from_project
        }    
        $NetworkNameToNetworkTagsMapping.Add($NetworkName, $Network.target_tags)
    }

    return $NetworkNameToNetworkTagsMapping
}

function Get-RMNetworkNameByUserInput {
    param (
        [string] $NetworkName
    )
    if (!$NetworkName.Contains("from_project")) {
        return $NetworkName
    }

    $Name = $NetworkName.Substring(0, $NetworkName.IndexOf("-from_project:"))
    $Project = $NetworkName.Substring($NetworkName.LastIndexOf(":") + 1, $NetworkName.Length - $NetworkName.LastIndexOf(":") - 1)
    return "projects/$Project/global/networks/$Name"
}

function Get-RMSQLLicenseMapping {
    param()
    $SQLLicenseMapping = [ordered] @{}
    $SQLLicenseMapping.Add("SQL Server 2012 Enterprise", "projects/windows-sql-cloud/global/licenses/sql-server-2012-enterprise")
    $SQLLicenseMapping.Add("SQL Server 2012 Standard", "projects/windows-sql-cloud/global/licenses/sql-server-2012-standard")
    $SQLLicenseMapping.Add("SQL Server 2012 Web", "projects/windows-sql-cloud/global/licenses/sql-server-2012-web")
    $SQLLicenseMapping.Add("SQL Server 2014 Enterprise", "projects/windows-sql-cloud/global/licenses/sql-server-2014-enterprise")
    $SQLLicenseMapping.Add("SQL Server 2014 Standard", "projects/windows-sql-cloud/global/licenses/sql-server-2014-standard")
    $SQLLicenseMapping.Add("SQL Server 2014 Web", "projects/windows-sql-cloud/global/licenses/sql-server-2014-web")
    $SQLLicenseMapping.Add("SQL Server 2016 Enterprise", "projects/windows-sql-cloud/global/licenses/sql-server-2016-enterprise")
    $SQLLicenseMapping.Add("SQL Server 2016 Express", "projects/windows-sql-cloud/global/licenses/sql-server-2016-express")
    $SQLLicenseMapping.Add("SQL Server 2016 Web", "projects/windows-sql-cloud/global/licenses/sql-server-2016-web")
    $SQLLicenseMapping.Add("SQL Server 2017 Enterprise", "projects/windows-sql-cloud/global/licenses/sql-server-2017-enterprise")
    $SQLLicenseMapping.Add("SQL Server 2017 Express", "projects/windows-sql-cloud/global/licenses/sql-server-2017-express")
    $SQLLicenseMapping.Add("SQL Server 2017 Standard", "projects/windows-sql-cloud/global/licenses/sql-server-2017-standard")
    $SQLLicenseMapping.Add("SQL Server 2017 Web", "projects/windows-sql-cloud/global/licenses/sql-server-2017-web")
    $SQLLicenseMapping.Add("SQL Server 2019 Enterprise", "projects/windows-sql-cloud/global/licenses/sql-server-2019-enterprise")
    $SQLLicenseMapping.Add("SQL Server 2019 Express", "projects/windows-sql-cloud/global/licenses/sql-server-2019-express")
    $SQLLicenseMapping.Add("SQL Server 2019 Standard", "projects/windows-sql-cloud/global/licenses/sql-server-2019-standard")
    $SQLLicenseMapping.Add("SQL Server 2019 Web", "projects/windows-sql-cloud/global/licenses/sql-server-2019-web")

    return $SQLLicenseMapping
}

function Read-RMNodeGroupName {
    param(
        [System.Object] $CloudAttribute
    )
    while ($true) {
        $MigrateToSoleTenantNode = Read-RMBoolean -UserMessage "Do you want to migrate to sole-tenant node" -DefaultValue "false"
        if (!$MigrateToSoleTenantNode) {
            return ""
        }

        $NodeGroupNames = Get-RMAvailableNodeGroupName -CloudAttribute $CloudAttribute
        if ($null -eq $NodeGroupNames) {
            Write-RMError -Message "No node groups were found, please create a node group and try again"
            continue
        }
        return Read-RMString -UserMessage "Enter node group name" -Options $NodeGroupNames `
            -ParameterName "Node Group Name" -IsRequired $true
    }
}

function Get-RMRegionByRegionName {
    param (
        [string] $RegionName,
        [System.Object] $Region
    )

    foreach($Reg in $Region) {
        if ($RegionName -ieq $Reg.name) {
            return $Region
        }
    }
    return $null
}

function Get-RMSubnetByNetworkName {
    param (
        [string] $NetworkName,
        [System.Object] $NetworkObject
    )

    foreach ($Network in $NetworkObject) {
        if ($NetworkName -ieq $Network.name) {
            return $Network.subnets
        }
    }
    return $null
}

function Get-RMDefaultProjectByIdentifier {
    param(
        [System.Object] $ProjectObject,
        [string] $Identifier
    )

    foreach ($Project in $ProjectObject) {
        if ($Identifier -ieq $Project.identifier) {
            return $Project
        }
    }

    return $null
}

function Get-RMProjectIdentifierByProjectName {
    param (
        [System.Object] $ProjectObject,
        [string] $ProjectName
    )
    
    foreach ($Project in $ProjectObject) {
        if ($ProjectName -ieq $Project.name) {
            return $Project
        }
    }

    return $null
}

function Get-RMNetworkByNertworkName {
    param (
        [System.Object] $NetworkObject,
        [string]  $NetworkName
    )

    foreach ($Network in $NetworkObject) {
        if ($NetworkName -ieq $Network.name) {
            return $Network
        }
    }
    return $null
}

function Get-RMDiskType {
    param (
        [string] $DiskType
    )

    switch ($DiskType) {
        "Standard Persistent" { 
            $DiskType = "pd-standard"
            Break;
         }
        "Balanced Persistent" {
            $DiskType = "pd-balanced"
            Break;
        }
        "SSD Persistent" {
            $DiskType = "pd-ssd"
            Break;
        }
    }
    return $DiskType
}

function Get-RMAvailableNodeGroupName {
    param(
        [System.Object] $CloudAttribute
    )

    if ($null -eq $CloudAttribute.properties.projects[0].regions[0].zones[0].node_groups -or `
            $CloudAttribute.properties.projects[0].regions[0].zones[0].node_groups.Count -eq 0) {
        return $null
    }

    $NodeGroupNames = @()
    foreach ($NodeGroup in $CloudAttribute.properties.projects[0].regions[0].zones[0].node_groups) {
        if ($NodeGroup.status -ine "READY") {
            continue
        }
        $NodeGroupNames += $NodeGroup.node_group_name
    }

    return $NodeGroupNames
}

function Get-RMNetworkTier {
    param(
        [string] $NetworkTierName
    )

    switch ($NetworkTierName) {
        "Premium" {
            $NetworkTierName = "PREMIUM"
            Break
        }

        "Standard" {
            $NetworkTierName = "STANDARD"
            Break
        }
    }

    return $NetworkTierName
}