日: 2018年10月24日

  • redashのuserをgitで管理する

    redashのuserをgitで管理する

    はじめに

    [本記事はredash meetup 4.0.0で発表させていただいた内容に肉付けしたものです]

    redashはデータベースに接続できるツールなのでuserの管理がとても重要になる。
    userを定期的に棚卸しをし、メンテナンスしていくことはセキュリティを維持する上で必須だ。弊社では

    1. CLIでuser一覧を出す
    2. それをgitlabで管理
    3. gitlabに上がったということをchatworkで担当者に伝える
    4. 問題なければ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日は更新され、この日が棚卸し完了日と位置づけすることにより、最終棚卸し日がいつだったのかわかるようにしている。