Keyverno Chainsawでscript
に変数を渡す方法についての解説です。
Chainsawはテストケースごとにnamespaceをランダムで生成します。その名前は、apply
などであれば($namespace)
変数でアクセスできます。しかし、script
は直接アクセスできなので注意が必要です。
うまくいかない方法
安直にscript.content
に($namespace)
を書いてもうまくいきません。content
中の($namespace)
は文字列展開されません。
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
metadata:
name: my-test
spec:
steps:
- try:
- script:
content: |
#!/bin/bash
set -ux
echo "Current namespace is ($namespace)"
# ^^^^^^^^^^^^ これは展開されない
上の例だと、ただシェルで
echo "Current namespace is ($namespace)"
を実行しただけで、環境変数にnamespace
がないため次の出力結果のようにエラーになります。
| 11:03:42 | my-test | step-1 | CMD | RUN |
=== COMMAND
/nix/store/3z1jypscq2ld48kl089ywgwd8ri2rjxq-bash-5.2p37/bin/sh -c #!/bin/bash
set -ux
echo "Current namespace is ($namespace)"
| 11:03:42 | my-test | step-1 | SCRIPT | LOG |
=== STDERR
sh: line 3: namespace: unbound variable
| 11:03:42 | my-test | step-1 | SCRIPT | ERROR |
=== ERROR
exit status 127
正しいやり方
変数をスクリプトに正しく渡すには、env
を介在させます。例えば次のようにです。
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
metadata:
name: my-test
spec:
steps:
- try:
- script:
env: # これを追加
- name: NAMESPACE # 環境変数名
value: ($namespace) # 値。ここは変数展開が効く。
content: |
#!/bin/bash
set -ux
echo "Current namespace is $NAMESPACE"
# ^^^^^^^^^^ スクリプトとしては環境変数を参照する
このようにenv
を追加し、Chainsawの変数をシェルの環境変数にマッピングしてあげる必要があります。
所感
ちょっと回りくどさはありますが、この方法でうまく動きます。