超便利！(Oracle Cloud Infrastructure)OCICLIのラッパーツール [ o ] (オー) の使い方

# １．はじめに

※OCICLIのセットアップ方法は本記事には含みません
※コマンド内の「 \　」は改行です。見栄えを重視していますので、コピペだと正しく動作しない場合があります。


[o] とは、OCICLIのコマンドを簡素化してくれるラッパーツールです。
インストール（とうか配置だけ）すれば、 `oci os ns get` と入力するコマンドを　`o os ns get go` とするだけ。
ociをoに置き換えるだけ。
実行は最後に　`go` をつける。　`go` 付けなかったら実際には実行されずコマンドのテストだけできる。

まずは、そもそも何がどう超便利なの？

## 何が超便利なの？

#### 其の一：COCILI叩く時OCID探すのに疲弊しせんか？　→ 曖昧な記憶だけでCLI実行できます！

- [o] には、OCIDを探す２つの専用コマンドがあります

以下の様に入力すると、GUIの表示名(DisplayName)に合わせたOCIDを探すことができます

```
[root@ol79 ~]# o ocid sub-vcn0
ocid1.subnet.oc1.phx.aaaaaaaabnl4ez4usavsamplasamplasample3b6zdwm5iiq2ckkgktmjbfa
ocid1.subnet.oc1.phx.aaaaaaaacmj2aoihdpjsamplasamplasamplej7uqlycrpgw46mpfmpjwhda
ocid1.subnet.oc1.phx.aaaaaaaa3so4urqvmk4samplasamplasamplep656vcm53jzh57oz6nckr5a
ocid1.subnet.oc1.phx.aaaaaaaaedwatypcxfsamplasamplasampsle4q3pqik7msxgysdyh7nsh4a
ocid1.subnet.oc1.phx.aaaaaaaaxmatnnoiursamplasamplasamplebo5te7llvznlgosnxwgsrynmq
```

以下では、特定のOCIDをあいまい検索しのリソース一覧しています。例では「subnet」が含まれるもの。

```
[root@ol79 ~]# o ocids subnet
ocid1.subnet.oc1.phx.aaaaaaaabnl4ez4samplasamplasampleksx3b6zdwmg5iiq2ckkgktmjbfa nicaregi/sub-vcn0-ad1
ocid1.subnet.oc1.phx.aaaaaaaacmj2aoisamplasamplasamplehbuvj7uqlycrpgw46mpfmpjwhda nicaregi/sub-vcn0-ad2
ocid1.subnet.oc1.phx.aaaaaaaa3so4urqvsamplasamplasamplexfeop66vcm53jzh57oz6nckr5a nicaregi/sub-vcn0-ad3
ocid1.subnet.oc1.phx.aaaaaaaaedwatypcxfof2n3ksamplasamplasampleik7msxgysdyh7nsh4a nicaregi/sub-vcn0-pri1
ocid1.subnet.oc1.phx.aaaaaaaaxmatnnoiusamplasamplasamplesobo57llvznlgosnxwgsrynmq nicaregi/sub-vcn0-pub0
ocid1.subnet.oc1.phx.aaaaaaaalpar2stf2zg2cvwsamplasamplasampleeoggxqidprovlgtqhta nicaregi/sub-vcn1-pri0
ocid1.subnet.oc1.phx.aaaaaaaa5fry5nkd3zubi4ihf7aylsamplasamplasamejuk76ein3xxm3fq nicaregi/sub1
ocid1.subnet.oc1.phx.aaaaaaaalaw57myemay72ndg5l2g7zmemj6samplasamplasampleef2niga nicaregi/sub2_pub
```

