vSphere Web Services API(SOAP API)の触り方

はじめに

vSphere 環境をコマンドライン環境や何らかのスクリプトから操作するとき、典型的には PowerCLI や govmomi、pyVmomi、VMware vSphere Automation SDK などのツールがよく利用されますが、こうしたツールを使わずに API を直接触れる と、vSphere に実装された新機能をリリースと同時に使い始められ てたいへん便利です。実際、vSphere vMotion Notifications がリリースされたときも、ツールが更新されるまでは、API を直接触る 以外にそれを試す手段がありませんでした。

vSphere の API には、古くからある SOAP API(vSphere Web Services API)と新しい REST API(vSphere Automation API)の大きく二つがあります。操作が簡単なのは間違いなく REST API ですが、SOAP API でしか行えない操作もたくさんあり、また、SOAP API を(広義の)REST API のように触れる Virtual Infrastructure JSON API も vCenter Server 8.0 U1 以降が必要で、まだまだ一般的ではありません。

したがって現状では、昔ながらの SOAP API こそ が、極論、大抵のことはどうにかできる API であると言えます。そこでこのエントリでは、SOAP APIvSphere Web Services APIを直接触る方法 を実例と共に紹介します。

なお、コマンド例は curl と PowerShell で紹介 していますが、結局は HTTP で XML をやりとりするだけなので、お作法さえわかれば他の HTTP クライアントでももちろん利用できます。また、SOAP API は Managed Object BrowserMOB)でも操作できますが、Web ブラウザでの操作であり自動化には向かないため、今回は取り上げません。

基本的な考え方

基本のお作法

vSphere Web Services API を HTTP クライアントから操作する際の基本は次の通りです。

  • HTTP リクエスト
    • 常に 同一のエンドポイントhttps://<FQDN>/sdk/vimService)に対して送信する
      • https://<FQDN>/sdk でも可
    • 常に ヘッダに content-typesoapaction を含める
      • content-type: text/xml; charset="utf-8"
      • soapaction: urn:vim25/8.0.2.0(vCenter Server のバージョンに合わせる)
    • 常に POST する
    • 常に リクエストボディに XML を含める
  • HTTP レスポンス
    • レスポンスボディの XML から情報を読み取る
  • 認証
    • ユーザ名とパスワードで認証 する(SAML トークンを使った認証も可)
  • Cookie
    • 認証に成功すると レスポンスヘッダの set-cookie でセッション ID が返される
    • 以降は セッション ID を Cookie に含める ことで認証済みユーザとして操作できる

なお、SAML トークンを使った認証 は本エントリでは取り上げません。

公式ドキュメント

vSphere Web Services API に関する公式のドキュメントとして、リファレンスとプログラミングガイド、セットアップガイドが公開されています。

基本的には、プログラミングガイドを読んで目的に応じた大まかな処理の流れをつかみ、文中で示されている具体的なメソッドなどをとっかかりにしてリファレンスを芋づる式に調べていくことになります。

はじめにプログラミングガイドの vSphere Web Services API Programming Model に含まれる以下あたりも目を通しておくと、本エントリで紹介する操作の流れも追いやすくなるでしょう。

なお、目的の(またはそれに近い)操作が govc でできるのであれば、-trace オプションにより HTTP のリクエストとレスポンスがすべて標準エラー出力に吐かれるようになるので、これも参考資料として非常に強力です。詳細は govc のドキュメントに記載があります。

参考: コマンド例(Bash / curl)

Bash で curl を使う場合の実際のコマンド例です。

curl で XML をやりとりするとき、適切な改行やインデントで整形されているほうが多少なりとも人間にやさしくなります。このため、ここでは次の方針としています。

  • リクエストボディの記述にはヒアドキュメントを利用する
  • レスポンスボディは xmllint にパイプして整形(または必要な値を抽出)する

この方針のもとでコマンドを組むと、例えば次のようになります。

$ WSAPI_URL=https://kuro-vcs01.kurokobo.internal/sdk
$ curl \
  -sX POST ${WSAPI_URL} \
  -b ./cookies.txt \
  -H 'content-type: text/xml; charset="utf-8"' \
  -H 'soapaction: urn:vim25/8.0.2.0' \
  -d @- << EOF | xmllint --format -
