TechReport

技術者情報

ソリューション

2018年2月21日(水)公開

第214回

PowerShellでConoHaをどうにかしてみる-Vol.1

ConoHa APIを使ってPowerShellのオリジナルコマンドでサーバー管理

GMOインターネットが提供するVPSサービス「ConoHa」のAPIを使って、オリジナルコマンドを使ったサーバー管理方法を3回に渡ってレポートします。
Vol.1では、APIを利用するメリットや利用方法をご紹介します。

記事INDEX

ConoHaのAPI

ConoHaはGMOインターネットが提供するVPSサービスです。初期費用無しでひと月630円から使えます。
現時点では残念ながらWindowsはありませんが、豊富なテンプレートイメージと高速SSDで快適サーバーがすぐに利用できるサービスです。

https://www.conoha.jp/

VPSサービス「ConoHa byGMO」
VPSサービス「ConoHa byGMO」

ConoHaのサービス管理はWebで提供されているコントロールパネルから行いますが、独自のプログラムから制御もできるようにAPIが公開されています。

ConoHaのREST API情報
ConoHaのREST API情報

ConoHaのAPIはHTTPSベースのREST APIとなっており、指定されたURL対して、GETやPOSTのリクエストを送ることによってデータのやりとりを行い、利用することができます。実行結果はJSON形式で成形されたデータを受け取ることになります。今回作成するPowerShellのコマンドは、このRESTAPIを利用して作り込んでいきます。

●PowrShellからAPIを利用するメリット

ConoHaのAPIを利用した場合、結果はすべてJSON形式の文字列として返されることになります。プログラムではこのJSONの文字列を解析して目的の情報を取り出す必要があります。また、取り出した情報も単純な文字列となりますので、これらを使ってなにかアクションをと考えた場合、さらに一工夫が必要となります。PowerShellでは、JSON形式のデータを自動的に解析してオブジェクトとして扱えるPSCustomObjectという便利な機能が用意されています。

例えば、仮想マシン情報をPowerShellからAPIを利用して取得した場合、JSONデータを受け取ると、動的なオブジェクトとしてきちんと分類した状態で格納し、その属性として仮想マシン名や状態、メモリの容量などきちんと名前付された値として取り扱うことができるようになります。オブジェクトとして扱えることで、変数に格納したり、汎用的なPowerShellのコマンドをそのまま利用することも可能となるので、開発効率が格段にアップします。PowerShellはWindowsに標準で搭載されているシェル&開発言語で、PowerShell ISEというエディタツールもあらかじめインストールされているので、手軽に開発をはじめることができます。

例:ConoHa上の稼働中サーバーを全て停止するコマンドを一行で実行。

Get-cVM | ? State -eq "Active" | Stop-cVM

APIを利用するには

