diff --git a/examples/validationTransformer/README.md b/examples/validationTransformer/README.md new file mode 100644 index 000000000..d2134d0f0 --- /dev/null +++ b/examples/validationTransformer/README.md @@ -0,0 +1,222 @@ +# a transformer plugin performing validation + +[base]: ../docs/glossary.md#bases +[kubeval]: https://github.com/instrumenta/kubeval +[plugin]: ../../docs/plugins.md + +Kustomize doesn't validate the resources that it loads +from files or [bases], but kustomize has a [plugin] +system that allows one to validate the +loaded resources. + +One way to validate Kubernetes resources is to run +[kubeval] against the resource file. For example, +an invalid resource file gives similar error: +```shell +$ kubeval my-invalid-rc.yaml +The document my-invalid-rc.yaml contains an invalid ReplicationController +--> spec.replicas: Invalid type. Expected: integer, given: string +``` + +One can write a Kustomize transformer [plugin] to +run [kubeval] against the resources that have been +loaded by Kustomize. + + +Make a place to work: + + +``` +DEMO_HOME=$(mktemp -d) +mkdir -p $DEMO_HOME/valid +mkdir -p $DEMO_HOME/invalid +PLUGINDIR=$DEMO_HOME/kustomize/plugin/someteam.example.com/v1/validator +mkdir -p $PLUGINDIR +``` + +## write a transformer plugin + +Download the [kubeval] binary depending on the operating system +and add it to $PATH. + + +``` +OS=`uname | sed -e 's/Linux/linux/' -e 's/Darwin/darwin/'` +wget https://github.com/instrumenta/kubeval/releases/download/0.9.2/kubeval-${OS}-amd64.tar.gz +tar xf kubeval-${OS}-amd64.tar.gz +export PATH=$PATH:`pwd` +``` + +Kustomize has the following assumption of a transformer plugin: +- The resources are passed to the transformer plugin from stdin. +- The configuration file for the transformer plugin is passed in + as the first argument. +- The working directory of the plugin is the kustomization + directory where it is used as a transformer. +- The transformed resources are written to stdout by the plugin. +- If the return code of the transformer plugin is non zero, + Kustomize regards there is an error during the transformation. + +A transformer plugin for the validation can be written as a +bash script, which execute the [kubeval] binary and return proper +output and exit code. + + +``` +cat <<'EOF' > $PLUGINDIR/Validator +#!/bin/bash + +if ! [ -x "$(command -v kubeval)" ]; then + echo "Error: kubeval is not installed." + exit 1 +fi + +temp_file=$(mktemp) +output_file=$(mktemp) +cat - > $temp_file + +kubeval $temp_file > $output_file + +if [ $? -eq 0 ]; then + cat $temp_file + rm $temp_file $output_file + exit 0 +fi + +cat $output_file +rm $temp_file $output_file +exit 1 + +EOF +chmod +x $PLUGINDIR/Validator +``` + +## use the transformer plugin + +Define a kustomization containing a valid ConfigMap +and the transformer plugin. + + +``` +cat <<'EOF' >$DEMO_HOME/valid/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: cm +data: + foo: bar +EOF + +cat <<'EOF' >$DEMO_HOME/valid/validation.yaml +apiVersion: someteam.example.com/v1 +kind: Validator +metadata: + name: notImportantHere +EOF + +cat <<'EOF' >$DEMO_HOME/valid/kustomization.yaml +resources: +- configmap.yaml + +transformers: +- validation.yaml +EOF +``` + +Define a kustomization containing an invalid ConfigMap +and the transformer plugin. + + +``` +cat <<'EOF' >$DEMO_HOME/invalid/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: cm +data: +- foo: bar +EOF + +cat <<'EOF' >$DEMO_HOME/invalid/validation.yaml +apiVersion: someteam.example.com/v1 +kind: Validator +metadata: + name: notImportantHere +EOF + +cat <<'EOF' >$DEMO_HOME/invalid/kustomization.yaml +resources: +- configmap.yaml + +transformers: +- validation.yaml +EOF +``` + +The directory structure is as the following: + +``` +/tmp/tmp.fAYMfLZJs4 +├── invalid +│   ├── configmap.yaml +│   ├── kustomization.yaml +│   └── validation.yaml +├── kustomize +│   └── plugin +│   └── someteam.example.com +│   └── v1 +│   ├── kubeval +│   └── Validator +└── valid + ├── configmap.yaml + ├── kustomization.yaml + └── validation.yaml +``` + +Define a helper function to run kustomize with the +correct environment and flags for plugins: + + +``` +function kustomizeBd { + XDG_CONFIG_HOME=$DEMO_HOME \ + kustomize build \ + --enable_alpha_plugins \ + $DEMO_HOME/$1 +} +``` + +Build the valid variant + + +``` +kustomizeBd valid +``` +The output contains a ConfigMap as + +```yaml +apiVersion: v1 +data: + foo: bar +kind: ConfigMap +metadata: + name: cm +``` + +Build the invalid variant + +``` +kustomizeBd invalid +``` + +The output is an error as +```shell +data: Invalid type. Expected: object, given: array +``` + +## cleanup + + +```shell +rm -rf $DEMO_HOME +``` \ No newline at end of file diff --git a/examples/validationTransformer/invalid.yaml b/examples/validationTransformer/invalid.yaml new file mode 100644 index 000000000..e4da7867a --- /dev/null +++ b/examples/validationTransformer/invalid.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: cm +data: +- foo: bar \ No newline at end of file diff --git a/examples/validationTransformer/valid.yaml b/examples/validationTransformer/valid.yaml new file mode 100644 index 000000000..b6116f140 --- /dev/null +++ b/examples/validationTransformer/valid.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: cm +data: + foo: bar