REST APIでOACスナップショットを作成する方法

このシリーズの他の記事は、[オラクル・クラウドの個人ブログ一覧 ](https://qiita.com/letian/items/10152a4fec813c1b7d98)からご覧いただけます。

# 初めに
Oracle Analytics Cloud (OAC)のスナップショットを作成するには、コンソールだけでなく、REST APIを使用することも可能です。日常のバックアップをスクリプト化したい場合、この方法が適しています。

この例では、プライベート・タイプのOACインスタンスをサービスGW経由でオブジェクト・ストレージにスナップショットを作成する方法を紹介します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/bd333adb-ef48-6c16-438c-11b6f1a763e5.png", width="400">


__目次__
- [1. 事前準備](#1-事前準備)
  - [1-1. 認証情報の取得](#1-1-認証情報の取得)
  - [1-2. JSONファイルの作成](#1-2-jsonファイルの作成)
  - [1-3. トークンの発行](#1-3-トークンの発行)
    - [方法-1. コンソールからダウンロード](#方法-1-コンソールからダウンロード)
    - [方法-2. CURLコマンドで取得](#方法-2-curlコマンドで取得)
- [2. スナップショットの作成](#2-スナップショットの作成)
- [3. 進捗状況の確認](#3-進捗状況の確認)
- [トラブルシューティング](#トラブルシューティング)

# 1. 事前準備
この例では、REST APIを実行するクライアントは、OACインスタンスと同じサブネット内にあるComputeインスタンスです。ネットワークリソース（ルート表、NSG、サービスGW）の設定に関する詳細な説明は省略します。

## 1-1. 認証情報の取得
OACスナップショットはOCIオブジェクト・ストレージに保存されます。OACインスタンスがオブジェクト・ストレージにアクセスするためには、以下の認証情報を提供する必要があります。

テナンシOCID、ユーザーOCID、リージョンID、API秘密キー、APIキーのフィンガープリント

これらの情報は、<strong>OCI-CLIの構成ファイル</strong>の構成ファイルに含まれています。構成ファイルがすでにある場合は、そこから取得してください。まだお持ちでない方は、以下の方法で認証情報を取得してください。

アイデンティティ → 自分のプロファイル → APIキー → APIキーの追加

秘密キーをダウンロードし、追加ボタンを押す。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/d56bcb32-2e59-6f5b-e70a-5adad9b34453.png", width="500">

コピーを押し、構成ファイルの中身をメモしてください。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/5f95b7db-ca7a-93c8-6769-4d17a240c358.png", width="500">

## 1-2. JSONファイルの作成
次のようにJSONファイルを作成します。
__new_snapshot.json__
```json
{
    "type": "CREATE",
    "name": "myfirstsnapshot",
    "storage": {
        "type": "OCI_NATIVE",
        "bucket": "OAC_Snapshot",
        "auth": {
            "type": "OSS_AUTH_OCI_USER_ID",
            "ociRegion": "ap-tokyo-1",
            "ociTenancyId": "<Tenancy_OCID>",
            "ociUserId": "<User_OCID>",
            "ociKeyFingerprint": "<your_fingerprint>",
            "ociPrivateKeyWrapped": "<cat myprivate_key.pem | base64 -w 0>"
        }
    },
    "bar": {
        "uri": "file:///myfirstsnapshot.bar",
        "password": "<to_give_your_snapshot_a_password>"
    }
}
```

| 項目 | 値 |コメント|
|:-|:-|:--|
|name|スナップショット名|例：myfirstsnapshot|
|bucket|格納先のバケット名|例：OAC_Snapshot|
|ociRegion|リージョン識別子|例：ap-tokyo-1|
|ociTenancyId|テナントOCID|[STEP 1-1](#1-1-認証情報の取得)で取得|
|ociUserId|ユーザーOCID|[STEP 1-1](#1-1-認証情報の取得)で取得|
|ociKeyFingerprint|秘密キーのフィンガープリント|[STEP 1-1](#1-1-認証情報の取得)で取得|
|ociPrivateKeyWrapped|暗号化された秘密キー|※１|
|uri|スナップショットのURI|※２|
|password|スナップショットのパスワード|※３|

※１、次のコマンドでAPI秘密キーをエンコードします。
Linuxの場合: `cat myprivate-key.pem | base64 -w 0 > mywrapped-private-key.pem`
Macの場合: `cat myprivate-key.pem | base64 -o mywrapped-private-key.pem`

※２、この例では、バケットの直下にオブジェクトを作成するため、フォルダは使用しません。フォルダを使用したい場合は、次のように記述してください。
`file:///myfolder/myfirstsnapshot.bar`

※３、スナップショットにパスワードを指定する際は、以下の条件を満たしていることを確認してください：
- 14文字以上50文字以下であること
- 少なくとも1つの数字（0-9）を含むこと
- 少なくとも1つの大文字（A-Z）を含むこと
- 少なくとも1つの小文字（a-z）を含むこと
- 少なくとも1つの特殊文字を含むこと、使用可能な特殊文字は次のとおりです：
!#$%&'()+,-./:;<=>?@[]^_`{|}~*

## 1-3. トークンの発行
スナップショットを作成するには、トークンを発行する必要があります。次の2つの方法のいずれかを使用できます。

### 方法-1. コンソールからダウンロード
アナリティクス・インスタンス → インスタンスの詳細 → 追加詳細

「<strong>アプリケーション</strong>」のリンクをクリックして、アプリの詳細画面に移動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/128562b9-88a5-0cd2-48ff-9adfb84d7611.png)

「アクセス・トークン」を選択し、「トークンのダウンロード」を押してダウンロードします。（デフォルトのファイル名は、<strong>tokens.tok</strong>です。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/b97bff69-604e-cae4-f1b1-b7e8dd0b15c0.png)

ファイルの中身：
```
{"access_token":"<トークン_中略>","token_type":"Bearer","expires_in":100}
```
※、有効時間は<strong>100秒</strong>です。

### 方法-2. CURLコマンドで取得
スナップショットの作成をスクリプトで自動化したい場合、この方法がおすすめです。トークンを発行するには、以下の情報を取得しておいてください。

- [ドメインURL](#ドメインurl)
- [スコープ文字列](#スコープ文字列)
- [「クライアントID」と「クライアント・シークレット」](#クライアントidとクライアントシークレット)

#### ドメインURL
「追加詳細」のタブから取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/35008cd1-2e7a-3057-1890-21f53fbab76a.png)
例：`https://<IDCS_instance>.identity.oraclecloud.com`

#### スコープ文字列
上記画面で「<strong>アプリケーション</strong>」のリンクをクリックし、アプリの詳細画面に移動します。

「OAuth 構成」タブ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/5ea131f4-68e3-8bf6-d62e-ee9d4071a62d.png)

スコープ文字列の構成: 「<strong>プライマリ・オーディエンス</strong>」と 「<strong>スコープ</strong>」を結合する 
例: `https://<string>.analytics.ocp.oraclecloud.comurn:opc:resource:consumer::all`

#### 「クライアントID」と「クライアント・シークレット」
スコープ文字列と同じ画面から取得します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/c69b5d0b-3642-c776-5aaa-640b7e723744.png", width="350">

取得後、次のコマンドでエンコードしてください。
`echo -n client_id:client_secret | base64 -w 0`

#### トークンを発行するコマンド
```bash
curl --request POST --url https://<IDCS_instance>.identity.oraclecloud.com/oauth2/v1/token  \
--header 'authorization: Basic <echo -n client_id:client_secret | base64 -w 0>' \
--header 'content-type: application/x-www-form-urlencoded;charset=UTF-8' \
-d 'grant_type=password&username=<username>&password=<password>&scope=<scope>'
```

| 項目 | 値 |例|
|:-|:-|:-|
|IDCS_instance|ドメインURL|`https://<IDCS_instance>.identity.oraclecloud.com`|
|暗号化されたClient IDとClient Secret||`echo -n client_id:client_secret \| base64 -w 0`|
|username|OCI ユーザー名||
|password|OCI ユーザーのパスワード|
|scope|スコープ文字列|`https://xxxxxxx.analytics.ocp.oraclecloud.comurn:opc:resource:consumer::all`|

コマンドの出力結果：
```
{"access_token":"<トークン_中略>","token_type":"Bearer","expires_in":100}
```

# 2. スナップショットの作成
:::note
トークンはOACインスタンスが停止している場合でも発行できますが、スナップショットを作成するためには、インスタンスが<strong>アクティブ</strong>な状態である必要があります。
:::

```
curl -i --header "Authorization: Bearer ${access_token}" \
        --request POST https://${hostname}/api/20210901/snapshots \
        -d @new_snapshot.json
```
| 項目 | 値 |コメント|
|:-|:-|:-|
|access_token|トークン|[STEP 1-3](#1-3-トークンの発行)で取得|
|hostname|インスタンスのホスト名|OACの「追加詳細」から取得できる。例：`<host_string>.analytics.ocp.oraclecloud.com`<br>|
|new_snapshot.json|| [STEP 1-2](#1-2-jsonファイルの作成)で作成したファイル|

CURLコマンドの出力は、次のようです。
```
HTTP/1.1 202 Accepted
Date: <中略>
Content-Type: application/json; charset=utf-8
Content-Length: 35
Connection: keep-alive
X-ORACLE-DMS-ECID: 57a67cf4-ebbb-4ec7-8079-ae77795c2ddc-00002a86
ETag: W/"23-d9x1y9Mzt6zwWxjB98QRA9W8qp8"
oa-work-request-id: lfc-cj:7-ch:203
X-ORACLE-DMS-RID: 0
Strict-Transport-Security: max-age=31536000;
vary: X-Forwarded-Proto,origin

{"workRequestId":"lfc-cj:7-ch:203"}
```
最終行の「<strong>workRequestId</strong>」をメモしてください。

# 3. 進捗状況の確認
上記ステップの出力に作業リクエストIDが返されます。そのIDを使用して進捗状況を確認します。トークンの有効時間（100秒）が過ぎる場合、再発行してください。
```
curl -i --header "Authorization: Bearer ${access_token}" \
     --request GET https://${hostname}/api/20210901/workRequests/${work_request_id}
```

- ${work_request_id} -- 実際の作業リクエストIDで置き換える。

※、進捗状況（status）は、３つ種類があります（"IN_PROGRESS","SUCCEEDED", "FAILED"）。

:::note info
成功した場合、作業リクエストの詳細は次のように表示されます。
HTTP/1.1 200 <strong>OK</strong>
<中略>
{"id":"lfc-cj:7-ch:203","operationType":"CREATE_SNAPSHOT","percentComplete":100,"status":"<strong>SUCCEEDED</strong>","timeAccepted":"<中略>","timeStarted":"<中略>","timeFinished":"<中略>","resources":[{"resourceType":"SNAPSHOT","id":"<中略>","actionResult":"<strong>CREATED</strong>"}]}
:::

OCIコンソールから作成されたスナップショットを確認します:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/fc65c674-2498-67fc-499d-631bd09fed5d.png)
※、同じファイル名の既存のスナップショットがある場合、そのスナップショットは上書きされます。

# トラブルシューティング
__現象-1__
スナップショットを作成した際に次のエラーが発生しました。  
```
HTTP/1.1 401 Unauthorized
Date: <中略>
Content-Type: text/html
Content-Length: 172
Connection: keep-alive
www-authenticate: Bearer error="invalid_token", error_description="Token Expired"
vary: origin
```
考えられる理由：トークンの有効期限が切れた（100秒）。
対策：トークンを再取得し、有効期限内にもう一度作成してください。

__現象-2__
スナップショットを作成した際に次のエラーが発生しました。  

:::note alert
作業リクエストの確認結果：
{"id":"<中略>","operationType":"CREATE_SNAPSHOT","percentComplete":100,"status":"<strong>FAILED</strong>","timeAccepted":"<中略>","timeStarted":"<中略>","timeFinished":"<中略>","errors":[{"code":"InternalServerError","message":"<strong>Cloud Storage Error</strong>"}]}
:::
考えられる理由：オブジェクトストレージにアクセスするための認証情報が間違っている。
対策：`new_snapshot.json`の内容を確認してください。

以上です。

----
__関連記事__
[オラクル・クラウドの個人シリーズ・ブログ](https://qiita.com/letian/items/10152a4fec813c1b7d98)
[Oracle Analytics Cloud に関するFAQ](https://qiita.com/letian/items/eaca95c40a24c9d2027a)
[CLI/APIでOracle Analytics Cloudインスタンスを作成するために、アクセストークンを生成する方法](https://qiita.com/letian/items/de470f3e5fef1229d663)

----
__OAC ドキュメント__
REST API for Oracle Analytics Cloud - Quick Start: [英語](https://docs.oracle.com/en/cloud/paas/analytics-cloud/acapi/quick-start.html) [日本語機械翻訳](https://docs.oracle.com/cd//E83857_01/paas/analytics-cloud/acapi/quick-start.html)
REST API for Oracle Analytics Cloud - Create a snapshot: [英語](https://docs.oracle.com/en/cloud/paas/analytics-cloud/acapi/op-20210901-snapshots-post.html) [日本語機械翻訳](https://docs.oracle.com/cd//E83857_01/paas/analytics-cloud/acapi/op-20210901-snapshots-post.html)

__OCI CLI コマンド・リファレンス__
[Docs » analytics](https://docs.oracle.com/en-us/iaas/tools/oci-cli/3.45.1/oci_cli_docs/cmdref/analytics.html)