GcpUploadClient.ps1


Class GcpUploadClient : UploadClient {
    # properties
    [string]$GcpServiceAccountKeyFile
    [string]$BucketName

    # Default constructor
    GcpUploadClient([hashtable]$values) : base ($values) {
        $this.CopyValues(@{
            GcpServiceAccountKeyFile = @{
                required = $True
            }
        }, $values)

        $this.BucketName = $this.CloudDiskName.Split('.')[0]
    }

    Cleanup() {
        $GcpServiceAccountKey = Get-Content -Raw -Path $this.GcpServiceAccountKeyFile | ConvertFrom-Json

        try {
            $disk = Get-GceImage -Name $this.CloudDiskName -Project $GcpServiceAccountKey.project_id
            if ($disk) {
                LogIt "Deleting existing disk image $($this.CloudDiskName) from GCP $disk"
                Remove-GceImage -Name $this.CloudDiskName -Project $GcpServiceAccountKey.project_id
            }
        }
        catch {
            LogIt "No existing disk image $($this.CloudDiskName)"
        }
    }

    # Upload exported image from a share to Gcp.
    [psobject]Upload([string]$smbPassword, [bool]$azcopy) {
        if ([string]::IsNullOrWhiteSpace($smbPassword)) {
            throw "Upload requires SMB share user password to be supplied."
        }

        if (-not (($this.BucketName.Length -le 63) -and ($this.BucketName -cmatch '^[a-z]([-a-z0-9]*[a-z0-9])?$'))) {
            throw "Invalid CloudDiskName '$($this.CloudDiskName)'. The stem must meet the requirements for Google Cloud image names. See https://cloud.google.com/compute/docs/reference/rest/v1/images."
        }

        LogIt "Uploading disk to GCP"
    
        $cloudupload = {
            param($SharePath, $Arguments)
            $fullPath = Join-Path -Path $SharePath -ChildPath $Arguments[0]
            LogIt "Copying '$fullPath' to '$($this.CloudDiskName)' with $($this.GcpServiceAccountKeyFile)"
            Copy-ToGcpDisk -File $fullPath -BucketName $this.BucketName -ServiceAccountKeyFile $this.GcpServiceAccountKeyFile
        }

        ExecuteOnSmbShareAsUser $cloudupload $this.smbConfig.UserAndDomain $smbPassword $this.smbConfig.ShareUnc @($this.smbConfig.ExportFilePath)
        
        LogIt "Copied disk to '$($this.CloudDiskName)' in bucket '$($this.BucketName)'"

        return @{
            bucketName = $this.BucketName
            diskName = $this.CloudDiskName
        }
    }
}