Citrix.Image.Uploader/AhvFunctions.ps1
$TaskStates = @('ABORTED', 'CANCELED', 'FAILED', 'QUEUED', 'RUNNING', 'PAUSED', 'SKIPPED', 'SUCCEEDED', 'SCHEDULED') $FailedTaskStates = @('ABORTED', 'CANCELED', 'FAILED', 'SKIPPED') $SuccessTaskStates = @('SUCCEEDED') Function ApiCall([string]$Hostname, [int]$Port, [string]$Username, [string]$Password, [string]$Method, [string]$Route, [hashtable]$Body = $Null, [string]$FilePath = $Null) { $url = "https://$($Hostname):$($Port)/$Route" $bytes = [System.Text.Encoding]::UTF8.GetBytes("$Username" + ':' + "$Password") $authorization = [System.Convert]::ToBase64String($bytes) $parameters = @{ Headers = @{ "Authorization" = "Basic $authorization" } Method = $Method } if ($Body) { $parameters['Headers']['Content-Type'] = 'application/json' $parameters['Body'] = $Body | ConvertTo-Json Log "REST $Method $url with $($parameters['Body'])" $True } elseif ($FilePath) { $parameters['Headers']['Content-Type'] = 'application/octet-stream' $parameters['Headers']['X-Nutanix-Destination-Container'] = '64588254-e6ec-4c00-b65a-bad687cc6a22' # $parameters['InFile'] = $FilePath $content = Get-Content -Path $FilePath $parameters['Body'] = $content Log "REST $Method $url with file $FilePath" $True } else { Log "REST $Method $url" $True } try { return Invoke-WebRequest -Uri $url @parameters | ConvertFrom-Json } catch { throw "REST $Method $url with $json failed: $_" } } Function WaitForTask([string]$Hostname, [int]$Port, [string]$Username, [string]$Password, [string]$TaskUuid, [int]$Timeout, [int]$Wait = 10) { Log "Waiting for task $TaskUuid" $iterations = $Timeout / $Wait $count = 0 While ($count++ -le $iterations) { $task = ApiCall -Hostname $Hostname -Port $Port -Username $Username -Password $Password -Method "GET" -Route "api/nutanix/v3/tasks/$TaskUuid" Log "WaitForTask $(ConvertTo-Json $task)" $False if ($SuccessTaskStates -Contains $task.status) { return $task } elseif ($FailedTaskStates -Contains $task.status) { throw "WaitForTask status $($task.status) error $($task.error_detail)" } Start-Sleep -Seconds $Wait } throw "Timeout waiting for task" } Function CreateImageOld([string]$Hostname, [int]$Port, [string]$Username, [string]$Password, [string]$Name, [string]$ImageType, [string]$Description = $Null) { Log "Creating image $Name of type $ImageType" $body = @{ name = $Name imageType = $ImageType } $image = ApiCall -Hostname $Hostname -Username $Username -Password $Password -Port $Port -method "POST" -route "/api/nutanix/v0.8/images" -Body $body Log "Create image request $(ConvertTo-Json $image)" $taskUuid = $image.taskUuid $task = WaitForTask -Hostname $Hostname -Port $Port -Username $Username -Password $Password -TaskUuid $taskUuid -Timeout 90 Log "created image task uuid=$TaskUuid task=$(ConvertTo-Json $task)" $False return $task.entity_reference_list[0].uuid } Function CreateImage([string]$Hostname, [int]$Port, [string]$Username, [string]$Password, [string]$Name, [string]$ImageType, [string]$Description = $Null) { Log "Creating image $Name of type $ImageType" $body = @{ metadata = @{ kind = "image" } spec = @{ name = $Name resources = @{ image_type = $ImageType } } } if ($Description) { $body['spec']['description'] = $Description } $image = ApiCall -Hostname $Hostname -Username $Username -Password $Password -Port $Port -method "POST" -route "api/nutanix/v3/images" -Body $body Log "Create image request $(ConvertTo-Json $image)" $taskUuid = $image.status.execution_context.task_uuid $task = WaitForTask -Hostname $Hostname -Port $Port -Username $Username -Password $Password -TaskUuid $taskUuid -Timeout 90 Log "created image task uuid=$TaskUuid task=$(ConvertTo-Json $task)" $False return $image.metadata.uuid } Function UploadImage([string]$Hostname, [int]$Port, [string]$Username, [string]$Password, [string]$ImageUuid, [string]$Path) { Log "Uploading image $Path to $ImageUuid" # $upload = ApiCall -Hostname $Hostname -Username $Username -Password $Password -Port $Port -method "PUT" -route "api/nutanix/v3/images/$ImageUuid/file" -FilePath $Path $upload = ApiCall -Hostname $Hostname -Username $Username -Password $Password -Port $Port -method "PUT" -route "api/nutanix/v0.8/images/$ImageUuid/upload" -FilePath $Path Log "Upload image request $(ConvertTo-Json $upload)" $taskUuid = $upload.task_uuid $task = WaitForTask -Hostname $Hostname -Port $Port -Username $Username -Password $Password -TaskUuid $taskUuid -Timeout 300 Log "upload image task=$(ConvertTo-Json $task)" } Function SslNoCertCheck() { Add-Type @" using System.Net; using System.Security.Cryptography.X509Certificates; public class TrustAllCertsPolicy : ICertificatePolicy { public bool CheckValidationResult( ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) { return true; } } "@ [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy } Function UploadToAhv([string]$Hostname, [int]$Port, [string]$Username, [string]$Password, [string]$Name, [string]$Path, [string]$Description = $Null, [bool]$SslNoCheck = $True) { if ($SslNoCheck) { Log "Not checking SSL cert for $Hostname" SslNoCertCheck } Log "Uploading to AHV $Hostname : $Port as $Username" $imageUuid = CreateImage -Hostname $Hostname -Port $Port -Username $Username -Password $Password -ImageType "DISK_IMAGE" -Name $Name -Description $Description UploadImage -Hostname $Hostname -Port $Port -Username $Username -Password $Password -ImageUuid $imageUuid -Path $Path Log "Copied disk $Path to AHV image $imageUuid" return $imageUuid } |