APIを使用してvSphereと独自アプリケーションを連携させよう!

皆さんこんにちは! VMware担当の大谷です。
 前回は、vSphere ClientからvCenterのAPIを使って仮想マシンの電源制御をしました。今回はもう1歩踏み込んで、アプリケーションからAPIを呼び出し仮想マシンの電源ONをやってみます。

  • プログラムからREST APIを使うには?

     前回はGUIを使ってAPIのURLにHTTPSのGETとPOSTリクエストを送信しました。今回はこれと同じ動作をプログラム言語上で再現したいと思います。

  • REST APIのリクエストはHTTP つまりWebサーバーへのアクセスと同じです

     Webサーバーと同じということはやり方も同じということです。要するにプログラム内のHTTPクライアントからWebサーバーにアクセスするだけですね。ただ、Webブラウザを使っていると判りませんが、Webサイトへアクセスする時にはある決まりに従っています。
    Webサーバーと通信するためのHTTPは、大きく分けると2つの要素、ヘッダとボディで構成されています。ヘッダ部分には、サーバーにアクセスするための認証に必要なユーザー情報やトークン、GET/POSTなどのメソッドといった基本情報を入れておきます。ボディ部分はサーバーに渡すデータ本体です。何を渡すかはAPIの仕様によって様々ですが、今回使うAPIはボディの情報を必要としないため空白文字を送ります。一般的にはボディ部分にJSON形式のテキストデータを入れておきます。JSONについては詳しく解説している他のサイトをご覧ください。

  • APIを利用するにはお作法があります!

     APIによって前準備や呼び出す方法が異なりますが、vCenter APIの場合は、最初にユーザー名とパスワードで認証し、APIにアクセスするためのセッションIDを受け取ります。以降はこのセッションIDをヘッダにセットして各種APIにリクエストを送信します。

  • 仮想マシンの電源ONに必要な要素は?

     前回のコラムではvCenterのデベロッパーセンターを使って手作業でパラメータを設定しました。今回はプログラム言語を使うということで、全自動で処理できるようにしたいと思います。
     仮想マシンの電源をONにするための順序は、

    1.ユーザー認証をおこないセッションIDを取得する
    2.仮想マシンの情報を取得しvm名を調べる
    3.vm名を使って仮想マシンの電源制御APIにアクセスする

    という3ステップの処理が必要になりそうです。それでは各ステップについて、実際のプログラムを見ていきましょう。

  • (C#)コードを書く前の準備作業

     C#でアプリケーションを作る前準備として、REST APIを呼び出すためのHTTPクライアントとJSONシリアライザーを用意します。これらは外部からダウンロードできる拡張機能として簡単に組み込むことができます。今回のアプリケーション開発にはVisual Studio 2019を使用していますので、NuGetパッケージマネージャーを使ってインストールします。

     Newtonsoft_JsonがJSONシリアライザーで、RestSharpがHTTPクライアントです。これらのようなNuGetパッケージを活用すると、アプリケーション開発の効率を上げることができるのでとっても便利です。

  • (Python)コードを書く前の準備作業

     今回PythonのHTTPクライアントとしてrequestsを使用します。使用中の環境にまだインストールされていない方はコンソールを開きpip install requestsと入力してパッケージをインストールしてください。

  • (C#のみ)受け取ったJSONデータの入れ物を作ります

     REST APIのデータ送受信にはJSONを使用しますが、C#の場合はJSONデータを受け取るために前準備が必要です。プログラム言語にとってJSONというものはただのテキストデータ、つまり文字の塊としか認識できません。これを、プログラム言語上で意味のあるデータとして認識させるための処理、またはプログラム言語上のデータをJSON文字列に変換することが必要です。この処理のことをシリアライズ・デシリアライズと呼び、処理するプログラムはシリアライザーと呼ばれています。Pythonの場合はJSONデータ送信用の入れ物は自分で定義が必要ですが、受け取ったJSONデータの入れ物は自動的に用意してくれます。

     今回は2種類の入れ物を用意します。1つ目は、ユーザー認証後に返されるセッションIDの入れ物で、2つ目は仮想マシンの情報です。

    C#

            //
            // データモデルを定義します
            //
    
            /// <summary>
            /// セッションID
            /// </summary>
            public class SessionID
            {
                public string value { get; set; }
            }
    
            /// <summary>
            /// 仮想マシンの情報
            /// </summary>
            public class VMInfo
            {
                public List<VMDesc> value { get; set; }
            }
    
            /// <summary>
            /// 仮想マシンの情報 詳細部分
            /// </summary>
            public class VMDesc
            {
                /// <summary>
                /// 内部的に一意なvm名
                /// </summary>
                public string vm { get; set; }
                /// <summary>
                /// vCenter上で表示される仮想マシンの名前
                /// </summary>
                public string name { get; set; }
                /// <summary>
                /// 仮想マシンの電源状態
                /// </summary>
                public string power_state { get; set; }
            }
    
      

     仮想マシンの情報は複数台分を一度に取得できるため、配列(この例ではListを使っています) 
    として定義が必要です。各パラメータに何が入るかはコメントを参照してください。

  • その1 ユーザー認証を要求してセッションIDを取得します

     前準備ができたらユーザー認証部分のプログラムを書いていきます。本当はレスポンスのエラー処理と例外処理を入れるのですが、コードが長くなってしまうので今回は書きません!

    C#

    using System;
    using System.Text;
    using System.Collections.Generic;
    using RestSharp;
    using Newtonsoft.Json;
    
    namespace vCenterAPI_C
    {
        class Program
        {
            static void Main(string[] args)
            {
                //
                // Step 1 : ユーザー認証をしてAPIを使うためのSession IDを取得します
                //
                string Cred = "administrator@vsphere.local:vCenterのパスワード";
    
                // httpクライアントを作り自己証明証明書の場合SSL証明書の検証に失敗するので無視するようにします
                // (これがないとリクエストが失敗します)
                var client = new RestClient("https://vCenterのFQDNかIPドレス/rest/com/vmware/cis/session");
                client.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
    
                // 送信するリクエストを作ってBASIC認証のためのユーザー名とパスワードをBASE64エンコードしてセットします
                var request = new RestRequest();
                request.AddHeader("Authorization", $"Basic {Convert.ToBase64String(Encoding.UTF8.GetBytes(Cred))}");
     
               // vCenter Serverにリクエストを送信します
                var response = client.Post(request);
    
                // vCenter APIを利用するためのセッションIDを文字列データに変換します
                var sessionID = JsonConvert.DeserializeObject<SessionID>(response.Content);
            }
        }
    }
    
      

    Python

    import sys
    import requests
    import json
    import base64
    
    #
    # Step 1 : ユーザー認証をしてAPIを使うためのSession IDを取得します
    #
    
    # 認証用のユーザー名とパスワードをBASE64エンコードします
    cred = (base64.b64encode("administrator@vsphere.local:vCenterのパスワード".encode())).decode("ASCII")
    
    # httpヘッダ情報をセットします
    headers = {
      "Content-Type": "application/json",
      "Authorization": "Basic " + cred
    }
    
    # リクエストを送信します
    response = requests.request("POST", "https://vCenterのFQDNかIPドレス/rest/com/vmware/cis/session",
                                headers=headers, data="", verify=False)
    sessionID = json.loads(response.content)
    
      

     プログラムのおおまかな流れは次の通りです。(HTTPクライアントを作る処理はC#のみです)
    1.HTTPクライアントを作る。同時にSSL証明書のエラーを無視する設定にする
    2.HTTPヘッダ部分にvCenterのユーザー名とパスワードをBASE64エンコードしてセット
    3.リクエストを送信、レスポンスをデシリアライズしてセッションIDを取り出す

     (C#)sessionID.value (Python)sessionID[“value”]に取得したセッションIDの文字列が入ります。以降はこの文字列をHTTPヘッダにセットしてAPIにアクセスします。

  • その2 仮想マシンの情報を取得してvm名を取り出します

     電源制御に必要なvm名(vCenter内部で管理されている一意な仮想マシン名)をAPIから取得します。リクエストには先ほど取得したセッションIDを使います。

    C#

    //
    // Step 2 : 仮想マシンの情報を取得します
    //
    
    // 仮想マシン情報を取得するURLとGETメソッドのパラメータとして仮想マシン名を指定します
    restClient = new RestClient("https://vCenterのFQDNかIPアドレス/rest/vcenter/vm?filter.names=ho-testpc");
    restClient.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
    
    // リクエストを作ってセッションIDをセットします
    request = new RestRequest();
    request.AddHeader("vmware-api-session-id", sessionID.value);
    
    // リクエストを送信します。情報取得はGETメソッドです
    response = restClient.Get(request);
    
    // 仮想マシンの情報をデータに変換します
    var vmInfo = JsonConvert.DeserializeObject<VMInfo>(response.Content);
    
      

    Python

    #
    # Step 2 : 仮想マシンの情報を取得します 
    #
    
    # httpヘッダ情報をセットします
    headers = {
      "Content-Type": "application/json",
      "vmware-api-session-id": sessionID["value"]
    }
    
    # リクエストを送信します
    response = requests.request("GET", "https://vCenterのFQDNかIPアドレス/rest/vcenter/vm?filter.names=ho-testpc",
                                headers=headers, data="", verify=False)
    vmInfo = json.loads(response.content)
      

    1.HTTPクライアントを作る
    2.HTTPヘッダにセッションIDをセット
    3.リクエストを送信、レスポンスをデシリアライズして仮想マシンの情報を取り出す

     (C#)vmInfo.value[0].vm (Python)vmInfo[“value”][0][“vm”]からvm名を取得できます。

  • その3 vm名を使って仮想マシンの電源をONにする

     APIを使って仮想マシンの電源をONにします。一応リクエストを送信する前に、現在の電源状態を調べ、既にONになっていればプログラムを終了します。

    C#

    //
    // Step 3 : 仮想マシンの電源をONにします
    //
    
    // 仮想マシンの電源状態がONの場合は処理しません
    if (vmInfo.value[0].power_state == "POWERED_ON")
    {
    Console.WriteLine($"仮想マシン{vmInfo.value[0].name}は既に電源ONになっています");
        Environment.Exit(0);
    }
    
    // 仮想マシン情報を取得するURLとGETメソッドのパラメータとして仮想マシン名を指定します
    restClient = new RestClient($"https://vCenterのFQDNかIPアドレス/rest/vcenter/vm/{vmInfo.value[0].vm}/power/start");
    restClient.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
    
    // リクエストを送信します(requestは使い回します)。電源制御はPOSTメソッドです
    response = restClient.Post(request);
    
    Console.WriteLine($"仮想マシン{vmInfo.value[0].name}を電源ONしました");
      

    Python

    #
    # Step 3 : 仮想マシンの電源をONにします
    #
    
    # 仮想マシンの電源状態がONの場合は処理しません
    if vmInfo["value"][0]["power_state"] == "POWERED_ON":
        print("仮想マシン" + vmInfo["value"][0]["name"] + "は既に電源ONになっています")
        sys.exit(0)
    
    # リクエストを送信します
    response = requests.request("POST", "https://vCenterのFQDNかIPアドレス/rest/vcenter/vm/" +
                                vmInfo["value"][0]["vm"] + "/power/start",
                                headers=headers, data="", verify=False)
    
    print("仮想マシン" + vmInfo["value"][0]["name"] + "を電源ONしました")
      

    1.仮想マシンの電源状態を調べ既にONならプログラムを終了する
    2.HTTPクライアントを作る(C#のみ)
    3.HTTPヘッダにセッションIDをセット
    4.リクエストを送信

 これでアプリケーションプログラムからAPIにアクセスして仮想マシンの電源をONにできました。呼び出し方やレスポンスの処理は、どんなAPIを使ってもほとんど同じですが、ボディに複雑なパラメータをセットするAPIもあります。

このように、基本的な使い方を覚えてしまえば、アプリケーションとvSphereの連携が簡単に実現できます。ぜひAPIを活用してシステムやアプリケーションを賢くしてみてください!

VMwareの記事




※閲覧にはiDATEN(韋駄天)へのログインが必要です。