PoC to add Components to a separate components list (instead of resources)

If this idea is preferred, the code could really do with a refactor (probably using closures to control the behaviour of accumulate directory)
This commit is contained in:
Paul Martin
2020-05-14 19:16:04 +01:00
parent fdfb58cc3e
commit c5c53011da
3 changed files with 101 additions and 23 deletions

View File

@@ -164,6 +164,10 @@ func (kt *KustTarget) accumulateTarget(ra *accumulator.ResAccumulator) (
if err != nil { if err != nil {
return nil, errors.Wrap(err, "accumulating resources") return nil, errors.Wrap(err, "accumulating resources")
} }
ra, err = kt.accumulateComponents(ra, kt.kustomization.Components)
if err != nil {
return nil, errors.Wrap(err, "accumulating components")
}
tConfig, err := builtinconfig.MakeTransformerConfig( tConfig, err := builtinconfig.MakeTransformerConfig(
kt.ldr, kt.kustomization.Configurations) kt.ldr, kt.kustomization.Configurations)
if err != nil { if err != nil {
@@ -273,7 +277,7 @@ func (kt *KustTarget) accumulateResources(
return nil, fmt.Errorf("accumulateFile %q, loader.New %q", errF, errL) return nil, fmt.Errorf("accumulateFile %q, loader.New %q", errF, errL)
} }
var errD error var errD error
ra, errD = kt.accumulateDirectory(ra, ldr) ra, errD = kt.accumulateDirectory(ra, ldr, false)
if errD != nil { if errD != nil {
return nil, fmt.Errorf("accumulateFile %q, accumulateDirector: %q", errF, errD) return nil, fmt.Errorf("accumulateFile %q, accumulateDirector: %q", errF, errD)
} }
@@ -282,8 +286,27 @@ func (kt *KustTarget) accumulateResources(
return ra, nil return ra, nil
} }
// accumulateResources fills the given resourceAccumulator
// with resources read from the given list of paths.
func (kt *KustTarget) accumulateComponents(
ra *accumulator.ResAccumulator, paths []string) (*accumulator.ResAccumulator, error) {
for _, path := range paths {
// Components always refer to directories
ldr, errL := kt.ldr.New(path)
if errL != nil {
return nil, fmt.Errorf("loader.New %q", errL)
}
var errD error
ra, errD = kt.accumulateDirectory(ra, ldr, true)
if errD != nil {
return nil, fmt.Errorf("accumulateDirectory: %q", errD)
}
}
return ra, nil
}
func (kt *KustTarget) accumulateDirectory( func (kt *KustTarget) accumulateDirectory(
ra *accumulator.ResAccumulator, ldr ifc.Loader) (*accumulator.ResAccumulator, error) { ra *accumulator.ResAccumulator, ldr ifc.Loader, isComponent bool) (*accumulator.ResAccumulator, error) {
defer ldr.Cleanup() defer ldr.Cleanup()
subKt := NewKustTarget( subKt := NewKustTarget(
ldr, kt.validator, kt.rFactory, kt.tFactory, kt.pLdr) ldr, kt.validator, kt.rFactory, kt.tFactory, kt.pLdr)
@@ -292,6 +315,13 @@ func (kt *KustTarget) accumulateDirectory(
return nil, errors.Wrapf( return nil, errors.Wrapf(
err, "couldn't make target for path '%s'", ldr.Root()) err, "couldn't make target for path '%s'", ldr.Root())
} }
if isComponent && subKt.kustomization.Kind != types.ComponentKind {
return nil, fmt.Errorf(
"expected kind '%s' for path '%s' but got '%s'", types.ComponentKind, ldr.Root(), subKt.kustomization.Kind)
} else if !isComponent && subKt.kustomization.Kind == types.ComponentKind {
return nil, fmt.Errorf(
"expected kind != '%s' for path '%s'", types.ComponentKind, ldr.Root())
}
var subRa *accumulator.ResAccumulator var subRa *accumulator.ResAccumulator
if subKt.kustomization.Kind == types.ComponentKind { if subKt.kustomization.Kind == types.ComponentKind {

View File

@@ -62,8 +62,10 @@ func writeComponentProd(th kusttest_test.Harness) {
th.WriteK("/app/prod", ` th.WriteK("/app/prod", `
resources: resources:
- ../base - ../base
- ../patch
- db - db
components:
- ../patch
`) `)
th.WriteF("/app/prod/db", ` th.WriteF("/app/prod/db", `
apiVersion: v1 apiVersion: v1
@@ -105,16 +107,16 @@ metadata:
apiVersion: v1 apiVersion: v1
kind: Deployment kind: Deployment
metadata: metadata:
name: patched-stub name: patched-db
spec: spec:
replicas: 1 type: Logical
--- ---
apiVersion: v1 apiVersion: v1
kind: Deployment kind: Deployment
metadata: metadata:
name: db name: patched-stub
spec: spec:
type: Logical replicas: 1
`) `)
} }
@@ -135,9 +137,11 @@ configMapGenerator:
th.WriteK("/app/prod", ` th.WriteK("/app/prod", `
resources: resources:
- ../base - ../base
- db
components:
- ../patch - ../patch
- ../additionalpatch - ../additionalpatch
- db
`) `)
m := th.Run("/app/prod", th.MakeDefaultOptions()) m := th.Run("/app/prod", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, ` th.AssertActualEqualsExpected(m, `
@@ -162,16 +166,16 @@ metadata:
apiVersion: v1 apiVersion: v1
kind: Deployment kind: Deployment
metadata: metadata:
name: patched-stub name: patched-db
spec: spec:
replicas: 1 type: Logical
--- ---
apiVersion: v1 apiVersion: v1
kind: Deployment kind: Deployment
metadata: metadata:
name: db name: patched-stub
spec: spec:
type: Logical replicas: 1
`) `)
} }
@@ -183,7 +187,7 @@ func TestNestedComponents(t *testing.T) {
th.WriteF("/app/additionalpatch/kustomization.yaml", ` th.WriteF("/app/additionalpatch/kustomization.yaml", `
apiVersion: kustomize.config.k8s.io/v1alpha1 apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component kind: Component
resources: components:
- ../patch - ../patch
configMapGenerator: configMapGenerator:
- name: my-configmap - name: my-configmap
@@ -194,8 +198,10 @@ configMapGenerator:
th.WriteK("/app/prod", ` th.WriteK("/app/prod", `
resources: resources:
- ../base - ../base
- ../additionalpatch
- db - db
components:
- ../additionalpatch
`) `)
m := th.Run("/app/prod", th.MakeDefaultOptions()) m := th.Run("/app/prod", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, ` th.AssertActualEqualsExpected(m, `
@@ -220,16 +226,16 @@ metadata:
apiVersion: v1 apiVersion: v1
kind: Deployment kind: Deployment
metadata: metadata:
name: patched-stub name: patched-db
spec: spec:
replicas: 1 type: Logical
--- ---
apiVersion: v1 apiVersion: v1
kind: Deployment kind: Deployment
metadata: metadata:
name: db name: patched-stub
spec: spec:
type: Logical replicas: 1
`) `)
} }
@@ -283,16 +289,16 @@ metadata:
apiVersion: v1 apiVersion: v1
kind: Deployment kind: Deployment
metadata: metadata:
name: patched-stub name: patched-db
spec: spec:
replicas: 1 type: Logical
--- ---
apiVersion: v1 apiVersion: v1
kind: Deployment kind: Deployment
metadata: metadata:
name: db name: patched-stub
spec: spec:
type: Logical replicas: 1
`) `)
} }
@@ -334,6 +340,44 @@ metadata:
`) `)
} }
func TestComponentsCannotBeAddedToResources(t *testing.T) {
th := kusttest_test.MakeHarness(t)
writeComponentBase(th)
writeComponentPatch(th)
th.WriteF("/app/custinres/kustomization.yaml", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
- ../patch
`)
err := th.RunWithErr("/app/custinres", th.MakeDefaultOptions())
if !strings.Contains(
err.Error(),
"expected kind != 'Component' for path '/app/patch'") {
t.Fatalf("unexpected error: %s", err)
}
}
func TestResourcesCannotBeAddedToComponents(t *testing.T) {
th := kusttest_test.MakeHarness(t)
writeComponentBase(th)
writeComponentPatch(th)
th.WriteF("/app/resincust/kustomization.yaml", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
components:
- ../base
- ../patch
`)
err := th.RunWithErr("/app/resincust", th.MakeDefaultOptions())
if !strings.Contains(
err.Error(),
"accumulating components: accumulateDirectory: \"expected kind 'Component' for path '/app/base' but got 'Kustomization'") {
t.Fatalf("unexpected error: %s", err)
}
}
func TestMissingOptionalComponentApiVersion(t *testing.T) { func TestMissingOptionalComponentApiVersion(t *testing.T) {
th := kusttest_test.MakeHarness(t) th := kusttest_test.MakeHarness(t)
writeComponentBase(th) writeComponentBase(th)

View File

@@ -75,10 +75,14 @@ type Kustomization struct {
// //
// Resources specifies relative paths to files holding YAML representations // Resources specifies relative paths to files holding YAML representations
// of kubernetes API objects, or specifcations of other kustomizations // of kubernetes API objects, or specifications of other kustomizations
// via relative paths, absolute paths, or URLs. // via relative paths, absolute paths, or URLs.
Resources []string `json:"resources,omitempty" yaml:"resources,omitempty"` Resources []string `json:"resources,omitempty" yaml:"resources,omitempty"`
// Components specifies relative paths to specifications of other Components
// via relative paths, absolute paths, or URLs.
Components []string `json:"components,omitempty" yaml:"components,omitempty"`
// Crds specifies relative paths to Custom Resource Definition files. // Crds specifies relative paths to Custom Resource Definition files.
// This allows custom resources to be recognized as operands, making // This allows custom resources to be recognized as operands, making
// it possible to add them to the Resources list. // it possible to add them to the Resources list.