<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Body>
    ...
  </Body>
</Envelope>
EOF

レスポンスボディから(整形せずに)値を直接取り出したい場合は、以下のように --xpath などでがんばれます。なお、レスポンスの XML は多数の名前空間で構成されているため、xmllint でのハンドリングは少々しんどさがあり、基本、試行錯誤する覚悟が必要です。

$ WSAPI_URL=https://kuro-vcs01.kurokobo.internal/sdk
$ curl \
  -sX POST ${WSAPI_URL} \
  -b ./cookies.txt \
  -H 'content-type: text/xml; charset="utf-8"' \
  -H 'soapaction: urn:vim25/8.0.2.0' \
  -d @- << EOF | xmllint --xpath "//*[local-name()='hoge']/text()" -
<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Body>
    ...
  </Body>
</Envelope>
EOF

参考: コマンド例(PowerShell / Invoke-WebRequest)

PowerShell では、Invoke-WebRequest で操作できます。実例として vSphere vMotion Notifications を試すために作った PowerShell モジュールを GitHub で公開 しています。このモジュールでは、WSDL(本エントリ末尾で紹介)は利用せずに、XML 文字列をベタ書きして Invoke-WebRequest で操作しています。

Cookie を有効にするために、-SessionVariable-WebSession を使っています。また、レスポンスは xml にキャストする(((Invoke-WebRequest).Content))と扱いやすくなります。画面に XML を出力する際に見た目を整えたい場合は、Format-XML が便利です。

本エントリで紹介する実例

参照系と更新系のユースケースとして、本エントリでは以下の実例を紹介します。

  • (1) 仮想マシンの設定を取得する
  • (2) 仮想マシンの設定を変更する
  • (3) ホストの詳細オプションの値を取得する
  • (4) ホストの詳細オプションの値を変更する

ただし、いずれの場合でも まずは認証済みセッションを作成 して、さらに操作する 管理対象オブジェクトの特定 が必要なため、これも含めて紹介します。

以降、完全なコマンド例ではなく、リクエストとレスポンスの XML 部分のみ記載します。

前提 (1): 認証とセッションの作成

後続の操作のため、まずは認証をして認証済みセッションを作成します。

認証には ガイドで示されている手順 の通り SessionManager オブジェクトの Login を実行しますが、前提として、使う SessionManager の ID をすべての親玉たる ServiceInstance オブジェクトの RetrieveServiceContent で調べる必要があります。これには次のリクエストを行います。

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Body>
    <RetrieveServiceContent xmlns="urn:vim25">
      <_this type="ServiceInstance">ServiceInstance</_this>
    </RetrieveServiceContent>
  </Body>
</Envelope>

レスポンスボディの <sessionManager> の値を確認します。

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <RetrieveServiceContentResponse xmlns="urn:vim25">
      <returnval>
        <rootFolder type="Folder">group-d1</rootFolder>
        <propertyCollector type="PropertyCollector">propertyCollector</propertyCollector>
        <viewManager type="ViewManager">ViewManager</viewManager>
        ...
        <sessionManager type="SessionManager">SessionManager</sessionManager>
        ...
      </returnval>
    </RetrieveServiceContentResponse>
  </soapenv:Body>
</soapenv:Envelope>

<sessionManager> の値から、使うべき SessionManager オブジェクトの ID が SessionManager と確認できるので、続けてこれを _this で渡して Login を実行します。リファレンス の通り、パラメータは _thisuserNamepasswordlocale です。locale はなくてもよいですが、明示したほうが機械的に処理する際に言語の違いで悩む心配がなくなって安心です。

リクエストボディは以下の通りです。

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Body>
    <Login xmlns="urn:vim25">
      <_this type="SessionManager">SessionManager</_this>
      <userName>wsapi@vsphere.local</userName>
      <password>VMware123!</password>
      <locale>en_US</locale>
    </Login>
  </Body>
</Envelope>

