TurbonomicのAPIを叩いてみよう with Python

# はじめに

この記事ではARM（Application Resource Management）製品である、[IBM Turbonomic](https://www.ibm.com/jp-ja/products/turbonomic)にて提供されているREST APIをPythonで叩き、取得したデータをJSONファイルとして保存する方法を記載いたします。

Turbonomic自体にも様々なダッシュボードが用意されていますが、ご自身の手でTurbonomicからデータを取得し利用したいシーンなどがあると思いますので、ご参考程度に読んでいただければと思います。

Turbonomicにはフリートライアルもありますのでこちらの記事もぜひ！

https://qiita.com/YoHey/items/52bd8ec4464dbaa87a5f

# Turbonomic側の準備

はじめにTurbonomicのコンソール画面にて、API実行用のローカルユーザーを作成します。

Turbonomicにログインし、画面左端の **SETTINGS** をクリックします。
Turbonomic Settings画面が表示されたら、**User Management** をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118463/9c708524-87f1-2ff8-c216-483d77de5918.png)

User Management画面が表示されたら、右上の **NEW LOCAL USER** をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118463/91bb866a-b3f9-e038-4e9b-2ac39723dff1.png)

**USERNAME**, **PASSWORD** を入力し、ROLEは今回は **Site Administorator** を選択し、**SAVE USER** をクリックします。

:::note info
ROLEとOPTIONSについては[公式ドキュメント](https://www.ibm.com/docs/ja/tarm/8.10.0?topic=tasks-managing-user-accounts)にて説明があります。
必要に応じて参照し適切なロールを設定してください。
:::
:::note warn
ここで入力したユーザー名・パスワードをPythonでも使うので忘れない様に！
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118463/15caf238-4a63-4ad4-2b7f-4607cf305c7a.png)

これでTurbonomic側の準備は完了です。

# ターミナルで疎通確認

Pythonで書く前に作成したユーザーでデータが取得できることを確認したいと思います。
コマンドの例は[ドキュメントにも記載](https://www.ibm.com/docs/ja/tarm/8.10.2?topic=reference-getting-started-turbonomic-rest-api)があります

ターミナル or コマンドプロンプト を開き各コマンドをご自身の情報に書き換えて実行してみましょう。

## 認証トークンの取得

```cmd:コマンド
curl -s -k -c ① \
-H 'accept: application/json' \
'https://②/api/v3/login?hateoas=true' \
-d 'username=③&password=④'
```
①…cookieの保存場所/名前。例)`/tmp/cookie`
②…TurbonomicのIPアドレスまたはホスト名
③…先ほど作成したローカルユーザーの名前
④…先ほど作成したローカルユーザーのパスワード


下記の様なレスポンスが返ってきたらOKです。

```cmd
{"uuid":"9999999999999","username":"adachi","roles":[{"name":"SITE_ADMIN"}],"loginProvider":"Local","authToken":"XXXXXX","showSharedUserSC":false}%   
```

## データの取得

認証が通ったので、ユーザーのリストを下記コマンドで取得してみます。
①…cookieの保存場所/名前。例)`/tmp/cookie`
②…TurbonomicのIPアドレスまたはホスト名
```cmd
curl -k -X 'GET' -b ① \
'https://②/api/v3/users' \
-H 'accept: application/json' 
```

成功すると下記の様なレスポンスが得られます。(みやすい様に整形してあります。)

```json
[
	{
		"uuid": "9999999999999",
		"displayName": "adachi",
		"username": "adachi",
		"roles": [
			{
				"name": "SITE_ADMIN"
			}
		],
		"loginProvider": "Local",
		"type": "DedicatedCustomer",
		"showSharedUserSC": false
	},
	{
		"uuid": "1111111111111",
		"displayName": "xxxxx",
		"username": "xxxxx",
		"roles": [
			{
				"name": "OPERATIONAL_OBSERVER"
			}
		],
		"loginProvider": "Local",
		"type": "DedicatedCustomer",
		"showSharedUserSC": false
	}
]
```

これでREST API経由でデータが取得できることが確認できました。
ここまででデータが取得できない方は認証情報の見直しや、コマンドが合っているかを確認してください。

# Pythonでデータ取得

step by stepでソースコードを記載していきます。

## ライブラリのインストール

:::note info
環境によってはpipではなくpip3を使用ください。
:::

```cmd
pip install requests
```

## 認証トークン取得コマンドの書き換え

```python
import requests

def login_to_turbonomic(base_url, username, password):
    session = requests.Session()
    url = f"{base_url}/api/v3/login"
    headers = {
        'accept': 'application/json'
    }
    payload = {
        'username': username,
        'password': password
    }    
    params = {
        'hateoas': 'true'
    }

    response = session.post(url, headers=headers, data=payload, params=params, verify=True)
    if response.status_code == 200:
        return session
    else:
        response.raise_for_status()

BASE_URL = "https://Turbonomicのホスト名"

# ログイン処理
session = login_to_turbonomic(BASE_URL, 'ユーザー名', 'パスワード')
```

