PowerVS IBM i 日記(22): Windows から IBM Cloud API で PowerVS にアクセスする

# Windows から IBM Cloud API で PowerVS にアクセスする

**2020/11/20 追記**
問い合わせたところ Docs の記述が古く、東京やシドニーにも API の Endpoint はあるとのことでした。

東京： tok.power-iaas.cloud.ibm.com
シドニー： syd.power-iaas.cloud.ibm.com

このエンドポイントで、各々のDC の PowerVS サービスが API 経由で使えるのが確認できました。

「ibmcloud regions」のレスポンスとは違うので、注意が必要です。
-- 追記終了 --

「[IBM Cloud CLI で PowerVS に アクセスする](https://qiita.com/6onoda/items/01f0edd723316fcfa637)」「[IBM Cloud CLI で インスタンスを作成する・変更・削除する](https://qiita.com/6onoda/items/d1aeb68c50e502fa12f4)」では、タイトルのように「IBM Cloud **CLI**」を使って PowerVS を操作しました。

今回は「IBM Cloud **API**」を使ってPowerVS を操作してみたいと思います。
なお、今回も **Windows** でやってみました。

「[Power Systems Virtual Server on IBM Cloud で FlashCopy (Snapshot, Restore, Clone) を操作する](https://qiita.com/khayama/items/f0bf62dc04677a321e0c)」という記事がすでにあるのですが、実体験しないとよく分からないということで、Windows からやってみたいという記事です。

FlashCopy の操作なんて Web ポータルにも IBM Cloud CLI にも無い !
でも API からなら、Web ポータルにも IBM Cloud CLI にも無い機能が使えるようです。
API にも守備範囲を広げておきましょう。

今回は前編として、IBM Cloud API で PowerVS の情報にアクセスするところまでです。

後半のスナップショットの操作は「[ Windows から IBM Cloud API で PowerVS のスナップショットを作成・復元する](https://qiita.com/6onoda/items/5884ab22cafcd5263121)」になります。

## 処理結果を変数代入する方法と JSON の処理

「[IBM Cloud CLI で PowerVS に アクセスする](https://qiita.com/6onoda/items/01f0edd723316fcfa637)」「[IBM Cloud CLI で インスタンスを作成する・変更・削除する](https://qiita.com/6onoda/items/d1aeb68c50e502fa12f4)」では、CLI でリソースの  ID を確認して、コピペで実行コマンドに指定していました。

Mac や Linux で実行結果を変数に代入したいときは「`」(バッククォート)で囲めばいいだけです。

```
result=`command parm`
```

結果が JSON で返ってくる場合「[jq](https://stedolan.github.io/jq/)」を使って、欲しい部分を抜きだしたりします。

```
result=`command parm | jq .key`
```

Windows では、どうすれば実行結果を変数に代入できるのでしょう。Qiita に記事がありました。

* 「[【Windowsバッチ】コマンド実行結果を環境変数に代入する方法](https://qiita.com/RagWork/items/d8c404cba9d204a719c3)」


```
rem hoge.txtの行数を取得してLINECOUNTに代入するコマンド
for /f "usebackq" %%A in (`type hoge.txt ^| find /c /v ""`) do set LINECOUNT=%%A
echo %LINECOUNT%
```

さすがに却下です。

PowerShell は ? おお、直接代入できます。

```
PS C:\Users\YASUHIROOnoda> $date=date
PS C:\Users\YASUHIROOnoda> $date

2020年10月27日 17:01:27
```

なお、PowerShell の初心者なので、変な使い方をしているかもしれませんが、大目に見てください。

JSON の処理はどうしましょう。

jq には [jq のサイト](https://stedolan.github.io/jq/)に Windows バイナリーがあったり、Windows 用のパッケージ・マネージャーである [chocolatey](https://chocolatey.org/packages/jq) で導入できたりします。

今回、PowerShell を使うことを決めました。
PowerShell には ConvertFrom-Json というコマンドレットで、JSON の処理ができるようです。
これを使いましょう。

* [ConvertFrom-Json](https://docs.microsoft.com/ja-jp/powershell/module/Microsoft.PowerShell.Utility/ConvertFrom-Json?view=powershell-5.1)


JSON 形式で返ってくる出力をパイプで ConvertFrom-Json に渡すことで、JSON のデータが単なる文字列から、キーでアクセス可能なオブジェクトに変換されます。

```
$JSON = (command parm | ConvertFrom-Json)
```

キーに対する値は、変数にキーを受けることでアクセスできます。

```
$JSON.key
```

2 段階に分けずに値を取得してもいいでしょう。

```
$VALUE = (command parm | ConvertFrom-Json).key
```

## Power Cloud API 入門

資料は「[Power Cloud API](https://cloud.ibm.com/apidocs/power-cloud)」になります。

いわゆる REST の API です。オプションを指定して URL を呼び出せば、結果が得られたり、処理が実行されたりします。
資料の実行方法も「Curl」のガイドしかありません。
(他の IBM Cloud の API には言語に合わせた SDK が用意されていて Java や Python から直接呼び出せたりするのですが…)

### 接続先

REST API なので、接続先ホストの URL が必要です。
「https://{リジョン名}.power-iaas.cloud.ibm.com」と指定すること、一部のリージョンしか指定できないことが書いてあります。

> Endpoint URL
>
The Power Systems Virtual Server service uses regional endpoints. To target your region, replace {region} with the prefix that represents the geographic area where your service instance resides. Currently, the us-east, us-south, eu-de, lon, and tor regions are only supported.
>
https://{region}.power-iaas.cloud.ibm.com

IBM Cloud のリージョンの一覧は「ibmcloud regions」で確認できます。

```
ibmcloud regions
```

表示されました。

```
PS C:\Users\YASUHIROOnoda> ibmcloud regions
API エンドポイントが設定されていません。
パブリック・リージョンをリストしています...

名前       表示名
au-syd     Sydney
in-che     Chennai
jp-tok     Tokyo
kr-seo     Seoul
eu-de      Frankfurt
eu-gb      London
us-south   Dallas
us-east    Washington DC
```

これまでよく使っていたシドニーのリージョン名は「au-syd」です。

エンド・ポイントになるべき「au-syd.power-iaas.cloud.ibm.com」というホスト名は存在しませんでした。
PowerVS のサービスは提供されていますが、資料にある通り API は提供されていないようです。

```
C:\Users\YASUHIROOnoda>curl https://au-syd.power-iaas.cloud.ibm.com
curl: (6) Could not resolve host: au-syd.power-iaas.cloud.ibm.com
```

現在、ダラスにも PowerVS のサービスを持っています。
「us-south Dallas」ですので、ダラスのエンド・ポイントを確認します。

404 ですが応答が返ってきました。API のエンド・ポイントとして使えそうです。
今回は、こちらでテストしましょう。

```
C:\Users\YASUHIROOnoda>curl https://us-south.power-iaas.cloud.ibm.com
{"code":404,"message":"path / was not found"}
```

### 認証

IAM のアクセストークンとインスタンス ID (クラウド・リソース・ネーム:CRN)が必要だと書いてあります。

> Authentication
>
To work with the Power Systems Virtual Server API, you must include your IBM Cloud IAM access token and the Power Systems Virtual Server instance ID, also known as your Cloud Resource Name (CRN), in every request. The first part of your CRN contains your Tenant ID and the second part contains your Cloud Instance ID. The following example shows a typical CRN:
>
crn:v1:staging:public:power-iaas:us-east:a/abcdefghijklmnopqrstuvwxyzabcdef:121d5ee5-b87d-4a0e-86b8-aaff422135478::
>
Tenant ID {tenant_id} = abcdefghijklmnopqrstuvwxyzabcdef
Cloud Instance ID {cloud_instance_id} = 121d5ee5-b87d-4a0e-86b8-aaff422135478
You can retrieve an access token by first creating an API key, and then exchanging your API key for a IBM Cloud IAM token. For more information, see Retrieving an access token programmatically and Retrieving your instance ID.

#### IAM のアクセストークンの取得

IAM のアクセストークンは、IBM Cloud CLI で取得できます。

```
ibmcloud iam oauth-tokens
```

「[Power Systems Virtual Server on IBM Cloud で FlashCopy (Snapshot, Restore, Clone) を操作する](https://qiita.com/khayama/items/f0bf62dc04677a321e0c)」では、下記のようにIAM のアクセストークンの取得していました。

出力形式を JSON にして jq で必要な部分を取得していますね。

```
export ACCESS_TOKEN=$(ibmcloud iam oauth-tokens --output JSON | jq -r '.iam_token')
echo $ACCESS_TOKEN
```

PowerShell では「ConvertFrom-Json」で JSON データを取得できます。
CLI の結果の JSON をパイプで「ConvertFrom-Json」に渡し、キー iam_token でアクセスします。

```
$TOKEN = (ibmcloud iam oauth-tokens --output JSON | ConvertFrom-Json ).iam_token
```

#### インスタンス ID (クラウド・リソース・ネーム:CRN)の取得

インスタンス ID は ポータルでは サービス ID と呼ばれる特定のデータセンターに作った PowerVS のサービスにつけられたID です。

下記のレベルに対応する ID です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/239a0e35-ed4f-f2fa-2c9b-cfbbc5031989.png)

指定する CRN は、これまでも「ibmcloud pi service-list」で取得してきました。

PowerShell で取得しましょう。

```
$CRN = (ibmcloud pi service-list --json | ConvertFrom-Json )
```

2ヶ所に PowerVS のサービスを持っているので、当然、ふたつ返ってきます。

```
PS C:\Users\YASUHIROOnoda> $CRN

CRN                                                                                                                 Name
---                                                                                                                 ----
crn:v1:bluemix:public:power-iaas:syd04:a/e877c6e935024906adaa6336c7113334:8b97a1ed-437a-4bcf-bbad-207189c67caa::    SYD04
crn:v1:bluemix:public:power-iaas:us-south:a/e877c6e935024906adaa6336c7113334:64583f35-cc04-476b-b14d-486469561a31:: DAL
```

CRN と Name のふたつのプロパティがあります。 
Where-Object で ダラスのサービスに付けた「DAL」という名前でフィルタリングして「CRN」の値を取得します。

```
PS C:\Users\YASUHIROOnoda> $CRN_DAL = ($CRN | Where-Object {$_.Name -eq "DAL"} ).CRN
PS C:\Users\YASUHIROOnoda> $CRN_DAL
crn:v1:bluemix:public:power-iaas:us-south:a/e877c6e935024906adaa6336c7113334:64583f35-cc04-476b-b14d-486469561a31::
```
これで、最低限の準備ができました。

## API の実行 - イメージ一覧のリスト

API の一つであるイメージ一覧のリストを実行してみましょう。

* [List all images available for copying into cloud instances](
https://cloud.ibm.com/apidocs/power-cloud#pcloud-images-getall)

実行例として下記が記載されています。

```
curl -X GET \
   https://us-east.power-iaas.cloud.ibm.com/pcloud/v1/images \
  -H 'Authorization: Bearer <>' \
  -H 'CRN: crn:v1...' \
  -H 'Content-Type: application/json' \
```

今回の場合、下記のように書き換えました。
なお「`」は、PowerShell での継続行指定です。

エンド・ポイントにダラスを示す「us-south」を指定します。
「pcloud/v1/images」のパスでイメージの一覧を取得したいことを示します。

```
$IMAGES = ( `
curl.exe -X GET `
   https://us-south.power-iaas.cloud.ibm.com/pcloud/v1/images `
  -H "Authorization: $TOKEN" `
  -H "CRN: $CRN_DAL" `
  -H "Content-Type: application/json"  `
| ConvertFrom-Json )
```

ここでのポイントは「**curl**」ではなく「curl.**exe**」を呼び出している事です。

[PowerShell では、curl は Invoke-WebRequest コマンドレットの別名になっています](https://qiita.com/tatsuki1112/items/dec473f93ca1bda239fb)。
そのため単に「**curl**」と実行すると、Invoke-WebRequest が呼び出されます。
通常 の curl と Invoke-WebRequest のオプションは大きく違います。一般的な curl のオプション指定は PowerShell の curl の呼び出しには適用できません。

Invoke-WebRequest のオプションにパラメーターを合わせることもできたのですが、[Windows 10には、2018年のWindows 10 Ver.1803（RS3）からcurl.exeコマンドが標準で付属](https://ascii.jp/elem/000/004/021/4021036/)しています。
オプション指定も同等なので、curl.exe を使うこととしました。

結果を確認します。

$IMAGES には JSON データの全体が入っています。

```
PS C:\Users\YASUHIROOnoda> $IMAGES

images
------
{@{creationDate=2020-06-25T18:22:01.000Z; description=; href=/pcloud/v1/images/d469355f-effa-4c5d-9c85-33338d6c3789;...
```

各イメージは「images」の子になってるので、その部分を確認します。
イメージの一覧が取得できることが確認できました。

```
PS C:\Users\YASUHIROOnoda> $IMAGES.images

creationDate   : 2020-06-25T18:22:01.000Z
description    :
href           : /pcloud/v1/images/d469355f-effa-4c5d-9c85-33338d6c3789
imageID        : d469355f-effa-4c5d-9c85-33338d6c3789
lastUpdateDate : 2020-06-25T18:22:01.000Z
name           : 7100-05-04
specifications : @{architecture=ppc64; containerFormat=bare; diskFormat=raw; endianness=big-endian; hypervisorType=phyp
                 ; operatingSystem=aix}
state          : active
storageType    : tier3

creationDate   : 2020-01-29T20:54:37.000Z
description    :
href           : /pcloud/v1/images/e63b2550-5d5c-46bb-b70e-38395aaec4a7
imageID        : e63b2550-5d5c-46bb-b70e-38395aaec4a7
lastUpdateDate : 2020-01-29T20:54:37.000Z
name           : 7100-05-05
specifications : @{architecture=ppc64; containerFormat=bare; diskFormat=raw; endianness=big-endian; hypervisorType=phyp
                 ; operatingSystem=aix}
state          : active
storageType    : standard-legacy

(以下、略)
```

IBM Cloud API による PowerVS へのアクセスが確認できました。

---
当日記のIndexは[こちら](https://qiita.com/6onoda/items/f146c78c0c1bbe905a42)です。

---
許可の無い転載を禁じます。
この記事は筆者の個人的な責任で無保証で提供しています。
当記事に関してIBMやビジネスパートナーに問い合わせることは、固くお断りします。