RedashのScriptデータソースで独自のデータソースを作成する

この記事は Redash Advent Calendar 2017 5日目の記事です。

qiita.com

昨日はhideji2さんの 「RedashのPythonDataSourceを使ってデータのヘルスチェックをしてみた話」でした。

qiita.com

Scriptデータソースとは

RedashにはScriptデータソースという、任意のスクリプトをデータソースとして使える機能が含まれています。

この記事では、Scriptデータソースを使って自由にデータソースを定義する方法を紹介します。

Dockerで環境構築

Dockerを使用して環境構築をします。

以下のYAMLdocker-compose.yml として保存してください。

version: '2'
services:
  server:
    image: redash/redash:latest
    command: server
    depends_on:
      - postgres
      - redis
    ports:
      - "5000:5000"
    environment:
      PYTHONUNBUFFERED: 0
      REDASH_LOG_LEVEL: "INFO"
      REDASH_REDIS_URL: "redis://redis:6379/0"
      REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
      REDASH_COOKIE_SECRET: veryverysecret
      REDASH_WEB_WORKERS: 4
      REDASH_ADDITIONAL_QUERY_RUNNERS: "redash.query_runner.script"
    restart: always
  worker:
    image: redash/redash:latest
    command: scheduler
    environment:
      PYTHONUNBUFFERED: 0
      REDASH_LOG_LEVEL: "INFO"
      REDASH_REDIS_URL: "redis://redis:6379/0"
      REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
      QUEUES: "queries,scheduled_queries,celery"
      WORKERS_COUNT: 2
      REDASH_ADDITIONAL_QUERY_RUNNERS: "redash.query_runner.script"
    restart: always
  redis:
    image: redis:3.0-alpine
    restart: always
  postgres:
    image: postgres:9.5.6-alpine
    restart: always
  nginx:
    image: redash/nginx:latest
    ports:
      - "80:80"
    depends_on:
      - server
    links:
      - server:redash
    restart: always

REDASH_ADDITIONAL_QUERY_RUNNERS という環境変数を使用してScriptデータソースを使えるようにします。

環境変数については2日目の記事に詳しく書かれていますので、興味がある方はぜひチェックしてください。

qiita.com

docker-compose.yml が準備できたら、Redashのデータベースを初期化するため、以下のコマンドを実行します。

$ docker-compose run --rm server bash -c "sleep 15 && /app/bin/docker-entrypoint create_db"
$ docker-compose up

Redashが起動したらhttp://localhostにアクセスし、admin ユーザーを作成します。

サンプルスクリプト

以下のスクリプトwrestlers.sh として保存します。

#!/bin/bash
JSON=$(cat << EOS
{
  "columns": [
    {"friendly_name": "Name", "type": "string", "name": "name"},
    {"friendly_name": "Ring name", "type": "string", "name": "ring_name"},
    {"friendly_name": "finishing moves", "type": "string", "name": "finishing_move"},
    {"friendly_name": "Born on", "type": "string", "name": "born_on"}
  ],
  "rows": [
    {"name": "Kanji Inoki", "ring_name": "Antonio Inoki", "finishing_move":"Enzuigiri", "born_on": "1943-02-20"},
    {"name": "Baba Shōhei", "ring_name": "Giant Baba", "finishing_move":"Big boot", "born_on": "1938-01-23"}
  ]
}
EOS
)
/bin/echo $JSON

ファイル名やデータの内容については割愛しますが、RedashのAPIなどで使用されているフォーマットに従ったJSONを返すことが必須となっています。

このフォーマットについては公式ドキュメントにも記載があります。

Data Source Results Format · Redash Help Center

wrestlers.sh を保存したら、以下のコマンドでスクリプトをRedashのWorkerコンテナにコピーし、実行権限を付与します。

$ docker-compose exec worker mkdir /tmp/redash
$ docker cp wrestlers.sh `docker-compose ps | grep worker | awk '{print $1}'`:/tmp/redash/
$ docker-compose exec -u root worker chmod a+x /tmp/redash/wrestlers.sh

データソースの設定

続いて、以下のコマンドでデータソースを追加します。

$ docker-compose exec server ./manage.py ds new --type insecure_script --options '{"path": "*", "shell": true}' wrestlers

path には * を指定していますが、本来はスクリプトの実行を許可するパスを明示的に /tmp/redash のように指定することができるようですが、現時点ではパスを指定すると動作しなくなってしまうため、この記事では * と指定しています。

ここまでで環境構築は完了です。

データソース名から、安全ではない(Insecure)機能だということもわかりました。

本番での使用を検討する際には、任意のスクリプトを実行できるという意味で非常に危険な機能ではありますが、この記事ではScriptデータソースの紹介が主目的なので、先に進みます。

Scriptデータソースを使用したクエリを実行する

動作確認に使用するクエリをRedashの画面上で作成します。

新規クエリをデータソースとして wrestlers を選択し、以下の内容で作成してください。

 /tmp/redash/wrestlers.sh

実行すると、以下のような結果が表示されます。

f:id:ariarijp:20171204213541p:plain

指定したスクリプトの標準出力をクエリの結果として取得できることがわかりました。

この記事の例ではbashで書いていますが、PHPでもGoでもRubyでも、出力がRedashのフォーマットに準じたものであれば、どんな言語で書いても良いというのは、強みになることがあるかもしれません。

まとめ

簡単にまとめます。

  • Scriptデータソースを使用することで、任意のスクリプト言語などでデータソースを独自に定義することができる
  • Scriptデータソースの利用時はセキュリティリスクを含むため、使用を検討する場合は権限などを正しく設定するなどの注意が必要

本番導入へのセキュリティリスクもあり、使い方が難しい機能ですが、うまく使いこなせるとRedashをより快適に使えるようになるかもしれません。

明日はtkmotekiさんが何か書いてくれるようです。気になりますね。

宣伝

Redash Advent Calender 2017を作成した id:kakku22 と一緒にRedash Meetupを開催します。

connpass.com

初回は初学者向けのハンズオンとしていますが、次回以降は導入事例などの情報共有もできるように続けていければと考えていますので、興味を持っていただけたら Twitter あたりでお声がけいただけると嬉しいです。