- でもそもそも、コマンドを実行する際も OCIDが不要です！　やってみましょう。(それぞれの意味について後述します）
以下、サブネットをリストしています
通常のOCICLIでは以下の様に入力すると思います。

```
# oci network subnet list　\ 
   -c ocid1.tenancy.oc1..aaaaaaaaqhcdnsrd2samplasamplasampleutzzxzt2zcrisucg7pzhq
```


「o」を使うとOCID入力する必要はありません！
内部的に先程のocid で引っ張ってきてくれています。
そして、きちんと OCICLI　で実際に流れるコマンドもに変換されて実行しているので、安心！


```
# o network subnet list -c nicaregi go 

oci network subnet list\ 
   --compartment-id ocid1.tenancy.oc1..aaaaaaaaqhcdnsrd2samplasamplasampleutzzxzt2zcrisucg7pzhq  

display-name  subnet-domain-name             cidr-block    prohi lifecycle a time-created     compartment       id  
sub2_pub      sub2pub.vcnv6.oraclevcn.com    177.17.1.0/24 False AVAILABLE N 2021-04-15T00:34 nicaregi    zef2niga 
sub1          sub1.vcnv6.oraclevcn.com       177.17.0.0/24 True  AVAILABLE N 2021-04-15T00:34 nicaregi    n3xxm3fq 
sub-vcn1-pri0 subprd2.vcnprd2.oraclevcn.com  10.1.0.0/24   True  AVAILABLE N 2021-01-25T05:29 nicaregi    vlgtqhta 
sub-vcn0-ad3  sub3.vcnprd.oraclevcn.com      10.0.13.0/24  True  AVAILABLE 3 2020-11-14T13:47 nicaregi    z6nckr5a 
sub-vcn0-ad2  ad2.vcnprd.oraclevcn.com       10.0.12.0/24  True  AVAILABLE 2 2020-11-14T13:47 nicaregi    fmpjwhda 
sub-vcn0-ad1  ad1.vcnprd.oraclevcn.com       10.0.11.0/24  True  AVAILABLE 1 2020-11-14T13:46 nicaregi    gktmjbfa 
sub-vcn0-pub0 sub11141345350.vcnprd.oraclevc 10.0.0.0/24   False AVAILABLE N 2020-11-14T13:45 nicaregi    wgsrynmq 
sub-vcn0-pri1 sub11141345351.vcnprd.oraclevc 10.0.1.0/24   True  AVAILABLE N 2020-11-14T13:45 nicaregi    yh7nsh4a 
```

#### 其の二：コマンド結果のJSON情報量多すぎ、フィルタのJMESPath構文難しい、、→ 出力形式をCSVやテーブルなど、簡単に変更でき、フィルタできる！

- 先程の例のように「o」ではデフォルトでテーブル出力されます。OCICLIはデフォルトJSON形式です。
- OCICLIでは単にテーブル表示にすると全項目が出てくるので JMESPath構文を使ってフィルタしないと見栄えが悪くなります。
- 例えば、以下、FastConnectプロバイダの一覧を出力し、仮想回線がL2かL3かをリストしています（GUIでは確認できない内容）

```
[root@ol79 ~]# oci network fast-connect-provider-service list\
--compartment-id ocid1.tenancy.oc1..aaaaaaaaqhcdnsrsamplesamplesampleklutzzxzt2zcrisucg7pzhq\
--region ap-osaka-1\
--output table\
--query 'data[].["provider-name","private-peering-bgp-management","type","supported-virtual-circuit-types"]'

+----------------------+------------------+---------+-----------------------+
| Column1              | Column2          | Column3 | Column4               |
+----------------------+------------------+---------+-----------------------+
| SINET5               | CUSTOMER_MANAGED | LAYER2  | ['PRIVATE', 'PUBLIC'] |
| IIJ                  | PROVIDER_MANAGED | LAYER3  | ['PRIVATE', 'PUBLIC'] |
| Megaport             | CUSTOMER_MANAGED | LAYER2  | ['PRIVATE', 'PUBLIC'] |
| Tokai Communications | CUSTOMER_MANAGED | LAYER2  | ['PRIVATE', 'PUBLIC'] |
| NTT Communications   | PROVIDER_MANAGED | LAYER3  | ['PRIVATE', 'PUBLIC'] |
| NTT Communications   | PROVIDER_MANAGED | LAYER3  | ['PRIVATE', 'PUBLIC'] |
| Equinix              | CUSTOMER_MANAGED | LAYER2  | ['PRIVATE', 'PUBLIC'] |
| Colt                 | CUSTOMER_MANAGED | LAYER2  | ['PRIVATE', 'PUBLIC'] |
| NTT Communications   | CUSTOMER_MANAGED | LAYER2  | ['PRIVATE', 'PUBLIC'] |
| AT TOKYO             | CUSTOMER_MANAGED | LAYER2  | ['PRIVATE', 'PUBLIC'] |
+----------------------+------------------+---------+-----------------------+
```

- 「o」では表型式のカスタマイズは 引数「-o」で制御します（コマンド使い方は後述）
- 後述もしますが、[#] で区切るとテーブル形式、[/] はテキスト形式　[,]はCSV　
- [-o json] とすればOCICLIと同じ、JSON形式での出力となります


```
[root@ol79 ~]# o -o provider-name#public-peering-bgp-management#type#supported-virtual-circuit-types \
network fast-connect-provider-service list -c nicaregi --region ap-osaka-1 go

oci network fast-connect-provider-service list\
   --compartment-id ocid1.tenancy.oc1..aaaaaaaaqhcdnsrsamplesamplesampleklutzzxzt2zcrisucg7pzhq \
   --region ap-osaka-1 

provider-name        public-peering-bgp-management type   supported-virtual-circuit-types 
SINET5               ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
IIJ                  PROVIDER_MANAGED              LAYER3 PRIVATE, PUBLIC
Megaport             ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
Tokai Communications ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
NTT Communications   ORACLE_MANAGED                LAYER3 PRIVATE, PUBLIC
NTT Communications   ORACLE_MANAGED                LAYER3 PRIVATE, PUBLIC
Equinix              ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
Colt                 ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
NTT Communications   ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
AT TOKYO             ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
```

#### 其の三：次のコマンド何だったけ？ → 順序関係無しで曖昧入力で該当コマンドを一覧！

- OCICLIはコマンド補完有効化できますが、なんかもっさりしていて遅いです。「o」なら高速！
- 「どんなコンピュートがあるかリストしたいなー」 と思ったときは　`compute instance list` 　と入力するのが正しいのですが、以下の様にまちがえてもコマンドをリストしてくれます。

```
[root@ol79 ~]# o compute list
Possible commands:
    compute-management cluster-network list-instances
    compute-management instance-pool list-instances
    compute-management instance-configuration list
    compute-management cluster-network list
    compute-management instance-pool list
    compute global-image-capability-schema-version list
    compute capacity-reservation instance-shape list
    compute dedicated-vm-host instance-shape list
    compute image-shape-compatibility-entry list
    compute global-image-capability-schema list
    compute capacity-reservation instance list
    compute dedicated-vm-host host-shape list
    compute instance-console-connection list
    compute dedicated-vm-host-instance list
    compute image-capability-schema list
    compute boot-volume-attachment list
    compute capacity-reservation list
    compute dedicated-vm-host list
    compute volume-attachment list
    compute pic subscription list
    compute console-history list
    compute device list-instance
    compute vnic-attachment list
    compute instance list-vnics
    compute pic listing list
    compute pic version list
    compute pic listing get
    compute instance list
    compute image list
    compute shape list
use: o <command> for options
```

- 正しいコマンドを入力すると、他に該当するコマンドと、目的のコマンドのオプションまで表示してくれます。

```
root@ol79 ~]# o compute instance list
Possible matches:
    compute-management instance-pool list-instances
    compute-management instance-configuration list
    compute-management instance-pool list
    compute capacity-reservation instance-shape list
    compute dedicated-vm-host instance-shape list
    compute capacity-reservation instance list
    compute instance-console-connection list
    compute instance list-vnics

Best match:
oci compute instance list
    requires    --compartment-id [text]
    optional    --all
                --availability-domain [text]
                --capacity-reservation-id [text]
                --display-name [text]
                --from-json [text]
                --lifecycle-state [CREATING_IMAGE|MOVING|PROVISIONING|RUNNING|STARTING|STOPPED|STOPPING|TERMINATED|TERMINATING]
                --limit [integer]
                --page [text]
                --page-size [integer]
                --sort-by [DISPLAYNAME|TIMECREATED]
                --sort-order [ASC|DESC]
```


#### 其の四：日時指定する時の時刻入力が面倒、、　→ now　とか使えます！

- 例えば以下はOCICLIで 日本時間(JST)の2021年11月18日00:00～23:59 のロードバランサのBytesReceivedをモニタリングから取得しています。
- OCICLIでは「今日1日」という指定はできず、日時での指定が必要になります。

```
oci monitoring metric-data summarize-metrics-data \
--namespace oci_lbaas --query-text "BytesReceived[1m]{resourceId = "ocid1.loadbalancer.oc1.phx.aaaaaaaaho2gcxc7rzr56vq4q6iuxdn3tctqhusgdhj5bccpyn6h26xhf5ba"}.mean()" \
--start-time "2021-11-18T00:00:00+09:00" \ 
--end-time "2021-11-18T23:59:59+09:00" \
--query 'data[]."aggregated-datapoints"'

・
・
・
    },
    {
      "timestamp": "2021-11-18T12:49:00+00:00",
      "value": 4596.0
    },
    {
      "timestamp": "2021-11-18T12:50:00+00:00",
      "value": 4569.0
    },
    {
      "timestamp": "2021-11-18T12:51:00+00:00",
      "value": 4540.0
    },
・
・
・
```

- 「o」を使つと 今日を todayで表現できます。※ただし、UTC時間になるので、JST指定のやり方は模索中・・
- 　先程の様に今日１日を表現する場合は、　`--start-time today` （当日の始まり 00:00) ~ `--end-time today+24h` （翌日の00:00)　とできます。
- （他の日付入力方法は後述）

