はじめに
[本記事はredash meetup 4.0.0で発表させていただいた内容に肉付けしたものです]
redashはデータベースに接続できるツールなのでuserの管理がとても重要になる。
userを定期的に棚卸しをし、メンテナンスしていくことはセキュリティを維持する上で必須だ。弊社では
- CLIでuser一覧を出す
- それをgitlabで管理
- gitlabに上がったということをchatworkで担当者に伝える
- 問題なければmerge
merge日=最終棚卸し日
というフローを採用し運用している。
しかし、想定していた運用を採用するうえではソースを変更する必要があった。
現在 version 5.0.2のCLI
残念ながらこの画像からわかる通り、非常に貧弱である。
version 5からuserをdisableする機能が導入されたが、userがenableなのか、disableなのかという情報がCLIからだとわからない。
pull requestの作成
機能としては存在しているのに、CLIで見れないとなると単純に表示させていないだけなのかもと察しソースを読んだ。
Userのenableなのか、disableの情報を表示するメソッドを見つけた
https://github.com/getredash/redash/blob/68272678b85ef4a6498543ef6a33a2071e607628/redash/models.py#L439
おそらくGUIであればこの処理を叩いて画面に表示している。
機能があるのであればCUIも同じように叩けばよいのでは?という仮説のもとファイルを変更した
https://github.com/getredash/redash/pull/2951/files
これでenableなのか、disableなのかがコマンドラインで確認できるようになった。
自分の管理するredashはdockerで動いているので、linux上でviコマンドで編集し、docker cpコマンドでコンテナ内に転送することで変更を動いているredashに反映させた。
OSSのソースに手を入れるというと相当な知識がないと変更できないかと思っていたが、progateでpython覚えた程度でも変更できた。
最初テストケースを書かずにpushしたらCIでコケたので、恥ずかしながらそこでredashのテストコードの存在を知った。。
せっかくなのでpull reqを出すと翌日mergeしてもらい、これがコントリビュートにつながった。
その後CLI機能を拡張すべく2つpull requestを出させていただき、いずれも承認された。
redashでユーザーを取得しGitLabへpushへ
gitlab-cliの設定する必要があるので事前にセットアップする
https://tsukada.sumito.jp/2018/10/17/python-gitlab/
shellをcronで動かし、その中でpythonのスクリプトを動かす
#!/bin/bash
hostname=`uname -n`
_roomid=123456789
output=/tmp/$hostname
cd ~/redash-user/
git pull
nohup /usr/bin/docker exec -i redash_server_1 ./manage.py users list > ~/redash-user/$hostname &
sleep 10;
ps -ef | grep "./manage.py users list" | grep -v grep | awk '{print $2}' | xargs kill -9
git checkout -b $hostname
git add $hostname
git commit -m $hostname
git push origin $hostname
python merge.py
pythonはGitLabへpushするのに使っている。コードはこちら
import os
import gitlab
hostname = '%s' % os.uname()[1]
gl = gitlab.Gitlab('https://gitlab.sumito.com/', private_token='abcdefgggggggg')
gl.auth()
project = gl.projects.get(123, lazy=True)
mr = project.mergerequests.create({'source_branch': (hostname),
'target_branch': 'master',
'title': (hostname) + ' user list'
})
mrs = project.mergerequests.list(state='opened', order_by='updated_at')[0]
print(mrs.attributes['web_url'])
以下のようにcronを仕込み月に一度listを更新し、GitLabにpushするようにしている。
0 0 1 * * sh /root/redash-user/redashUsers.sh 1> /tmp/stdout.log 2> /tmp/stderr.log
GitLabにMergeRequest上がっているのを取得、chat投げる処理
これも同様にshellからpythonを動かすようにしている。
#!/bin/bash
cd /root/redash-user/
hostname=`uname -n`
_roomid=123456789
tmp=$(/usr/bin/python ./chat.py)
tmowl=`echo $tmp | grep git.sumito.com | wc -l`
output=/tmp/gomi
if [ $tmowl -eq 0 ] ; then
exit
else
/usr/bin/cat << _EOT_ > /tmp/gomi
[toall]
[info]
[title]latest redash account Please check it!!
[/title]
`/usr/bin/python ./chat.py`
[/info]
_EOT_
_body=`/usr/bin/cat $output`
/usr/bin/curl -X POST -H "X-ChatWorkToken: 123456789" -d "body=${_body}" "https://api.chatwork.com/v2/rooms/${_roomid}/messages"
fi
pythonはこちら
import os
import gitlab
hostname = '%s' % os.uname()[1]
gl = gitlab.Gitlab('https://git.sumito.com/', private_token='123456789')
gl.auth()
# your project ID
project = gl.projects.get(123, lazy=True)
mrs = project.mergerequests.list(state='opened', order_by='updated_at')
mr_url = [mr.attributes['web_url'] for mr in mrs]
print("{}".format("\n ".join(mr_url)))
アカウントの棚卸し
以下のように表示される
この状態ではmerge requestが発行された状態なので、
管理者はこのリクエストを確認し、最新の状態を確認。問題なければmergeする
当然gitなので最新merge日は更新され、この日が棚卸し完了日と位置づけすることにより、最終棚卸し日がいつだったのかわかるようにしている。