## ユーザー一覧取得コマンドの書き換え

```diff_python
import requests

def login_to_turbonomic(base_url, username, password):
    session = requests.Session()
    url = f"{base_url}/api/v3/login"
    headers = {
        'accept': 'application/json'
    }
    payload = {
        'username': username,
        'password': password
    }    
    params = {
        'hateoas': 'true'
    }

    response = session.post(url, headers=headers, data=payload, params=params, verify=True)
    if response.status_code == 200:
        return session
    else:
        response.raise_for_status()

+ def get_users(session, base_url):
+     url = f"{base_url}/api/v3/users"
+     headers = {
+         'accept': 'application/json'
+     }
+ 
+     # SSL証明書の検証をスキップする場合は verify=False を引数に追加ください。
+     response = session.get(url, headers=headers)
+     if response.status_code == 200:
+         return response.json()
+     else:
+         response.raise_for_status()

BASE_URL = "https://TurbonomicのIPアドレスまたはホスト名"

# ログイン処理
session = login_to_turbonomic(BASE_URL, 'ユーザー名', 'パスワード')

+ # ユーザー一覧取得
+ users = get_users(session, BASE_URL)
```

## JSONファイルとして保存

```diff_python
import requests
+ import json

def login_to_turbonomic(base_url, username, password):
    session = requests.Session()
    url = f"{base_url}/api/v3/login"
    headers = {
        'accept': 'application/json'
    }
    payload = {
        'username': username,
        'password': password
    }    
    params = {
        'hateoas': 'true'
    }

    response = session.post(url, headers=headers, data=payload, params=params, verify=True)
    if response.status_code == 200:
        return session
    else:
        response.raise_for_status()

def get_users(session, base_url):
    url = f"{base_url}/api/v3/users"
    headers = {
        'accept': 'application/json'
    }

    # SSL証明書の検証をスキップする場合は verify=False を引数に追加ください。
    response = session.get(url, headers=headers)
    if response.status_code == 200:
        return response.json()
    else:
        response.raise_for_status()

+ def json_dump(data, filename):
+     with open(filename + '.json', 'w') as f:
+         json.dump(data, f, indent=4)

BASE_URL = "https://TurbonomicのIPアドレスまたはホスト名"

# ログイン処理
session = login_to_turbonomic(BASE_URL, 'ユーザー名', 'パスワード')

# ユーザー一覧取得
users = get_users(session, BASE_URL)

+ # データをJSONとして保存
+ json_dump(users, 'users')
```

## 完成したソースコード

```python
import requests
import json

def login_to_turbonomic(base_url, username, password):
    session = requests.Session()
    url = f"{base_url}/api/v3/login"
    headers = {
        'accept': 'application/json'
    }
    payload = {
        'username': username,
        'password': password
    }    
    params = {
        'hateoas': 'true'
    }

    response = session.post(url, headers=headers, data=payload, params=params, verify=True)
    if response.status_code == 200:
        return session
    else:
        response.raise_for_status()

def get_users(session, base_url):
    url = f"{base_url}/api/v3/users"
    headers = {
        'accept': 'application/json'
    }

    # SSL証明書の検証をスキップする場合は verify=False を引数に追加ください。
    response = session.get(url, headers=headers)
    if response.status_code == 200:
        return response.json()
    else:
        response.raise_for_status()

def json_dump(data, filename):
    with open(filename + '.json', 'w') as f:
        json.dump(data, f, indent=4)

BASE_URL = "https://TurbonomicのIPアドレスまたはホスト名"

# ログイン処理
session = login_to_turbonomic(BASE_URL, 'ユーザー名', 'パスワード')

# ユーザー一覧取得
users = get_users(session, BASE_URL)

# データをJSONとして保存
json_dump(users, 'users')
```

任意の名前で保存し、実行してみましょう。
.pyと同じフォルダに`users.json`というファイルが生成されていると思います。

中身を確認すると先ほどコマンドで取得したデータと同じものが書き込まれているのではないでしょうか。

# 最後に

これでPythonを使って、Turbonomicからデータを取得することができました。
今回は取得結果をそのままJSONファイルとして保存しましたが、もちろん保存前に加工をしたりすることもできます。
本ソースコードを改修する際はぜひpandasやrequestsモジュールの使い方を調べつつ拡張ください。

Turbonomicにどの様なエンドポイントが存在するかについては、ドキュメントもしくは、Swaggerにてご確認ください。

https://www.ibm.com/docs/ja/tarm/8.10.2?topic=documentation-api-reference

Swaggerへのアクセスは、https://TurbonomicのIPアドレスまたはホスト名/swagger/external/index.html となります。