```
[root@ol79 ~]# o -o json -o aggregated-datapoints\
monitoring metric-data summarize-metrics-data \
--namespace oci_lbaas --query-text "BytesReceived[1m]{resourceId = "ocid1.loadbalancer.oc1.phx.aaaaaaaaho2gcxc7rzr56vq4q6iuxdn3tctqhusgdhj5bccpyn6h26xhf5ba"}.mean()"\
--start-time today\
--end-time today+24h

oci monitoring metric-data summarize-metrics-data
    requires    --compartment-id [text]
                --namespace [text]
                --query-text [text]
    optional    --compartment-id-in-subtree [boolean]
                --end-time [datetime]
                --from-json [text]
                --resolution [text]
                --resource-group [text]
                --start-time [datetime]

oci monitoring metric-data summarize-metrics-data\
   --namespace oci_lbaas \
   --query-text 'BytesReceived[1m]{resourceId = ocid1.loadbalancer.oc1.phx.aaaaaaaaho2gcxc7rzr56vq4q6iuxdn3tctqhusgdhj5bccpyn6h26xhf5ba}.mean()' \
   --start-time 2021-11-18 \
   --end-time 2021-11-18T14:10:54Z 

・
・
・
          "value": 4596.0
        },
        {
          "timestamp": "2021-11-18T14:01:00+00:00",
          "value": 4596.0
        },
        {
          "timestamp": "2021-11-18T14:02:00+00:00",
          "value": 4596.0
        },
        {
          "timestamp": "2021-11-18T14:03:00+00:00",
          "value": 4596.0
        },
        {
          "timestamp": "2021-11-18T14:04:00+00:00",
          "value": 4603.0
・
・
・
```




