RiverMeadow.Development.Source/RiverMeadow.Development.Source.psm1
Import-Module -Name $PSScriptRoot\..\Util\Util Import-Module -Name $PSScriptRoot\..\Common\Common function Add-RMSource { param( [Alias("sip")] [string] $SourceIP, [Alias("shpa")] [bool] $SourceHasPreinstalledAgent, [Alias("scoa")] [bool] $StoreCredsOnAppliance, [Alias("un")] [string] $Username, [Alias("pw")] [string] $Password, [Alias("cpw")] [string] $ConfirmPassword, [Alias('usshpk')] [bool] $UseSSHPrivateKey, [Alias("pk")] [string] $PrivateKey, [Alias("pp")] [string] $Passphrase, [Alias("cpp")] [string] $ConfirmPassphrase, [Alias("dm")] [string] $Domain, [Alias("rmt")] [string[]] $RiverMeadowTags, [Alias("ai")] [string[]] $AdvancedInstructions, [Alias("cmg")] [bool] $CreateMoveGroup, [Alias("mgn")] [string] $MoveGroupName, [Alias("tmd")] [string] $TargetMigrationDate, [Alias("are")] [string] $AssignedResourceEmail ) $UserLoginStatus = Test-UserLoggedIn if (!$UserLoginStatus) { return } if (0 -eq $PSBoundParameters.Count) { Add-RMSourceInteractive } else { Add-RMSourceNonInteractive @PSBoundParameters } } function Add-RMSourceInteractive { $CurrentProjectId = Get-Variable -Name "RMContext-CurrentProjectId" -ValueOnly $SourceIP = Read-RMIPAddress -UserMessage "Enter the source IP address" -ParameterName "Source IP address" -IsRequired $true $SourceHasPreinstalledAgent = Read-RMBoolean -UserMessage "Does source has preinstalled agent" -DefaultValue "false" if(!$SourceHasPreinstalledAgent){ $StoreCredsOnAppliance = Read-RMBoolean -UserMessage "Store the source credentials on migration appliance" -DefaultValue "false" } if (!$SourceHasPreinstalledAgent -and !$StoreCredsOnAppliance) { $Username = Read-RMString -UserMessage "Enter the username" -ParameterName "Username" -IsRequired $true $UseSSHPrivateKey = Read-RMBoolean -UserMessage "Use SSH private key" -DefaultValue "false" if ($UseSSHPrivateKey) { $PrivateKey = Read-RMString -UserMessage "Enter the private key" -ParameterName "Private key" -IsRequired $true $Password = Read-RMSecureString -UserMessage "Enter the passphrase" -ParameterName "Passphrase" ` -ConfirmMessage "Confirm the passphrase" -ConfirmParameterName "Confirm passphrase" -IsRequired $false } else { $Password = Read-RMSecureString -UserMessage "Enter the password" -ParameterName "Password" ` -ConfirmMessage "Confirm the password" -ConfirmParameterName "Confirm password" -IsRequired $true } $Domain = Read-RMString -UserMessage "Enter the domain name" -ParameterName "Domain name" -IsRequired $false } $RiverMeadowTags = Read-RMToken -UserMessage "Enter one or more RiverMeadow tags, separated by commas" -DefaultValue "None" ` -ParameterName "RiverMeadow tags" -Separator "," -IsRequired $false $ReadValue = Read-RMPair -UserMessage "Enter one or more advanced instructions in the format 'key=value' and separated by commas" ` -DefaultValue "None" -Separator "=" $AdvancedInstructions = Get-RMStringAsHashtable -InputString $ReadValue $CreateMoveGroup = Read-RMBoolean -UserMessage "Create new move group" -DefaultValue "false" if ($CreateMoveGroup) { $DateFormat = "MM/dd/yyyy" $UserMessage = "Enter target migration date in the format '{0}'" -f $DateFormat $MoveGroupName = Read-RMString -UserMessage "Enter new move group name" -ParameterName "Move group name" -IsRequired $true $TargetMigrationDate = Read-RMDate -UserMessage $UserMessage -DateFormat $DateFormat ` -ParameterName "Target migration date" -DefaultValue "None" -IsRequired $false $AssignedResourceEmail = Read-RMString -UserMessage "Enter assigned resource email" -DefaultValue "None" ` -ParameterName "Assigned resource email" -IsRequired $false } else { $MoveGroupList = @() $Response = Get-RMMoveGroupList -Organization $CurrentProjectId -PageNumber 0 $MoveGroupList += $Response for ($index = 1; $index -lt $Response.page.totalPages; $index++) { $MoveGroupList += Get-RMMoveGroupList -OrganizationId $CurrentProjectId -PageNumber $index } $MoveGroupName = Read-RMString -UserMessage "Enter the move group name to which the source should be added" ` -Options $MoveGroupList.content.name -DefaultValue "None" -IsRequired $false -ParameterName "Move group name" } $UserInput = @{ SourceIP = $SourceIP CurrentProjectId = $CurrentProjectId SourceHasPreinstalledAgent = $SourceHasPreinstalledAgent StoreCredsOnAppliance = $StoreCredsOnAppliance Username = $Username Password = $Password PrivateKey = $PrivateKey Domain = $Domain RiverMeadowTags = $RiverMeadowTags AdvancedInstructions = $AdvancedInstructions CreateMoveGroup = $CreateMoveGroup MoveGroupName = $MoveGroupName TargetMigrationDate = $TargetMigrationDate AssignedResourceEmail = $AssignedResourceEmail } New-RMSource @UserInput } function Add-RMSourceNonInteractive { param ( [string] $SourceIP, [bool] $SourceHasPreinstalledAgent, [bool] $StoreCredsOnAppliance, [string] $Username, [string] $Password, [string] $ConfirmPassword, [bool] $UseSSHPrivateKey, [string] $PrivateKey, [string] $Passphrase, [string] $ConfirmPassphrase, [string] $Domain, [string[]] $RiverMeadowTags, [string[]] $AdvancedInstructions, [bool] $CreateMoveGroup, [string] $MoveGroupName, [string] $TargetMigrationDate, [string] $AssignedResourceEmail ) $Errors = Confirm-RMAddSourceParameter -UserParameter $PSBoundParameters $IsValidDate = Confirm-RMDateFormat -InputDate $TargetMigrationDate -DateFormat "MM/dd/yyyy" if ($Errors.Count -gt 0) { if (!$IsValidDate) { Write-RMError -Message "TargetMigrationDate is invalid, the TargetMigrationDate should be in the format 'mm/dd/yyyy'." } Out-RMUserParameterResult -ErrorMessage $Errors return } if (!$IsValidDate) { Write-RMError -Message "TargetMigrationDate is invalid, the TargetMigrationDate should be in the format 'mm/dd/yyyy'." return } $UserInput = @{} $CurrentProjectId = Get-Variable -Name "RMContext-CurrentProjectId" -ValueOnly $UserInput.Add("CurrentProjectId", $CurrentProjectId) $UserInput.Add("SourceIP", $SourceIP) if ($SourceHasPreinstalledAgent) { $UserInput.Add("SourceHasPreinstalledAgent", $SourceHasPreinstalledAgent) } else { if ($StoreCredsOnAppliance) { $UserInput.Add("StoreCredsOnAppliance", $StoreCredsOnAppliance) } } if (!$SourceHasPreinstalledAgent -and !$StoreCredsOnAppliance) { $UserInput.Add("Username", $Username) if ($UseSSHPrivateKey) { $UserInput.Add("PrivateKey", $PrivateKey) $UserInput.Add("Password", $Passphrase) } else { $UserInput.Add("Password", $Password) } $UserInput.Add("Domain", $Domain) } if ($null -eq $RiverMeadowTags) { $RiverMeadowTags = @() } $UserInput.Add("RiverMeadowTags", $RiverMeadowTags) $AdvancedInstructionsAsHashTable = Get-RMStringArrayAsHashtable -InputItems $AdvancedInstructions $UserInput.Add("AdvancedInstructions", $AdvancedInstructionsAsHashTable) if ($CreateMoveGroup) { $UserInput.Add("CreateMoveGroup", $CreateMoveGroup) $UserInput.Add("MoveGroupName", $MoveGroupName) $UserInput.Add("TargetMigrationDate", $TargetMigrationDate) $UserInput.Add("AssignedResourceEmail", $AssignedResourceEmail) } else { $UserInput.Add("MoveGroupName", $MoveGroupName) } New-RMSource @UserInput } function New-RMSource { param( [string] $SourceIP, [string] $CurrentProjectId, [bool] $SourceHasPreinstalledAgent, [bool] $StoreCredsOnAppliance, [string] $Username, [string] $Password, [string] $PrivateKey, [string] $Domain, [string[]] $RiverMeadowTags, [hashtable] $AdvancedInstructions, [bool] $CreateMoveGroup, [string] $MoveGroupName, [string] $TargetMigrationDate, [string] $AssignedResourceEmail ) $CredsStorage = "local" if ($StoreCredsOnAppliance) { $CredsStorage = "ca" } $MoveGroupID = $null if ($CreateMoveGroup) { $MoveGroupID = "00000000-0000-0000-0000-000000000000" } else { if ("" -ne $MoveGroupName) { $MoveGroup = Get-MoveGroupByName -MoveGroupName $MoveGroupName -OrganizationId $CurrentProjectId if ($null -eq $MoveGroup) { throw "Invalid move group." } $MoveGroupID = $MoveGroup.id } } $ControlConnectionType = $null if ($SourceHasPreinstalledAgent) { $ControlConnectionType = "agent" } $SourceRequest = @{ "name"= $SourceIP "host"= $SourceIP #e.g string format:"Azure:Standard_D5_v2" #TODO We will add cloud size features in the future "cloud_sizing"= "" "instructions"= $AdvancedInstructions "credentials"= @{ "storage" = $CredsStorage "username" = $Username "password" = $Password "domain" = $Domain "private_key" = $PrivateKey } "move_group_id" = $MoveGroupID "move_group_name" = $MoveGroupName "target_migration_date" = $TargetMigrationDate "assigned_resource_email" = $AssignedResourceEmail "tags"= $RiverMeadowTags "organization_id" = $CurrentProjectId "control_connection_type" = $ControlConnectionType } $SourceRequestJson = $SourceRequest |ConvertTo-Json -Depth 100 $Uri = Get-Variable -Name "RMContext-ReactorURI" -ValueOnly $RMLoginResult = Get-Variable -Name "RMContext-UserLogin" -ValueOnly $Headers = @{ Accept = "application/rm+json" "X-Auth-Token" = $RMLoginResult.token } $Params = @{ Method = "Post" Uri = $Uri + "/sources" Body = $SourceRequestJson ContentType = "application/json" Headers = $Headers } try { Invoke-RMRestMethod -Params $Params | Out-Null } catch { # Invoke-RMRestMethod has already shown the error, so just return return } Write-Output "Source has been added successfully" | Out-Host } function Confirm-RMAddSourceParameter { param( [hashtable] $UserParameter ) $Errors = @() if (!$UserParameter.ContainsKey("SourceIP") -or [string]::IsNullOrEmpty("SourceIP")) { $Errors += "SourceIP is required" } else { $IsValidSourceIP = Confirm-RMIPAddress -IPAddress $UserParameter.SourceIP if (!$IsValidSourceIP) { $Errors += "Invalid Source IP Address." } } if (!(($UserParameter.ContainsKey("SourceHasPreinstalledAgent") -and $UserParameter["SourceHasPreinstalledAgent"]) ` -or ($UserParameter.ContainsKey("StoreCredsOnAppliance") -and $UserParameter["StoreCredsOnAppliance"]))) { if (!$UserParameter.ContainsKey("Username") -or [string]::IsNullOrEmpty($UserParameter["Username"])) { $Errors += "Username is required" } if ($UserParameter.ContainsKey("UseSSHPrivateKey") -and $UserParameter["UseSSHPrivateKey"] -eq $true) { if (!$UserParameter.ContainsKey("PrivateKey") -or [string]::IsNullOrEmpty($UserParameter["PrivateKey"])) { $Errors += "PrivateKey is required, when 'UseSSHPrivateKey' is true" } if ($UserParameter["Passphrase"] -ne $UserParameter["ConfirmPassphrase"]) { $Errors += "Passphrase and ConfirmPassphrase must match" } } else { if(!$UserParameter.ContainsKey("Password") -or [string]::IsNullOrEmpty($UserParameter["Password"])) { $Errors += "Password is required" } if (!$UserParameter.ContainsKey("ConfirmPassword") -or [string]::IsNullOrEmpty($UserParameter["ConfirmPassword"])) { $Errors += "ConfirmPassword is required" } if ($UserParameter["Password"] -ne $UserParameter["ConfirmPassword"]) { $Errors += "Password and ConfirmPassword must match" } } } if ($UserParameter.ContainsKey("CreateMoveGroup") -and $UserParameter["CreateMoveGroup"] -eq $true) { if (!$UserParameter.ContainsKey("MoveGroupName") -or [string]::IsNullOrEmpty($UserParameter["MoveGroupName"])) { $Errors += "MoveGroupName is required, when 'CreateMoveGroup' is true" } } return $Errors } Export-ModuleMember -Function Add-RMSource |