まずはサービスの申し込みが必要です。ConoHaのTopページ(https://www.conoha.jp/)より申し込みを行っておきましょう。サービスの申し込みが完了すると、コントロールパネルにログインできるようになります。ConoHaのAPIを利用するには、コントロールパネルにログインするためのユーザーアカウントとは別に、APIユーザーの登録が必要です。

まずはAPIユーザーを追加しておきましょう。コントロールパネルの左メニューから「API」を選択し、「追加」ボタンをクリックします。

コントロールパネルからAPIを選択
コントロールパネルからAPIを選択

APIユーザーのパスワードを設定して「保存」ボタンをクリックします。

APIユーザーパスワードを設定
APIユーザーパスワードを設定

ユーザー名は自動的に割り当てられます。
APIのユーザー登録が完了したら、テナント情報のプルダウンを開いてテナントIDとテナント名を確認します。テナント名はAPIのユーザー名と同一になっています。これらの情報はREST APIを利用する時に必要となります。

テナント情報の確認
テナント情報の確認

APIは利用する機能やリージョン(データーセンターの場所)ごとにエンドポイント(URL)が異なります。コード内ではこのエンドポイントを利用することになりますので確認しておきましょう。

エンドポイント情報
エンドポイント情報

ConoHaのAPIの利用方法は、ConoHa API Documentationに記載されています。リクエストデータを送信するURLや必要なパラメーター、Linuxのcurlコマンドで実行する場合のサンプルコードなどが記載されています。PowerShellから利用する場合にも、同様の情報が必要となりますのでこちらを参考にコマンドを作成していきます。

ConoHa API Documantation
ConoHa API Documantation
オリジナルコマンドの作成:Invoke-RestMethodの使い方

今回作成するサンプルコード


PowerShellには、REST APIを利用する場合に最適なコマンド「Invoke-RestMethod」が用意されています。コマンドの引数にURLとメソッド(POST、GET)を指定して、送信Dataを指定するだけで、APIからの情報を取得することができます。さらに、JSON形式のデータを自動的にPSCustomObjectに格納してくれるので、JSONの文字列データを解析して目的の情報を取り出すといった文字列操作は必要ありません。

簡単な例として、ConoHaのバージョン情報を取得してみましょう。

リクエストURLは「https://identity.tyo1.conoha.io/v2.0」、メソッドは「POST」となります。Invoke-RestMethodコマンドで実行するとこのようになります。

PS C:\> Invoke-RestMethod "https://identity.tyo1.conoha.io/v2.0" -Method GET

version
-------
@{status=stable; updated=2015-05-12T09:00:00Z; media-types=System.Object[]; id=v2.0; links=System.Object[]}

実行結果として「version」という見出しの配列(@{〇〇〇})文字列が表示されています。文字列のように見えますが、すでにPSCustomObjectとして格納されている状態です。

実行結果を$resという変数に格納して、プロパティー値として、「version.id」を表示してみましょう。バージョン情報が取得できました。

PS C:\> $res = Invoke-RestMethod "https://identity.tyo1.conoha.io/v2.0" -Method GET

$res.version.id
v2.0

APIの実行結果は、元々はJSON形式のデータで送られてきています。JSON形式のデータとして表示し、確認してみましょう。ConvertTo-JSONコマンドで実行結果を変換します。

PS C:\> $res = Invoke-RestMethod "https://identity.tyo1.conoha.io/v2.0" -Method GET

PS C:\> ConvertTo-JSON $res
{
"version": {
"status": "stable",
"updated": "2015-05-12T09:00:00Z",
"media-types": [
"@{base=application/json}",
"@{base=application/xml}"
],
"id": "v2.0",
"links": [
"@{href=https://identity.tyo1.conoha.io/v2.0/; rel=self}",
"@{href=https://www.conoha.jp/docs/; type=text/html; rel=describedby}"
]
}
}

APIの解説ページと同じJSONデータが確認できました。

オリジナルコマンドの作成:トークンの取得

先ほどのバージョン情報を取得する場合では必要ありませんでしたが、ConoHaのAPIを利用する場合には、コマンドにトークンと呼ばれる「認証済み」情報を付加して実行する必要があります。トークンは先ほどコントロールパネルで追加したテナント情報(テナントID、APIユーザー、パスワード)を元にREST APIを利用して発行されます。一度発行されたトークンは24時間の有効期限があり、その間であれば繰り返し利用することが可能です。

APIの解説ページを見てみましょう。

必要な情報としては、

ParameterValueStyleDescription
usernameユーザー名plainユーザー名
passwordユーザーパスワードplainユーザーパスワード
tenantId (Optional)Tenant IDplainテナントID

このようになっています。


curlコマンドのサンプルコードを見てみましょう。

curl -i -X POST \
-H "Accept: application/json" \
-d '{"auth":{"passwordCredentials":{"username":"ConoHa","password":"paSSword123456#$%"},"tenantId":"487727e3921d44e3bfe7ebb337bf085e"}}' \
https://identity.tyo1.conoha.io/v2.0/tokens

Invoke-RestMethod コマンドで必要となる情報としては、メソッドの”POST”、「-d」の送信する文字列データ、リクエスト先のURLとなります。

送信する文字列データは
'{"auth":{"passwordCredentials":{"username":"<ユーザー名>","password":"<ユーザーパスワード>"},"tenantId":"<テナントID>"}}'
となっています。
最後の「\」マークは改行コードなので省略します。

ここまでの情報をInvoke-RestMethodコマンドで置き換えるとこのようになります。

PS C:\> $apiUser = "gncu12345678"
$password = "paSSword123456#$%"
$tenantId = "487727e3921d44e3bfe7ebb337bf085e"
$body = '{"auth":{"passwordCredentials":{"username":"' + $apiUser + '","password":"' + $password+'"},"tenantId":"' + $tenantId+'"}}'
$tokenUrl = “https://identity.tyo1.conoha.io/v2.0/tokens”

Invoke-RestMethod $tokenUrl -Method POST -Body $body

Invoke-RestMethod $tokenUrl -Method POST -Body $body : Invoke-RestMethodコマンドに各設定値を指定して実行します。

ここまでを実行してみましょう。データが取得できていれば成功です。

access
------
@{token=; serviceCatalog=System.Object[]; user=; metadata=}

取得したトークン情報で必要となるのが、「access.token.id」(トークンID)の値です。トークンIDは他のAPIの機能を利用する場合に、Invoke-RestMethodコマンドのヘッダー情報「-Header」オプションに「@{"X-Auth-Token" = <トークンID>}」としてIDictionary型で指定することで認証済みのリクエストとして実行可能となります。
(参考:IDictionaryはキーと値を1つのペアとしたコレクション変数の型。)

ここまでをGet-cTokenHeaderという名前で1つのコマンドとしてまとめてみましょう。また、他のコマンドでも利用する可能性がある変数は、コマンドのブロック外で共通変数として定義しておきます。




実行結果はこのようになります。トークンIDを含んだIDictionary型のヘッダー情報が作成されていれば成功です。

PS C:\> Get-cTokenHeader

Name Value
---- -----
X-Auth-Token 0643af2d2105456690efad28107ed23d



取得したトークンは24時間の有効期限が設定されています。他のAPIを利用する場合に同じトークンIDが利用可能です。パフォーマンンスアップにもつながるので、トークンを再利用するためのロジックを追加しておきましょう。



1-3:スクリプト共通で利用する定数として定義しておきます。PowerShellではSet-VariableコマンドのConstantオプションで定数を定義できるのですが、ここは簡易的にしています。

 4:Get-cTokenHeaderコマンドで取得したトークン情報を格納しておく変数です。スクリプト内で共通に参照するので、「$script:」オプションを付けています。

10 :トークンを格納した変数にトークン情報が入っている場合と、空の場合で分岐します。

11 :トークン情報が入っている場合は、$token.access.token.expire からトークンの有効期限を取得します。

12 :トークンの有効期限が終了していた場合は、トークン情報を再取得します。

15 :トークン情報が空の場合は、トークン情報を取得します。




以上で効率的にトークンの再利用が可能となりました。

ここまで作成したコマンドは、スクリプトファイルとして「PSdeConoHa.ps1」という名前で保存しておきましょう。

サーバー一覧の取得

サーバー一覧を取得するコマンドを作成する前に、コントロールパネルからいくつかサーバー(=仮想マシン)を作成しておきましょう。左メニューから「サーバーの追加」を選択します。”タイプ:VPS”、”リージョン:東京”として、他の項目は任意で指定して作成しておきます。

サーバーの追加
サーバーの追加

VM一覧詳細取得のAPI解説ページを見てみましょう。

必要な情報としては、

ParameterValueStyleDescription
X-Auth-TokenUserトークンheaderトークンID
tenant_idTenant IDURIテナントID
changes-since (Optional)ISO 8601 dateTime (2016-04-04T17:08Z)query削除されたものを含む、指定時間からのVM一覧
image (Optional) queryVMに使用されているイメージID
flavor (Optional) queryVMに使用されているフレーバーID
name (Optional) queryVM名
marker (Optional) query表示される最後のUUID
limit (Optional) queryVMの表示数
status (Optional) queryVMの状態

となっています。

「Style」がqueryとなっている項目はオプションです。必須ではありませんので任意で指定します。必要な項目としては、「Userトークン」と「テナントID」となります。

curlコマンドのサンプルコードを見てみましょう。

curl -i -X GET \
-H "Accept: application/json" \
-H "X-Auth-Token: 35941e7df872405d84e5b026dba8323c" \
https://compute.tyo1.conoha.io/v2/1864e71d2deb46f6b47526b69c65a45d/servers/detail

Invoke-RestMethodコマンドで必要となる情報としては、メソッドの”GET”、「-H」のヘッダー情報としてトークン、リクエスト送信先のURLとなります。トークンは先ほど作成した「Get-cTokenHeader」コマンドで取得できます。
URLは https://compute.tyo1.conoha.io/v2/<テナントID>/servers/detailとなっています。東京以外のリージョンでサーバーを作成した場合は「compute.tyo1.conoha.io」の部分が異なりますので、コントロールパネルの「エンドポイント」で確認しましょう。

ここまでの情報をInvoke-RestMethodコマンドで置き換えるとこのようになります。

PS C:\> $tokenHeader = Get-cTokenHeader
$requestUrl = "https://compute.tyo1.conoha.io/v2/$tenantId/servers/detail"
Invoke-RestMethod $requestUrl -Headers $tokenHeader -Method GET

実行してみましょう。データが取得できていれば成功です。

servers
-------
{@{status=ACTIVE; updated=2017-11-13T02:31:57Z; hostId=6d67cc67c8e7f133bb22ed9ac52a8cc4d1c737595ec28...

実行結果のserversにはConoHa上のすべてのサーバーの詳細な情報が含まれています。試しに以下を実行してみると、仮想マシンの台数分だけ情報が繰り返し表示されます。

PS C:\> $tokenHeader = Get-cTokenHeader
$requestUrl = "https://compute.tyo1.conoha.io/v2/$tenantId/servers/detail"
$result = Invoke-RestMethod $requestUrl -Headers $tokenHeader -Method GET
$servers = $result.servers
ForEach($server in $servers){
$server
}

status : ACTIVE
updated : 2017-11-13T02:31:57Z
hostId : 6d67cc67c8e7f133bb22ed9ac52a8cc4d1c737595ec2892c3a7cc8
e4
OS-EXT-SRV-ATTR:host : cn-a11018.g2.tyo1.v4
addresses : @{ext-150-95-150-0-23=System.Object[]}
links : {@{href=https://compute.tyo1.conoha.io/v2/07af275f5800
401f83d9f1e2913fe37e/servers/a7b8c9c5-b17c-4446-9b06-3
37d17083bf4; rel=self}, @{href=https://compute.tyo1.co
noha.io/07af275f5800401f83d9f1e2913fe37e/servers/a7b8c
9c5-b17c-4446-9b06-337d17083bf4; rel=bookmark}}
key_name :
image : @{id=5a933dc9-c2ec-48d7-98e4-a72d408c9ffb; links=Syste
m.Object[]}
OS-EXT-STS:task_state :
OS-EXT-STS:vm_state : active
OS-EXT-SRV-ATTR:instance_name : tyo1-00118ab8
OS-SRV-USG:launched_at : 2017-11-05T07:23:09.000000
OS-EXT-SRV-ATTR:hypervisor_hostname : cn-a11018.g2.tyo1.v4
flavor : @{id=7eea7469-0d85-4f82-8050-6ae742394681; links=Syste
m.Object[]}
id : a7b8c9c5-b17c-4446-9b06-337d17083bf4
security_groups : {@{name=default}, @{name=gncs-ipv6-all}, @{name=gncs-i
pv4-all}}
OS-SRV-USG:terminated_at :
OS-EXT-AZ:availability_zone : nova
user_id : fcdaf312424446acb12adced7b449047
name : 150-95-151-89
created : 2017-11-05T07:22:59Z
tenant_id : 07af275f5800401f83d9f1e2913fe37e
OS-DCF:diskConfig : MANUAL
os-extended-volumes:volumes_attached : {}
accessIPv4 :
accessIPv6 :
progress : 0
OS-EXT-STS:power_state : 1
config_drive : True
metadata : @{instance_name_tag=vps-2017-11-05-16-15; backup_statu
s=active; backup_id=; properties={"vnc_keymap":"ja","h
w_video_model":"vga","hw_vif_model":"virtio","hw_disk_
bus":"virtio","cdrom_path":""}; backup_set=0}
.
.
.

情報量が非常に多いため、作成するコマンドではこれらの中から必要な情報を選択して表示することにします。Invoke-RestMethodコマンドの実行結果は元々PSCustomObjectが配列に格納されたものなので、Get-cVMという名前でサーバー一覧情報を取得して抽出するコマンドを作成し、同様にPSCustomObjectが配列に格納された実行結果を返すようにします。

23-25 :Paramで定義した変数$Nameはコマンドの引数として利用します。単一のサーバー情報を取得する場合に指定します。

28 :Invoke-RestMethodコマンドの実行結果を$resultに格納しておきます。

29 :サーバー情報は$result.serversで取得します。

31 :APIから取得したサーバー情報から抽出した情報を格納するための配列を定義します。この配列には一台一台のサーバー情報をPSCustomObjectに格納したものが入ります。

32 :サーバーを1台ごとに参照して情報を抽出します。

34 :$server.metadata.instance_name_tagが、ユーザーがコントロールパネルから見た場合のサーバー名(ネームタグ)となります。

36 :$flavorId = $server.flavor.idはサーバーのプラン情報のIDとなります。

37-40 :Get-cFlavorコマンドを作成して、プラン情報からサーバーのメモリ容量、CPU、ディスクサイズを取得します。

41 :IPv4のアドレスのみ取得しています。

43-50 :PSCustomObjectを定義して、取得した情報を「キー:値」のペアとして登録します。

51 :配列に格納しておきます。

55 :パラメーターで定義した$Nameに値が入っていた場合は、その名前でフィルタします。

58-59 :指定された仮想マシンが見つからない場合はエラーを表示します。

61 :コマンドの実行結果として、配列に格納されたPSCustomObjectを返します。

65 :flavorIDからサーバーのプランを抽出するためのコマンドを作成します。

67-69 :tenantIDとflavorIDを指定してAPIからプランを取得します。



コマンドを実行してみましょう。シンプルで分かりやすいサーバー情報が取得できいています。

PS C:\> Get-cVM

ID : a7b8c9c5-b17c-4446-9b06-337d17083bf4
Name : vps-2017-11-05-16-15
State : ACTIVE
Memory : 1
Disk : 50
vCPU : 2
IPAddress : 150.95.151.89

ID : 1e08705e-72a5-423a-b9d6-0783e37c98ec
Name : vps-2017-10-24-12-29
State : ACTIVE
Memory : 4
Disk : 50
vCPU : 4
IPAddress : 150.95.184.136

ID : fe3ec4d2-1af7-4800-a2f8-6ceadd00f8d8
Name : vps-2017-10-03-16-52
State : ACTIVE
Memory : 4
Disk : 50
vCPU : 4
IPAddress : 150.95.156.236

以上のように、ConoHaのREST APIはPowerShellのInvoke-RestMethodコマンドとPSCustomObjectを利用することで、とても使いやすいものとなります。

次回以降も引き続きPowerShellでConoHaをどうにかするべく、コマンドを作成していきましょう。また、オリジナルコマンドをさらに使いやすくするためにモジュールとして登録する方法も紹介する予定です。

樋口 勝一

GMOインターネット株式会社

1999年6月GMOインターネットに入社。Windowsを用いたホスティング事業の立ち上げの際、サービス開発からその後の保守・運用まで1人で担当。2010年には「お名前.comWindowsデスクトップ」をリリースし、マイクロソフト社と強い信頼関係を構築。2007年から連続で「マイクロソフトMVPアワード」を受賞し、Windowsのスペシャリストとして活躍。

執筆者一覧

Hyper-Vで本格的なサーバー仮想環境を構築。仮想環境を設定・操作できる!

できるPRO Windows Server 2016 Hyper-V
GMOインターネット株式会社 樋口 勝一 著

◇Hyper-Vのさまざまな機能がわかる
◇インストールからの操作手順を解説
◇チェックポイントやレプリカも活用できる
Windows Server 2016 Hyper-Vは、仮想化ソフトウェア基盤を提供する機能であり、クラウドの実現に不可欠のものです。
本書では、仮想化の基礎知識から、Hyper-Vでの仮想マシンや仮想スイッチの設定・操作、プライベートクラウドの構築、Azureとの連携などを解説します。

詳細はこちら → Amazonインプレスブックス

初めてのWindows Azure Pack本が発売

Windows Azure Pack プライベートクラウド構築ガイド
GMOインターネット株式会社 樋口 勝一 著

本書は、Windows Azure PackとHyper-Vを利用し、企業内IaaS(仮想マシン提供サービス)を構成するための、IT管理者に向けた手引書です。試用したサーバーは、最小限度の物理サーバーと仮想マシンで構成しています。Windows Azure Packに必要なコンポーネントのダウンロード、実際にプライベートクラウド構築する過程を、手順を追って解説しています。これからプライベートクラウドの構築を検討するうえで、作業負担の軽減に役立つ一冊です。

詳細はこちら