Looker SDK で効率化するアカウント管理

こんにちは、Data Division の id:beniyama です。

今回は Looker Advent Calendar 2019 7日目の記事として、最近 Looker 6.22 としてリリースされた Looker Python SDK を使ったアカウント管理の効率化事例をご紹介します。

アカウントはカジュアルに発行して使わないようなら停止したい

エンジニアを魅了する次世代 BI ツール『Looker』を Quipper が導入した理由(わけ) - Quipper Product Team Blog から早1年余、社内で発行してきた Looker アカウントも順調に増加し、今では結構な割合のメンバーが Looker を覗けるようになりました。

毎日ログインして日々の意思決定に使っているメンバーも増えてきた一方で、アカウント申請してみたものの継続的にログインするには至らずご無沙汰になってしまう人がいるのも事実です。

コスト管理も行っている運用側としては契約しているアカウント数に対する活用率の最大化を目指したいのですが、かといって事前承認のフローを重くして入り口を狭めるということはしていません。

『データの民主化』を推進するためには、端的に言うと『いつでも会えるダッシュボード』くらいの(導線的にも心理的にも)親近感があることが大事だと思っています。

ですので、代わりに「とりあえずカジュアルにアカウント発行するよ、でも一定期間使わないと停止(Disable)するよ。また使いたくなったら復活申請してね!」というポリシーで運用をしています。削除しなくても一旦停止という状態を持てるのが良いですね。

f:id:beniyama:20191206121501p:plain
Looker アカウントの申請フロー

上図のように Google フォームから必要事項を記入してもらい、申請が来ると Slack で通知が来るようにしています。今回ご紹介する SDK を使うとこの辺の新規ユーザー作成および権限付与も完全自動化が可能ですので、それもおいおいやっていきたいです。

Python SDK を使って一定期間ログインのないアカウントを停止する

もともと 120% カバレッジを標榜しているくらい充実している Looker の API ですが、先日公開された 6.22 では PythonJavascript & Typescript の SDK が提供されるようになりました。

discourse.looker.com

例えば PythonSDKlooker-sdk · PyPI に詳しい説明があります。

さて今回は

  • 全ての Looker アカウント情報を取得
  • ログイン済みかどうかをチェック、していたら最終ログイン日を取得
  • 最終ログイン日が指定された期間(デフォルトでは 180 日)より前であれば停止( disable 状態に変更)
  • ついでに今どれだけアカウントが発行されているかをロールごとにカウント

するようなスクリプトを作っていきます。

認証情報を looker.ini として記載

sdk-codegen/python at master · looker-open-source/sdk-codegen · GitHub にも記載がありますが、Looker 側で発行した API key やエンドポイントを looker.ini として指定し、スクリプト中からそれを読み込ませます。

[Looker]

# API version is required
api_version=3.1

# Base URL for API. Do not include /api/* in the url
base_url=https://YourLookerDomain.looker.com:19999

# API 3 client id
client_id=YourClientID

# API 3 client secret
client_secret=YourClientSecret

# Set to false if testing locally against self-signed certs. Otherwise leave True
verify_ssl=True

特に難しいところはないですが、

Base URL for API. Do not include /api/* in the url

をちゃんと読まず以前のコードをコピペした際にサブディレクトリ以降も指定してしまって軽くハマりました…

スクリプト側では

from looker_sdk import client, models

sdk = client.setup("looker.ini")

として認証を実施します。

SDK 越しに情報を取得する

例えば、

my_id = sdk.me(fields="id")

などとすると自分自身の Looker アカウント ID を取得できます。自分を停止することが可能なのかちょっとわかりませんが、万が一にでも disable にしてしまうと目も当てられないので自分が何者なのか把握しておきます。

他にも

all_users = sdk.all_users()

などとすると全ユーザーのリストが取得できます。

例えばこのリストをなめて下記のようにすると Looker 社側のアカウントかどうかを識別することが可能です。

for user in all_users:
    if user.presumed_looker_employee:
        looker_user_cnt += 1

停止されている(disabled な)アカウントかどうかは

user.is_disabled

で取得できます。

どういったプロパティがあるかは、例えばユーザー周りであれば User : Manage Users を見るとよくわかります。

ユーザーの最終ログインについては

user.credentials_email.logged_in_at

で取得が可能ですが、ここで注意が必要なのは上記は credentials_email、つまり email + パスワードによるログインについての情報のみとなります。

ですので、他のログイン種別をサポートしている場合は credentials_googlecredentials_ldap なども見る必要があると思います(参考)。

SDK 越しにユーザーの状態を変更する

今回は特定のユーザーの is_disabled フラグを立てたいので、下記のようにします。

sdk.update_user(user.id, body=models.WriteUser(is_disabled=True))

とても簡単ですね。

実行結果

このスクリプトを実行すると下記のような結果が出力されます。

$ pipenv run python disable_users.py

XXX XXXX (XXX.XXXX@quipper.com)'s last login date is 2019-05-31 00:00:00 (189 days before). Disable the user ?? y/N >>y
...successfully disabled.
XXX XXXX (XXX.XXXX@quipper.com)'s last login date is 2019-05-15 00:00:00 (205 days before). Disable the user ?? y/N >>
...skipped.
XXX XXXX (XXX.XXXX@quipper.com)'s last login date is 2018-12-14 00:00:00 (357 days before). Disable the user ?? y/N >>
...skipped.
XXX XXXX (XXX.XXXX@quipper.com)'s last login date is 2019-05-23 00:00:00 (197 days before). Disable the user ?? y/N >>
...skipped.
XXX XXXX (XXX.XXXX@quipper.com)'s last login date is 2019-06-03 00:00:00 (186 days before). Disable the user ?? y/N >>
...skipped.


-----------------------------
---------- Summary ----------
-----------------------------
 Total registered users: XXX (incl. 7 looker people)
 Active users: XXX
 No login users: 0
-----------------------------
 Users disabled in this operation: 1
 Errors: 0
-----------------------------
 Admin : XX
 User : XX
 Developer : XX
-----------------------------

現状は逐次 yes or no の確認インプットを入れていますが、問答無用で強制停止にするのであればバッチ化して毎日回すこともできます。

また、現在の Looker の管理画面では誰がどこのロールにいて、それぞれのロールが実際何人なのか把握しづらいこともあり、利用実績と契約枠を見比べやすくするために今回ロールごとの集計機能もついでに入れました。

まとめ

余り大きなニュースになっていませんが、公式に SDK がサポートされたことで API を使った様々な運用業務の自動化が一段と行いやすくなりました。

今後はアカウント発行の自動化からのオンボーディング体験の向上、Slack 通知などによる停止前のリマインド・利用喚起など様々な施策を打って、利用率のさらなる向上を目指したいと思います。

今回作成したサンプルコード

今回作成したスクリプトは下記 Gist に公開しています。

もともとは以前から公開されていた python_api_samples/disable_users.py at master · llooker/python_api_samples · GitHub を参考に開発したもので、今回の Python SDK リリースを機に各所を書き換えています。

gist.github.com

また、環境構築周りはこちらをご覧ください。

github.com