ある日の事です
ボス:うちのアカウントの IBM Cloud Classic 環境のサーバー一覧が欲しいな
私:はい、CLI で関連に取れますよ
ボス:じゃあ、お願い!
うん、これでいいはず
VSI 用
ibmcloud sl vs list
表示項目は
id hostname domain cpu memory public_ip private_ip datacenter action
BMS 用
ibmcloud sl hardware list
表示項目は
id hostname domain public_ip private_ip datacenter status
私:出力しました
ボス:うーん、どんな OS で作成者が誰も知りたいな。Excel にしてくれるとうれしいな。
私:は~い('◇')ゞ
それで、この投稿になります。
せっかく、スクリプト化したので、自分のメモもかねて公開します。
なお、稼働確認は Window 11 の wsl ubuntu で行っています。
詳細の取得
上記のやり取りのように「list」で取得できる情報にはOSや作成者情報は含まれていません。
先ほどの「list」コマンドで「id」が分かるので「detail [ID]」を、各々に実行すれば詳細がわかります。
VSI 用
ibmcloud sl vs detail [ID]
BMS 用
ibmcloud sl hardware detail [ID]
あと、JSON で出力すると、つけていない場合の単純な表形式の出力では表示されななかった情報も得られます。
--output JSON
json 形式の出力なので jq と組み合わせて、json の path でピンポイントで欲しい情報が得られます。
id 一覧の取得と利用
こんな感じで、JSON出力から、id のリストを取り出してループを回します。
ids=(`ibmcloud sl vs list --output JSON | jq ".[].id"`)
# id 毎に明細データ処理
for id in "${ids[@]}"; do
# ここで、各サーバーを処理
done
detail の出力は、標準? JSON?
素直に考えれば、JSON です。変なことをしなくても jq のパス指定で必要な値を直接取得できます。
ただ、JSON で取得できる内容を見たら細かすぎてパスを確定させるのが面倒!、今回必要なのは標準の表形式出力にあるので、そこから grep で抜き出せば、その方が楽かなと思ってしまいました。
そして テキスト検索・成型にはまりました。bash のループ、テキスト検索と成型のやり方について、すっかり忘れていました。
でも、今回は、そのまま突き進みました。
なお、VSI の場合の標準の表形出力は下記になります。
user01@6onoda:~$ ibmcloud sl vs detail 123456789
Name Value
ID 123456789
guid XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX
Hostname onoda-tgt
domain onoda.local
fqdn onoda-tgt.onoda.local
status Active
state Running
datacenter tok05
os EL
os version 7.0-64 Minimal for VSI
cpu cores 2
memory 4096
drives type name drive capacity
System Disk 0 25 GB
Swap Disk 1 2 GB
System Disk 2 10 GB
System Disk 7 64 MB
public ip 165.xxx.xxx.xxx
private ip 10.xxx.xxx.xxx
private network false
private cpu false
transient false
created 2022-10-21T00:50:59Z
updated 2023-02-21T07:18:05Z
last transaction Cloud Instance Port Control (2023-02-21T07:18:05Z)
billing Hourly
preset B1_2X4X25
owner xxxxxxx_6onoda@example.com
notes -
tags -
vlans type number id
PRIVATE 858 3047062
PUBLIC 852 3047060
security groups interface id name
public 3879902 onoda-tgt
今回取得したいこと
上記の出力で、下記から始まる行を grep すれは、今回の目的は達成できます。
「os」の後ろにブランクが二つ付いているのは「os version」と区別するためです。
"Hostname"
"public ip"
"private ip"
"os "
"os version"
"datacenter"
"owner"
VSI 用のcsv 出力用スクリプト
完成した VSI 用のスクリプトは下記になります。
items の配列は、出力したい列順に記載してください。上記でも書きましたが、「os」は grep でユニークになる程度にブランクを足す必要がありました。
#!/bin/bash
IFS=$'\n'
# 取得したい項目ヘッダーの配列
# 出力したい列順
items=(
"Hostname"
"public ip"
"private ip"
"os "
"os version"
"datacenter"
"owner"
)
# 項目の数
item_num=${#items[*]}
# id 一覧の取得
ids=(`ibmcloud sl vs list --output JSON | jq ".[].id"`)
# id 毎に明細データ処理
for id in "${ids[@]}"; do
# echo ${id}
detail=(`ibmcloud sl vs detail ${id}`)
# id を保持
result[0]=${id}
# 明細各行毎に項目ヘッダーと突き合わせ
for dline in ${detail[@]} ; do
for (( i=0; i < ${item_num} ; i++)); do
if (echo ${dline} | grep "^${items[i]}" > /dev/null) ; then
temp=`echo ${dline} | grep "^${items[i]}"`
result[i+1]=`echo ${temp} | sed -e "s/^${items[i]}//" | sed 's/^ *\| *$//'`
fi
done
done
# id毎にデータをcvsで出力
for (( i=0; i < ${item_num} ; i++)); do
echo -n '"'${result[i]}'",'
done
echo '"'${result[i]}'"'
done
BMS 用のcsv 出力用スクリプト
BMS 用のcsv 出力用スクリプトは下記になります。
#!/bin/bash
IFS=$'\n'
# 取得したい項目ヘッダーの配列
# 出力したい列順
items=(
"Hostname"
"public ip"
"private ip"
"os "
"os version"
"datacenter"
"owner"
)
# 項目の数
item_num=${#items[*]}
# id 一覧の取得
ids=(`ibmcloud sl hardware list --output JSON | jq ".[].id"`)
# id 毎に明細データ処理
for id in "${ids[@]}"; do
# echo ${id}
detail=(`ibmcloud sl hardware detail ${id}`)
# id を保持
result[0]=${id}
# 明細各行毎に項目ヘッダーと突き合わせ
for dline in ${detail[@]} ; do
for (( i=0; i < ${item_num} ; i++)); do
if (echo ${dline} | grep "^${items[i]}" > /dev/null) ; then
temp=`echo ${dline} | grep "^${items[i]}"`
result[i+1]=`echo ${temp} | sed -e "s/^${items[i]}//" | sed 's/^ *\| *$//'`
fi
done
done
# id毎にデータをcvsで出力
for (( i=0; i < ${item_num} ; i++)); do
echo -n '"'${result[i]}'",'
done
echo '"'${result[i]}'"'
done
VSI と BMS 用が違うのは、対象が「vs」か「hardware」かという点だけです。
ids=(`ibmcloud sl vs list --output JSON | jq ".[].id"`)
...
detail=(`ibmcloud sl vs detail ${id}`)
...
ids=(`ibmcloud sl hardware list --output JSON | jq ".[].id"`)
...
detail=(`ibmcloud sl hardware detail ${id}`)
...
今回のやり方で出来ないこと
行のへッダーがユニークであることを前提にしているので、下記の System drive の情報はうまく取得できません。
drives type name drive capacity
System Disk 0 25 GB
Swap Disk 1 2 GB
System Disk 2 10 GB
System Disk 7 64 MB
また、当然ですが標準の表形出力に表示されない情報は取得できません。