
1. Extending templater with kyaml functions and creating combined catalogue to be able to request/update the existing resources. This is based on 'everything is transformer' concept introduced in kustomize 4.x That includes gathering all secrets into 1 variable catalogue and special mechanism to regenerate/merge with manual secrets. 2. Implementing 'catalogue per cluster' approach for secrets. 3. Rearranging secrets so it's possible to use: pgp (each person may have his own key), age, Hachicorp Vault and etc and the list of people who can decrypt documents is set in a special file. Since in some cases there should be a separate list of people who can decrypt data - this list is set for each cluster (ephemeral and target) separatelly. Closes: #586 Change-Id: I038f84dd138d5ad4a35f4862c61ff2124c2fd530
435 lines
6.9 KiB
Go
435 lines
6.9 KiB
Go
/*
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
https://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package extlib
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"bytes"
|
|
"strings"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"sigs.k8s.io/kustomize/kyaml/kio"
|
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
|
|
|
kfilters "sigs.k8s.io/kustomize/kyaml/kio/filters"
|
|
)
|
|
|
|
func TestKFilter(t *testing.T) {
|
|
testCases := []struct {
|
|
in string
|
|
expectedOut kio.Filter
|
|
}{
|
|
{
|
|
in: `
|
|
kind: GrepFilter
|
|
path:
|
|
- metadata
|
|
- annotations
|
|
- test-annotation
|
|
value: ^x$
|
|
invertMatch: true
|
|
`,
|
|
expectedOut: kfilters.GrepFilter{
|
|
Path: []string{
|
|
"metadata",
|
|
"annotations",
|
|
"test-annotation",
|
|
},
|
|
Value: "^x$",
|
|
InvertMatch: true,
|
|
},
|
|
},
|
|
{
|
|
in: `
|
|
kind: NonExistentFilter
|
|
path:
|
|
- metadata
|
|
`,
|
|
expectedOut: nil,
|
|
},
|
|
{
|
|
in: `
|
|
kind: GrepFilter
|
|
path: "incorrectdata"
|
|
`,
|
|
expectedOut: nil,
|
|
},
|
|
{
|
|
in: `
|
|
kind: Modifier
|
|
pipeline: "incorrectdata"
|
|
`,
|
|
expectedOut: nil,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
r := kFilter(tc.in)
|
|
|
|
// GrepFilter is a special case
|
|
grepFilter, ok := r.(kfilters.GrepFilter)
|
|
if ok {
|
|
require.NotNil(t, grepFilter.Compare)
|
|
grepFilter.Compare = nil
|
|
r = grepFilter
|
|
}
|
|
|
|
assert.Equal(t, tc.expectedOut, r)
|
|
}
|
|
}
|
|
|
|
func TestKPipe(t *testing.T) {
|
|
testCases := []struct {
|
|
in string
|
|
filters string
|
|
expectedOut string
|
|
}{
|
|
{
|
|
in: `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: cf1
|
|
---
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: cf2
|
|
---
|
|
apiVersion: v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: cf1
|
|
`,
|
|
filters: `
|
|
kind: GrepFilter
|
|
path:
|
|
- metadata
|
|
- name
|
|
value: cf1
|
|
---
|
|
kind: GrepFilter
|
|
path:
|
|
- kind
|
|
value: ConfigMap
|
|
`,
|
|
expectedOut: `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: cf1
|
|
`,
|
|
},
|
|
{
|
|
in: `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: cf1
|
|
`,
|
|
filters: `
|
|
kind: InvalidFilter
|
|
`,
|
|
expectedOut: `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: cf1
|
|
`,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
// convert in to []*yaml.RNode
|
|
b := kio.PackageBuffer{}
|
|
p := kio.Pipeline{
|
|
Inputs: []kio.Reader{&kio.ByteReader{Reader: bytes.NewBufferString(tc.in)}},
|
|
Outputs: []kio.Writer{&b},
|
|
}
|
|
err := p.Execute()
|
|
require.NoError(t, err)
|
|
|
|
// get list of filters
|
|
kfilters := []interface{}{}
|
|
for _, flt := range strings.Split(tc.filters, "\n---\n") {
|
|
kfilters = append(kfilters, kFilter(flt))
|
|
}
|
|
|
|
nodes := kPipe(b.Nodes, kfilters)
|
|
|
|
// convert to string and compare with expected
|
|
out := &bytes.Buffer{}
|
|
err = kio.ByteWriter{Writer: out}.Write(nodes)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tc.expectedOut[1:], out.String())
|
|
}
|
|
}
|
|
|
|
func TestYFilter(t *testing.T) {
|
|
testCases := []struct {
|
|
in string
|
|
expectedOut yaml.Filter
|
|
}{
|
|
{
|
|
in: `
|
|
kind: PathGetter
|
|
path: ["data", "fld1"]
|
|
`,
|
|
expectedOut: &yaml.PathGetter{
|
|
Kind: "PathGetter",
|
|
Path: []string{
|
|
"data",
|
|
"fld1",
|
|
},
|
|
},
|
|
},
|
|
{in: `
|
|
kind: PathGetter
|
|
path: "data"
|
|
`,
|
|
expectedOut: nil,
|
|
},
|
|
{in: `
|
|
kind: nonExistingFilter
|
|
path: "data"
|
|
`,
|
|
expectedOut: nil,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
out := yFilter(tc.in)
|
|
assert.Equal(t, tc.expectedOut, out)
|
|
}
|
|
}
|
|
|
|
func TestYPipe(t *testing.T) {
|
|
testCases := []struct {
|
|
in string
|
|
filters string
|
|
expectedIn string
|
|
expectedOut string
|
|
}{
|
|
{
|
|
in: `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: cf1
|
|
`,
|
|
filters: `
|
|
kind: PathGetter
|
|
path: ["metadata"]
|
|
---
|
|
kind: FieldSetter
|
|
name: "name"
|
|
stringValue: "cf2"
|
|
`,
|
|
expectedIn: `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: cf2
|
|
`,
|
|
expectedOut: `
|
|
cf2
|
|
`,
|
|
},
|
|
{
|
|
in: `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: cf1
|
|
`,
|
|
filters: `
|
|
kind: InvalidPathGetter
|
|
path: ["metadata"]
|
|
`,
|
|
},
|
|
{
|
|
in: `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: cf1
|
|
`,
|
|
filters: `
|
|
kind: PathGetter
|
|
path: ["xmetadata"]
|
|
---
|
|
kind: FieldSetter
|
|
name: "namex"
|
|
stringValue: "cf2"
|
|
`,
|
|
expectedIn: `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: cf1
|
|
`,
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
inRNode, err := yaml.Parse(tc.in)
|
|
require.NoError(t, err)
|
|
|
|
// get list of filters
|
|
yfilters := []interface{}{}
|
|
for _, flt := range strings.Split(tc.filters, "\n---\n") {
|
|
yfilters = append(yfilters, yFilter(flt))
|
|
}
|
|
|
|
outRNode := yPipe(inRNode, yfilters)
|
|
|
|
if tc.expectedOut != "" {
|
|
require.NotNil(t, outRNode)
|
|
out, err := outRNode.String()
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tc.expectedOut[1:], out)
|
|
}
|
|
|
|
if tc.expectedIn != "" {
|
|
in, err := inRNode.String()
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tc.expectedIn[1:], in)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestYValue(t *testing.T) {
|
|
testCases := []struct {
|
|
in string
|
|
expectedOut interface{}
|
|
}{
|
|
{
|
|
in: `
|
|
x
|
|
`,
|
|
expectedOut: "x",
|
|
},
|
|
{
|
|
in: `
|
|
kind: x
|
|
value: b
|
|
list:
|
|
- a
|
|
- b
|
|
`,
|
|
expectedOut: map[string]interface{}{
|
|
"kind": "x",
|
|
"list": []interface{}{
|
|
"a",
|
|
"b",
|
|
},
|
|
"value": "b",
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
inRNode, err := yaml.Parse(tc.in)
|
|
require.NoError(t, err)
|
|
|
|
out := yValue(inRNode)
|
|
assert.Equal(t, tc.expectedOut, out)
|
|
}
|
|
}
|
|
|
|
func TestKYFilter(t *testing.T) {
|
|
testCases := []struct {
|
|
in string
|
|
filters string
|
|
expectedOut string
|
|
}{
|
|
{
|
|
in: `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: cf1
|
|
labels: {}
|
|
---
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: cf2
|
|
labels: {}
|
|
---
|
|
apiVersion: v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: cf1
|
|
labels: {}
|
|
`,
|
|
filters: `
|
|
kind: PathGetter
|
|
path: ["metadata", "labels"]
|
|
---
|
|
kind: FieldSetter
|
|
name: "newlabel"
|
|
stringValue: "newvalue"
|
|
`,
|
|
expectedOut: `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: cf1
|
|
labels: {newlabel: newvalue}
|
|
---
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: cf2
|
|
labels: {newlabel: newvalue}
|
|
---
|
|
apiVersion: v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: cf1
|
|
labels: {newlabel: newvalue}
|
|
`,
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
// convert in to []*yaml.RNode
|
|
b := kio.PackageBuffer{}
|
|
p := kio.Pipeline{
|
|
Inputs: []kio.Reader{&kio.ByteReader{Reader: bytes.NewBufferString(tc.in)}},
|
|
Outputs: []kio.Writer{&b},
|
|
}
|
|
err := p.Execute()
|
|
require.NoError(t, err)
|
|
|
|
// get list of filters
|
|
yfilters := []interface{}{}
|
|
for _, flt := range strings.Split(tc.filters, "\n---\n") {
|
|
yfilters = append(yfilters, yFilter(flt))
|
|
}
|
|
|
|
kfilters := []interface{}{newKYFilter(yfilters)}
|
|
nodes := kPipe(b.Nodes, kfilters)
|
|
|
|
// convert to string and compare with expected
|
|
out := &bytes.Buffer{}
|
|
err = kio.ByteWriter{Writer: out}.Write(nodes)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tc.expectedOut[1:], out.String())
|
|
}
|
|
}
|