This commit is contained in:
Jonathan Wong
2019-11-21 11:55:24 -08:00
40 changed files with 220 additions and 148 deletions

View File

@@ -23,10 +23,12 @@ linters:
- nakedret
- staticcheck
- structcheck
# - stylecheck (panics)
# - typecheck (fails in lots of places)
# stylecheck demands that acronyms not be treated as words
# in camelCase, so JsonOp become JSONOp, etc. Yuck.
# - stylecheck
- typecheck
- unconvert
# - unused (panics)
- unused
- unparam
- varcheck

View File

@@ -389,6 +389,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b h1:XfVGCX+0T4WOStkaOsJRllbsiImhB2jgVBGc9L0lPGc=
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=

View File

@@ -70,7 +70,9 @@ func (rv *refVarTransformer) replaceVars(in interface{}) (interface{}, error) {
// This field can potentially contain a $(VAR) since it is
// of string type.
return expansion2.Expand(s, rv.mappingFunc), nil
//nolint:staticcheck (erroneously claims that `case nil` is unreachable)
// staticcheck erroneously claims that `case nil`
// is unreachable here, so suppressing it.
//nolint:staticcheck
case nil:
return nil, nil
default:

View File

@@ -10,8 +10,8 @@ import (
)
// Demo custom configuration of a builtin transformation.
// This is a NamePrefixer that only touches Deployments
// and Services.
// This is a NamePrefixer that touches Deployments
// and Services exclusively.
func TestCustomNamePrefixer(t *testing.T) {
tc := kusttest_test.NewPluginTestEnv(t).Set()
defer tc.Reset()
@@ -99,118 +99,3 @@ metadata:
name: zzz-myService
`)
}
// Demo custom configuration as a base.
func TestReusableCustomNamePrefixer(t *testing.T) {
tc := kusttest_test.NewPluginTestEnv(t).Set()
defer tc.Reset()
tc.BuildGoPlugin(
"builtin", "", "PrefixSuffixTransformer")
tc.BuildGoPlugin(
"builtin", "", "LabelTransformer")
th := kusttest_test.NewKustTestHarnessAllowPlugins(t, "/app/foo")
// This kustomization file contains resources that
// all happen to be plugin configurations. This makes
// these plugins all available as part of a base,
// re-usable in any number of other kustomizations.
// Just specify the path (or URL) to this base in the
// "transformers:" field (not the "resources" field).
th.WriteK("/app/mytransformers", `
resources:
- prefixer.yaml
- labeller.yaml
`)
th.WriteF("/app/mytransformers/prefixer.yaml", `
apiVersion: builtin
kind: PrefixSuffixTransformer
metadata:
name: myPrefixer
prefix: zzz-
fieldSpecs:
- kind: Deployment
path: metadata/name
- kind: Service
path: metadata/name
`)
th.WriteF("/app/mytransformers/labeller.yaml", `
apiVersion: builtin
kind: LabelTransformer
metadata:
name: myLabeller
labels:
company: acmeCorp
fieldSpecs:
- path: spec/template/metadata/labels
kind: Deployment
`)
th.WriteK("/app/foo", `
resources:
- deployment.yaml
- role.yaml
- service.yaml
transformers:
- ../mytransformers
`)
th.WriteF("/app/foo/deployment.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeployment
spec:
template:
metadata:
labels:
backend: awesome
spec:
containers:
- name: whatever
image: whatever
`)
th.WriteF("/app/foo/role.yaml", `
apiVersion: v1
kind: Role
metadata:
name: myRole
`)
th.WriteF("/app/foo/service.yaml", `
apiVersion: v1
kind: Service
metadata:
name: myService
`)
m, err := th.MakeKustTarget().MakeCustomizedResMap()
if err != nil {
t.Fatalf("Err: %v", err)
}
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: zzz-myDeployment
spec:
template:
metadata:
labels:
backend: awesome
company: acmeCorp
spec:
containers:
- image: whatever
name: whatever
---
apiVersion: v1
kind: Role
metadata:
name: myRole
---
apiVersion: v1
kind: Service
metadata:
name: zzz-myService
`)
}

View File

@@ -0,0 +1,186 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package target_test
import (
"testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
// Demo custom configuration as a base.
// This test shows usage of three custom configurations sitting
// in a base, allowing them to be reused in any number of
// kustomizations.
func TestReusableCustomTransformers(t *testing.T) {
tc := kusttest_test.NewPluginTestEnv(t).Set()
defer tc.Reset()
tc.BuildGoPlugin(
"builtin", "", "PrefixSuffixTransformer")
tc.BuildGoPlugin(
"builtin", "", "AnnotationsTransformer")
tc.BuildGoPlugin(
"builtin", "", "LabelTransformer")
th := kusttest_test.NewKustTestHarnessAllowPlugins(t, "/app/staging")
// First write three custom configurations for builtin plugins.
// A custom name prefixer that only touches Deployments and Services.
th.WriteF("/app/mytransformers/deploymentServicePrefixer.yaml", `
apiVersion: builtin
kind: PrefixSuffixTransformer
metadata:
name: myPrefixer
prefix: bob-
fieldSpecs:
- kind: Deployment
path: metadata/name
- kind: Service
path: metadata/name
`)
// A custom annotator exclusively annotating Roles.
th.WriteF("/app/mytransformers/roleAnnotator.yaml", `
apiVersion: builtin
kind: AnnotationsTransformer
metadata:
name: myAnnotator
annotations:
# Imagine that SRE has not approved this role yet.
status: probationary
fieldSpecs:
- path: metadata/annotations
create: true
kind: Role
`)
// A custom labeller that only labels Deployments,
// and only labels them at their top metadata level
// exclusively. It does not modify selectors or
// add labels to pods in the template.
th.WriteF("/app/mytransformers/deploymentLabeller.yaml", `
apiVersion: builtin
kind: LabelTransformer
metadata:
name: myLabeller
labels:
pager: 867-5301
fieldSpecs:
- path: metadata/labels
create: true
kind: Deployment
`)
// Combine these custom transformers in one kustomization file.
// This kustomization file contains only resources that
// all happen to be plugin configurations. This makes
// these plugins re-usable as a group in any number of other
// kustomizations.
th.WriteK("/app/mytransformers", `
resources:
- deploymentServicePrefixer.yaml
- roleAnnotator.yaml
- deploymentLabeller.yaml
`)
// Finally, define the kustomization for the (arbitrarily named)
// staging environment.
th.WriteK("/app/staging", `
# Bring in the custom transformers.
transformers:
- ../mytransformers
# Also use the "classic" labeller, which behind the scenes uses
# the LabelTransformer, but with a broad configuration targeting
# many resources and fields (including selector fields).
# It's a big hammer - probably too big; the output shows all the
# places 'acmeCorp' now appears as a result. To avoid this,
# define your own config for your own LabelTransformer instance
# as shown above.
commonLabels:
company: acmeCorp
# Specify the resources to modify.
resources:
- deployment.yaml
- role.yaml
- service.yaml
`)
th.WriteF("/app/staging/deployment.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeployment
spec:
template:
metadata:
labels:
backend: flawless
spec:
containers:
- name: whatever
image: whatever
`)
th.WriteF("/app/staging/role.yaml", `
apiVersion: v1
kind: Role
metadata:
name: myRole
`)
th.WriteF("/app/staging/service.yaml", `
apiVersion: v1
kind: Service
metadata:
name: myService
`)
m, err := th.MakeKustTarget().MakeCustomizedResMap()
if err != nil {
t.Fatalf("Err: %v", err)
}
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
company: acmeCorp
pager: 867-5301
name: bob-myDeployment
spec:
selector:
matchLabels:
company: acmeCorp
template:
metadata:
labels:
backend: flawless
company: acmeCorp
spec:
containers:
- image: whatever
name: whatever
---
apiVersion: v1
kind: Role
metadata:
annotations:
status: probationary
labels:
company: acmeCorp
name: myRole
---
apiVersion: v1
kind: Service
metadata:
labels:
company: acmeCorp
name: bob-myService
spec:
selector:
company: acmeCorp
`)
}

View File

@@ -222,11 +222,6 @@ func (kt *KustTarget) computeInventory(
return ra.Transform(p)
}
func (kt *KustTarget) shouldAddHashSuffixesToGeneratedResources() bool {
return kt.kustomization.GeneratorOptions == nil ||
!kt.kustomization.GeneratorOptions.DisableNameSuffixHash
}
// AccumulateTarget returns a new ResAccumulator,
// holding customized resources and the data/rules used
// to do so. The name back references and vars are

View File

@@ -252,9 +252,10 @@ func (r *Resource) Behavior() types.GenerationBehavior {
return r.options.Behavior()
}
// NeedHashSuffix checks if the resource need a hash suffix
// NeedHashSuffix returns true if a resource content
// hash should be appended to the name of the resource.
func (r *Resource) NeedHashSuffix() bool {
return r.options != nil && r.options.NeedsHashSuffix()
return r.options != nil && r.options.ShouldAddHashSuffixToName()
}
// GetNamespace returns the namespace the resource thinks it's in.

View File

@@ -28,18 +28,17 @@ func (g *GenArgs) String() string {
}
return "{" +
strings.Join([]string{
"nsfx:" + strconv.FormatBool(g.NeedsHashSuffix()),
"nsfx:" + strconv.FormatBool(g.ShouldAddHashSuffixToName()),
"beh:" + g.Behavior().String()},
",") +
"}"
}
// NeedsHashSuffix returns true if the hash suffix is needed.
// It is needed when the two conditions are both met
// 1) GenArgs is not nil
// 2) DisableNameSuffixHash in GeneratorOptions is not set to true
func (g *GenArgs) NeedsHashSuffix() bool {
return g.args != nil && (g.opts == nil || !g.opts.DisableNameSuffixHash)
// ShouldAddHashSuffixToName returns true if a resource
// content hash should be appended to the name of the resource.
func (g *GenArgs) ShouldAddHashSuffixToName() bool {
return g.args != nil &&
(g.opts == nil || !g.opts.DisableNameSuffixHash)
}
// Behavior returns Behavior field of GeneratorArgs

View File

@@ -1,4 +1,4 @@
# cmd/kyaml
# cmd/config
This package exists to expose kyaml filters directly as cli commands for the purposes
of development of the kyaml package and as a reference implementation for using the libraries.

View File

@@ -11,7 +11,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/kyaml/cmd"
"sigs.k8s.io/kustomize/cmd/config/cmd"
)
// TODO(pwittrock): write tests for reading / writing ResourceLists

View File

@@ -8,7 +8,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/kyaml/cmd"
"sigs.k8s.io/kustomize/cmd/config/cmd"
)
const (

View File

@@ -11,7 +11,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/kyaml/cmd"
"sigs.k8s.io/kustomize/cmd/config/cmd"
)
func TestCountCommand_files(t *testing.T) {

View File

@@ -11,7 +11,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/kyaml/cmd"
"sigs.k8s.io/kustomize/cmd/config/cmd"
"sigs.k8s.io/kustomize/kyaml/kio/filters/testyaml"
)

View File

@@ -11,7 +11,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/kyaml/cmd"
"sigs.k8s.io/kustomize/cmd/config/cmd"
)
// TestGrepCommand_files verifies grep reads the files and filters them

View File

@@ -12,7 +12,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/kyaml/cmd"
"sigs.k8s.io/kustomize/cmd/config/cmd"
)
// TestCmd_files verifies fmt reads the files and filters them

View File

@@ -1,4 +1,4 @@
module sigs.k8s.io/kustomize/cmd/kyaml
module sigs.k8s.io/kustomize/cmd/config
go 1.13

View File

@@ -142,5 +142,6 @@ k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/utils v0.0.0-20191030222137-2b95a09bc58d/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=

View File

@@ -7,7 +7,7 @@ import (
"os"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/kyaml/cmd"
"sigs.k8s.io/kustomize/cmd/config/cmd"
"sigs.k8s.io/kustomize/kyaml/yaml/merge2"
"sigs.k8s.io/kustomize/kyaml/yaml/merge3"
)

View File

@@ -71,7 +71,7 @@ cluster in the form of a complete resource list.
The cluster merges this with the previously applied
state and the actual state to arrive at a new desired
state, which the cluster's reconcilation loop attempts
state, which the cluster's reconciliation loop attempts
to create. This is the foundation of level-based state
management in k8s.

View File

@@ -2,7 +2,7 @@
Kustomize supports building a [remote target], but the URLs are limited to common [Git repository specs].
To extend the supported format, Kustomize has a [plugin] system that allows one to integrate third-party tools such as [hashicorp/go-getter] to "download things from a string URL suing a variety of protocols", extract the content and generated resources as part of kustomize build.
To extend the supported format, Kustomize has a [plugin] system that allows one to integrate third-party tools such as [hashicorp/go-getter] to "download things from a string URL using a variety of protocols", extract the content and generated resources as part of kustomize build.
[remote target]: https://github.com/kubernetes-sigs/kustomize/blob/master/examples/remoteBuild.md
[Git repository specs]: https://github.com/kubernetes-sigs/kustomize/blob/master/api/internal/git/repospec_test.go

View File

@@ -4,5 +4,5 @@ set -e
cd kyaml
make all
cd ../cmd/kyaml
cd ../cmd/config
make all

View File

@@ -2,7 +2,7 @@
set -o xtrace
for dir in api kustomize pseudo kyaml plugin cmd/kyaml
for dir in api kustomize pseudo kyaml plugin cmd/config
do
for item in api apimachinery client-go
do