OPAのReviewするInputの中身を取り出す

はじめに

TMCで学ぶOPAシリーズでも紹介したように、OPAは強力なツールです。 Rego言語をテストするのにRego Playgroundが使えます。

https://play.openpolicyagent.org/

ただ、この"Input"になる情報はどうやって取り出せばいいんだろう。。。と思っていたら方法がちゃんとかいてありました。

https://github.com/open-policy-agent/gatekeeper#viewing-the-request-object

この記事ではそのやり方をメモしておきます。

やり方

とりあえず、以下のようになんでもエラーを返すConstraintTemplateを作ります。

 1cat <<EOF | kubectl apply -f -
 2apiVersion: templates.gatekeeper.sh/v1beta1
 3kind: ConstraintTemplate
 4metadata:
 5  name: k8sdenyall
 6spec:
 7  crd:
 8    spec:
 9      names:
10        kind: K8sDenyAll
11  targets:
12    - target: admission.k8s.gatekeeper.sh
13      rego: |
14        package k8sdenyall
15
16        violation[{"msg": msg}] {
17          msg := sprintf("REVIEW OBJECT: %v", [input.review])
18        }
19EOF

さらに、それにもとづいた、constraintsを作成します。 この例では、Namespaceの作成時にひっかかるようにしています。

 1cat <<EOF | kubectl apply -f -
 2apiVersion: constraints.gatekeeper.sh/v1beta1
 3kind: K8sDenyAll
 4metadata:
 5  name: deny-all-namespaces
 6spec:
 7  match:
 8    kinds:
 9      - apiGroups: [""]
10        kinds: ["Namespace"]
11EOF

この状態で、NamespaceをつくるとエラーとともにInputに使えるJsonをそのまま吐き出します。

1kubectl create ns hoge
2Error from server ([denied by deny-all-namespaces] REVIEW OBJECT: {"object": {"apiVersion": "v1", "kind": "Namespace", "metadata": {"uid": "39365652-a7fb-4463-b23d-e00c6dc43374", "creationTimestamp": "2020-10-01T13:33:52Z", "name": "hoge"}, "spec": {"finalizers": ["kubernetes"]}, "status": {"phase": "Active"}}, "oldObject": null, "uid": "11b3051f-1c27-4d82-8bac-d4a0535b01e3", "requestKind": {"group": "", "version": "v1", "kind": "Namespace"}, "userInfo": {"username": "kubernetes-admin", "groups": ["system:masters", "system:authenticated"]}, "name": "hoge", "operation": "CREATE", "dryRun": false, "options": {"kind": "CreateOptions", "apiVersion": "meta.k8s.io/v1"}, "_unstable": {}, "kind": {"group": "", "version": "v1", "kind": "Namespace"}, "resource": {"resource": "namespaces", "group": "", "version": "v1"}, "requestResource": {"group": "", "version": "v1", "resource": "namespaces"}}): admission webhook "validation.gatekeeper.sh" denied the request: [denied by deny-all-namespaces] REVIEW OBJECT: {"object": {"apiVersion": "v1", "kind": "Namespace", "metadata": {"uid": "39365652-a7fb-4463-b23d-e00c6dc43374", "creationTimestamp": "2020-10-01T13:33:52Z", "name": "hoge"}, "spec": {"finalizers": ["kubernetes"]}, "status": {"phase": "Active"}}, "oldObject": null, "uid": "11b3051f-1c27-4d82-8bac-d4a0535b01e3", "requestKind": {"group": "", "version": "v1", "kind": "Namespace"}, "userInfo": {"username": "kubernetes-admin", "groups": ["system:masters", "system:authenticated"]}, "name": "hoge", "operation": "CREATE", "dryRun": false, "options": {"kind": "CreateOptions", "apiVersion": "meta.k8s.io/v1"}, "_unstable": {}, "kind": {"group": "", "version": "v1", "kind": "Namespace"}, "resource": {"resource": "namespaces", "group": "", "version": "v1"}, "requestResource": {"group": "", "version": "v1", "resource": "namespaces"}}

便利である。

まとめ

OPAのInputは簡単にゲットできる。