Exec function implementation

This commit is contained in:
Phillip Wittrock
2020-05-03 15:44:10 -07:00
parent fd70213ca2
commit 096ad8c95c
7 changed files with 157 additions and 4 deletions

View File

@@ -31,7 +31,7 @@
// //
// Validator Functions // Validator Functions
// //
// Functions may validate resources, returning Results as go errors. Results may contain // Functions may validate resources, returning results as go errors. results may contain
// different items for different validation failures. // different items for different validation failures.
// //
// Configuring Functions // Configuring Functions

View File

@@ -281,7 +281,7 @@ functionConfig:
} }
// ExampleCommand_validate validates that all Deployment resources have the replicas field set. // ExampleCommand_validate validates that all Deployment resources have the replicas field set.
// If any Deployments do not contain spec.replicas, then the function will return Results // If any Deployments do not contain spec.replicas, then the function will return results
// which will be set on ResourceList.results // which will be set on ResourceList.results
func ExampleCommand_validate() { func ExampleCommand_validate() {
cmd := framework.Command(nil, func(nodes []*yaml.RNode) ([]*yaml.RNode, error) { cmd := framework.Command(nil, func(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
@@ -320,7 +320,7 @@ func ExampleCommand_validate() {
}) })
} }
// framework will only consider Results an error if it has at least 1 item // framework will only consider results an error if it has at least 1 item
return nodes, framework.Result{ return nodes, framework.Result{
Name: "replicas-validator", Name: "replicas-validator",
Items: validationResults, Items: validationResults,

View File

@@ -0,0 +1,5 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// Package exec contains the exec function implementation.
package exec

View File

@@ -0,0 +1,34 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package exec
import (
"io"
"os/exec"
"sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
type Filter struct {
// Path is the path to the executable to run
Path string `yaml:"path,omitempty"`
// Args are the arguments to the executable
Args []string `yaml:"args,omitempty"`
runtimeutil.FunctionFilter
}
func (c *Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
c.FunctionFilter.Run = c.Run
return c.FunctionFilter.Filter(nodes)
}
func (c *Filter) Run(reader io.Reader, writer io.Writer) error {
cmd := exec.Command(c.Path, c.Args...)
cmd.Stdin = reader
cmd.Stdout = writer
return cmd.Run()
}

View File

@@ -0,0 +1,112 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package exec_test
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/kyaml/fn/runtime/exec"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
func TestFunctionFilter_Filter(t *testing.T) {
var tests = []struct {
name string
input []string
functionConfig string
expectedOutput []string
expectedError string
instance exec.Filter
}{
{
name: "exec_sed",
input: []string{
`apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-foo`,
`apiVersion: v1
kind: Service
metadata:
name: service-foo`,
},
expectedOutput: []string{
`apiVersion: apps/v1
kind: StatefulSet
metadata:
name: deployment-foo
annotations:
config.kubernetes.io/path: 'statefulset_deployment-foo.yaml'
`,
`apiVersion: v1
kind: Service
metadata:
name: service-foo
annotations:
config.kubernetes.io/path: 'service_service-foo.yaml'
`,
},
expectedError: "",
instance: exec.Filter{
Path: "sed",
Args: []string{"s/Deployment/StatefulSet/g"},
},
},
}
for i := range tests {
tt := tests[i]
t.Run(tt.name, func(t *testing.T) {
// initialize the inputs for the FunctionFilter
var inputs []*yaml.RNode
for i := range tt.input {
node, err := yaml.Parse(tt.input[i])
if !assert.NoError(t, err) {
t.FailNow()
}
inputs = append(inputs, node)
}
if tt.functionConfig != "" {
fc, err := yaml.Parse(tt.functionConfig)
if !assert.NoError(t, err) {
t.FailNow()
}
tt.instance.FunctionConfig = fc
}
// run the function
output, err := tt.instance.Filter(inputs)
// check for errors
if tt.expectedError != "" {
if !assert.EqualError(t, err, tt.expectedError) {
t.FailNow()
}
return
}
if !assert.NoError(t, err) {
t.FailNow()
}
// verify the output
var actual []string
for i := range output {
s, err := output[i].String()
if !assert.NoError(t, err) {
t.FailNow()
}
actual = append(actual, strings.TrimSpace(s))
}
var expected []string
for i := range tt.expectedOutput {
expected = append(expected, strings.TrimSpace(tt.expectedOutput[i]))
}
if !assert.Equal(t, expected, actual) {
t.FailNow()
}
})
}
}

View File

@@ -1 +0,0 @@
package runtimeutil

View File

@@ -1,3 +1,6 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package runtimeutil package runtimeutil
type DeferFailureFunction interface { type DeferFailureFunction interface {