# ２．[o]のセットアップ

### ①インストール

- 前提条件
    - OCICLIはセットアップ済み （※2022/10/24追記：yumからはインストールしたOCICLIでは、oの更新が非常ー－に遅いので、手動インストール（といっても、1行流すだけ）を推奨※）
    - 環境はOracle Linux on Virtual Box です
    - OCICLIはバージョン 2.25.0 以上

- バージョン確認

```
[root@ol79 ~]# oci -v
3.3.1
```


- まずは鉄板ですが、CLIが通る事を確認するコマンド。テナンシのネームスペースが引っ張れるかどうか。

```
[root@ol79 ~]# oci os ns get
{
  "data": "axpsample3"
}
```

- ociコマンドの配置先を確認

```
[root@ol79 ~]# which oci
/root/bin/oci
```

- 以下を実行　（そのままコピペ）

```
o_src=https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/examples/project_o/o
where=$(which oci) && wget -q $o_src -O ${where%ci} && chmod a+x ${where%ci}
```

- [o]がociコマンドと同じディレクトリに配置される

```
[root@ol79 ~]# which o
/root/bin/o
```

### ②初期セットアップ

- 最初 o を実行すると以下が表示されます。
- 続いて　`o oci_commands` を実行します。$HOME/.oci/oci_commands　ディレクトリに現行OCICLIバージョンに基づくコマンドをダウンロードして格納しています 

