From b4dbac1b84c4a99e4d9b6a6fee8982cbba36ac43 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Wed, 29 May 2019 13:49:31 -0700 Subject: [PATCH] add validation transformer --- pkg/kusttest/kusttestharness.go | 20 ++++- pkg/plugins/execplugin.go | 2 +- .../v1/validator/Validator | 35 ++++++++ .../v1/validator/validator_test.go | 79 +++++++++++++++++++ travis/pre-commit.sh | 4 + 5 files changed, 135 insertions(+), 5 deletions(-) create mode 100755 plugin/someteam.example.com/v1/validator/Validator create mode 100644 plugin/someteam.example.com/v1/validator/validator_test.go diff --git a/pkg/kusttest/kusttestharness.go b/pkg/kusttest/kusttestharness.go index fa10aa645..c2e7c1b4b 100644 --- a/pkg/kusttest/kusttestharness.go +++ b/pkg/kusttest/kusttestharness.go @@ -120,6 +120,21 @@ func (th *KustTestHarness) LoadAndRunGenerator( func (th *KustTestHarness) LoadAndRunTransformer( config, input string) resmap.ResMap { + resMap, err := th.runTransformer(config, input) + if err != nil { + th.t.Fatalf("Err: %v", err) + } + return resMap +} + +func (th *KustTestHarness) ErrorFromLoadAndRunTransformer( + config, input string) error { + _, err := th.runTransformer(config, input) + return err +} + +func (th *KustTestHarness) runTransformer( + config, input string) (resmap.ResMap, error) { transConfig, err := th.rf.RF().FromBytes([]byte(config)) if err != nil { th.t.Fatalf("Err: %v", err) @@ -133,10 +148,7 @@ func (th *KustTestHarness) LoadAndRunTransformer( th.t.Fatalf("Err: %v", err) } err = g.Transform(resMap) - if err != nil { - th.t.Fatalf("Err: %v", err) - } - return resMap + return resMap, err } func tabToSpace(input string) string { diff --git a/pkg/plugins/execplugin.go b/pkg/plugins/execplugin.go index 294097eb1..6835be800 100644 --- a/pkg/plugins/execplugin.go +++ b/pkg/plugins/execplugin.go @@ -148,7 +148,7 @@ func (p *ExecPlugin) Transform(rm resmap.ResMap) error { // invoke the plugin with resources as the input output, err := p.invokePlugin(resources) if err != nil { - return err + return fmt.Errorf("%v %s", err, string(output)) } // update the original ResMap based on the output diff --git a/plugin/someteam.example.com/v1/validator/Validator b/plugin/someteam.example.com/v1/validator/Validator new file mode 100755 index 000000000..a669196ee --- /dev/null +++ b/plugin/someteam.example.com/v1/validator/Validator @@ -0,0 +1,35 @@ +#!/bin/bash + + +# Validator transformer plugin by kubeval +# https://github.com/instrumenta/kubeval +# +# Assumes that kubeval is available from $PATH +# +# Reads Kubernetes resources from stdin +# Validates them and output in the stdout +# +# Example execution: +# cat | ./plugin/someteam.example.com/v1/Validator + +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 + diff --git a/plugin/someteam.example.com/v1/validator/validator_test.go b/plugin/someteam.example.com/v1/validator/validator_test.go new file mode 100644 index 000000000..c3cc89140 --- /dev/null +++ b/plugin/someteam.example.com/v1/validator/validator_test.go @@ -0,0 +1,79 @@ +// +build notravis + +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package main_test + +import ( + "strings" + "testing" + + "sigs.k8s.io/kustomize/pkg/kusttest" + "sigs.k8s.io/kustomize/plugin" +) + +func TestValidatorHappy(t *testing.T) { + tc := plugin.NewEnvForTest(t).Set() + defer tc.Reset() + + tc.BuildExecPlugin("someteam.example.com", "v1", "Validator") + th := kusttest_test.NewKustTestPluginHarness(t, "/app") + + rm := th.LoadAndRunTransformer(` +apiVersion: someteam.example.com/v1 +kind: Validator +metadata: + name: notImportantHere +`, + `apiVersion: v1 +kind: ConfigMap +metadata: + annotations: + foo: bar + name: some-cm +data: + foo: bar +`) + + th.AssertActualEqualsExpected(rm, ` +apiVersion: v1 +data: + foo: bar +kind: ConfigMap +metadata: + annotations: + foo: bar + name: some-cm +`) +} + +func TestValidatorUnHappy(t *testing.T) { + tc := plugin.NewEnvForTest(t).Set() + defer tc.Reset() + + tc.BuildExecPlugin("someteam.example.com", "v1", "Validator") + th := kusttest_test.NewKustTestPluginHarness(t, "/app") + + err := th.ErrorFromLoadAndRunTransformer(` +apiVersion: someteam.example.com/v1 +kind: Validator +metadata: + name: notImportantHere +`, + `apiVersion: v1 +kind: ConfigMap +metadata: + annotations: {} + name: some-cm +data: +- foo: bar +`) + if err == nil { + t.Fatalf("expected an error") + } + if !strings.Contains(err.Error(), + "data: Invalid type. Expected: object, given: array") { + t.Fatalf("incorrect error %v", err) + } +} diff --git a/travis/pre-commit.sh b/travis/pre-commit.sh index 67d1df014..09c7295e1 100755 --- a/travis/pre-commit.sh +++ b/travis/pre-commit.sh @@ -40,6 +40,10 @@ function testNoTravisGoTest { go test -v sigs.k8s.io/kustomize/plugin/someteam.example.com/v1/chartinflator/... \ -run TestChartInflator -tags=notravis mdrip --mode test --label helmtest README.md ./examples/chart.md + go test -v sigs.k8s.io/kustomize/plugin/someteam.example.com/v1/validator/... \ + -run TestValidatorHappy -tags=notravis + go test -v sigs.k8s.io/kustomize/plugin/someteam.example.com/v1/validator/... \ + -run TestValidatorUnHappy -tags=notravis } function testExamples {