このリクエストがエラーなく完了してレスポンスが返ってくれば(ステータスコードが 200 であれば)認証は完了です。レスポンスヘッダの set-cookievmware_soap_session が返されるため、これを何らかの手段で保存しておきます。

前提 (2): 操作する管理対象オブジェクトの特定

操作の対象が 仮想マシンホストネットワークデータストア など、とにかく インベントリに含まれるモノ であった場合、操作対象に相当する管理対象オブジェクト(Managed Object、MO)の特定が必要です。

人間はインベントリ内のモノをその 名前 で認識しますが、内部的にはそれぞれに 管理対象オブジェクト ID が与えられており、API での操作対象の指示にはこの ID を利用します。したがって、名前から管理対象オブジェクト ID を特定する必要があります。

例えば、対象が 仮想マシン であった場合、これは次のような流れで実現します。ガイドでも流れが紹介 されています。

以下、仮想マシン kuro-exec01 の管理対象オブジェクト ID を特定するものとして、操作方法を紹介します。

ContainerView の作成

まずは、『このフォルダの中から仮想マシンを再帰的に探して集めて箱に入れておいてね』的なリクエストを送ります。ViewManager オブジェクトの CreateContainerView で、探索対象の型(VirtualMachine オブジェクト)とルートフォルダを指定して ContainerView オブジェクトを作成します。パラメータとして渡している ViewManager オブジェクトの ID とルートフォルダは、いずれも先述の ServiceInstance オブジェクトの RetrieveServiceContent の結果に含まれています。

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Body>
    <CreateContainerView xmlns="urn:vim25">
      <_this type="ViewManager">ViewManager</_this>
      <container type="Folder">group-d1</container>
      <type>VirtualMachine</type>
      <recursive>true</recursive>
    </CreateContainerView>
  </Body>
</Envelope>

レスポンスは次の通りです。作成された ContainerView オブジェクトの情報が returnval として含まれています。この値は後続のリクエストで使用します。

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <CreateContainerViewResponse xmlns="urn:vim25">
      <returnval type="ContainerView">session[52a1d72b-a551-4c17-99a1-0214d65d4ef6]5293b717-07cc-cfd8-fd6a-d5a7b0cccb86</returnval>
    </CreateContainerViewResponse>
  </soapenv:Body>
</soapenv:Envelope>

仮想マシン以外の型のオブジェクトを探索する場合でも、リクエストの <type> を変更すれば対応できます。

RetrievePropertiesEx の実行と対象の特定

続けて、『さっきの箱の中に入っている仮想マシンの名前を調べて教えてね』的なリクエストを送ります。PropertyCollector オブジェクトの RetrievePropertiesEx で、取得したいプロパティとして VirtualMachine オブジェクトの name を指定し、探索対象として先ほどの ContainerView オブジェクトを指定します。RetrievePropertiesEx は、メソッド名の通り、対象のオブジェクトから任意のプロパティを取得するためのメソッドです。

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Body>
    <RetrievePropertiesEx xmlns="urn:vim25">
      <_this type="PropertyCollector">propertyCollector</_this>
      <specSet>
        <propSet>
          <type>VirtualMachine</type>
          <pathSet>name</pathSet>
        </propSet>
        <objectSet>
          <obj type="ContainerView">session[527102d1-b0db-1b07-ab00-e545fc76ca41]5253a3b5-b708-89eb-9c36-fec2253787f4</obj>
          <skip>true</skip>
          <selectSet xmlns:XMLSchema-instance="http://www.w3.org/2001/XMLSchema-instance" XMLSchema-instance:type="TraversalSpec">
            <type>ContainerView</type>
            <path>view</path>
          </selectSet>
        </objectSet>
      </specSet>
      <options>
        <maxObjects>1000</maxObjects>
      </options>
    </RetrievePropertiesEx>
  </Body>
</Envelope>

