RiverMeadow.Source/SourceUtil/SourceUtil.psm1
using module '../../Common/Result' Import-Module -Name @(Join-Path $PSScriptRoot .. | Join-Path -ChildPath .. | Join-Path -ChildPath Util | Join-Path -ChildPath Util) Import-Module -Name @(Join-Path $PSScriptRoot .. | Join-Path -ChildPath .. | Join-Path -ChildPath Preflight | Join-Path -ChildPath Preflight) function Get-RMSourcesForCurrentProject { param() $LoginStatus = Test-UserLoggedIn if ($LoginStatus.ReturnCode -eq [RMReturn]::ERROR) { return $LoginStatus } $CurrentProjectId = Get-Variable -Name "RMContext-CurrentProjectId" -ValueOnly $Result = @() $Response = Get-RMSourcesInternal -OrganizationId $CurrentProjectId -PageNumber 0 $Result += $Response for ($index = 1; $index -lt $Response.page.totalPages; $index++) { $Result += Get-RMSourcesInternal -OrganizationId $CurrentProjectId -PageNumber $index } return $Result } function Get-RMSourcesInternal { param( [string] $OrganizationId, [int] $PageNumber ) $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 = "Get" Uri = $Uri.Value + "/organizations/" + $OrganizationId + "/sources?size=25&page=" + $PageNumber + "&sort=created_at%2Cdesc" Headers = $Headers } return Invoke-RMRestMethod -Params $Params } function Get-RMSourceById { param( [string] $SourceId ) $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 = "Get" Uri = $Uri.Value + "/sources/" + $SourceId Headers = $Headers } return Invoke-RMRestMethod -Params $Params } function Get-MountPoint { param( [System.Object] $Source ) $MountPoints = @() if ("windows" -ieq $Source.os_type) { foreach ($Mount in $Source.attributes.storage.mounts.psobject.properties.value) { $MountPoints += @{mount_point = $Mount.path} } } else { foreach ($Mount in $Source.attributes.storage.mounts.psobject.properties.value) { if ("disk" -ieq $Mount.nature -or "subvolume" -ieq $Mount.nature -and "squashfs" -ine $Mount.fs_type) { $MountPoints += @{mount_point = $Mount.path} } } } return $MountPoints } function Get-RMSourceByIP { param( [string] $IPAddress ) $CurrentProjectId = Get-Variable -Name "RMContext-CurrentProjectId" -ValueOnly $PageIndex = 0 do { $Sources = Get-RMSourcesInternal -OrganizationId $CurrentProjectId -PageNumber $PageIndex foreach ($Source in $Sources.content) { if ($IPAddress -eq $Source.host) { return $Source } } $PageIndex++ } while ($PageIndex -lt $Sources.page.totalPages) $ProjectName = Get-Variable -Name "RMContext-CurrentProjectName" -ValueOnly $OrgName = Get-Variable -Name "RMContext-CurrentOrganizationName" -ValueOnly throw [System.Management.Automation.ItemNotFoundException]::new(` "Source with IP address '$IPAddress' does not exist in project '$ProjectName' of organization '$OrgName', cannot start the migration. Please add the source in the project and try again.") } function Start-RMSourcePreflight { param ( [System.Object] $Source ) $RequestAttributes = @{ "type" = "source" "resource_id"= $Source.id "overrides"= @{} } $SourceAttributesRequest = @($RequestAttributes) $SourceAttributesRequestJson = ConvertTo-Json $SourceAttributesRequest $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 + "/preflights" Body = $SourceAttributesRequestJson ContentType = "application/json" Headers = $Headers } Write-Output "Starting source preflight..." | Out-Host return Invoke-RMRestMethod -Params $Params } function Get-RMSourceWithAttribute { param( [System.Object] $Source, [System.Object] $CloudAccount, [bool] $IgnoreValidationErrors, [RMMigrationReturn] $RMMigrationReturn ) if ($Source.attribute_state -eq "running") { throw "Source attribute collection state is 'running', please wait for the attribute collection to complete." } Update-RMSourceWithAppliance -SourceId $Source.id -ApplianceId $CloudAccount.appliance.id $Response = Start-RMSourcePreflight -Source $Source Write-Output "Waiting for source preflight to complete..." | Out-Host $PreflightResult = Watch-RMPreflightStatus -PreflightId $Response.preflights[0].id ` -TimeOutMessage "Timed out waiting for collection to complete" $Source = Get-RMSourceById -SourceId $Source.id if (![string]::IsNullOrEmpty($Source.attribute_error)) { $PreflightID = $Response.preflights[0].id $AttributeCollectionError = $Source.attribute_error throw "Source attribute collection with ID: $PreflightID has failed with error $AttributeCollectionError" } $ShouldExit = Out-RMPreflight -PreflightResult $PreflightResult -IgnoreValidationErrors $IgnoreValidationErrors -RMMigrationReturn $RMMigrationReturn return $Source, $ShouldExit } function Update-RMSourceWithAppliance { param ( [System.Object] $SourceId, [string] $ApplianceId ) $RequestAttributes = @{ "data_only_migration" = $false "appliance_id" = $ApplianceId } $RequestAttributesJson = ConvertTo-Json $RequestAttributes $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 = "Put" Uri = $Uri + "/sources/" + $SourceId Body = $RequestAttributesJson ContentType = "application/json" Headers = $Headers } Invoke-RMRestMethod -Params $Params | Out-Null } function Read-RMSource { param() while ($true) { $SourceIP = Read-RMIPAddress -UserMessage "Enter the IP address of the source machine to be migrated"` -ParameterName "Source IP address" -IsRequired $true #TODO: Add IP address validation try { $Source = Get-RMSourceByIP -IPAddress $SourceIP } catch [System.Management.Automation.ItemNotFoundException] { Write-RMError -Message "Source with IP address '$SourceIP' does not exist in project '$ProjectName' of organization '$OrgName'." continue } return $Source } } function Test-RMSourceHasDynamicDisks { param( [System.Object] $Source ) if ($Source.os_type -ine "windows") { return $false } foreach ($Disk in $Source.attributes.storage.disks.psobject.Properties.Value) { if ($null -ne $Disk.flags -and $Disk.flags -contains "dynamic_disk") { return $true } } return $false } # No Export-ModuleMember is being used which will automatically export all the functions # of this module and we want all the functions to be exported. |