mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-11 17:12:51 +00:00
refactor function filters
This commit is contained in:
@@ -57,8 +57,10 @@ type RunFns struct {
|
||||
// and only use explicit sources
|
||||
NoFunctionsFromInput *bool
|
||||
|
||||
// for testing purposes only
|
||||
containerFilterProvider func(string, string, string, *yaml.RNode) kio.Filter
|
||||
// functionFilterProvider provides a filter to perform the function.
|
||||
// this is a variable so it can be mocked in tests
|
||||
functionFilterProvider func(
|
||||
filter filters.FunctionSpec, api *yaml.RNode) kio.Filter
|
||||
}
|
||||
|
||||
// Execute runs the command
|
||||
@@ -110,21 +112,21 @@ func (r RunFns) getNodesAndFilters() (
|
||||
func (r RunFns) getFilters(nodes []*yaml.RNode) ([]kio.Filter, error) {
|
||||
var fltrs []kio.Filter
|
||||
|
||||
// implicit filters from the input Resources
|
||||
// fns from annotations on the input resources
|
||||
f, err := r.getFunctionsFromInput(nodes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fltrs = append(fltrs, f...)
|
||||
|
||||
// explicit filters from a list of directories
|
||||
// fns from directories specified on the struct
|
||||
f, err = r.getFunctionsFromFunctionPaths()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fltrs = append(fltrs, f...)
|
||||
|
||||
// explicit filters from a list of directories
|
||||
// explicit fns specified on the struct
|
||||
f, err = r.getFunctionsFromFunctions()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -156,7 +158,6 @@ func (r RunFns) getFunctionsFromInput(nodes []*yaml.RNode) ([]kio.Filter, error)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var fltrs []kio.Filter
|
||||
buff := &kio.PackageBuffer{}
|
||||
err := kio.Pipeline{
|
||||
Inputs: []kio.Reader{&kio.PackageBuffer{Nodes: nodes}},
|
||||
@@ -167,95 +168,50 @@ func (r RunFns) getFunctionsFromInput(nodes []*yaml.RNode) ([]kio.Filter, error)
|
||||
return nil, err
|
||||
}
|
||||
sortFns(buff)
|
||||
for i := range buff.Nodes {
|
||||
api := buff.Nodes[i]
|
||||
network := ""
|
||||
img, path := filters.GetContainerName(api)
|
||||
|
||||
required, err := filters.GetContainerNetworkRequired(api)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if required {
|
||||
if !r.Network {
|
||||
// TODO(eddizane): Provide error info about which function needs the network
|
||||
return fltrs, errors.Errorf("network required but not enabled with --network")
|
||||
}
|
||||
network = r.NetworkName
|
||||
}
|
||||
|
||||
fltrs = append(fltrs, r.containerFilterProvider(img, path, network, api))
|
||||
}
|
||||
return fltrs, nil
|
||||
return r.getFunctionFilters(false, buff.Nodes...)
|
||||
}
|
||||
|
||||
// getFunctionsFromFunctionPaths returns the set of functions read from r.FunctionPaths
|
||||
// as a slice of Filters
|
||||
func (r RunFns) getFunctionsFromFunctionPaths() ([]kio.Filter, error) {
|
||||
var fltrs []kio.Filter
|
||||
buff := &kio.PackageBuffer{}
|
||||
for i := range r.FunctionPaths {
|
||||
err := kio.Pipeline{
|
||||
Inputs: []kio.Reader{kio.LocalPackageReader{PackagePath: r.FunctionPaths[i]}},
|
||||
Inputs: []kio.Reader{
|
||||
kio.LocalPackageReader{PackagePath: r.FunctionPaths[i]},
|
||||
},
|
||||
Outputs: []kio.Writer{buff},
|
||||
}.Execute()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
for i := range buff.Nodes {
|
||||
api := buff.Nodes[i]
|
||||
network := ""
|
||||
img, path := filters.GetContainerName(api)
|
||||
|
||||
required, err := filters.GetContainerNetworkRequired(api)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if required {
|
||||
if !r.Network {
|
||||
// TODO(eddiezane): Provide error info about which function needs the network
|
||||
return fltrs, errors.Errorf("network required but not enabled with --network")
|
||||
}
|
||||
network = r.NetworkName
|
||||
}
|
||||
|
||||
c := r.containerFilterProvider(img, path, network, api)
|
||||
cf, ok := c.(*filters.ContainerFilter)
|
||||
if ok {
|
||||
// functions provided by FunctionPaths are globally scoped
|
||||
cf.GlobalScope = true
|
||||
}
|
||||
fltrs = append(fltrs, c)
|
||||
}
|
||||
return fltrs, nil
|
||||
return r.getFunctionFilters(true, buff.Nodes...)
|
||||
}
|
||||
|
||||
// getFunctionsFromFunctions returns the set of explicitly provided functions as
|
||||
// Filters
|
||||
func (r RunFns) getFunctionsFromFunctions() ([]kio.Filter, error) {
|
||||
var fltrs []kio.Filter
|
||||
for i := range r.Functions {
|
||||
api := r.Functions[i]
|
||||
network := ""
|
||||
img, path := filters.GetContainerName(api)
|
||||
return r.getFunctionFilters(true, r.Functions...)
|
||||
}
|
||||
|
||||
required, err := filters.GetContainerNetworkRequired(api)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if required {
|
||||
func (r RunFns) getFunctionFilters(global bool, fns ...*yaml.RNode) (
|
||||
[]kio.Filter, error) {
|
||||
var fltrs []kio.Filter
|
||||
for i := range fns {
|
||||
api := fns[i]
|
||||
spec := filters.GetFunctionSpec(api)
|
||||
if spec.Container.Network.Required {
|
||||
if !r.Network {
|
||||
// TODO(eddizane): Provide error info about which function needs the network
|
||||
// TODO(eddiezane): Provide error info about which function needs the network
|
||||
return fltrs, errors.Errorf("network required but not enabled with --network")
|
||||
}
|
||||
network = r.NetworkName
|
||||
spec.Network = r.NetworkName
|
||||
}
|
||||
|
||||
c := r.containerFilterProvider(img, path, network, api)
|
||||
c := r.functionFilterProvider(*spec, api)
|
||||
cf, ok := c.(*filters.ContainerFilter)
|
||||
if ok {
|
||||
// functions provided by Functions are globally scoped
|
||||
if global && ok {
|
||||
cf.GlobalScope = true
|
||||
}
|
||||
fltrs = append(fltrs, c)
|
||||
@@ -327,17 +283,26 @@ func (r *RunFns) init() {
|
||||
}
|
||||
}
|
||||
|
||||
// if containerFilterProvider hasn't been set, use the default
|
||||
if r.containerFilterProvider == nil {
|
||||
r.containerFilterProvider = func(image, path, network string, api *yaml.RNode) kio.Filter {
|
||||
cf := &filters.ContainerFilter{
|
||||
Image: image,
|
||||
Config: api,
|
||||
Network: network,
|
||||
StorageMounts: r.StorageMounts,
|
||||
GlobalScope: r.GlobalScope,
|
||||
}
|
||||
return cf
|
||||
}
|
||||
// functionFilterProvider set the filter provider
|
||||
if r.functionFilterProvider == nil {
|
||||
r.functionFilterProvider = r.ffp
|
||||
}
|
||||
}
|
||||
|
||||
// ffp provides function filters
|
||||
func (r *RunFns) ffp(spec filters.FunctionSpec, api *yaml.RNode) kio.Filter {
|
||||
if spec.Container.Image != "" {
|
||||
return &filters.ContainerFilter{
|
||||
Image: spec.Container.Image,
|
||||
Config: api,
|
||||
Network: spec.Network,
|
||||
StorageMounts: r.StorageMounts,
|
||||
GlobalScope: r.GlobalScope,
|
||||
}
|
||||
}
|
||||
return noOpFilter
|
||||
}
|
||||
|
||||
var noOpFilter = kio.FilterFunc(func(in []*yaml.RNode) ([]*yaml.RNode, error) {
|
||||
return in, nil
|
||||
})
|
||||
|
||||
@@ -47,10 +47,15 @@ func TestRunFns_init(t *testing.T) {
|
||||
api, err := yaml.Parse(`apiVersion: apps/v1
|
||||
kind:
|
||||
`)
|
||||
spec := filters.FunctionSpec{
|
||||
Container: filters.ContainerSpec{
|
||||
Image: "example.com:version",
|
||||
},
|
||||
}
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
filter := instance.containerFilterProvider("example.com:version", "", "", api)
|
||||
filter := instance.functionFilterProvider(spec, api)
|
||||
assert.Equal(t, &filters.ContainerFilter{Image: "example.com:version", Config: api}, filter)
|
||||
}
|
||||
|
||||
@@ -69,7 +74,16 @@ kind:
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
filter := instance.containerFilterProvider("example.com:version", "", "", api)
|
||||
|
||||
spec := filters.FunctionSpec{
|
||||
Container: filters.ContainerSpec{
|
||||
Image: "example.com:version",
|
||||
},
|
||||
}
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
filter := instance.functionFilterProvider(spec, api)
|
||||
assert.Equal(t, &filters.ContainerFilter{
|
||||
Image: "example.com:version", Config: api, GlobalScope: true}, filter)
|
||||
}
|
||||
@@ -131,7 +145,7 @@ func TestRunFns_Execute__initDefault(t *testing.T) {
|
||||
tt := tests[i]
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
(&tt.instance).init()
|
||||
(&tt.instance).containerFilterProvider = nil
|
||||
(&tt.instance).functionFilterProvider = nil
|
||||
if !assert.Equal(t, tt.expected, tt.instance) {
|
||||
t.FailNow()
|
||||
}
|
||||
@@ -505,7 +519,7 @@ func TestCmd_Execute(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
instance := RunFns{Path: dir, containerFilterProvider: getFilterProvider(t)}
|
||||
instance := RunFns{Path: dir, functionFilterProvider: getFilterProvider(t)}
|
||||
if !assert.NoError(t, instance.Execute()) {
|
||||
t.FailNow()
|
||||
}
|
||||
@@ -534,9 +548,9 @@ func TestCmd_Execute_setFunctionPaths(t *testing.T) {
|
||||
|
||||
// run the functions, providing the path to the directory of filters
|
||||
instance := RunFns{
|
||||
FunctionPaths: []string{tmpF.Name()},
|
||||
Path: dir,
|
||||
containerFilterProvider: getFilterProvider(t),
|
||||
FunctionPaths: []string{tmpF.Name()},
|
||||
Path: dir,
|
||||
functionFilterProvider: getFilterProvider(t),
|
||||
}
|
||||
// initialize the defaults
|
||||
instance.init()
|
||||
@@ -566,9 +580,9 @@ func TestCmd_Execute_setOutput(t *testing.T) {
|
||||
|
||||
out := &bytes.Buffer{}
|
||||
instance := RunFns{
|
||||
Output: out, // write to out
|
||||
Path: dir,
|
||||
containerFilterProvider: getFilterProvider(t),
|
||||
Output: out, // write to out
|
||||
Path: dir,
|
||||
functionFilterProvider: getFilterProvider(t),
|
||||
}
|
||||
// initialize the defaults
|
||||
instance.init()
|
||||
@@ -614,9 +628,9 @@ func TestCmd_Execute_setInput(t *testing.T) {
|
||||
}
|
||||
|
||||
instance := RunFns{
|
||||
Input: input, // read from input
|
||||
Path: outDir,
|
||||
containerFilterProvider: getFilterProvider(t),
|
||||
Input: input, // read from input
|
||||
Path: outDir,
|
||||
functionFilterProvider: getFilterProvider(t),
|
||||
}
|
||||
// initialize the defaults
|
||||
instance.init()
|
||||
@@ -659,8 +673,8 @@ func setupTest(t *testing.T) string {
|
||||
// getFilterProvider fakes the creation of a filter, replacing the ContainerFiler with
|
||||
// a filter to s/kind: Deployment/kind: StatefulSet/g.
|
||||
// this can be used to simulate running a filter.
|
||||
func getFilterProvider(t *testing.T) func(string, string, string, *yaml.RNode) kio.Filter {
|
||||
return func(s, _, _ string, node *yaml.RNode) kio.Filter {
|
||||
func getFilterProvider(t *testing.T) func(filters.FunctionSpec, *yaml.RNode) kio.Filter {
|
||||
return func(f filters.FunctionSpec, node *yaml.RNode) kio.Filter {
|
||||
// parse the filter from the input
|
||||
filter := yaml.YFilter{}
|
||||
b := &bytes.Buffer{}
|
||||
|
||||
Reference in New Issue
Block a user