レスポンスは次の通りで、ルートフォルダ配下の全仮想マシンの情報が、リクエスト通り name プロパティの内容と共に返ってきます。ここから、今回操作したい仮想マシン kuro-exec01 の ID が vm-14011 であることが特定できます。

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <RetrievePropertiesExResponse xmlns="urn:vim25">
      <returnval>
        <objects>
          <obj type="VirtualMachine">vm-14011</obj>
          <propSet>
            <name>name</name>
            <val xsi:type="xsd:string">kuro-exec01</val>
          </propSet>
        </objects>
        <objects>
          <obj type="VirtualMachine">vm-14012</obj>
          <propSet>
            <name>name</name>
            <val xsi:type="xsd:string">kuro-exec02</val>
          </propSet>
        </objects>
        <objects>
          <obj type="VirtualMachine">vm-14013</obj>
          <propSet>
            <name>name</name>
            <val xsi:type="xsd:string">kuro-exec03</val>
          </propSet>
        </objects>
        ...
      </returnval>
    </RetrievePropertiesExResponse>
  </soapenv:Body>
</soapenv:Envelope>

仮想マシン以外の型のオブジェクトを探索する場合でも、name プロパティはどの型にもあるはずなので、ほとんど同じです。

ContainerView の削除

仮想マシンが特定できたら、作成した ContainerView オブジェクトをそれ自身の DestroyView で破棄します。

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Body>
    <DestroyView xmlns="urn:vim25">
      <_this type="ContainerView">session[527102d1-b0db-1b07-ab00-e545fc76ca41]5253a3b5-b708-89eb-9c36-fec2253787f4</_this>
    </DestroyView>
  </Body>
</Envelope>

実例 (1): 仮想マシンの設定を取得する

ここから、具体的な参照操作の例として、仮想マシン kuro-exec01 の設定情報を取得することを考えます。今回は、仮想マシンの vmOpNotificationTimeout の値を確認したいものとして、これを含んでいる VirtualMachine オブジェクトの config プロパティ(VirtualMachineConfigInfo オブジェクト)を取得します。

これには、ガイドでも紹介 されていますが、管理対象オブジェクト ID の特定にも利用した PropertyCollector オブジェクトの RetrievePropertiesEx を再度利用します。先ほどは ContainerView オブジェクトを対象にしましたが、ここでは単一の仮想マシンが対象です。

リクエストには、前述の手順で特定した管理対象オブジェクト ID が必要です。

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Body>
    <RetrievePropertiesEx xmlns="urn:vim25">
      <_this type="PropertyCollector">propertyCollector</_this>
      <specSet>
        <propSet>
          <type>VirtualMachine</type>
          <pathSet>config</pathSet>
        </propSet>
        <objectSet>
          <obj type="VirtualMachine">vm-14011</obj>
          <skip>false</skip>
        </objectSet>
      </specSet>
      <options></options>
    </RetrievePropertiesEx>
  </Body>
</Envelope>

レスポンスとして、config プロパティの中身である VirtualMachineConfigInfo オブジェクトが返ってきます。ここから、仮想マシンの具体的な設定が読み取れます。

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <RetrievePropertiesExResponse xmlns="urn:vim25">
      <returnval>
        <objects>
          <obj type="VirtualMachine">vm-14011</obj>
          <propSet>
            <name>config</name>
            <val xsi:type="VirtualMachineConfigInfo">
              ...
              <name>kuro-exec01</name>
              ...
              <vmOpNotificationToAppEnabled>false</vmOpNotificationToAppEnabled>
              <vmOpNotificationTimeout>-1</vmOpNotificationTimeout>
              ...
            </val>
          </propSet>
        </objects>
      </returnval>
    </RetrievePropertiesExResponse>
  </soapenv:Body>
</soapenv:Envelope>

目的の項目 vmOpNotificationTimeout は、値が -1 であることが確認できました。

実例 (2): 仮想マシンの設定を変更する

仮想マシンの設定を変更するには、VirtualMachine オブジェクトの ReconfigVM_Task を利用します。_this で ID を指定して、設定したい値を spec として渡すだけです。今回は vmOpNotificationToAppEnabledtrue を設定しています。

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Body>
    <ReconfigVM_Task xmlns="urn:vim25">
      <_this type="VirtualMachine">vm-14011</_this>
      <spec>
        <vmOpNotificationToAppEnabled>true</vmOpNotificationToAppEnabled>
      </spec>
    </ReconfigVM_Task>
  </Body>