```
[root@ol79 ~]# o
No /root/.oci/oci_commands file.
Create it with:

    o oci_commands

It takes about two minutes.


[root@ol79 ~]#o oci_commands　　<--1,2分かかるかも？
・
・
・
・
   oci lb backend-set update
    oci lb backend-set-health get
    oci lb certificate create
    oci lb certificate de
```


- 完成！ 以上で、最初に述べた超便利を体感できます。


# ３．コマンドリファレンス

大元のサイトはこちら。こちらの通りだと実行できない部分も補足しています。
https://github.com/oracle/oci-cli/tree/master/scripts/examples/project_o


#### `o ocid <OCIのリソースのDisplayName>`：対象リソースのOCIDを表示

Compute のOCIDを確認

```
[root@ol79 ~]# o ocid ol79
ocid1.instance.oc1.phx.anyhqljtvun44mycsamplesamplesamplelm57fvrzk2pry3t3rcq 
```

#### `o ocids <OCIDに含まれる名称>`：OCIDをあいまい検索

Computeインスタンスを一覧

```
[root@ol79 ~]# o ocids instance
ocid1.instance.oc1.phx.anyhqljtvun44mymscpiyakwqnmxxcxasmplesamples2kl4acl32gg25jq        nicaregi/ocidev
ocid1.instance.oc1.phx.anyhqljtvun44myc5mf4yeqlrsmplesamplesplesampleszk2pry3t3rcq       nicaregi/ol79
ocid1.instanceagentcommand.oc1.phx.amaaaaaavun44mya4dmplesampuim5dkceowvmh5nkzz26thyjjia nicaregi/agent-command-20211025-2319
```

#### 基本コマンド  `o -o <出力> <OCIコマンド>` ：出力型式の指定、変換

-  -o <出力>: 出力するキーを指定。この時、JSONでよくある「-」ハイフンが含む値もそのままでOK
-  また、一部文字列でキーを引っ掛けることができる
-  ※ただし、 Data[ Key1 { Key2:Value,Key3:Value } ] のような場合、`-o`ではトップレベルのKey1しか引っ張ることができません。2階層目以降のKeyおよびValueのみを出力したい場合は、OCIコマンドでJMPath構文を用いるか、Linuxコマンドでパイプでつなげます
    - テーブル表示： `-o display#lifecycle` または `-o 'display|lifecycle'`　
    - テキスト出力： `-o display/lifecycle` 1行に1つのフィールドを表示
    - csv型式出力： `-o display,lifecycle` カンマで区切る
    - JSON出力： `-o json` フィルタリングされていないJSONですべての属性を表示

    - 長い値を切り捨てるためのカスタム（pythonic）文字列フォーマット
        - -o 'display{:.20}|create{:10.10}|id{:>8.8}' は、次の表が表示されます。
            - display-name の最初の20文字最長の名前に合うサイズの列（最大20文字）。
            - 時間作成 の最初の10文字列は正確に10文字になります
            - idの最後の8文字（OCID）

