IICSのSecure Agentの稼働状況をREST APIで確認する

Informatica Intelligent Cloud Services(IICS)のREST APIを用いて、Secure Agentのステータスを確認するAWS Lambdaを実装する。
2020.12.09

本エントリはクラスメソッド インフォマティカ Advent Calendar 2020のエントリです。

データアナリティクス事業本部、池田です。 アドベントカレンダー9日目です!
以前のブログ で、Informatica Intelligent Cloud Services(以下IICS) のSecure Agentの起動や停止の話を書きました。 今回は、 Informatica Intelligent Cloud Services REST API というものを使って、Secure Agentが動いているかステータスを確認してみます。

APIのバージョンについて

Informatica Intelligent Cloud Services REST APIには、執筆時点で version 2version 3 が存在します。 version 3の方のagentservice によると、

After you send a POST request to start or stop a Secure Agent service, you can check the status of the service using the REST API V2 agent resource.

とのことなので、GUIのコンソールでできるような操作を全てするには、 少なくとも両方のバージョンを使用する必要がありそうです。 (バージョンによってログインやセッションID周りが変わってくるようで、 注意が必要そうでした。→ REST API versions

今回やりたいのは、version 2でできるSecure Agentのステータスの確認なので、 他のリソースもversion 2に寄せて作業をしていきます。

実装コード(AWS Lambda上のPython)

特に意味はありませんがなんとなくPythonで書きたかったので、 Pythonを AWS Lambda 上で動かすことにしました。 バージョンは Python 3.7 です。

↓コード全体はこんな感じ。

クリックでコードを表示する/折りたたむ
import os
import traceback
import json
import boto3
from urllib import request

def lambda_handler(event, context):
    # login
    LOGIN_URL = os.environ["IICS_LOGIN_SERVER"] + "/ma/api/v2/user/login"
    LOGIN_USER = os.environ["IICS_LOGIN_USER"]
    LOGIN_PW = os.environ["IICS_LOGIN_PW"]
    LOGIN_HEADER = {"Content-Type": "application/json",
                    "Accept": "application/json"}
    LOGIN_PAYLOAD = {"@type": "login",
                     "username": LOGIN_USER, "password": LOGIN_PW}

    req_login = request.Request(LOGIN_URL, method="POST", headers=LOGIN_HEADER,
                                data=json.dumps(LOGIN_PAYLOAD).encode())
    with request.urlopen(req_login) as res:
        body = json.loads(res.read())
        SERVER_URL = body["serverUrl"]
        SESSION_ID = body["icSessionId"]

    try:
        # agent
        AGENT_ID = os.environ["IICS_AGENT_ID"]
        AGENT_URL = SERVER_URL + "/api/v2/agent/details/" + AGENT_ID
        AGENT_HEADER = {"Accept": "application/json",
                        "icSessionId": SESSION_ID}

        req_agent = request.Request(AGENT_URL, method="GET",
                                    headers=AGENT_HEADER)
        with request.urlopen(req_agent) as res:
            details = json.loads(res.read())
    except Exception:
        print(traceback.format_exc())
        raise
    finally:
        # logout
        LOGOUT_URL = SERVER_URL + "/api/v2/user/logout"
        LOGOUT_HEADER = {"Content-Type": "application/json",
                         "Accept": "application/json",
                         "icSessionId": SESSION_ID}

        req_logout = request.Request(LOGOUT_URL, method="POST",
                                     headers=LOGOUT_HEADER)
        try:
            with request.urlopen(req_logout):
                pass
        except Exception:
            print(traceback.format_exc())

    # status
    result = {details["name"] + " active": details["active"]}
    for engine in details["agentEngines"]:
        result[engine["agentEngineStatus"]["appDisplayName"]] = \
            engine["agentEngineStatus"]["status"]
    print(result)

    # SNS publish
    TOPIC_ARN = os.environ["SNS_TOPIC_ARN"]
    subject = "[STATUS] " + details["name"]

    sns = boto3.client("sns")
    sns.publish(TopicArn=TOPIC_ARN,
                Subject=subject,
                Message=json.dumps(result, indent=4))

Lambdaの環境変数として、↓を登録しています。

  • IICS_LOGIN_SERVER: https://dm-ap.informaticacloud.comhttps://dm-us.informaticacloud.com などログインURL冒頭部分
  • IICS_LOGIN_USER: IICSにログインするユーザ
  • IICS_LOGIN_PW: IICSにログインするパスワード
  • IICS_AGENT_ID: Secure AgentのID
  • SNS_TOPIC_ARN: 結果の送付先のSNSのARN

Secure AgentのIDは、コンソールで当該Agentを開いた状態のURLなどから取得できます。 (→ 参考
簡略化のため環境変数にしましたが、ログイン情報は AWS Systems Manager パラメータストア 管理などが良いかもしれません。

urllib ライブラリでREST APIへ繋ぎ、 Amazon SNS に結果を通知しています。
完全に余談ですが… 始めにローカルでPython標準でない requests ライブラリで実装してしまって、 Lambda上ですぐには動かずにurllibの方に書き換えました… 個人的にはrequestsの方が書きやすい気がしました。どうでも良い話ですが。

ログイン

ログイン は、https://dm-us.informaticacloud.com/ma/api/v2/user/login (※使用する環境により異なる) というリソースに対して、IICSのユーザとパスワードを含めたPOSTリクエストを実行します。

    LOGIN_HEADER = {"Content-Type": "application/json",
                    "Accept": "application/json"}
    LOGIN_PAYLOAD = {"@type": "login",
                     "username": LOGIN_USER, "password": LOGIN_PW}

    req_login = request.Request(LOGIN_URL, method="POST", headers=LOGIN_HEADER,
                                data=json.dumps(LOGIN_PAYLOAD).encode())
    with request.urlopen(req_login) as res:
        body = json.loads(res.read())
        SERVER_URL = body["serverUrl"]
        SESSION_ID = body["icSessionId"]

レスポンスにはログイン後の各操作で必要になる icSessionId (セッションID)と serverUrl (組織のURL)が含まれます。

セッションIDについては、 こちら

The session ID expires after 30 minutes of inactivity.

30分使わないと切れるそうです。

Secure Agentの詳細の取得

今回のメインの部分です。 Secure Agentの詳細情報 を取得します。
{serverUrl}/api/v2/agent/details/{agent ID} というリソースに対して、 ヘッダに前節で取得したicSessionIdを含めてGETしてやります。

        # agent
        AGENT_ID = os.environ["IICS_AGENT_ID"]
        AGENT_URL = SERVER_URL + "/api/v2/agent/details/" + AGENT_ID
        AGENT_HEADER = {"Accept": "application/json",
                        "icSessionId": SESSION_ID}

        req_agent = request.Request(AGENT_URL, method="GET",
                                    headers=AGENT_HEADER)
        with request.urlopen(req_agent) as res:
            details = json.loads(res.read())

このレスポンスからSecure Agentの状態( active )や、 各サービスの状態( status )を取得します。

ログアウト

ガイドライン によると、 ちゃんと ログアウト までするのがベストプラクティスのようなので、ログアウトします。

However, best practice is to log out before the session ends.

ヘッダにicSessionId含めて、 {serverUrl}/api/v2/user/logout にPOSTします。

        # logout
        LOGOUT_URL = SERVER_URL + "/api/v2/user/logout"
        LOGOUT_HEADER = {"Content-Type": "application/json",
                         "Accept": "application/json",
                         "icSessionId": SESSION_ID}

        req_logout = request.Request(LOGOUT_URL, method="POST",
                                     headers=LOGOUT_HEADER)
        try:
            with request.urlopen(req_logout):
                pass
        except Exception:
            print(traceback.format_exc())

(ひとまずステータスが取得できれば良いので、エラーは握り潰しています。)

動かす

Lambdaを動かしてみます。
(通知先のSNSトピックはメールアドレスでサブスクライブしています。)

↓稼働している時


↓停止している時


ステータスがメールで確認できました!

おわりに

普段GUIのコンソールでやっているような操作をAPIから行うことができました。
今回はPythonで実装しましたが、 AWS EC2 上に Secure Agentを導入しているような場合は、EC2上で動かすbashなどで実装しても良いかもしれません。

APIは他にもいろいろあるので、触っていきたいと思います。たぶん。

参考文献