</Envelope>

レスポンスとして、リクエストした変更を処理する Task オブジェクトの情報が返ってきます。

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <ReconfigVM_TaskResponse xmlns="urn:vim25">
      <returnval type="Task">task-10260</returnval>
    </ReconfigVM_TaskResponse>
  </soapenv:Body>
</soapenv:Envelope>

作成された Task オブジェクトの ID が task-10260 とわかるので、進捗を確認するため、これの info プロパティを取得します。使用するのは、おなじみの PropertyCollector オブジェクトの RetrievePropertiesEx です。

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Body>
    <RetrievePropertiesEx xmlns="urn:vim25">
      <_this type="PropertyCollector">propertyCollector</_this>
      <specSet>
        <propSet>
          <type>Task</type>
          <pathSet>info</pathSet>
        </propSet>
        <objectSet>
          <obj type="Task">task-10260</obj>
          <skip>false</skip>
        </objectSet>
      </specSet>
      <options></options>
    </RetrievePropertiesEx>
  </Body>
</Envelope>

進捗はレスポンスの <state> で確認できます。実行待ちの場合は queued、実行中は running、完了すると success、失敗すると error です。queuedrunning だった場合は、<status>success または error になるまで RetrievePropertiesEx を繰り返し実行します。

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <RetrievePropertiesExResponse xmlns="urn:vim25">
      <returnval>
        <objects>
          <obj type="Task">task-10260</obj>
          <propSet>
            <name>info</name>
            <val xsi:type="TaskInfo">
              <key>task-10260</key>
              <task type="Task">task-10260</task>
              <name>ReconfigVM_Task</name>
              <descriptionId>VirtualMachine.reconfigure</descriptionId>
              <entity type="VirtualMachine">vm-14011</entity>
              <entityName>kuro-exec01</entityName>
              <state>success</state>
              <cancelled>false</cancelled>
              <cancelable>false</cancelable>
              <reason xsi:type="TaskReasonUser">
                <userName>VSPHERE.LOCAL\Administrator</userName>
              </reason>
              <queueTime>...</queueTime>
              <startTime>...</startTime>
              <completeTime>...</completeTime>
              <eventChainId>573132</eventChainId>
            </val>
          </propSet>
        </objects>
      </returnval>
    </RetrievePropertiesExResponse>
  </soapenv:Body>
</soapenv:Envelope>

実例 (3): ホストの詳細オプションの値を取得する

続けて、ホストからの情報の取得の例です。

ここではホストの詳細オプションのうち VmOpNotificationToApp.Timeout の値を確認したいものとします。対象のホストは kuro-esxi01.kurokobo.internal で、この管理対象オブジェクト ID は host-14 です(前述の手順で HostSystem オブジェクトを対象に探索して特定します)。

詳細オプションを調べるには、まずは PropertyCollector オブジェクトの RetrievePropertiesEx で、対象の HostSystem オブジェクトの configManager.advancedOption プロパティから OptionManager オブジェクトを取得します。

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Body>
    <RetrievePropertiesEx xmlns="urn:vim25">
      <_this type="PropertyCollector">propertyCollector</_this>
      <specSet>
        <propSet>
          <type>HostSystem</type>
          <pathSet>configManager.advancedOption</pathSet>
        </propSet>
        <objectSet>
          <obj type="HostSystem">host-14</obj>
          <skip>false</skip>
        </objectSet>
      </specSet>
      <options></options>
    </RetrievePropertiesEx>
  </Body>
</Envelope>

レスポンスで OptionManager オブジェクトの ID が返ってきます。

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <RetrievePropertiesExResponse xmlns="urn:vim25">
      <returnval>
        <objects>
          <obj type="HostSystem">host-14</obj>
          <propSet>
            <name>configManager.advancedOption</name>
            <val type="OptionManager" xsi:type="ManagedObjectReference">EsxHostAdvSettings-14</val>
          </propSet>
        </objects>
      </returnval>
    </RetrievePropertiesExResponse>
  </soapenv:Body>
</soapenv:Envelope>

