[OCI]Cloud ShellでコンピュートインスタンスのIPアドレスを取得するPythonスクリプト

この記事は、[Writing Python scripts to run from the OCI Console Cloud Shell](https://medium.com/oracledevs/writing-python-scripts-to-run-from-the-oci-console-cloud-shell-a0be1091384c) の内容を実行したものです。

# OCI Cloud Shell
OCI Cloud Shellは、OCI WebコンソールからアクセスできるWebブラウザベースのShellターミナルです。
Cloud Shellには次の機能があります。

- 事前認証されたOCI CLI
    - Cloud ShellでCLIの使用を開始するための設定は不要
- Oracle Cloud Infrastructureサービスと相互作用するための主要な開発者ツールとプリインストールされた言語ランタイムを備えた完全なLinuxシェル
    - 各言語のOCI SDKやOracle Instant Client
- ホームディレクトリ用に5 GBのストレージ
    - Cloud Shellセッション間で作業を保存可能
- コンソールの異なるページにナビゲートしたときに、アクティブなままになるコンソールの永続フレーム

# ComputeインスタンスのIPアドレスの取得スクリプト例）

```list_ipaddress.py
#!/usr/bin/env python
 
import oci
 
delegation_token = open('/etc/oci/delegation_token', 'r').read()
signer = oci.auth.signers.InstancePrincipalsDelegationTokenSigner(
  delegation_token=delegation_token
)

search_client = oci.resource_search.ResourceSearchClient({},signer=signer)
compute_client = oci.core.ComputeClient({},signer=signer)
network_client = oci.core.VirtualNetworkClient({},signer=signer)
 
resp = search_client.search_resources(
  oci.resource_search.models.StructuredSearchDetails(
  type="Structured",
  query="query instance resources"
  )
)
 
for instance in resp.data.items:
  resp = compute_client.list_vnic_attachments(
  compartment_id=instance.compartment_id,
  instance_id=instance.identifier
  )
 
  for vnic_attachment in resp.data:
    vnic = network_client.get_vnic(vnic_attachment.vnic_id).data
    print("\t".join([
    instance.display_name,
    vnic.display_name,
    vnic.private_ip,
    vnic.public_ip
    ]))
```

## 実行例

```
$ python ./list_ipaddress.py
fmwf    fmwf    10.0.0.4       150.136.236.XXX
db01    db01    10.0.0.3       150.136.37.XXX
gpu01   gpu01   10.0.0.5       150.136.89.XXX
fn      fn      10.0.0.2        158.101.118.XXX
```

# スクリプトの補足
### singer
Cloud Shell内で実行する Python スクリプトを書く際には、Cloud Shellの既存の認証を利用することで、
スクリプトを実行する際に必要となる個別の API キー設定を省くことができます。
既存のインスタンスプリンシパル委任トークンをロードして、signerを生成します。

```
#!/usr/bin/env python
 
import oci
 
delegation_token = open('/etc/oci/delegation_token', 'r').read()
signer = oci.auth.signers.InstancePrincipalsDelegationTokenSigner(
  delegation_token=delegation_token
)
```
### 認証済みクライアントを作成
現在のリージョン内のすべてのインスタンスの検索や
インスタンスの詳細を問い合わせたり、IPアドレスを取得したりする
APIクライアントの定義

```
search_client = oci.resource_search.ResourceSearchClient({},signer=signer)
compute_client = oci.core.ComputeClient({},signer=signer)
network_client = oci.core.VirtualNetworkClient({},signer=signer)
```

### IPアドレスを取得
各インスタンスのすべてのアタッチされたvnicを検索し
各vnicについて、パブリックとプライベートの両方のIPアドレスを取得

```
for instance in resp.data.items:
  resp = compute_client.list_vnic_attachments(
  compartment_id=instance.compartment_id,
  instance_id=instance.identifier
  )
 
  for vnic_attachment in resp.data:
    vnic = network_client.get_vnic(vnic_attachment.vnic_id).data
    print("\t".join([
    instance.display_name,
    vnic.display_name,
    vnic.private_ip,
    vnic.public_ip
    ]))
```

# 参考情報

- [OCI Python-SDK](https://docs.cloud.oracle.com/en-us/iaas/Content/API/SDKDocs/pythonsdk.htm)
- [Cloud Shell](https://docs.cloud.oracle.com/en-us/iaas/Content/API/Concepts/cloudshellintro.htm)
- [Instance Principles — Calling Services from an Instance](https://docs.cloud.oracle.com/en-us/iaas/Content/Identity/Tasks/callingservicesfrominstances.htm#ConfiguringtheSDKCLIorTerraform)