GCEのインスタンス一覧をPythonで取得

タイトルの内容、たいしたことではないのですが、Google Cloudの流儀やドキュメントの見方に慣れるまでは、ちょっとしたことでも時間がかかってしまいます。

Pythonなどのプログラミング言語からGoogle CloudのAPIにアクセスするためのライブラリは、以下のページにあるとおり充実しているようです。

[Google Cloud クライアント ライブラリ  |  Cloud API](https://cloud.google.com/apis/docs/cloud-client-libraries?hl=ja)

この中のPythonのライブラリを動かしてみました。

手順

- 秘密鍵取得
- パッケージインストール
- Pythonのソースコードを書く

# 秘密鍵取得

サービスアカウントの秘密鍵というのをJSONファイルで取得することが必要らしいです。

以下のコマンドを実行すると `service-account-key.json` というファイルが生成されます。ファイル名はコマンドのパラメータで指定します。

```shell
$ gcloud --project=xxxxxxxx iam service-accounts keys create service-account-key.json --iam-account=xxxxxxxx@developer.gserviceaccount.com
```

JSONの中身はこんなファイルでした。

```json
{
  "type": "service_account",
  "project_id": "xxxxxxxx",
  "private_key_id": "xxxxxxxx",
  "private_key": "-----BEGIN PRIVATE KEY-----\nMIIE....==\n-----END PRIVATE KEY-----\n",
  "client_email": "xxxxxxxx@developer.gserviceaccount.com",
  "client_id": "xxxxxxxx",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/xxxxxxxx%40developer.gserviceaccount.com"
}
```

環境変数でこのJSONファイルを指定します。カレントディレクトリに置いてありますが、通常は絶対パスで指定したほうがよさそうです。Python実行時にこの環境変数が参照されます。

```shell
$ export GOOGLE_APPLICATION_CREDENTIALS=service-account-key.json
```

# パッケージインストール

Pythonで必要なパッケージをインストールします。

```shell
$ pip install google-cloud-compute

$ pip list | grep google-cloud-compute
google-cloud-compute     0.3.0

```

# Pythonのソースコード

```python
import json

import google.auth
import google.cloud.compute_v1

# 認証
credentials, project = google.auth.default()

zone = "asia-northeast1-b"

client = google.cloud.compute_v1.services.instances.InstancesClient(
    credentials = credentials,
)

# GCEのインスタンス一覧を取得
res = client.list(
    project = project,
    zone = zone,
)

# resはListPager型で、forでループできる
# JSONLで出力
for elem in res:
    print(json.dumps({
        "name": elem.name,
        "machine_type": elem.machine_type,
        "ip": ",".join([i.network_i_p for i in elem.network_interfaces]),
        "status": elem.status.name,
        "zone": elem.zone,
        "link": elem.self_link,
    }))
```

# ドキュメントへのリンク

GCPのドキュメントにまだ慣れていないので、リンクを貼って備忘録とします。

`google.auth.default()` の箇所については、認証で、以下のページに書いてあります。
https://googleapis.dev/python/google-api-core/latest/auth.html

clientの生成の仕方は、以下のページ。
https://googleapis.dev/python/compute/latest/compute_v1/instances.html#google.cloud.compute_v1.services.instances.InstancesClient

`client.list` など、clientで使えるメソッドは、以下のページ。
https://googleapis.dev/python/compute/latest/compute_v1/instances.html#google.cloud.compute_v1.services.instances.InstancesClient.list

`client.list` からのレスポンスの型は `ListPager` という型で、以下のページ。for文でループできました。
https://googleapis.dev/python/compute/latest/compute_v1/instances.html#google.cloud.compute_v1.services.instances.pagers.ListPager

その `ListPager` の要素は `client.list` メソッドのドキュメントに書いてある通り、`Instance` という型で、以下のページ。
https://googleapis.dev/python/compute/latest/compute_v1/types.html#google.cloud.compute_v1.types.Instance

`Instance` の `network_interfaces` は `NetworkInterface` という型を要素とするリストで、 `NetworkInterface` は以下のページ。
https://googleapis.dev/python/compute/latest/compute_v1/types.html#google.cloud.compute_v1.types.NetworkInterface

`Instance` の `status` は `Status` とい型で、以下のページ。
https://googleapis.dev/python/compute/latest/compute_v1/types.html#google.cloud.compute_v1.types.Instance.Status