- 実行する時は最後に「go」を入れる。入れない場合は、テスト実行でコマンドがただしいかどうかを確認できる
- 他はOCICLIと同じ。

- 以下は [-o] オプション使用例（　[o]　のすぐ後に　`-o` いれること）：
 
```
[root@ol79 ~]# o -o provider-name#public-peering-bgp-management#type#supported-virtual-circuit-types network fast-connect-provider-service list -c nicaregi go

oci network fast-connect-provider-service list\
   --compartment-id ocid1.tenancy.oc1..aaaaaaaaqhcdnsrd2asamplesamplev5n6xklutzzxzt2zcrisucg7pzhq

provider-name  public-peering-bgp-management type   supported-virtual-circuit-types
OMCS           ORACLE_MANAGED                LAYER3 PRIVATE, PUBLIC
Telia Carrier  ORACLE_MANAGED                LAYER3 PRIVATE, PUBLIC
Lumen          ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
Verizon        ORACLE_MANAGED                LAYER3 PRIVATE
CoreSite       ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
Zayo           ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
EdgeConneX     ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
C3ntro         ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
Megaport       ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
QTS            ORACLE_MANAGED                LAYER2 None
Digital Realty ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
AT&T           PROVIDER_MANAGED              LAYER3 PRIVATE, PUBLIC
Telia Carrier  ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
Equinix        ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
PacketFabric   ORACLE_MANAGED                LAYER2 PRIVATE, PUBLIC
```



# ４．[o]コマンド運用編

### OCICLIをアップデートした時の対処方法

※OCICLIのアップデート自体には触れていません。

最新のコマンドを実行するためには、OCICLIは頻繁にアップデートしなければいけません。
[o]自体は、アップデート頻度はほぼありませんが、OCICLIのコマンドセットを更新しなければいけません。
OCICLLIアップデート後に以下を実行します。
1~2分かかります。
これで、[o]でも、最新のコマンドに基づいた各種便利機能が利用できるようになります。

```
[root@ol79 ~]#o oci_commands
・
・
・
・
   oci lb backend-set update
    oci lb backend-set-health get
    oci lb certificate create
・
・
```

### OCICLIに複数のプロファイルが存在する場合

$HOME/.oci/config　ファイル内で複数のテナンシ環境が入っていることもあります。
そんな時はテナンシごとの内容や、`o ocid`コマンドなどの検索が有効になるように
[o]側にも情報を連携しなければいけません。

以下を実行します。1～2分ほど。
実行後、「$HOME/.oci/ocids」ファイルに情報が書き込まれます。

```
[root@ol79 ~]# export OCI_CLI_PROFILE=nicaregi　　<--ここで$HOME/.oci/configに登録しているプロファイル名を指定

[root@ol79 ~]# o ocid1.tenancy.oc1..aaaaaaaaqhcdnsrd2asamplesamplexzt2zcrisucg7pzhq <--テナンシOCIDを指定
Setting up your /root/.oci/ocids file:

oci iam compartment get\
   --compartment-id ocid1.tenancy.oc1..aaaaaaaaqhcdnsrd2asamplesamplexzt2zcrisucg7pzhq

name
nicaregi

oci iam availability-domain list\
   --compartment-id ocid1.tenancy.oc1..aaaaaaaaqhcdnsrd2ac7gscd2asamplesamcv5n6d2asamplesamisucg7pzhq

name
MXhJ:PHX-AD-1
MXhJ:PHX-AD-2
MXhJ:PHX-AD-3

oci iam region list
・
・
・
・
```




# ５．参考情報

- o - a smart oci-cli wrapper
    - - https://github.com/oracle/oci-cli/tree/master/scripts/examples/project_o


自分も触りながら確認しているので何か情報があれば提供いただけると幸いです。
質問も賜ります。