URAMIRAIKAN

1020のなれの果て (since 2005.6.19)

vCloud Director環境下のStorage vMotion

 お仕事で「vCloud Director管理下のVMをストレージポリシーは変更せずにStorage vMotionできる?」と質問されたので、ちょっと確認した備忘録。
 VMwareのKBでは、だいぶ古いけど該当項目がありました(もっと新しいのがあるかも?)。

 ストレージポリシーとかの整合性に注意すれば普通にvCenter ServerからStorage vMotionしても問題なさそうですが、REST APIで実行するのが良さそうです。
 ただ、APIを一つ一つ手作業で操作するのは手間なので、いつも通りスクリプトにしました。

 実行環境は例によってWindowsなので、PowerShellの"Invoke-RestMethod"とかでAPIにアクセスしていきます。

Param ( [Parameter(Mandatory = $True, HelpMessage="Target Organization")][alias("org","o")][ValidateNotNullOrEmpty()][string]$OrgName, [Parameter(Mandatory = $True, HelpMessage="Target VM name")][alias("name","n")][ValidateNotNullOrEmpty()][string]$TargetVmName, [Parameter(Mandatory = $True, HelpMessage="Destination Datastore")][alias("dest","d")][ValidateNotNullOrEmpty()][string]$DestStore ) # vCloud Director $VcdUser = "administrator" $VcdPass = "password" # vCloud API $ApiEp = "https://vcd.example.com/api" $ApiVer = "20.0" # Authentication $Auth = $VcdUser + "@system:" + $VcdPass $Encoded = [System.Text.Encoding]::UTF8.GetBytes($Auth) $EncodedPassword = [System.Convert]::ToBase64String($Encoded) $SendUri = $ApiEp + "/sessions" $Headers = @{ "Authorization" = "Basic " + $EncodedPassword; "Accept" = "application/*+xml;version=$ApiVer" } $Res = Invoke-WebRequest -Headers $Headers -Uri $SendUri -Method POST $VcdAuth = $Res.Headers["x-vcloud-authorization"] $Headers = @{ "x-vcloud-authorization" = $VcdAuth; "Accept" = "application/*+xml;version=$ApiVer" } # Get Organization Information $SendUri = $ApiEp + "/admin" $Res = Invoke-RestMethod -Headers $Headers -Uri $SendUri -Method GET foreach ($objOrg in $Res.vCloud.OrganizationReferences.OrganizationReference) { if ($objOrg.Name -eq $OrgName) { $OrgUri = $objOrg.href } } # Get Target VM Information $SendUri = $ApiEp + "/query?type=adminVM&fields=name,datastoreName&filter=org==" + $OrgUri $Res = Invoke-RestMethod -Headers $Headers -Uri $SendUri -Method GET foreach ($objVm in $Res.QueryResultRecords.AdminVMRecord) { if ($objVm.Name -eq $TargetVmName) { if ($objVm.DatastoreName -ne $DestStore) { $VmUri = $objVm.href } else { exit } } } # Get Destination Datastore Information $SendUri = $ApiEp + "/query?type=datastore&fields=name" $Res = Invoke-RestMethod -Headers $Headers -Uri $SendUri -Method GET foreach ($objStore in $Res.QueryResultRecords.DatastoreRecord) { if ($objStore.Name -eq $DestStore) { $StoreUri = $objStore.href } } # Relocate Vm $RelocateXml = @" <?xml version="1.0" encoding="UTF-8"?> <RelocateParams xmlns="http://www.vmware.com/vcloud/v1.5"> <Datastore href="$StoreUri"/> </RelocateParams> "@ $SendUri = $VmUri + "/action/relocate" $Headers = @{ "x-vcloud-authorization" = $VcdAuth; "Accept" = "application/*+xml;version=$ApiVer"; "Content-Type" = "application/vnd.vmware.vcloud.relocateVmParams+xml"; } $Res = Invoke-RestMethod -Headers $Headers -Uri $SendUri -Method POST -Body $RelocateXml $Res.Task | Format-List exit

 最終的に必要となるパラメータは「対象VMのURL」と「移行先データストアのURL」となるので、"/query"等を使って必要な情報を集めていきます。

 スクリプト実行時の引数は3つにしました。

.\RelocateVm.ps1 -o <対象VMの所属する組織名> -n <対象VM名> -d <移行先データストア名>

 簡単に確認した限りでは期待した動作になったので、あとはいつも通り使いながら修正していく感じで。