この OptionManager オブジェクトの QueryOptions で、取得したい詳細オプションを指定します。

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Body>
    <QueryOptions xmlns="urn:vim25">
      <_this type="OptionManager">EsxHostAdvSettings-14</_this>
      <name>VmOpNotificationToApp.Timeout</name>
    </QueryOptions>
  </Body>
</Envelope>

レスポンスで値が返ってきます。

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <QueryOptionsResponse xmlns="urn:vim25">
      <returnval>
        <key>VmOpNotificationToApp.Timeout</key>
        <value xsi:type="xsd:long">300</value>
      </returnval>
    </QueryOptionsResponse>
  </soapenv:Body>
</soapenv:Envelope>

実例 (4): ホストの詳細オプションの値を変更する

実例 (3) では、詳細オプションの確認に OptionManager オブジェクトの QueryOptions を使用しました。同じ OptionManager オブジェクトの UpdateOptions を使えば、設定を変更できます。ここでは、実例 (3) で調べた VmOpNotificationToApp.Timeout の値を変更したいものとします。

OptionManager オブジェクトを取得するところまでは実例 (3) とまったく一緒で、あとは QueryOptions の代わりに UpdateOptions を使うだけです。

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Body>
    <UpdateOptions xmlns="urn:vim25">
      <_this type="OptionManager">EsxHostAdvSettings-14</_this>
      <changedValue xmlns:XMLSchema-instance="http://www.w3.org/2001/XMLSchema-instance" XMLSchema-instance:type="OptionValue">
        <key>VmOpNotificationToApp.Timeout</key>
        <value XMLSchema-instance:type="xsd:long">600</value>
      </changedValue>
    </UpdateOptions>
  </Body>
</Envelope>

エラーなくレスポンスが返れば、作業は完了です。

補足: WSDL の利用

vSphere Web Services API 用の WSDL も用意されており、次のいずれかの方法で入手できます。

SoapUI など URL から WSDL をインポートできる SOAP クライアントを使うのであれば、vCenter Server からのインポートが便利です。リクエストボディも自動生成されるサンプルをベースにしてさくさく作れます。

PowerShell でも、New-WebServiceProxy コマンドレットで WSDL を基にローカルプロキシを作成できます(ただし、作成に数分かかります)。完全にはテストしていませんが、がんばればこの手段でも操作は可能そうです。例えば、ContainerView を作るところまでの処理は以下の通りです。

$WSProxy = New-WebServiceProxy -Uri https://kuro-vcs01.kurokobo.internal/sdk/vimService?wsdl -Namespace WSProxy -Class "vSWSAPI"
$WSProxy.Url = "https://kuro-vcs01.kurokobo.internal/sdk/vimService"
$WSProxy.CookieContainer = New-Object System.Net.CookieContainer

$SI = New-Object -TypeName "WSProxy.ManagedObjectReference" -Property @{type="ServiceInstance"; value="ServiceInstance"}
$SC = $WSProxy.RetrieveServiceContent($SI)

$WSProxy.Login($SC.sessionManager, "wsapi@vsphere.local","VMware123!", "en_US")
$WSProxy.CreateContainerView($SC.viewManager, $SC.rootFolder, "VirtualMachine", $true)
...

おわりに

vSphere Web Services API を直接触る方法を紹介しました。日本語の情報がほぼないことから、そもそも需要がないということにもなりそうですが、かゆいところに好きなだけ手を伸ばせる手段でもあるため、知っておくと自力で歩ける範囲が少し広がります。

PowerCLI や pyVmomi など使いやすいように整備されたツールはいくつもありますが、結局は API のラッパの類でしかなく、凝った処理のために API の仕様とツールの実装を探らざるを得なくなることもあります。そうしたとき、それらのツールの裏側の処理を想像できるようになっておくことは、何らかの助けにはなりそうです。

@kurokobo

くろいです。ギターアンサンブルやら音響やらがフィールドの IT やさんなアルトギター弾き。たまこう 48 期ぎたさん、SFC '07 おんぞう、新日本ギターアンサンブル、Rubinetto。今は野良気味。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です