JSON 形式の未加工のレスポンスを見てみることにします。
2. gcloud projects list --format="json"
[
{
"createTime": "2016-04-28T22:33:12.274Z",
"labels": {
"env": "test",
"version": "alpha"
},
"lifecycleState": "ACTIVE",
"name": "scesproject1",
"parent": {
"id": "297814986428",
"type": "organization"
},
"projectId": "windy-bearing-129522",
"projectNumber": "222844913538"
},
{
"createTime": "2016-05-11T03:08:13.359Z",
"labels": {
"env": "test",
"version": "beta"
},
"lifecycleState": "ACTIVE",
"name": "scesproject2",
"parent": {
"id": "297814986428",
"type": "organization"
},
"projectId": "canvas-syntax-130823",
"projectNumber": "346904393285"
}
]
この JSON 形式を基に、興味のある情報を選択して出力を好きなように加工したくなったとします。ここでは
createdTime の順序で並べ替え、表示するプロパティを絞り込んで表形式に整形しましょう。
3. gcloud projects list --format="table[box,title='My Project List'](createTime:sort=1,name,projectNumber,projectId:label=ProjectID,parent.id:label=Parent)"
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ My Project List │
├──────────────────────────┬──────────────┬────────────────┬──────────────────────┬──────────────┤
│ CREATE_TIME │ NAME │ PROJECT_NUMBER │ ProjectID │ Parent │
├──────────────────────────┼──────────────┼────────────────┼──────────────────────┼──────────────┤
│ 2016-04-28T22:33:12.274Z │ scesproject1 │ 222844913538 │ windy-bearing-129522 │ 297814986428 │
│ 2016-05-11T03:08:13.359Z │ scesproject2 │ 346904393285 │ canvas-syntax-130823 │ 297814986428 │
└──────────────────────────┴──────────────┴────────────────┴──────────────────────┴──────────────┘
ヒント
: --format='flattened' フラグを使用すれば、プロパティから JSON Path と値を抽出できます。
ボックスが不要で、日時の部分を年 - 月 - 日の形式でシンプルに表示する罫線なしの表を作りたい場合は、次のようにします。
4. gcloud projects list --format="table(createTime.date('%Y-%m-%d'),name,projectNumber,projectId)"
CREATE_TIME NAME PROJECT_NUMBER PROJECT_ID
2016-05-11 scesproject2 346904393285 canvas-syntax-130823
2016-04-28 scesproject1 222844913538 windy-bearing-129522
もう少し複雑な整形を行ってみましょう。Compute Engine ゾーンのリストを作り、JSON 形式で表示します。
5. gcloud compute zones list --format="json"
{
"creationTimestamp": "2014-05-30T18:35:16.514-07:00",
"description": "us-central1-a",
"id": "2000",
"kind": "compute#zone",
"name": "us-central1-a",
"region": "us-central1",
"selfLink": "https://www.googleapis.com/compute/v1/projects/windy-bearing-129522/
zones/us-central1-a",
"status": "UP"
},
selfLink に注目してください。これが、パースしようとしている完全修飾名です。この場合も、gcloud は JSON 値を選択してそれを抽出し、パースする関数を提供して作業を助けてくれます。
selfLink.scope() 関数を使用することで、selfLink の URL セグメントの最後の部分を取り出してみましょう。
6. gcloud compute zones list --format="value(selfLink.scope())"
us-central1-a
この値は、.basename() 関数でも抽出できます。
7. gcloud compute zones list --format="value(selfLink.basename())"
us-central1-a
selfLink の /projects よりも後の部分は、次のようにして抽出します。
8. gcloud compute zones list --format="value(selfLink.scope(projects))"
windy-bearing-129522/zones/us-central1-a
GCP オブジェクトの中には複数の値を持つリソースが含まれていて、それらの値をすべて拾い出して並べなければならないことがよくあります。たとえば、特定の Compute Engine インスタンス向けに有効にされているすべてのスコープのリストを作ってみましょう。
9. gcloud compute instances list --format="json"
"serviceAccounts": [
{
"email": "[email protected] ",
"scopes": [
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring.write",
"https://www.googleapis.com/auth/cloud.useraccounts.readonly"
]
}
],
複数の値を持つリソースを 1 つにまとめます。
10. gcloud compute instances list --format="flattened(name,serviceAccounts[].email,serviceAccounts[].scopes[].basename())"
name: instance-1
serviceAccounts[0].email: [email protected]
serviceAccounts[0].scopes[0]: devstorage.read_only
serviceAccounts[0].scopes[1]: logging.write
serviceAccounts[0].scopes[2]: monitoring.write
serviceAccounts[0].scopes[3]: cloud.useraccounts.readonly
複数の値を持つリソースには、値ごとに別々の行を与えるような表示方法もあります。
11. gcloud compute instances list --filter=name:instance-1 --flatten="serviceAccounts[].scopes[]" --format="csv(name,id,serviceAccounts.email,serviceAccounts.scopes.basename())"
name,id,email,scopes
instance-1,763097360168409044,[email protected] ,
devstorage.read_only
instance-1,763097360168409044,[email protected] ,
logging.write
instance-1,763097360168409044,[email protected] ,
monitoring.write
instance-1,763097360168409044,[email protected] ,
servicecontrol
instance-1,763097360168409044,[email protected] ,
service.management
同じ情報を読みやすく構造化された形式で表示します。
12. gcloud compute instances list --filter=name:instance-1 --format="table[box,no-heading](name,id,serviceAccounts:format='table[box,no-heading](email,scopes:format=\"table[box,no-heading](.)\")')"
┌────────────┬────────────────────┐
│ instance-1 │ 763097360168409044 │
└────────────┴────────────────────┘
┌────────────────────────────────────────────────────┐
│ [email protected] │
└────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ https://www.googleapis.com/auth/devstorage.read_only │
│ https://www.googleapis.com/auth/logging.write │
│ https://www.googleapis.com/auth/monitoring.write │
│ https://www.googleapis.com/auth/servicecontrol │
│ https://www.googleapis.com/auth/service.management │
└──────────────────────────────────────────────────────┘
次は、整形における最後のサンプルです。未加工の状態で表示すると以下のようになる情報において、複数の値を持つリソースをパースし、サービス アカウント キーとサービス アカウントを表示します。
13. gcloud beta iam service-accounts keys list --iam-account [email protected] --project mineral-minutia-820 --format="json"
[
{
"name": "projects/mineral-minutia-820/serviceAccounts/svc-2-429@mineral
-minutia-820.iam.gserviceaccount.com/keys/
04bd2d56d0cc5746b125d17f95d4b0dd654accca",
"validAfterTime": "2016-03-11T05:30:04.000Z",
"validBeforeTime": "2026-03-09T05:30:04.000Z"
},
{
"name": "projects/mineral-minutia-820/serviceAccounts/svc-2-
[email protected] /keys/
1deb44e2f54328fc7bb316e5a87315e3314f114f",
"validAfterTime": "2016-01-02T18:54:26.000Z",
"validBeforeTime": "2025-12-30T18:54:26.000Z"
},
....
]
それでは、
.scope() を使って serviceAccount の部分だけを取り出し、最初の '/' で区切られた部分を
segment(0) で取り出しましょう。
14. gcloud beta iam service-accounts keys list --iam-account [email protected] --project mineral-minutia-820 --format="table(name.scope(serviceAccounts).segment(0):label='service Account',name.scope(keys):label='keyID',validAfterTime)"
(click to enlarge)
フィルタ
次はフィルタです。フィルタを使えば、整形したいリソースだけを選択して処理できます。
たとえば、リソース(プロジェクト、VM など)にラベルが付いており、そのラベルが特定の値になっているプロジェクトだけを表示したいものとします。次の例は、
label.env='test' で
label.version=alpha の場合です。
15. gcloud projects list --format="json" --filter="labels.env=test AND labels.version=alpha"
[
{
"createTime": "2016-04-28T22:33:12.274Z",
"labels": {
"env": "test",
"version": "alpha"
},
"lifecycleState": "ACTIVE",
"name": "scesproject1",
"parent": {
"id": "297814986428",
"type": "organization"
},
"projectId": "windy-bearing-129522",
"projectNumber": "222844913538"
}
]
キーに変換を加えることも可能です。次の例では、
createTime キーを日付だけに変換したうえでフィルタを適用しています。
16. gcloud projects list --format="table(projectNumber,projectId,createTime)" --filter="createTime.date('%Y-%m-%d', Z)='2016-05-11'"
PROJECT_NUMBER PROJECT_ID CREATE_TIME
346904393285 canvas-syntax-130823 2016-05-11T03:08:13.359Z
上で選択されているフィルタは、実際に JSON 構造(
labels.env=test )を参照していることに注意してください。もちろん、フィルタはさまざまに組み合わせて使うことが可能です。
変換
変換を使えば、表示される値を直接操作できます。これまでに挙げたいくつかの例(
.scope() 、
.basename() 、
.segment() など)でも、すでに使用しています。変換で面白いのは、.map() で結合、チェインできることと、複数の値を持つデータに適用できることです。
次の例をご覧ください。
parent.id キーがあれば “YES”、なければ “NO” を出力するように条件に基づいて変換しています。このようにすれば、プロジェクトが特定の基準を満たしているかどうか(この場合は、Organization Node の一部かどうか)をすばやく見分けることができます。
17. gcloud projects list --format="table(projectId,parent.id.yesno(yes="YES", no=”NO”):label='Has Parent':sort=2)"
PROJECT_ID Has Parent
mineral-minutia-820 NO
fabled-ray-104117 YES
rk-test-0506 YES
user2proj1 YES
user2project2 YES
18. gcloud compute instances list --format="flattened(name,serviceAccounts[].email,serviceAccounts[].scopes.map().scope())"
name: instance-1
serviceAccounts[0].email: [email protected]
serviceAccounts[0].scopes[0]: devstorage.read_only
serviceAccounts[0].scopes[1]: logging.write
serviceAccounts[0].scopes[2]: monitoring.write
serviceAccounts[0].scopes[3]: cloud.useraccounts.readonly
スクリプト
最後に、
gcloud コマンドを結合し、埋め込まれている情報を簡単に抽出するスクリプトを作ってみましょう。
次の例では、すべてのプロジェクトに含まれるサービス アカウントのすべてのキーのリストを表示します。そのためには、最初にすべてのプロジェクトを反復処理し、次にプロジェクトごとにすべてのサービス アカウントを取り出し、最後にサービス アカウントごとに作られたすべてのキーのリストを作らなければなりません。これは、基本的には反復処理のためのループをネストした形になります。
bash スクリプトでは次のようになります。
#!/bin/bash
for project in $(gcloud projects list --format="value(projectId)")
do
echo "ProjectId: $project"
for robot in $(gcloud beta iam service-accounts list --project $project --format="value(email)")
do
echo " -> Robot $robot"
for key in $(gcloud beta iam service-accounts keys list --iam-account $robot --project $project --format="value(name.basename())")
do
echo " $key"
done
done
done
Windows PowerShell では次のようになります。
foreach ($project in gcloud projects list --format="value(projectId)")
{
Write-Host "ProjectId: $project"
foreach ($robot in gcloud beta iam service-accounts list --project $project --format="value(email)")
{
Write-Host " -> Robot $robot"
foreach ($key in gcloud beta iam service-accounts keys list --iam-account $robot --project $project --format="value(name.basename())")
{
Write-Host " $key"
}
}
}
レスポンス フィールドをパースして配列にまとめてから処理しなければならないこともよくあります。次の例では、インスタンスのサービス アカウント情報をパースして配列にまとめ、操作しやすくしています。
この例の場合、CSV の serviceAccounts[].scope フィールドは複数の値を持ち、個々の値はセミコロンで句切られている(separator=;)ことに注意してください。つまり、下の gcloud コマンドのレスポンス行は、
name,id,email,scope_1;scope_2;scope_3 という形式になっています。このスクリプトは、基本的に例 12 のレスポンスをパースしています。
#!/bin/bash
for scopesInfo in $(
gcloud compute instances list --filter=name:instance-1 \
--format="csv[no-heading](name,id,serviceAccounts[].email.list(),
serviceAccounts[].scopes[].map().list(separator=;))")
do
IFS=',' read -r -a scopesInfoArray<<< "$scopesInfo"
NAME="${scopesInfoArray[0]}"
ID="${scopesInfoArray[1]}"
EMAIL="${scopesInfoArray[2]}"
SCOPES_LIST="${scopesInfoArray[3]}"
echo "NAME: $NAME, ID: $ID, EMAIL: $EMAIL"
echo ""
IFS=';' read -r -a scopeListArray<<< "$SCOPES_LIST"
for SCOPE in "${scopeListArray[@]}"
do
echo " SCOPE: $SCOPE"
done
done
以上で、
gcloud コマンドの出力を効果的にフィルタおよび整形する方法がおわかりいただけたと思います。これらのテクニックは、
gcloud のすべてのレスポンスに応用できます。未加工のレスポンスを見て、どのように加工したいかを考え、そのように整形するだけです。
* この投稿は米国時間 6 月 14 日、Google Cloud Platform の Technical Account Manager である Salmaan Rashid によって投稿されたもの(投稿はこちら )の抄訳です。
コマンドライン ツールの gcloud は、Google Cloud Platform の管理や操作に使用できるゲートウェイです。コマンドライン ツールについては、cat | sed | awk | grep | cut などのシステム ツールを使ってツールの出力情報を抽出すると考えがちですが、gcloud の場合はこうしたシステム ツールの代わりとなるオプションが用意されています。
この投稿では、gcloud からの出力を自動的にパースしたり、整形したりするオプションについて取り上げます。また、埋め込まれているデータを取り出すために、bash や PowerShell といったスクリプトでコマンドをつなぐ方法も紹介します。
gcloud には、さまざまな形での拡張や結合をサポートした次の 3 つの機能が備わっています。
変換 : 返されたデータに対して変換、論理操作を直接適用します。
整形
アクセス対象のプロジェクト リストを作るお馴染みのコマンドの出力を整形する方法から始めましょう。
1. gcloud projects list
PROJECT_ID NAME PROJECT_NUMBER
canvas-syntax-130823 scesproject2 346904393285
windy-bearing-129522 scesproject1 222844913538
JSON 形式の未加工のレスポンスを見てみることにします。
2. gcloud projects list --format="json"
[
{
"createTime": "2016-04-28T22:33:12.274Z",
"labels": {
"env": "test",
"version": "alpha"
},
"lifecycleState": "ACTIVE",
"name": "scesproject1",
"parent": {
"id": "297814986428",
"type": "organization"
},
"projectId": "windy-bearing-129522",
"projectNumber": "222844913538"
},
{
"createTime": "2016-05-11T03:08:13.359Z",
"labels": {
"env": "test",
"version": "beta"
},
"lifecycleState": "ACTIVE",
"name": "scesproject2",
"parent": {
"id": "297814986428",
"type": "organization"
},
"projectId": "canvas-syntax-130823",
"projectNumber": "346904393285"
}
]
この JSON 形式を基に、興味のある情報を選択して出力を好きなように加工したくなったとします。ここでは createdTime の順序で並べ替え、表示するプロパティを絞り込んで表形式に整形しましょう。
3. gcloud projects list --format="table[box,title='My Project List'](createTime:sort=1,name,projectNumber,projectId:label=ProjectID,parent.id:label=Parent)"
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ My Project List │
├──────────────────────────┬──────────────┬────────────────┬──────────────────────┬──────────────┤
│ CREATE_TIME │ NAME │ PROJECT_NUMBER │ ProjectID │ Parent │
├──────────────────────────┼──────────────┼────────────────┼──────────────────────┼──────────────┤
│ 2016-04-28T22:33:12.274Z │ scesproject1 │ 222844913538 │ windy-bearing-129522 │ 297814986428 │
│ 2016-05-11T03:08:13.359Z │ scesproject2 │ 346904393285 │ canvas-syntax-130823 │ 297814986428 │
└──────────────────────────┴──────────────┴────────────────┴──────────────────────┴──────────────┘
ヒント : --format='flattened' フラグを使用すれば、プロパティから JSON Path と値を抽出できます。
ボックスが不要で、日時の部分を年 - 月 - 日の形式でシンプルに表示する罫線なしの表を作りたい場合は、次のようにします。
4. gcloud projects list --format="table(createTime.date('%Y-%m-%d'),name,projectNumber,projectId)"
CREATE_TIME NAME PROJECT_NUMBER PROJECT_ID
2016-05-11 scesproject2 346904393285 canvas-syntax-130823
2016-04-28 scesproject1 222844913538 windy-bearing-129522
もう少し複雑な整形を行ってみましょう。Compute Engine ゾーンのリストを作り、JSON 形式で表示します。
5. gcloud compute zones list --format="json"
{
"creationTimestamp": "2014-05-30T18:35:16.514-07:00",
"description": "us-central1-a",
"id": "2000",
"kind": "compute#zone",
"name": "us-central1-a",
"region": "us-central1",
"selfLink": "https://www.googleapis.com/compute/v1/projects/windy-bearing-129522/
zones/us-central1-a",
"status": "UP"
},
selfLink に注目してください。これが、パースしようとしている完全修飾名です。この場合も、gcloud は JSON 値を選択してそれを抽出し、パースする関数を提供して作業を助けてくれます。
selfLink.scope() 関数を使用することで、selfLink の URL セグメントの最後の部分を取り出してみましょう。
6. gcloud compute zones list --format="value(selfLink.scope())"
us-central1-a
この値は、.basename() 関数でも抽出できます。
7. gcloud compute zones list --format="value(selfLink.basename())"
us-central1-a
selfLink の /projects よりも後の部分は、次のようにして抽出します。
8. gcloud compute zones list --format="value(selfLink.scope(projects))"
windy-bearing-129522/zones/us-central1-a
GCP オブジェクトの中には複数の値を持つリソースが含まれていて、それらの値をすべて拾い出して並べなければならないことがよくあります。たとえば、特定の Compute Engine インスタンス向けに有効にされているすべてのスコープのリストを作ってみましょう。
9. gcloud compute instances list --format="json"
"serviceAccounts": [
{
"email": "1071284184436-compute@developer.gserviceaccount.com",
"scopes": [
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring.write",
"https://www.googleapis.com/auth/cloud.useraccounts.readonly"
]
}
],
複数の値を持つリソースを 1 つにまとめます。
10. gcloud compute instances list --format="flattened(name,serviceAccounts[].email,serviceAccounts[].scopes[].basename())"
name: instance-1
serviceAccounts[0].email: 1071284184436-compute@developer.gserviceaccount.com
serviceAccounts[0].scopes[0]: devstorage.read_only
serviceAccounts[0].scopes[1]: logging.write
serviceAccounts[0].scopes[2]: monitoring.write
serviceAccounts[0].scopes[3]: cloud.useraccounts.readonly
複数の値を持つリソースには、値ごとに別々の行を与えるような表示方法もあります。
11. gcloud compute instances list --filter=name:instance-1 --flatten="serviceAccounts[].scopes[]" --format="csv(name,id,serviceAccounts.email,serviceAccounts.scopes.basename())"
name,id,email,scopes
instance-1,763097360168409044,1071284184436-compute@developer.gserviceaccount.com,
devstorage.read_only
instance-1,763097360168409044,1071284184436-compute@developer.gserviceaccount.com,
logging.write
instance-1,763097360168409044,1071284184436-compute@developer.gserviceaccount.com,
monitoring.write
instance-1,763097360168409044,1071284184436-compute@developer.gserviceaccount.com,
servicecontrol
instance-1,763097360168409044,1071284184436-compute@developer.gserviceaccount.com,
service.management
同じ情報を読みやすく構造化された形式で表示します。
12. gcloud compute instances list --filter=name:instance-1 --format="table[box,no-heading](name,id,serviceAccounts:format='table[box,no-heading](email,scopes:format=\"table[box,no-heading](.)\")')"
┌────────────┬────────────────────┐
│ instance-1 │ 763097360168409044 │
└────────────┴────────────────────┘
┌────────────────────────────────────────────────────┐
│ 1071284184431-compute@developer.gserviceaccount.com│
└────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ https://www.googleapis.com/auth/devstorage.read_only │
│ https://www.googleapis.com/auth/logging.write │
│ https://www.googleapis.com/auth/monitoring.write │
│ https://www.googleapis.com/auth/servicecontrol │
│ https://www.googleapis.com/auth/service.management │
└──────────────────────────────────────────────────────┘
次は、整形における最後のサンプルです。未加工の状態で表示すると以下のようになる情報において、複数の値を持つリソースをパースし、サービス アカウント キーとサービス アカウントを表示します。
13. gcloud beta iam service-accounts keys list --iam-account svc-2-429@mineral-minutia-820.iam.gserviceaccount.com --project mineral-minutia-820 --format="json"
[
{
"name": "projects/mineral-minutia-820/serviceAccounts/svc-2-429@mineral
-minutia-820.iam.gserviceaccount.com/keys/
04bd2d56d0cc5746b125d17f95d4b0dd654accca",
"validAfterTime": "2016-03-11T05:30:04.000Z",
"validBeforeTime": "2026-03-09T05:30:04.000Z"
},
{
"name": "projects/mineral-minutia-820/serviceAccounts/svc-2-
429@mineral-minutia-820.iam.gserviceaccount.com/keys/
1deb44e2f54328fc7bb316e5a87315e3314f114f",
"validAfterTime": "2016-01-02T18:54:26.000Z",
"validBeforeTime": "2025-12-30T18:54:26.000Z"
},
....
]
それでは、.scope() を使って serviceAccount の部分だけを取り出し、最初の '/' で区切られた部分を segment(0) で取り出しましょう。
14. gcloud beta iam service-accounts keys list --iam-account svc-2-429@mineral-minutia-820.iam.gserviceaccount.com --project mineral-minutia-820 --format="table(name.scope(serviceAccounts).segment(0):label='service Account',name.scope(keys):label='keyID',validAfterTime)"
(click to enlarge)
フィルタ
次はフィルタです。フィルタを使えば、整形したいリソースだけを選択して処理できます。
たとえば、リソース(プロジェクト、VM など)にラベルが付いており、そのラベルが特定の値になっているプロジェクトだけを表示したいものとします。次の例は、label.env='test' で label.version=alpha の場合です。
15. gcloud projects list --format="json" --filter="labels.env=test AND labels.version=alpha"
[
{
"createTime": "2016-04-28T22:33:12.274Z",
"labels": {
"env": "test",
"version": "alpha"
},
"lifecycleState": "ACTIVE",
"name": "scesproject1",
"parent": {
"id": "297814986428",
"type": "organization"
},
"projectId": "windy-bearing-129522",
"projectNumber": "222844913538"
}
]
キーに変換を加えることも可能です。次の例では、createTime キーを日付だけに変換したうえでフィルタを適用しています。
16. gcloud projects list --format="table(projectNumber,projectId,createTime)" --filter="createTime.date('%Y-%m-%d', Z)='2016-05-11'"
PROJECT_NUMBER PROJECT_ID CREATE_TIME
346904393285 canvas-syntax-130823 2016-05-11T03:08:13.359Z
上で選択されているフィルタは、実際に JSON 構造(labels.env=test )を参照していることに注意してください。もちろん、フィルタはさまざまに組み合わせて使うことが可能です。
変換
変換を使えば、表示される値を直接操作できます。これまでに挙げたいくつかの例(.scope() 、.basename() 、.segment() など)でも、すでに使用しています。変換で面白いのは、.map() で結合、チェインできることと、複数の値を持つデータに適用できることです。
次の例をご覧ください。parent.id キーがあれば “YES”、なければ “NO” を出力するように条件に基づいて変換しています。このようにすれば、プロジェクトが特定の基準を満たしているかどうか(この場合は、Organization Node の一部かどうか)をすばやく見分けることができます。
17. gcloud projects list --format="table(projectId,parent.id.yesno(yes="YES", no=”NO”):label='Has Parent':sort=2)"
PROJECT_ID Has Parent
mineral-minutia-820 NO
fabled-ray-104117 YES
rk-test-0506 YES
user2proj1 YES
user2project2 YES
18. gcloud compute instances list --format="flattened(name,serviceAccounts[].email,serviceAccounts[].scopes.map().scope())"
name: instance-1
serviceAccounts[0].email: 1071284184436-compute@developer.gserviceaccount.com
serviceAccounts[0].scopes[0]: devstorage.read_only
serviceAccounts[0].scopes[1]: logging.write
serviceAccounts[0].scopes[2]: monitoring.write
serviceAccounts[0].scopes[3]: cloud.useraccounts.readonly
スクリプト
最後に、gcloud コマンドを結合し、埋め込まれている情報を簡単に抽出するスクリプトを作ってみましょう。
次の例では、すべてのプロジェクトに含まれるサービス アカウントのすべてのキーのリストを表示します。そのためには、最初にすべてのプロジェクトを反復処理し、次にプロジェクトごとにすべてのサービス アカウントを取り出し、最後にサービス アカウントごとに作られたすべてのキーのリストを作らなければなりません。これは、基本的には反復処理のためのループをネストした形になります。
bash スクリプトでは次のようになります。
#!/bin/bash
for project in $(gcloud projects list --format="value(projectId)")
do
echo "ProjectId: $project"
for robot in $(gcloud beta iam service-accounts list --project $project --format="value(email)")
do
echo " -> Robot $robot"
for key in $(gcloud beta iam service-accounts keys list --iam-account $robot --project $project --format="value(name.basename())")
do
echo " $key"
done
done
done
Windows PowerShell では次のようになります。
foreach ($project in gcloud projects list --format="value(projectId)")
{
Write-Host "ProjectId: $project"
foreach ($robot in gcloud beta iam service-accounts list --project $project --format="value(email)")
{
Write-Host " -> Robot $robot"
foreach ($key in gcloud beta iam service-accounts keys list --iam-account $robot --project $project --format="value(name.basename())")
{
Write-Host " $key"
}
}
}
レスポンス フィールドをパースして配列にまとめてから処理しなければならないこともよくあります。次の例では、インスタンスのサービス アカウント情報をパースして配列にまとめ、操作しやすくしています。
この例の場合、CSV の serviceAccounts[].scope フィールドは複数の値を持ち、個々の値はセミコロンで句切られている(separator=;)ことに注意してください。つまり、下の gcloud コマンドのレスポンス行は、name,id,email,scope_1;scope_2;scope_3 という形式になっています。このスクリプトは、基本的に例 12 のレスポンスをパースしています。
#!/bin/bash
for scopesInfo in $(
gcloud compute instances list --filter=name:instance-1 \
--format="csv[no-heading](name,id,serviceAccounts[].email.list(),
serviceAccounts[].scopes[].map().list(separator=;))")
do
IFS=',' read -r -a scopesInfoArray<<< "$scopesInfo"
NAME="${scopesInfoArray[0]}"
ID="${scopesInfoArray[1]}"
EMAIL="${scopesInfoArray[2]}"
SCOPES_LIST="${scopesInfoArray[3]}"
echo "NAME: $NAME, ID: $ID, EMAIL: $EMAIL"
echo ""
IFS=';' read -r -a scopeListArray<<< "$SCOPES_LIST"
for SCOPE in "${scopeListArray[@]}"
do
echo " SCOPE: $SCOPE"
done
done
以上で、gcloud コマンドの出力を効果的にフィルタおよび整形する方法がおわかりいただけたと思います。これらのテクニックは、gcloud のすべてのレスポンスに応用できます。未加工のレスポンスを見て、どのように加工したいかを考え、そのように整形するだけです。