LoginSignup
2
3

More than 3 years have passed since last update.

OPA 事始め

Last updated at Posted at 2021-02-14

Open Policy Agent (OPA) 事始め

Copyright: Hiro Osaki 2021

はじめに

このドキュメントは、Open Policy Agent (OPA) を一度触ってみたいという方向けです.

最短経路は8分で済みます. ソースコードもHello worldレベルを目指します.

(本記事は, OPA up and runningのQiita転載版になります.)

1. 初めてのRego: Rego Playground

OPAとそこで使われるRego言語がどんなものなのかを掴むのに, OPAをインストールす必要はありません. 最速の方法は, Styraが開発した"Rego Playground" というWebサービスを使うことです.

1.1. Rego言語のプログラムを動かしてみる (所要: 5分)

  • 初の Rego 言語 プログラミングにチャレンジしましょう. 左のウィンドウの一番下に, 以下の3行を足します.
  newdata = msg {
    msg := concat("", ["Received the message: ", input.message])
  }

この3行は、新しいデータ newdata を追加するコードです.

  • 再度 Evaluate をクリック.

OUTPUT ウィンドウに新しいデータ newdata が追加されます.

その結果はこのようになります.

{
"hello": true,
"newdata": "Received the message: world"
}

2行目の "newdata": ... が、新しいデータです. それ以外の "hello" は, もともとのソースコード hello {...} の結果です.

  • inputを変える

    • 右の INPUT ウィンドウに "message":... と書かれてあります.
    • この中身を "message": "distopia" に変えてみます.
    • Evaluate を再度クリック. このような結果が出るでしょう. { "hello": false, "newdata": "Received the message: distopia" }
    • hello の結果を見ます. 先ほどの true から false に結果が変わっています. 理由は,

    hello の中身に m == "world" と書かれているためです.

    この文は, もし message"world" なら, 返り値は true になることを意味します.

    そうでなければ, 返り値は false です.

  • data を使ってみる

    • data ウィンドウに以下を書き込みます. { "rule": "be good" }
    • 左のウィンドウの最後の行に以下を追記します. importdata = msg { msg := concat("", ["Received the static data: ", data.rule]) }
    • Evaluate を再度クリック.
    • 新たなコードの結果が表示されます.
    "importdata": "Received the static data: be good",
    

1.2. まとめ: OPA が何をするのか (所要: 3分)

  • Rego Playground を使ってみて分かること.
    1. OPA はポリシーファイルを読み込む.
      ポリシーファイルは Rego 言語で newdata = msg {...} のように記述されます. (Playgroundの左ウィンドウ)
    2. OPA は input のデータを受け取る.
      input のデータはJSONフォーマットでなければなりません. (Playgroundの右上ウィンドウ)
    3. OPA は data のデータも受け取る.
      data のデータもJSONフォーマットでなければなりません. (Playgroundの右中央のウィンドウ. data は初期値で {}になっています)
    4. OPA はポリシーの処理により output を生成する.
      生成される output もJSONフォーマットです. (Playgroundの右下ウィンドウ)
  • まとめ: OPA はRegoファイルを読み込み, JSON データを処理します. そして, OPA は 出力のJSONデータを生成します.

  • 詳細は, 公式ドキュメントのintroduction https://www.openpolicyagent.org/docs/latest/ に記載されています.

2. 自分の環境でOPAを起動する

2.1. OPA をインストールする(所要: ~ 5分)

  • MacOSなら, 以下のコマンドでインストールできます.
  brew install opa

2.2. OPAの起動を確認する (所要: 5分))

  • opa run を実行してみます.
  $ opa run

その実行中に, a = 3exit を実行できます.

  $ opa run
  OPA 0.26.0 (commit , built at )

  Run 'help' to see a list of commands and check for updates.

  > a = 3
  Rule 'a' defined in package repl. Type 'show' to see rules.
  > x = 3
  Rule 'x' defined in package repl. Type 'show' to see rules.
  > show
  package repl

  a = 3

  x = 3
  > exit

2.3. OPAをサーバとして起動する (所要: 5分)

  • example.regoというファイルを作成します.
  mkdir example/
  cd example/
  # create example.rego

以下をexample.regoとして保存します. 1章と中身は同じですね.

  package play

  default hello = false

  hello {
      m := input.message
      m == "world"
  }

  newdata = msg {
      msg := concat("", ["Received the message: ", input.message])
  }

  importdata = msg {
      msg := concat("", ["Received the static data: ", data.rule])
  }

input.json も以下の内容で作成します. これも1章と同じです.

  # create input.json
  {
    "input": {
      "message": "world"
    }
  }
  • 以下コマンドを実行します.
  opa run -s ./example.rego
  • 別のコマンドラインから OPA サーバにリクエストを出します。

    • まずは /v1/data/play にアクセスします.
  $ curl localhost:8181/v1/data/play -i -d @input.json -H 'Content-Type: application/json'

  {"result":{"hello":true,"newdata":"Received the message: world"}}

  • 次に, /v1/data/play/hello にアクセスします.
  $ curl localhost:8181/v1/data/play/hello -i -d @input.json -H 'Content-Type: application/json'

  {"result":true}
  # Same as the value of "hello" in section 1.1
  • /v1/data/play/newdata
  $ curl localhost:8181/v1/data/play/newdata -i -d @input.json -H 'Content-Type: application/json'

  {"result":"Received the message: world"}
  # Same as the value of "newdata" in section 1.1
  • /v1/data/play/importdata
  $ curl localhost:8181/v1/data/play/importdata -i -d @input.json -H 'Content-Type: application/json'

  {}
  # This is undefined because no data is imported.

2.4. OPA にデータを読み込ませる (5 min)

  # create data.json
  {
    "rule": "be good"
  }

サーバの起動コマンドを以下のように変えて, OPAサーバを再度起動します.

  # add ./data.json to command arguments
  opa run -s ./example.rego ./data.json
  • OPAサーバにリクエストを送信します.

    • /v1/data/play
    $ curl localhost:8181/v1/data/play -i -d @input.json -H 'Content-Type: application/json'  
    
    {"result":{"hello":true,"importdata":"Received the static data: be good","newdata":"Received the message: world"}}
    # Field "importdata" was added.
    

このように、読み込んだデータに応じてOPAが処理を変えます.

  • /v1/data/play/importdata
  $ curl localhost:8181/v1/data/play/importdata -i -d @input.json -H 'Content-Type: application/json'

  {"result":"Received the static data: be good"}
  # Data was added. Same as the value of "importdata" in section 1.1

2.5. まとめ: OPAができること (所要: 3分)

  • OPA サーバが自分の環境で起動でき, HTTPリクエストに応じて処理を実行しました.
    • HTTP リクエストで JSONデータを送信します.
    • さらにボディは {"input": ***}の形式である必要があります.
  • OPA サーバは <server>/v1/api/data/<package name>[/<object name>] のようなエンドポイントを持ちます.
    • Regoファイルの最初の行 package play により, <package name>play であることを定義しています.
    • Regoファイルの中のルールの定義 hello {...} により, <object name>hello であることを定義しています.
  • OPAの返り値は, {"result": ***}の形式のJSONデータです.
    • 返り値の中身は, アクセスするエンドポイントによって変わります.
    • もし <package name> がリクエストされると, 返り値は "result" フィールドに全部の値を含みます.
    • もし <package name>/<object name> がリクエストされると, 返り値は "result" フィールドに指定されたオブジェクト = ルールの結果が含まれます.

3. 参考資料

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3