mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-07-18 18:18:36 +00:00
Compare commits
121 Commits
updateRele
...
kustomize/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8285af8cf1 | ||
|
|
5fa1282dcb | ||
|
|
5a0abc8b12 | ||
|
|
3f2508fa94 | ||
|
|
9d992aae68 | ||
|
|
8c906b804f | ||
|
|
4ff4940fa7 | ||
|
|
09aec5694a | ||
|
|
1f917c0499 | ||
|
|
225ffc7cd8 | ||
|
|
eb638cc312 | ||
|
|
7dfb96425e | ||
|
|
6d4c6127c8 | ||
|
|
6aa72b66ef | ||
|
|
f03fdc09cb | ||
|
|
30b6eeb460 | ||
|
|
bf67fcb6d6 | ||
|
|
4ae420cce1 | ||
|
|
87d2187436 | ||
|
|
f1dabbd4fc | ||
|
|
747e05f2a4 | ||
|
|
3514317b3d | ||
|
|
9299821571 | ||
|
|
d91f313137 | ||
|
|
161af9d99c | ||
|
|
b115c95ea1 | ||
|
|
20cd4bfef9 | ||
|
|
f6c06b58ef | ||
|
|
c45e05b7bd | ||
|
|
76bae738a0 | ||
|
|
0770661b2a | ||
|
|
67d5871e87 | ||
|
|
f98c683915 | ||
|
|
ffe9c9d947 | ||
|
|
4d42ffc7f8 | ||
|
|
d7dc7d911e | ||
|
|
04404ff61b | ||
|
|
f864e15c68 | ||
|
|
29a444fffc | ||
|
|
327035a43a | ||
|
|
ad7fed061e | ||
|
|
cea2986574 | ||
|
|
00f0fd7109 | ||
|
|
1c6481d011 | ||
|
|
f0bc926640 | ||
|
|
11d9ff5690 | ||
|
|
6a0a909e73 | ||
|
|
bd8f0c88e5 | ||
|
|
e5809e49cb | ||
|
|
880009b648 | ||
|
|
d083c7f1d0 | ||
|
|
684ce141de | ||
|
|
5c8c7a043a | ||
|
|
0fe7f65ef2 | ||
|
|
950c1de46d | ||
|
|
fc690f14a8 | ||
|
|
a6e03e4d11 | ||
|
|
60428be5fb | ||
|
|
4d402d4875 | ||
|
|
fbddd264be | ||
|
|
d3c46d3f7c | ||
|
|
dda3984a8f | ||
|
|
f889ca8885 | ||
|
|
341bacb9a2 | ||
|
|
badc1177d9 | ||
|
|
1680cc72c0 | ||
|
|
2f89de86f8 | ||
|
|
ab4e9c718b | ||
|
|
288c03ddca | ||
|
|
5c60285f25 | ||
|
|
6df0a45368 | ||
|
|
8206987580 | ||
|
|
6189ca9798 | ||
|
|
b8c1601a93 | ||
|
|
34d610a38d | ||
|
|
8e4c8464e7 | ||
|
|
43ab7a8e71 | ||
|
|
d2f23a4b8b | ||
|
|
0dc36a4f7c | ||
|
|
678ae12115 | ||
|
|
c4d937322f | ||
|
|
a2adb835b6 | ||
|
|
01b5c4e9da | ||
|
|
eb4c5dc035 | ||
|
|
e976386931 | ||
|
|
bae9986422 | ||
|
|
e7970d82a8 | ||
|
|
9bdd489c96 | ||
|
|
0f49fef5ed | ||
|
|
8d74b8c3b5 | ||
|
|
39a8798a87 | ||
|
|
980f407552 | ||
|
|
9ca8f4602d | ||
|
|
ba0f583ee5 | ||
|
|
f432f4d75e | ||
|
|
17793abacd | ||
|
|
64cd4ec1d5 | ||
|
|
fb822984e3 | ||
|
|
6d2a737c29 | ||
|
|
6e7713281e | ||
|
|
6a7bb9e33e | ||
|
|
0e9428c8b0 | ||
|
|
c838962432 | ||
|
|
548d10ef08 | ||
|
|
2db8487f02 | ||
|
|
b42f71a20f | ||
|
|
e9824aa749 | ||
|
|
92cc9fc5e1 | ||
|
|
e53b4c9884 | ||
|
|
e2973f6ecc | ||
|
|
2bf9fc816d | ||
|
|
ff55856c63 | ||
|
|
ceef219eec | ||
|
|
b21699a277 | ||
|
|
2ab85d2f63 | ||
|
|
320545884c | ||
|
|
16bbc2d67e | ||
|
|
6d860e8ace | ||
|
|
80c8a6df61 | ||
|
|
257707d839 | ||
|
|
c1cd872df6 |
27
Makefile
27
Makefile
@@ -15,7 +15,8 @@ verify-kustomize: \
|
|||||||
lint-kustomize \
|
lint-kustomize \
|
||||||
test-unit-kustomize-all \
|
test-unit-kustomize-all \
|
||||||
test-examples-kustomize-against-HEAD \
|
test-examples-kustomize-against-HEAD \
|
||||||
test-examples-kustomize-against-3.8.0
|
test-examples-kustomize-against-3.8.0 \
|
||||||
|
test-examples-kustomize-against-3.8.2
|
||||||
|
|
||||||
# The following target referenced by a file in
|
# The following target referenced by a file in
|
||||||
# https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/kustomize
|
# https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/kustomize
|
||||||
@@ -26,7 +27,8 @@ prow-presubmit-check: \
|
|||||||
test-unit-cmd-all \
|
test-unit-cmd-all \
|
||||||
test-go-mod \
|
test-go-mod \
|
||||||
test-examples-kustomize-against-HEAD \
|
test-examples-kustomize-against-HEAD \
|
||||||
test-examples-kustomize-against-3.8.0
|
test-examples-kustomize-against-3.8.0 \
|
||||||
|
test-examples-kustomize-against-3.8.2
|
||||||
|
|
||||||
.PHONY: verify-kustomize-e2e
|
.PHONY: verify-kustomize-e2e
|
||||||
verify-kustomize-e2e: test-examples-e2e-kustomize
|
verify-kustomize-e2e: test-examples-e2e-kustomize
|
||||||
@@ -45,17 +47,18 @@ $(MYGOBIN)/golangci-lint-kustomize:
|
|||||||
GO111MODULE=on go build -tags=tools -o $(MYGOBIN)/golangci-lint-kustomize github.com/golangci/golangci-lint/cmd/golangci-lint; \
|
GO111MODULE=on go build -tags=tools -o $(MYGOBIN)/golangci-lint-kustomize github.com/golangci/golangci-lint/cmd/golangci-lint; \
|
||||||
)
|
)
|
||||||
|
|
||||||
# Version pinned by api/go.mod
|
$(MYGOBIN)/gorepomod:
|
||||||
|
cd api; \
|
||||||
|
go install github.com/monopole/gorepomod
|
||||||
|
|
||||||
$(MYGOBIN)/mdrip:
|
$(MYGOBIN)/mdrip:
|
||||||
cd api; \
|
cd api; \
|
||||||
go install github.com/monopole/mdrip
|
go install github.com/monopole/mdrip
|
||||||
|
|
||||||
# Version pinned by api/go.mod
|
|
||||||
$(MYGOBIN)/stringer:
|
$(MYGOBIN)/stringer:
|
||||||
cd api; \
|
cd api; \
|
||||||
go install golang.org/x/tools/cmd/stringer
|
go install golang.org/x/tools/cmd/stringer
|
||||||
|
|
||||||
# Version pinned by api/go.mod
|
|
||||||
$(MYGOBIN)/goimports:
|
$(MYGOBIN)/goimports:
|
||||||
cd api; \
|
cd api; \
|
||||||
go install golang.org/x/tools/cmd/goimports
|
go install golang.org/x/tools/cmd/goimports
|
||||||
@@ -81,6 +84,7 @@ $(MYGOBIN)/kustomize:
|
|||||||
install-tools: \
|
install-tools: \
|
||||||
$(MYGOBIN)/goimports \
|
$(MYGOBIN)/goimports \
|
||||||
$(MYGOBIN)/golangci-lint-kustomize \
|
$(MYGOBIN)/golangci-lint-kustomize \
|
||||||
|
$(MYGOBIN)/gorepomod \
|
||||||
$(MYGOBIN)/mdrip \
|
$(MYGOBIN)/mdrip \
|
||||||
$(MYGOBIN)/pluginator \
|
$(MYGOBIN)/pluginator \
|
||||||
$(MYGOBIN)/stringer
|
$(MYGOBIN)/stringer
|
||||||
@@ -245,6 +249,19 @@ test-examples-kustomize-against-3.8.0: $(MYGOBIN)/mdrip
|
|||||||
cd kustomize; go install .; \
|
cd kustomize; go install .; \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
.PHONY:
|
||||||
|
test-examples-kustomize-against-3.8.2: $(MYGOBIN)/mdrip
|
||||||
|
( \
|
||||||
|
set -e; \
|
||||||
|
tag=v3.8.2; \
|
||||||
|
/bin/rm -f $(MYGOBIN)/kustomize; \
|
||||||
|
echo "Installing kustomize $$tag."; \
|
||||||
|
GO111MODULE=on go get sigs.k8s.io/kustomize/kustomize/v3@$${tag}; \
|
||||||
|
./hack/testExamplesAgainstKustomize.sh $$tag; \
|
||||||
|
echo "Reinstalling kustomize from HEAD."; \
|
||||||
|
cd kustomize; go install .; \
|
||||||
|
)
|
||||||
|
|
||||||
# linux only.
|
# linux only.
|
||||||
# This is for testing an example plugin that
|
# This is for testing an example plugin that
|
||||||
# uses kubeval for validation.
|
# uses kubeval for validation.
|
||||||
|
|||||||
@@ -11,3 +11,4 @@ aliases:
|
|||||||
- pwittrock
|
- pwittrock
|
||||||
- mortent
|
- mortent
|
||||||
- phanimarupaka
|
- phanimarupaka
|
||||||
|
- Shell32-Natsu
|
||||||
|
|||||||
@@ -31,14 +31,15 @@ func (p *ImageTagTransformerPlugin) Config(
|
|||||||
|
|
||||||
func (p *ImageTagTransformerPlugin) Transform(m resmap.ResMap) error {
|
func (p *ImageTagTransformerPlugin) Transform(m resmap.ResMap) error {
|
||||||
for _, r := range m.Resources() {
|
for _, r := range m.Resources() {
|
||||||
// If you're here because someone expected any field containing
|
// traverse all fields at first
|
||||||
// the string "containers" or "initContainers" to get an image
|
err := filtersutil.ApplyToJSON(imagetag.LegacyFilter{
|
||||||
// update (not just spec/template/spec/containers[], etc.) then
|
ImageTag: p.ImageTag,
|
||||||
// a code change is needed. See api/filters/imagetag/legacy
|
}, r)
|
||||||
// for the start of an implementation that won't use an
|
if err != nil {
|
||||||
// allowlist like FsSlice, and instead walks the object looking
|
return err
|
||||||
// for fields named containers or initContainers.
|
}
|
||||||
err := filtersutil.ApplyToJSON(imagetag.Filter{
|
// then use user specified field specs
|
||||||
|
err = filtersutil.ApplyToJSON(imagetag.Filter{
|
||||||
ImageTag: p.ImageTag,
|
ImageTag: p.ImageTag,
|
||||||
FsSlice: p.FieldSpecs,
|
FsSlice: p.FieldSpecs,
|
||||||
}, r)
|
}, r)
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ func (fltr Filter) filter(obj *yaml.RNode) error {
|
|||||||
// found the field -- set its value
|
// found the field -- set its value
|
||||||
return fltr.SetValue(obj)
|
return fltr.SetValue(obj)
|
||||||
}
|
}
|
||||||
|
if obj.IsTaggedNull() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
switch obj.YNode().Kind {
|
switch obj.YNode().Kind {
|
||||||
case yaml.SequenceNode:
|
case yaml.SequenceNode:
|
||||||
return fltr.seq(obj)
|
return fltr.seq(obj)
|
||||||
@@ -67,7 +70,7 @@ func (fltr Filter) field(obj *yaml.RNode) error {
|
|||||||
// lookup the field matching the next path element
|
// lookup the field matching the next path element
|
||||||
var lookupField yaml.Filter
|
var lookupField yaml.Filter
|
||||||
var kind yaml.Kind
|
var kind yaml.Kind
|
||||||
tag := "" // TODO: change to yaml.NodeTagEmpty
|
tag := yaml.NodeTagEmpty
|
||||||
switch {
|
switch {
|
||||||
case !fltr.FieldSpec.CreateIfNotPresent || fltr.CreateKind == 0 || isSeq:
|
case !fltr.FieldSpec.CreateIfNotPresent || fltr.CreateKind == 0 || isSeq:
|
||||||
// dont' create the field if we don't find it
|
// dont' create the field if we don't find it
|
||||||
@@ -95,9 +98,10 @@ func (fltr Filter) field(obj *yaml.RNode) error {
|
|||||||
return errors.WrapPrefixf(err, "fieldName: %s", fieldName)
|
return errors.WrapPrefixf(err, "fieldName: %s", fieldName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the value exists, but is null, then change it to the creation type
|
// if the value exists, but is null and kind is set,
|
||||||
|
// then change it to the creation type
|
||||||
// TODO: update yaml.LookupCreate to support this
|
// TODO: update yaml.LookupCreate to support this
|
||||||
if field.YNode().Tag == yaml.NodeTagNull {
|
if field.YNode().Tag == yaml.NodeTagNull && yaml.IsCreate(kind) {
|
||||||
field.YNode().Kind = kind
|
field.YNode().Kind = kind
|
||||||
field.YNode().Tag = tag
|
field.YNode().Tag = tag
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -433,7 +433,6 @@ spec:
|
|||||||
SetValue: filtersutil.SetScalar("bar"),
|
SetValue: filtersutil.SetScalar("bar"),
|
||||||
CreateKind: yaml.ScalarNode,
|
CreateKind: yaml.ScalarNode,
|
||||||
},
|
},
|
||||||
error: "obj '' at path 'spec/containers/image': expected sequence or mapping node",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "filedname with slash '/'",
|
name: "filedname with slash '/'",
|
||||||
|
|||||||
@@ -168,6 +168,44 @@ metadata:
|
|||||||
map:
|
map:
|
||||||
name: newName
|
name: newName
|
||||||
namespace: oldNs
|
namespace: oldNs
|
||||||
|
`,
|
||||||
|
filter: Filter{
|
||||||
|
FieldSpec: types.FieldSpec{Path: "map"},
|
||||||
|
Target: resid.Gvk{
|
||||||
|
Group: "apps",
|
||||||
|
Version: "v1",
|
||||||
|
Kind: "Secret",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"null value": {
|
||||||
|
input: `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: dep
|
||||||
|
map:
|
||||||
|
name: null
|
||||||
|
`,
|
||||||
|
candidates: `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: newName
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: NotSecret
|
||||||
|
metadata:
|
||||||
|
name: newName2
|
||||||
|
`,
|
||||||
|
originalNames: []string{"oldName", ""},
|
||||||
|
expected: `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: dep
|
||||||
|
map:
|
||||||
|
name: null
|
||||||
`,
|
`,
|
||||||
filter: Filter{
|
filter: Filter{
|
||||||
FieldSpec: types.FieldSpec{Path: "map"},
|
FieldSpec: types.FieldSpec{Path: "map"},
|
||||||
@@ -217,27 +255,6 @@ func TestNamerefFilterUnhappy(t *testing.T) {
|
|||||||
filter Filter
|
filter Filter
|
||||||
originalNames []string
|
originalNames []string
|
||||||
}{
|
}{
|
||||||
"invalid node type": {
|
|
||||||
input: `
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: dep
|
|
||||||
ref:
|
|
||||||
name: null
|
|
||||||
`,
|
|
||||||
candidates: "",
|
|
||||||
originalNames: []string{},
|
|
||||||
expected: "obj '' at path 'ref/name': node is expected to be either a string or a slice of string or a map of string",
|
|
||||||
filter: Filter{
|
|
||||||
FieldSpec: types.FieldSpec{Path: "ref/name"},
|
|
||||||
Target: resid.Gvk{
|
|
||||||
Group: "apps",
|
|
||||||
Version: "v1",
|
|
||||||
Kind: "Secret",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"multiple match": {
|
"multiple match": {
|
||||||
input: `
|
input: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ func (ns Filter) hacks(obj *yaml.RNode) error {
|
|||||||
// metaNamespaceHack is a hack for implementing the namespace transform
|
// metaNamespaceHack is a hack for implementing the namespace transform
|
||||||
// for the metadata.namespace field on namespace scoped resources.
|
// for the metadata.namespace field on namespace scoped resources.
|
||||||
// namespace scoped resources are determined by NOT being present
|
// namespace scoped resources are determined by NOT being present
|
||||||
// in a blacklist of cluster-scoped resource types (by apiVersion and kind).
|
// in a hard-coded list of cluster-scoped resource types (by apiVersion and kind).
|
||||||
//
|
//
|
||||||
// This hack should be updated to allow individual resources to specify
|
// This hack should be updated to allow individual resources to specify
|
||||||
// if they are cluster scoped through either an annotation on the resources,
|
// if they are cluster scoped through either an annotation on the resources,
|
||||||
|
|||||||
@@ -188,6 +188,26 @@ data:
|
|||||||
FieldSpec: types.FieldSpec{Path: "data/slice2"},
|
FieldSpec: types.FieldSpec{Path: "data/slice2"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"null value": {
|
||||||
|
input: `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: dep
|
||||||
|
data:
|
||||||
|
FOO: null`,
|
||||||
|
expected: `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: dep
|
||||||
|
data:
|
||||||
|
FOO: null`,
|
||||||
|
filter: Filter{
|
||||||
|
MappingFunc: expansion2.MappingFuncFor(replacementCounts, map[string]interface{}{}),
|
||||||
|
FieldSpec: types.FieldSpec{Path: "data/FOO"},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for tn, tc := range testCases {
|
for tn, tc := range testCases {
|
||||||
@@ -260,20 +280,6 @@ data:
|
|||||||
FieldSpec: types.FieldSpec{Path: "data"},
|
FieldSpec: types.FieldSpec{Path: "data"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"null input": {
|
|
||||||
input: `
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: dep
|
|
||||||
data:
|
|
||||||
FOO: null`,
|
|
||||||
expectedError: "obj '' at path 'data/FOO': invalid type encountered 0",
|
|
||||||
filter: Filter{
|
|
||||||
MappingFunc: expansion2.MappingFuncFor(replacementCounts, map[string]interface{}{}),
|
|
||||||
FieldSpec: types.FieldSpec{Path: "data/FOO"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for tn, tc := range testCases {
|
for tn, tc := range testCases {
|
||||||
|
|||||||
@@ -10,15 +10,13 @@ require (
|
|||||||
github.com/pkg/errors v0.8.1
|
github.com/pkg/errors v0.8.1
|
||||||
github.com/stretchr/testify v1.4.0
|
github.com/stretchr/testify v1.4.0
|
||||||
github.com/yujunz/go-getter v1.4.1-lite
|
github.com/yujunz/go-getter v1.4.1-lite
|
||||||
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e
|
||||||
gopkg.in/yaml.v2 v2.3.0
|
gopkg.in/yaml.v2 v2.3.0
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71
|
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71
|
||||||
k8s.io/api v0.17.0
|
k8s.io/api v0.17.0
|
||||||
k8s.io/apimachinery v0.17.0
|
k8s.io/apimachinery v0.17.0
|
||||||
k8s.io/client-go v0.17.0
|
k8s.io/client-go v0.17.0
|
||||||
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a
|
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a
|
||||||
sigs.k8s.io/kustomize/kyaml v0.6.1
|
sigs.k8s.io/kustomize/kyaml v0.8.1
|
||||||
sigs.k8s.io/yaml v1.2.0
|
sigs.k8s.io/yaml v1.2.0
|
||||||
)
|
)
|
||||||
|
|
||||||
replace sigs.k8s.io/kustomize/kyaml v0.6.1 => ../kyaml
|
|
||||||
|
|||||||
@@ -307,6 +307,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
|||||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||||
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
|
||||||
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||||
github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
|
github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
@@ -526,6 +528,8 @@ golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtn
|
|||||||
golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff h1:XdBG6es/oFDr1HwaxkxgVve7NB281QhxgK/i4voubFs=
|
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff h1:XdBG6es/oFDr1HwaxkxgVve7NB281QhxgK/i4voubFs=
|
||||||
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e h1:aZzprAO9/8oim3qStq3wc1Xuxx4QmAGriC4VU4ojemQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
@@ -584,6 +588,8 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphD
|
|||||||
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
|
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
|
||||||
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4=
|
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4=
|
||||||
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
|
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
|
||||||
|
sigs.k8s.io/kustomize/kyaml v0.8.1 h1:5GRanVGU6+iq3ERTiQD9VIfyGByFVB4z4GthP8NkRYE=
|
||||||
|
sigs.k8s.io/kustomize/kyaml v0.8.1/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
|
||||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
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=
|
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ func TestRefVarTransformer(t *testing.T) {
|
|||||||
' at path 'data/slice': invalid value type expect a string`,
|
' at path 'data/slice': invalid value type expect a string`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "var replacement panic in nil",
|
description: "var replacement in nil",
|
||||||
given: given{
|
given: given{
|
||||||
varMap: map[string]interface{}{},
|
varMap: map[string]interface{}{},
|
||||||
fs: []types.FieldSpec{
|
fs: []types.FieldSpec{
|
||||||
@@ -150,7 +150,19 @@ func TestRefVarTransformer(t *testing.T) {
|
|||||||
"nil": nil, // noticeably *not* a []string
|
"nil": nil, // noticeably *not* a []string
|
||||||
}}).ResMap(),
|
}}).ResMap(),
|
||||||
},
|
},
|
||||||
errMessage: `obj '' at path 'data/nil': invalid type encountered 0`,
|
expected: expected{
|
||||||
|
res: resmaptest_test.NewRmBuilder(
|
||||||
|
t, resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())).
|
||||||
|
Add(map[string]interface{}{
|
||||||
|
"apiVersion": "v1",
|
||||||
|
"kind": "ConfigMap",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "cm1",
|
||||||
|
},
|
||||||
|
"data": map[string]interface{}{
|
||||||
|
"nil": nil, // noticeably *not* a []string
|
||||||
|
}}).ResMap(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ overview of each component with the following sections going into more details.
|
|||||||
|
|
||||||
The overall structure is outlined in the following figure:
|
The overall structure is outlined in the following figure:
|
||||||

|
https://github.com/kubernetes-sigs/kustomize/blob/master/api/internal/crawl/pictures/token_config.png)
|
||||||
|
|
||||||
#### Crawler
|
#### Crawler
|
||||||
The leftmost component consists of a crawler with an http cache of GitHub
|
The leftmost component consists of a crawler with an http cache of GitHub
|
||||||
|
|||||||
@@ -271,6 +271,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
|||||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||||
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
|
||||||
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||||
github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
|
github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
@@ -470,6 +472,7 @@ golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDq
|
|||||||
golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
@@ -524,8 +527,8 @@ k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl
|
|||||||
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
|
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
|
||||||
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
|
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
|
||||||
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
|
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.6.1 h1:mwffj5vt3MPdbWV3fZnnwol8SO7sUoGdgejBlvseyak=
|
sigs.k8s.io/kustomize/kyaml v0.8.0 h1:/MqPML99XAm2pbrD/eTpePh5rnU5bpnuTPqb29LpSz4=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.6.1/go.mod h1:bEzbO5pN9OvlEeCLvFHo8Pu7SA26Herc2m60UeWZBdI=
|
sigs.k8s.io/kustomize/kyaml v0.8.0/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
|
||||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
||||||
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
||||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||||
|
|||||||
@@ -65,8 +65,8 @@ func TestLoader(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
for _, behavior := range []types.BuiltinPluginLoadingOptions{
|
for _, behavior := range []types.BuiltinPluginLoadingOptions{
|
||||||
types.BploUseStaticallyLinked,
|
/* types.BploUseStaticallyLinked,
|
||||||
types.BploLoadFromFileSys} {
|
types.BploLoadFromFileSys */} {
|
||||||
c, err := konfig.EnabledPluginConfig(behavior)
|
c, err := konfig.EnabledPluginConfig(behavior)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ const (
|
|||||||
namespace:
|
namespace:
|
||||||
- path: metadata/namespace
|
- path: metadata/namespace
|
||||||
create: true
|
create: true
|
||||||
|
- path: metadata/name
|
||||||
|
kind: Namespace
|
||||||
|
create: true
|
||||||
- path: subjects
|
- path: subjects
|
||||||
kind: RoleBinding
|
kind: RoleBinding
|
||||||
- path: subjects
|
- path: subjects
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNullValues(t *testing.T) {
|
func TestNullValues1(t *testing.T) {
|
||||||
th := kusttest_test.MakeHarness(t)
|
th := kusttest_test.MakeHarness(t)
|
||||||
th.WriteF("/app/deployment.yaml", `
|
th.WriteF("/app/deployment.yaml", `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
@@ -62,3 +62,36 @@ spec:
|
|||||||
name: example
|
name: example
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNullValues2(t *testing.T) {
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteF("deploy.yaml", `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: test
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: test
|
||||||
|
volumes: null
|
||||||
|
`)
|
||||||
|
th.WriteK(".", `
|
||||||
|
resources:
|
||||||
|
- deploy.yaml
|
||||||
|
`)
|
||||||
|
m := th.Run(".", th.MakeDefaultOptions())
|
||||||
|
th.AssertActualEqualsExpected(m, `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: test
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: test
|
||||||
|
volumes: null
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|||||||
@@ -215,25 +215,25 @@ spec2:
|
|||||||
template:
|
template:
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- image: nginx:v1
|
- image: nginx:v2
|
||||||
name: nginx3
|
name: nginx3
|
||||||
- image: my-nginx:latest
|
- image: my-nginx:previous
|
||||||
name: nginx4
|
name: nginx4
|
||||||
spec3:
|
spec3:
|
||||||
template:
|
template:
|
||||||
spec:
|
spec:
|
||||||
initContainers:
|
initContainers:
|
||||||
- image: postgres:alpine-9
|
- image: my-postgres:v3
|
||||||
name: postgresdb
|
name: postgresdb
|
||||||
- image: docker:17-git
|
- image: my-docker@sha256:25a0d4b4
|
||||||
name: init-docker
|
name: init-docker
|
||||||
- image: myprivaterepohostname:1234/my/image:latest
|
- image: myprivaterepohostname:1234/my/image:v1.0.1
|
||||||
name: myImage
|
name: myImage
|
||||||
- image: myprivaterepohostname:1234/my/image
|
- image: myprivaterepohostname:1234/my/image:v1.0.1
|
||||||
name: myImage2
|
name: myImage2
|
||||||
- image: my-app-image:v1
|
- image: my-app-image:v1
|
||||||
name: my-app
|
name: my-app
|
||||||
- image: gcr.io:8080/my-project/my-cool-app:latest
|
- image: my-cool-app:latest
|
||||||
name: my-cool-app
|
name: my-cool-app
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ type remoteTargetSpec struct {
|
|||||||
|
|
||||||
// Dir is where the resource is saved
|
// Dir is where the resource is saved
|
||||||
Dir filesys.ConfirmedDir
|
Dir filesys.ConfirmedDir
|
||||||
|
|
||||||
|
// TempDir is the directory created to hold all resources, including Dir
|
||||||
|
TempDir filesys.ConfirmedDir
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getter is a function that can gets resource
|
// Getter is a function that can gets resource
|
||||||
@@ -31,7 +34,7 @@ func newLoaderAtGetter(raw string, fSys filesys.FileSystem, referrer *fileLoader
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleaner := func() error {
|
cleaner := func() error {
|
||||||
return fSys.RemoveAll(rs.Dir.String())
|
return fSys.RemoveAll(rs.TempDir.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := getter(rs); err != nil {
|
if err := getter(rs); err != nil {
|
||||||
@@ -55,12 +58,12 @@ func newLoaderAtGetter(raw string, fSys filesys.FileSystem, referrer *fileLoader
|
|||||||
func getRemoteTarget(rs *remoteTargetSpec) error {
|
func getRemoteTarget(rs *remoteTargetSpec) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
rs.Dir, err = filesys.NewTmpConfirmedDir()
|
rs.TempDir, err = filesys.NewTmpConfirmedDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
rs.Dir = filesys.ConfirmedDir(rs.Dir.Join("repo"))
|
rs.Dir = filesys.ConfirmedDir(rs.TempDir.Join("repo"))
|
||||||
|
|
||||||
// Get the pwd
|
// Get the pwd
|
||||||
pwd, err := os.Getwd()
|
pwd, err := os.Getwd()
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ var orderFirst = []string{
|
|||||||
"ClusterRoleBinding",
|
"ClusterRoleBinding",
|
||||||
"ConfigMap",
|
"ConfigMap",
|
||||||
"Secret",
|
"Secret",
|
||||||
|
"Endpoints",
|
||||||
"Service",
|
"Service",
|
||||||
"LimitRange",
|
"LimitRange",
|
||||||
"PriorityClass",
|
"PriorityClass",
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ var lessThanTests = []struct {
|
|||||||
Gvk{Group: "a", Version: "b", Kind: "ValidatingWebhookConfiguration"}},
|
Gvk{Group: "a", Version: "b", Kind: "ValidatingWebhookConfiguration"}},
|
||||||
{Gvk{Group: "a", Version: "b", Kind: "Service"},
|
{Gvk{Group: "a", Version: "b", Kind: "Service"},
|
||||||
Gvk{Group: "a", Version: "b", Kind: "APIService"}},
|
Gvk{Group: "a", Version: "b", Kind: "APIService"}},
|
||||||
|
{Gvk{Group: "a", Version: "b", Kind: "Endpoints"},
|
||||||
|
Gvk{Group: "a", Version: "b", Kind: "Service"}},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIsLessThan1(t *testing.T) {
|
func TestIsLessThan1(t *testing.T) {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ var (
|
|||||||
ExitOnError = &commands.ExitOnError
|
ExitOnError = &commands.ExitOnError
|
||||||
)
|
)
|
||||||
|
|
||||||
// AddCommands adds the cfg, fn and live commands to kustomize.
|
// AddCommands adds the cfg and fn commands to kustomize.
|
||||||
func AddCommands(root *cobra.Command, name string) *cobra.Command {
|
func AddCommands(root *cobra.Command, name string) *cobra.Command {
|
||||||
commands.ExitOnError = true
|
commands.ExitOnError = true
|
||||||
|
|
||||||
@@ -48,7 +48,6 @@ func AddCommands(root *cobra.Command, name string) *cobra.Command {
|
|||||||
|
|
||||||
root.AddCommand(GetCfg(name))
|
root.AddCommand(GetCfg(name))
|
||||||
root.AddCommand(GetFn(name))
|
root.AddCommand(GetFn(name))
|
||||||
root.AddCommand(GetLive(name))
|
|
||||||
|
|
||||||
root.AddCommand(&cobra.Command{
|
root.AddCommand(&cobra.Command{
|
||||||
Use: "docs-merge",
|
Use: "docs-merge",
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ func GetLive(name string) *cobra.Command {
|
|||||||
|
|
||||||
cmd.AddCommand(
|
cmd.AddCommand(
|
||||||
applyCmd,
|
applyCmd,
|
||||||
initcmd.NewCmdInit(ioStreams),
|
initcmd.NewCmdInit(f, ioStreams),
|
||||||
preview.GetPreviewRunner(f, ioStreams).Command,
|
preview.GetPreviewRunner(f, ioStreams).Command,
|
||||||
diff.NewCmdDiff(f, ioStreams),
|
diff.NewCmdDiff(f, ioStreams),
|
||||||
destroy.GetDestroyRunner(f, ioStreams).Command)
|
destroy.GetDestroyRunner(f, ioStreams).Command)
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ require (
|
|||||||
k8s.io/cli-runtime v0.17.3
|
k8s.io/cli-runtime v0.17.3
|
||||||
k8s.io/client-go v0.17.3
|
k8s.io/client-go v0.17.3
|
||||||
k8s.io/kubectl v0.0.0-20191219154910-1528d4eea6dd
|
k8s.io/kubectl v0.0.0-20191219154910-1528d4eea6dd
|
||||||
sigs.k8s.io/cli-utils v0.19.0
|
sigs.k8s.io/cli-utils v0.20.2
|
||||||
sigs.k8s.io/kustomize/kyaml v0.6.1
|
sigs.k8s.io/kustomize/kyaml v0.8.1
|
||||||
)
|
)
|
||||||
|
|
||||||
replace sigs.k8s.io/kustomize/kyaml => ../../kyaml
|
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
|||||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||||
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
|
||||||
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
@@ -615,12 +617,14 @@ modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
|
|||||||
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
|
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
|
||||||
modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
||||||
modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
|
modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
|
||||||
sigs.k8s.io/cli-utils v0.19.0 h1:lAoR5okhSV/dIusodaQp5VbDpHMcKnvjqKYHU+AB3a4=
|
sigs.k8s.io/cli-utils v0.20.2 h1:jNMu4ExtvFXlmKqZMDJqySqK55vGtVRqoLht6eIMffw=
|
||||||
sigs.k8s.io/cli-utils v0.19.0/go.mod h1:B7KdqkSkHNIUn3cFbaR4aKUZMKtr+Benboi1w/HW/Fg=
|
sigs.k8s.io/cli-utils v0.20.2/go.mod h1:uT5cVxMrOoRplL8umtrJx5R51ZWsIKD7lQfPtot80uA=
|
||||||
sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9NPsg=
|
sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9NPsg=
|
||||||
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
|
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
|
||||||
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
|
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
|
||||||
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
|
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
|
||||||
|
sigs.k8s.io/kustomize/kyaml v0.8.1 h1:5GRanVGU6+iq3ERTiQD9VIfyGByFVB4z4GthP8NkRYE=
|
||||||
|
sigs.k8s.io/kustomize/kyaml v0.8.1/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
|
||||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
||||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
|
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
|
||||||
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU=
|
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU=
|
||||||
|
|||||||
@@ -4,9 +4,12 @@
|
|||||||
package commands
|
package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"sigs.k8s.io/kustomize/cmd/config/ext"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
||||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||||
@@ -31,6 +34,8 @@ func NewAnnotateRunner(parent string) *AnnotateRunner {
|
|||||||
c.Flags().StringVar(&r.Name, "name", "", "Resource name to annotate")
|
c.Flags().StringVar(&r.Name, "name", "", "Resource name to annotate")
|
||||||
c.Flags().StringVar(&r.Namespace, "namespace", "", "Resource namespace to annotate")
|
c.Flags().StringVar(&r.Namespace, "namespace", "", "Resource namespace to annotate")
|
||||||
c.Flags().StringSliceVar(&r.Values, "kv", []string{}, "annotation as KEY=VALUE")
|
c.Flags().StringSliceVar(&r.Values, "kv", []string{}, "annotation as KEY=VALUE")
|
||||||
|
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
|
||||||
|
"add annotations recursively in all the nested subpackages")
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,13 +44,14 @@ func AnnotateCommand(parent string) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AnnotateRunner struct {
|
type AnnotateRunner struct {
|
||||||
Command *cobra.Command
|
Command *cobra.Command
|
||||||
Values []string
|
Values []string
|
||||||
Kind string
|
Kind string
|
||||||
Name string
|
Name string
|
||||||
ApiVersion string
|
ApiVersion string
|
||||||
Namespace string
|
Namespace string
|
||||||
Path string
|
Path string
|
||||||
|
RecurseSubPackages bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *AnnotateRunner) runE(c *cobra.Command, args []string) error {
|
func (r *AnnotateRunner) runE(c *cobra.Command, args []string) error {
|
||||||
@@ -55,16 +61,54 @@ func (r *AnnotateRunner) runE(c *cobra.Command, args []string) error {
|
|||||||
rw := &kio.ByteReadWriter{Reader: c.InOrStdin(), Writer: c.OutOrStdout()}
|
rw := &kio.ByteReadWriter{Reader: c.InOrStdin(), Writer: c.OutOrStdout()}
|
||||||
input = []kio.Reader{rw}
|
input = []kio.Reader{rw}
|
||||||
output = []kio.Writer{rw}
|
output = []kio.Writer{rw}
|
||||||
} else {
|
|
||||||
rw := &kio.LocalPackageReadWriter{PackagePath: args[0], NoDeleteFiles: true}
|
return handleError(c, kio.Pipeline{
|
||||||
input = []kio.Reader{rw}
|
Inputs: input,
|
||||||
output = []kio.Writer{rw}
|
Filters: []kio.Filter{r},
|
||||||
|
Outputs: output,
|
||||||
|
}.Execute())
|
||||||
}
|
}
|
||||||
return handleError(c, kio.Pipeline{
|
|
||||||
|
e := executeCmdOnPkgs{
|
||||||
|
writer: c.OutOrStdout(),
|
||||||
|
needOpenAPI: false,
|
||||||
|
recurseSubPackages: r.RecurseSubPackages,
|
||||||
|
cmdRunner: r,
|
||||||
|
rootPkgPath: args[0],
|
||||||
|
}
|
||||||
|
|
||||||
|
err := e.execute()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *AnnotateRunner) executeCmd(w io.Writer, pkgPath string) error {
|
||||||
|
openAPIFileName, err := ext.OpenAPIFileName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rw := &kio.LocalPackageReadWriter{PackagePath: pkgPath, NoDeleteFiles: true, PackageFileName: openAPIFileName}
|
||||||
|
input := []kio.Reader{rw}
|
||||||
|
output := []kio.Writer{rw}
|
||||||
|
err = kio.Pipeline{
|
||||||
Inputs: input,
|
Inputs: input,
|
||||||
Filters: []kio.Filter{r},
|
Filters: []kio.Filter{r},
|
||||||
Outputs: output,
|
Outputs: output,
|
||||||
}.Execute())
|
}.Execute()
|
||||||
|
if err != nil {
|
||||||
|
// return err if there is only package
|
||||||
|
if !r.RecurseSubPackages {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
// print error message and continue if there are multiple packages to annotate
|
||||||
|
fmt.Fprintf(w, "%s\n", err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Fprint(w, "added annotations in the package\n")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *AnnotateRunner) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
func (r *AnnotateRunner) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAnnotateCommand(t *testing.T) {
|
func TestAnnotateCommand(t *testing.T) {
|
||||||
@@ -486,3 +488,77 @@ spec:
|
|||||||
replicas: 3
|
replicas: 3
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestAnnotateSubPackages(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
dataset string
|
||||||
|
packagePath string
|
||||||
|
args []string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "annotate-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
args: []string{"--kv", "foo=bar", "-R"},
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
added annotations in the package
|
||||||
|
|
||||||
|
${baseDir}/mysql/storage/
|
||||||
|
added annotations in the package
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "annotate-top-level-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
packagePath: "mysql",
|
||||||
|
args: []string{"--kv", "foo=bar"},
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
added annotations in the package
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "annotate-nested-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
packagePath: "mysql/storage",
|
||||||
|
args: []string{"--kv", "foo=bar"},
|
||||||
|
expected: `${baseDir}/mysql/storage/
|
||||||
|
added annotations in the package
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i := range tests {
|
||||||
|
test := tests[i]
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
// reset the openAPI afterward
|
||||||
|
openapi.ResetOpenAPI()
|
||||||
|
defer openapi.ResetOpenAPI()
|
||||||
|
sourceDir := filepath.Join("test", "testdata", test.dataset)
|
||||||
|
baseDir, err := ioutil.TempDir("", "")
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
copyutil.CopyDir(sourceDir, baseDir)
|
||||||
|
defer os.RemoveAll(baseDir)
|
||||||
|
runner := NewAnnotateRunner("")
|
||||||
|
actual := &bytes.Buffer{}
|
||||||
|
runner.Command.SetOut(actual)
|
||||||
|
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
|
||||||
|
err = runner.Command.Execute()
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize path format for windows
|
||||||
|
actualNormalized := strings.Replace(
|
||||||
|
strings.Replace(actual.String(), "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
|
||||||
|
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
|
||||||
|
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
|
||||||
|
if !assert.Equal(t, expectedNormalized, actualNormalized) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,9 +5,11 @@ package commands
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"sigs.k8s.io/kustomize/cmd/config/ext"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
||||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||||
@@ -19,15 +21,14 @@ import (
|
|||||||
func GetCatRunner(name string) *CatRunner {
|
func GetCatRunner(name string) *CatRunner {
|
||||||
r := &CatRunner{}
|
r := &CatRunner{}
|
||||||
c := &cobra.Command{
|
c := &cobra.Command{
|
||||||
Use: "cat DIR...",
|
Use: "cat DIR",
|
||||||
Short: commands.CatShort,
|
Short: commands.CatShort,
|
||||||
Long: commands.CatLong,
|
Long: commands.CatLong,
|
||||||
Example: commands.CatExamples,
|
Example: commands.CatExamples,
|
||||||
RunE: r.runE,
|
RunE: r.runE,
|
||||||
|
Args: cobra.MaximumNArgs(1),
|
||||||
}
|
}
|
||||||
fixDocs(name, c)
|
fixDocs(name, c)
|
||||||
c.Flags().BoolVar(&r.IncludeSubpackages, "include-subpackages", true,
|
|
||||||
"also print resources from subpackages.")
|
|
||||||
c.Flags().BoolVar(&r.Format, "format", true,
|
c.Flags().BoolVar(&r.Format, "format", true,
|
||||||
"format resource config yaml before printing.")
|
"format resource config yaml before printing.")
|
||||||
c.Flags().BoolVar(&r.KeepAnnotations, "annotate", false,
|
c.Flags().BoolVar(&r.KeepAnnotations, "annotate", false,
|
||||||
@@ -49,6 +50,8 @@ func GetCatRunner(name string) *CatRunner {
|
|||||||
"if true, exclude non-local-config in the output.")
|
"if true, exclude non-local-config in the output.")
|
||||||
c.Flags().StringVar(&r.OutputDest, "dest", "",
|
c.Flags().StringVar(&r.OutputDest, "dest", "",
|
||||||
"if specified, write output to a file rather than stdout")
|
"if specified, write output to a file rather than stdout")
|
||||||
|
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", true,
|
||||||
|
"print resources recursively in all the nested subpackages")
|
||||||
r.Command = c
|
r.Command = c
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
@@ -59,7 +62,6 @@ func CatCommand(name string) *cobra.Command {
|
|||||||
|
|
||||||
// CatRunner contains the run function
|
// CatRunner contains the run function
|
||||||
type CatRunner struct {
|
type CatRunner struct {
|
||||||
IncludeSubpackages bool
|
|
||||||
Format bool
|
Format bool
|
||||||
KeepAnnotations bool
|
KeepAnnotations bool
|
||||||
WrapKind string
|
WrapKind string
|
||||||
@@ -71,56 +73,102 @@ type CatRunner struct {
|
|||||||
IncludeLocal bool
|
IncludeLocal bool
|
||||||
ExcludeNonLocal bool
|
ExcludeNonLocal bool
|
||||||
Command *cobra.Command
|
Command *cobra.Command
|
||||||
|
RecurseSubPackages bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *CatRunner) runE(c *cobra.Command, args []string) error {
|
func (r *CatRunner) runE(c *cobra.Command, args []string) error {
|
||||||
// if there is a function-config specified, emit it
|
var writer = c.OutOrStdout()
|
||||||
|
if r.OutputDest != "" {
|
||||||
|
o, err := os.Create(r.OutputDest)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err)
|
||||||
|
}
|
||||||
|
defer o.Close()
|
||||||
|
writer = o
|
||||||
|
}
|
||||||
|
if len(args) == 0 {
|
||||||
|
input := &kio.ByteReader{Reader: c.InOrStdin()}
|
||||||
|
// if there is a function-config specified, emit it
|
||||||
|
outputs, err := r.out(writer)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return handleError(c, kio.Pipeline{Inputs: []kio.Reader{input}, Filters: r.catFilters(), Outputs: outputs}.Execute())
|
||||||
|
}
|
||||||
|
|
||||||
|
e := executeCmdOnPkgs{
|
||||||
|
writer: writer,
|
||||||
|
needOpenAPI: false,
|
||||||
|
recurseSubPackages: r.RecurseSubPackages,
|
||||||
|
cmdRunner: r,
|
||||||
|
rootPkgPath: args[0],
|
||||||
|
skipPkgPathPrint: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CatRunner) executeCmd(w io.Writer, pkgPath string) error {
|
||||||
|
openAPIFileName, err := ext.OpenAPIFileName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: openAPIFileName}
|
||||||
|
outputs, err := r.out(w)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = kio.Pipeline{
|
||||||
|
Inputs: []kio.Reader{input},
|
||||||
|
Filters: r.catFilters(),
|
||||||
|
Outputs: outputs,
|
||||||
|
}.Execute()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
// return err if there is only package
|
||||||
|
if !r.RecurseSubPackages {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
// print error message and continue if there are multiple packages to annotate
|
||||||
|
fmt.Fprintf(w, "%s in package %q\n", err.Error(), pkgPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "---")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CatRunner) catFilters() []kio.Filter {
|
||||||
|
var fltrs []kio.Filter
|
||||||
|
// don't include reconcilers
|
||||||
|
fltrs = append(fltrs, &filters.IsLocalConfig{
|
||||||
|
IncludeLocalConfig: r.IncludeLocal,
|
||||||
|
ExcludeNonLocalConfig: r.ExcludeNonLocal,
|
||||||
|
})
|
||||||
|
if r.Format {
|
||||||
|
fltrs = append(fltrs, filters.FormatFilter{})
|
||||||
|
}
|
||||||
|
if r.StripComments {
|
||||||
|
fltrs = append(fltrs, filters.StripCommentsFilter{})
|
||||||
|
}
|
||||||
|
return fltrs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CatRunner) out(w io.Writer) ([]kio.Writer, error) {
|
||||||
|
var outputs []kio.Writer
|
||||||
var functionConfig *yaml.RNode
|
var functionConfig *yaml.RNode
|
||||||
if r.FunctionConfig != "" {
|
if r.FunctionConfig != "" {
|
||||||
configs, err := kio.LocalPackageReader{PackagePath: r.FunctionConfig,
|
configs, err := kio.LocalPackageReader{PackagePath: r.FunctionConfig,
|
||||||
OmitReaderAnnotations: !r.KeepAnnotations}.Read()
|
OmitReaderAnnotations: !r.KeepAnnotations}.Read()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return outputs, err
|
||||||
}
|
}
|
||||||
if len(configs) != 1 {
|
if len(configs) != 1 {
|
||||||
return fmt.Errorf("expected exactly 1 functionConfig, found %d", len(configs))
|
return outputs, fmt.Errorf("expected exactly 1 functionConfig, found %d", len(configs))
|
||||||
}
|
}
|
||||||
functionConfig = configs[0]
|
functionConfig = configs[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
var inputs []kio.Reader
|
|
||||||
for _, a := range args {
|
|
||||||
inputs = append(inputs, kio.LocalPackageReader{
|
|
||||||
PackagePath: a,
|
|
||||||
IncludeSubpackages: r.IncludeSubpackages,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if len(inputs) == 0 {
|
|
||||||
inputs = append(inputs, &kio.ByteReader{Reader: c.InOrStdin()})
|
|
||||||
}
|
|
||||||
var fltr []kio.Filter
|
|
||||||
// don't include reconcilers
|
|
||||||
fltr = append(fltr, &filters.IsLocalConfig{
|
|
||||||
IncludeLocalConfig: r.IncludeLocal,
|
|
||||||
ExcludeNonLocalConfig: r.ExcludeNonLocal,
|
|
||||||
})
|
|
||||||
if r.Format {
|
|
||||||
fltr = append(fltr, filters.FormatFilter{})
|
|
||||||
}
|
|
||||||
if r.StripComments {
|
|
||||||
fltr = append(fltr, filters.StripCommentsFilter{})
|
|
||||||
}
|
|
||||||
|
|
||||||
var out = c.OutOrStdout()
|
|
||||||
if r.OutputDest != "" {
|
|
||||||
o, err := os.Create(r.OutputDest)
|
|
||||||
if err != nil {
|
|
||||||
return handleError(c, errors.Wrap(err))
|
|
||||||
}
|
|
||||||
defer o.Close()
|
|
||||||
out = o
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove this annotation explicitly, the ByteWriter won't clear it by
|
// remove this annotation explicitly, the ByteWriter won't clear it by
|
||||||
// default because it doesn't set it
|
// default because it doesn't set it
|
||||||
clear := []string{"config.kubernetes.io/path"}
|
clear := []string{"config.kubernetes.io/path"}
|
||||||
@@ -128,9 +176,8 @@ func (r *CatRunner) runE(c *cobra.Command, args []string) error {
|
|||||||
clear = nil
|
clear = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var outputs []kio.Writer
|
|
||||||
outputs = append(outputs, kio.ByteWriter{
|
outputs = append(outputs, kio.ByteWriter{
|
||||||
Writer: out,
|
Writer: w,
|
||||||
KeepReaderAnnotations: r.KeepAnnotations,
|
KeepReaderAnnotations: r.KeepAnnotations,
|
||||||
WrappingKind: r.WrapKind,
|
WrappingKind: r.WrapKind,
|
||||||
WrappingAPIVersion: r.WrapApiVersion,
|
WrappingAPIVersion: r.WrapApiVersion,
|
||||||
@@ -139,5 +186,5 @@ func (r *CatRunner) runE(c *cobra.Command, args []string) error {
|
|||||||
ClearAnnotations: clear,
|
ClearAnnotations: clear,
|
||||||
})
|
})
|
||||||
|
|
||||||
return handleError(c, kio.Pipeline{Inputs: inputs, Filters: fltr, Outputs: outputs}.Execute())
|
return outputs, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,13 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO(pwittrock): write tests for reading / writing ResourceLists
|
// TODO(pwittrock): write tests for reading / writing ResourceLists
|
||||||
@@ -112,7 +115,7 @@ metadata:
|
|||||||
app: nginx
|
app: nginx
|
||||||
spec:
|
spec:
|
||||||
replicas: 3
|
replicas: 3
|
||||||
`, b.String()) {
|
---`, b.String()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,8 +171,7 @@ metadata:
|
|||||||
annotations:
|
annotations:
|
||||||
app: nginx
|
app: nginx
|
||||||
spec:
|
spec:
|
||||||
replicas: 3
|
replicas: 3`), 0600)
|
||||||
`), 0600)
|
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -223,7 +225,7 @@ metadata:
|
|||||||
app: nginx
|
app: nginx
|
||||||
spec:
|
spec:
|
||||||
replicas: 3
|
replicas: 3
|
||||||
`, b.String()) {
|
---`, b.String()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -305,7 +307,7 @@ metadata:
|
|||||||
image: gcr.io/example/reconciler:v1
|
image: gcr.io/example/reconciler:v1
|
||||||
spec:
|
spec:
|
||||||
replicas: 3
|
replicas: 3
|
||||||
`, b.String()) {
|
---`, b.String()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -362,8 +364,7 @@ metadata:
|
|||||||
annotations:
|
annotations:
|
||||||
app: nginx
|
app: nginx
|
||||||
spec:
|
spec:
|
||||||
replicas: 3
|
replicas: 3`), 0600)
|
||||||
`), 0600)
|
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -420,7 +421,7 @@ metadata:
|
|||||||
app: nginx
|
app: nginx
|
||||||
spec:
|
spec:
|
||||||
replicas: 3
|
replicas: 3
|
||||||
`, string(actual)) {
|
---`, string(actual)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -477,8 +478,7 @@ metadata:
|
|||||||
annotations:
|
annotations:
|
||||||
app: nginx
|
app: nginx
|
||||||
spec:
|
spec:
|
||||||
replicas: 3
|
replicas: 3`), 0600)
|
||||||
`), 0600)
|
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -536,7 +536,132 @@ metadata:
|
|||||||
app: nginx
|
app: nginx
|
||||||
spec:
|
spec:
|
||||||
replicas: 3
|
replicas: 3
|
||||||
`, string(actual)) {
|
---`, string(actual)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCatSubPackages(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
dataset string
|
||||||
|
packagePath string
|
||||||
|
args []string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "cat-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
expected: `# Copyright 2019 The Kubernetes Authors.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: mysql-deployment
|
||||||
|
namespace: myspace
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: mysql
|
||||||
|
image: mysql:1.7.9
|
||||||
|
---
|
||||||
|
# Copyright 2019 The Kubernetes Authors.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: storage-deployment
|
||||||
|
namespace: myspace
|
||||||
|
spec:
|
||||||
|
replicas: 4
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: storage
|
||||||
|
image: storage:1.7.7
|
||||||
|
---`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cat-top-level-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
args: []string{"-R=false"},
|
||||||
|
packagePath: "mysql",
|
||||||
|
expected: `# Copyright 2019 The Kubernetes Authors.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: mysql-deployment
|
||||||
|
namespace: myspace
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: mysql
|
||||||
|
image: mysql:1.7.9
|
||||||
|
---`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cat-nested-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
packagePath: "mysql/storage",
|
||||||
|
args: []string{"-R=false"},
|
||||||
|
expected: `# Copyright 2019 The Kubernetes Authors.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: storage-deployment
|
||||||
|
namespace: myspace
|
||||||
|
spec:
|
||||||
|
replicas: 4
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: storage
|
||||||
|
image: storage:1.7.7
|
||||||
|
---`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i := range tests {
|
||||||
|
test := tests[i]
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
// reset the openAPI afterward
|
||||||
|
openapi.ResetOpenAPI()
|
||||||
|
defer openapi.ResetOpenAPI()
|
||||||
|
sourceDir := filepath.Join("test", "testdata", test.dataset)
|
||||||
|
baseDir, err := ioutil.TempDir("", "")
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
copyutil.CopyDir(sourceDir, baseDir)
|
||||||
|
defer os.RemoveAll(baseDir)
|
||||||
|
runner := commands.GetCatRunner("")
|
||||||
|
actual := &bytes.Buffer{}
|
||||||
|
runner.Command.SetOut(actual)
|
||||||
|
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
|
||||||
|
err = runner.Command.Execute()
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize path format for windows
|
||||||
|
actualNormalized := strings.Replace(
|
||||||
|
strings.Replace(actual.String(), "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
|
||||||
|
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
|
||||||
|
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
|
||||||
|
if !assert.Equal(t, expectedNormalized, actualNormalized) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ package commands
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-openapi/spec"
|
"github.com/go-openapi/spec"
|
||||||
@@ -13,9 +16,7 @@ import (
|
|||||||
"sigs.k8s.io/kustomize/cmd/config/ext"
|
"sigs.k8s.io/kustomize/cmd/config/ext"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
||||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||||
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
|
|
||||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
|
||||||
"sigs.k8s.io/kustomize/kyaml/setters"
|
"sigs.k8s.io/kustomize/kyaml/setters"
|
||||||
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
|
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
|
||||||
)
|
)
|
||||||
@@ -59,6 +60,8 @@ func NewCreateSetterRunner(parent string) *CreateSetterRunner {
|
|||||||
set.Flags().StringVar(&r.SchemaPath, "schema-path", "",
|
set.Flags().StringVar(&r.SchemaPath, "schema-path", "",
|
||||||
`openAPI schema file path for setter constraints -- file content `+
|
`openAPI schema file path for setter constraints -- file content `+
|
||||||
`e.g. {"type": "string", "maxLength": 15, "enum": ["allowedValue1", "allowedValue2"]}`)
|
`e.g. {"type": "string", "maxLength": 15, "enum": ["allowedValue1", "allowedValue2"]}`)
|
||||||
|
set.Flags().BoolVarP(&r.CreateSetter.RecurseSubPackages, "recurse-subpackages", "R", false,
|
||||||
|
"creates setter recursively in all the nested subpackages")
|
||||||
set.Flags().MarkHidden("version")
|
set.Flags().MarkHidden("version")
|
||||||
fixDocs(parent, set)
|
fixDocs(parent, set)
|
||||||
r.Command = set
|
r.Command = set
|
||||||
@@ -78,7 +81,7 @@ type CreateSetterRunner struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *CreateSetterRunner) runE(c *cobra.Command, args []string) error {
|
func (r *CreateSetterRunner) runE(c *cobra.Command, args []string) error {
|
||||||
return handleError(c, r.set(c, args))
|
return handleError(c, r.createSetter(c, args))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *CreateSetterRunner) preRunE(c *cobra.Command, args []string) error {
|
func (r *CreateSetterRunner) preRunE(c *cobra.Command, args []string) error {
|
||||||
@@ -111,42 +114,6 @@ func (r *CreateSetterRunner) preRunE(c *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if setterVersion == "v2" {
|
if setterVersion == "v2" {
|
||||||
var err error
|
|
||||||
r.OpenAPIFile, err = ext.GetOpenAPIFile(args)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := openapi.AddSchemaFromFile(r.OpenAPIFile); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if substitution with same name exists and throw error
|
|
||||||
ref, err := spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SubstitutionDefinitionPrefix + r.CreateSetter.Name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
subst, _ := openapi.Resolve(&ref)
|
|
||||||
// if substitution already exists with the input setter name, throw error
|
|
||||||
if subst != nil {
|
|
||||||
return errors.Errorf("substitution with name %s already exists, "+
|
|
||||||
"substitution and setter can't have same name", r.CreateSetter.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if setter with same name exists and throw error
|
|
||||||
ref, err = spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SetterDefinitionPrefix + r.CreateSetter.Name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
setter, _ := openapi.Resolve(&ref)
|
|
||||||
// if setter already exists with the input setter name, throw error
|
|
||||||
if setter != nil {
|
|
||||||
return errors.Errorf("setter with name %s already exists, "+
|
|
||||||
"if you want to modify it, please delete the existing setter and recreate it", r.CreateSetter.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
r.CreateSetter.Description = r.Set.SetPartialField.Description
|
r.CreateSetter.Description = r.Set.SetPartialField.Description
|
||||||
r.CreateSetter.SetBy = r.Set.SetPartialField.SetBy
|
r.CreateSetter.SetBy = r.Set.SetPartialField.SetBy
|
||||||
r.CreateSetter.Type = r.Set.SetPartialField.Type
|
r.CreateSetter.Type = r.Set.SetPartialField.Type
|
||||||
@@ -210,9 +177,20 @@ func (r *CreateSetterRunner) processSchema() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *CreateSetterRunner) set(c *cobra.Command, args []string) error {
|
func (r *CreateSetterRunner) createSetter(c *cobra.Command, args []string) error {
|
||||||
if setterVersion == "v2" {
|
if setterVersion == "v2" {
|
||||||
return r.CreateSetter.Create(r.OpenAPIFile, args[0])
|
e := executeCmdOnPkgs{
|
||||||
|
needOpenAPI: true,
|
||||||
|
writer: c.OutOrStdout(),
|
||||||
|
rootPkgPath: args[0],
|
||||||
|
recurseSubPackages: r.CreateSetter.RecurseSubPackages,
|
||||||
|
cmdRunner: r,
|
||||||
|
}
|
||||||
|
err := e.execute()
|
||||||
|
if err != nil {
|
||||||
|
return handleError(c, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
rw := &kio.LocalPackageReadWriter{PackagePath: args[0]}
|
rw := &kio.LocalPackageReadWriter{PackagePath: args[0]}
|
||||||
@@ -226,6 +204,41 @@ func (r *CreateSetterRunner) set(c *cobra.Command, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *CreateSetterRunner) executeCmd(w io.Writer, pkgPath string) error {
|
||||||
|
openAPIFileName, err := ext.OpenAPIFileName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.CreateSetter = settersutil.SetterCreator{
|
||||||
|
Name: r.CreateSetter.Name,
|
||||||
|
SetBy: r.CreateSetter.SetBy,
|
||||||
|
Description: r.CreateSetter.Description,
|
||||||
|
Type: r.CreateSetter.Type,
|
||||||
|
Schema: r.CreateSetter.Schema,
|
||||||
|
FieldName: r.CreateSetter.FieldName,
|
||||||
|
FieldValue: r.CreateSetter.FieldValue,
|
||||||
|
Required: r.CreateSetter.Required,
|
||||||
|
RecurseSubPackages: r.CreateSetter.RecurseSubPackages,
|
||||||
|
OpenAPIFileName: openAPIFileName,
|
||||||
|
OpenAPIPath: filepath.Join(pkgPath, openAPIFileName),
|
||||||
|
ResourcesPath: pkgPath,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = r.CreateSetter.Create()
|
||||||
|
if err != nil {
|
||||||
|
// return err if RecurseSubPackages is false
|
||||||
|
if !r.CreateSetter.RecurseSubPackages {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
// print error message and continue if RecurseSubPackages is true
|
||||||
|
fmt.Fprintf(w, "%s\n", err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(w, "created setter %q\n", r.CreateSetter.Name)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// schemaFromFile reads the contents from schemaPath and returns schema
|
// schemaFromFile reads the contents from schemaPath and returns schema
|
||||||
func schemaFromFile(schemaPath string) (*spec.Schema, error) {
|
func schemaFromFile(schemaPath string) (*spec.Schema, error) {
|
||||||
sc := &spec.Schema{}
|
sc := &spec.Schema{}
|
||||||
|
|||||||
@@ -7,12 +7,13 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/ext"
|
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -43,6 +44,7 @@ spec:
|
|||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
`,
|
`,
|
||||||
|
out: `created setter "replicas"`,
|
||||||
expectedOpenAPI: `
|
expectedOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -81,6 +83,7 @@ spec:
|
|||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
`,
|
`,
|
||||||
|
out: `created setter "replicas"`,
|
||||||
expectedOpenAPI: `
|
expectedOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -122,7 +125,7 @@ openAPI:
|
|||||||
- marker: ${my-tag-setter}
|
- marker: ${my-tag-setter}
|
||||||
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
|
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
|
||||||
`,
|
`,
|
||||||
err: "substitution with name my-image already exists, substitution and setter can't have same name",
|
err: `substitution with name "my-image" already exists, substitution and setter can't have same name`,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -140,7 +143,7 @@ openAPI:
|
|||||||
name: my-image
|
name: my-image
|
||||||
value: "nginx"
|
value: "nginx"
|
||||||
`,
|
`,
|
||||||
err: "setter with name my-image already exists, if you want to modify it, please delete the existing setter and recreate it",
|
err: `setter with name "my-image" already exists, if you want to modify it, please delete the existing setter and recreate it`,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -159,6 +162,7 @@ spec:
|
|||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
`,
|
`,
|
||||||
|
out: `created setter "replicas"`,
|
||||||
expectedOpenAPI: `
|
expectedOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -200,6 +204,7 @@ spec:
|
|||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
`,
|
`,
|
||||||
|
out: `created setter replicas`,
|
||||||
expectedOpenAPI: `
|
expectedOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -254,6 +259,7 @@ spec:
|
|||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
`,
|
`,
|
||||||
|
out: `created setter "list"`,
|
||||||
expectedOpenAPI: `
|
expectedOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -354,6 +360,7 @@ spec:
|
|||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
`,
|
`,
|
||||||
|
out: `created setter replicas`,
|
||||||
expectedOpenAPI: `
|
expectedOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -400,6 +407,7 @@ spec:
|
|||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
`,
|
`,
|
||||||
|
out: `created setter "replicas"`,
|
||||||
expectedOpenAPI: `
|
expectedOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -437,6 +445,7 @@ spec:
|
|||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
`,
|
`,
|
||||||
|
out: `created setter "foo.bar"`,
|
||||||
expectedOpenAPI: `
|
expectedOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -587,6 +596,7 @@ spec:
|
|||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
`,
|
`,
|
||||||
|
out: `created setter "replicas"`,
|
||||||
expectedOpenAPI: `
|
expectedOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -712,6 +722,7 @@ spec:
|
|||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
`,
|
`,
|
||||||
|
out: `created setter "replicas"`,
|
||||||
expectedOpenAPI: `
|
expectedOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -742,13 +753,14 @@ spec:
|
|||||||
openapi.ResetOpenAPI()
|
openapi.ResetOpenAPI()
|
||||||
defer openapi.ResetOpenAPI()
|
defer openapi.ResetOpenAPI()
|
||||||
|
|
||||||
f, err := ioutil.TempFile("", "k8s-cli-")
|
baseDir, err := ioutil.TempDir("", "")
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
defer os.Remove(f.Name())
|
defer os.RemoveAll(baseDir)
|
||||||
|
|
||||||
err = ioutil.WriteFile(f.Name(), []byte(test.inputOpenAPI), 0600)
|
f := filepath.Join(baseDir, "Krmfile")
|
||||||
|
err = ioutil.WriteFile(f, []byte(test.inputOpenAPI), 0600)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
@@ -768,13 +780,7 @@ spec:
|
|||||||
test.args = append(test.args, "--schema-path", sch.Name())
|
test.args = append(test.args, "--schema-path", sch.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
old := ext.GetOpenAPIFile
|
r, err := ioutil.TempFile(baseDir, "k8s-cli-*.yaml")
|
||||||
defer func() { ext.GetOpenAPIFile = old }()
|
|
||||||
ext.GetOpenAPIFile = func(args []string) (s string, err error) {
|
|
||||||
return f.Name(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := ioutil.TempFile("", "k8s-cli-*.yaml")
|
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
@@ -787,7 +793,7 @@ spec:
|
|||||||
runner := commands.NewCreateSetterRunner("")
|
runner := commands.NewCreateSetterRunner("")
|
||||||
out := &bytes.Buffer{}
|
out := &bytes.Buffer{}
|
||||||
runner.Command.SetOut(out)
|
runner.Command.SetOut(out)
|
||||||
runner.Command.SetArgs(append([]string{r.Name()}, test.args...))
|
runner.Command.SetArgs(append([]string{baseDir}, test.args...))
|
||||||
err = runner.Command.Execute()
|
err = runner.Command.Execute()
|
||||||
if test.err != "" {
|
if test.err != "" {
|
||||||
if !assert.NotNil(t, err) {
|
if !assert.NotNil(t, err) {
|
||||||
@@ -801,7 +807,14 @@ spec:
|
|||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !assert.Equal(t, test.out, out.String()) {
|
expectedOut := strings.Replace(test.out, "${baseDir}", baseDir, -1)
|
||||||
|
expectedNormalized := strings.Replace(expectedOut, "\\", "/", -1)
|
||||||
|
// normalize path format for windows
|
||||||
|
actualNormalized := strings.Replace(
|
||||||
|
strings.Replace(out.String(), "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
|
||||||
|
if !assert.Contains(t, actualNormalized, expectedNormalized) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -815,7 +828,7 @@ spec:
|
|||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
actualOpenAPI, err := ioutil.ReadFile(f.Name())
|
actualOpenAPI, err := ioutil.ReadFile(f)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
@@ -827,3 +840,92 @@ spec:
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCreateSetterSubPackages(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
dataset string
|
||||||
|
packagePath string
|
||||||
|
args []string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "create-setter-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
args: []string{"namespace", "myspace", "-R"},
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
created setter "namespace"
|
||||||
|
|
||||||
|
${baseDir}/mysql/storage/
|
||||||
|
created setter "namespace"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create-setter-top-level-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
packagePath: "mysql",
|
||||||
|
args: []string{"namespace", "myspace"},
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
created setter "namespace"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create-setter-nested-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
packagePath: "mysql/storage",
|
||||||
|
args: []string{"namespace", "myspace"},
|
||||||
|
expected: `${baseDir}/mysql/storage/
|
||||||
|
created setter "namespace"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create-setter-already-exists",
|
||||||
|
dataset: "dataset-with-setters",
|
||||||
|
packagePath: "mysql",
|
||||||
|
args: []string{"namespace", "myspace", "-R"},
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
setter with name "namespace" already exists, if you want to modify it, please delete the existing setter and recreate it
|
||||||
|
|
||||||
|
${baseDir}/mysql/nosetters/
|
||||||
|
created setter "namespace"
|
||||||
|
|
||||||
|
${baseDir}/mysql/storage/
|
||||||
|
setter with name "namespace" already exists, if you want to modify it, please delete the existing setter and recreate it
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i := range tests {
|
||||||
|
test := tests[i]
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
// reset the openAPI afterward
|
||||||
|
openapi.ResetOpenAPI()
|
||||||
|
defer openapi.ResetOpenAPI()
|
||||||
|
sourceDir := filepath.Join("test", "testdata", test.dataset)
|
||||||
|
baseDir, err := ioutil.TempDir("", "")
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
copyutil.CopyDir(sourceDir, baseDir)
|
||||||
|
defer os.RemoveAll(baseDir)
|
||||||
|
runner := commands.NewCreateSetterRunner("")
|
||||||
|
actual := &bytes.Buffer{}
|
||||||
|
runner.Command.SetOut(actual)
|
||||||
|
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
|
||||||
|
err = runner.Command.Execute()
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize path format for windows
|
||||||
|
actualNormalized := strings.Replace(
|
||||||
|
strings.Replace(actual.String(), "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
|
||||||
|
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
|
||||||
|
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
|
||||||
|
if !assert.Equal(t, expectedNormalized, actualNormalized) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,13 +5,11 @@ package commands
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/go-openapi/spec"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/ext"
|
"sigs.k8s.io/kustomize/cmd/config/ext"
|
||||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
|
||||||
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
|
|
||||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
|
||||||
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
|
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,10 +17,10 @@ import (
|
|||||||
func NewCreateSubstitutionRunner(parent string) *CreateSubstitutionRunner {
|
func NewCreateSubstitutionRunner(parent string) *CreateSubstitutionRunner {
|
||||||
r := &CreateSubstitutionRunner{}
|
r := &CreateSubstitutionRunner{}
|
||||||
cs := &cobra.Command{
|
cs := &cobra.Command{
|
||||||
Use: "create-subst DIR NAME",
|
Use: "create-subst DIR NAME",
|
||||||
Args: cobra.ExactArgs(2),
|
Args: cobra.ExactArgs(2),
|
||||||
PreRunE: r.preRunE,
|
PreRun: r.preRun,
|
||||||
RunE: r.runE,
|
RunE: r.runE,
|
||||||
}
|
}
|
||||||
cs.Flags().StringVar(&r.CreateSubstitution.FieldName, "field", "",
|
cs.Flags().StringVar(&r.CreateSubstitution.FieldName, "field", "",
|
||||||
"name of the field to set -- e.g. --field image")
|
"name of the field to set -- e.g. --field image")
|
||||||
@@ -30,6 +28,8 @@ func NewCreateSubstitutionRunner(parent string) *CreateSubstitutionRunner {
|
|||||||
"value of the field to create substitution for -- e.g. --field-value nginx:0.1.0")
|
"value of the field to create substitution for -- e.g. --field-value nginx:0.1.0")
|
||||||
cs.Flags().StringVar(&r.CreateSubstitution.Pattern, "pattern", "",
|
cs.Flags().StringVar(&r.CreateSubstitution.Pattern, "pattern", "",
|
||||||
`substitution pattern -- e.g. --pattern \${my-image-setter}:\${my-tag-setter}`)
|
`substitution pattern -- e.g. --pattern \${my-image-setter}:\${my-tag-setter}`)
|
||||||
|
cs.Flags().BoolVarP(&r.CreateSubstitution.RecurseSubPackages, "recurse-subpackages", "R", false,
|
||||||
|
"creates substitution recursively in all the nested subpackages")
|
||||||
_ = cs.MarkFlagRequired("pattern")
|
_ = cs.MarkFlagRequired("pattern")
|
||||||
_ = cs.MarkFlagRequired("field-value")
|
_ = cs.MarkFlagRequired("field-value")
|
||||||
fixDocs(parent, cs)
|
fixDocs(parent, cs)
|
||||||
@@ -49,49 +49,52 @@ type CreateSubstitutionRunner struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *CreateSubstitutionRunner) runE(c *cobra.Command, args []string) error {
|
func (r *CreateSubstitutionRunner) runE(c *cobra.Command, args []string) error {
|
||||||
return handleError(c, r.CreateSubstitution.Create(r.OpenAPIFile, args[0]))
|
e := executeCmdOnPkgs{
|
||||||
}
|
needOpenAPI: true,
|
||||||
|
writer: c.OutOrStdout(),
|
||||||
func (r *CreateSubstitutionRunner) preRunE(c *cobra.Command, args []string) error {
|
rootPkgPath: args[0],
|
||||||
var err error
|
recurseSubPackages: r.CreateSubstitution.RecurseSubPackages,
|
||||||
r.CreateSubstitution.Name = args[1]
|
cmdRunner: r,
|
||||||
|
}
|
||||||
|
err := e.execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return handleError(c, err)
|
||||||
}
|
|
||||||
|
|
||||||
r.OpenAPIFile, err = ext.GetOpenAPIFile(args)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := openapi.AddSchemaFromFile(r.OpenAPIFile); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if substitution with same name exists and throw error
|
|
||||||
ref, err := spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SubstitutionDefinitionPrefix + r.CreateSubstitution.Name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
subst, _ := openapi.Resolve(&ref)
|
|
||||||
// if substitution already exists with the input substitution name, throw error
|
|
||||||
if subst != nil {
|
|
||||||
return errors.Errorf("substitution with name %s already exists", r.CreateSubstitution.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if setter with same name exists and throw error
|
|
||||||
ref, err = spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SetterDefinitionPrefix + r.CreateSubstitution.Name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
setter, _ := openapi.Resolve(&ref)
|
|
||||||
// if setter already exists with input substitution name, throw error
|
|
||||||
if setter != nil {
|
|
||||||
return errors.Errorf(fmt.Sprintf("setter with name %s already exists, "+
|
|
||||||
"substitution and setter can't have same name", r.CreateSubstitution.Name))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *CreateSubstitutionRunner) executeCmd(w io.Writer, pkgPath string) error {
|
||||||
|
openAPIFileName, err := ext.OpenAPIFileName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.CreateSubstitution = settersutil.SubstitutionCreator{
|
||||||
|
Name: r.CreateSubstitution.Name,
|
||||||
|
FieldName: r.CreateSubstitution.FieldName,
|
||||||
|
FieldValue: r.CreateSubstitution.FieldValue,
|
||||||
|
RecurseSubPackages: r.CreateSubstitution.RecurseSubPackages,
|
||||||
|
Pattern: r.CreateSubstitution.Pattern,
|
||||||
|
OpenAPIFileName: openAPIFileName,
|
||||||
|
OpenAPIPath: filepath.Join(pkgPath, openAPIFileName),
|
||||||
|
ResourcesPath: pkgPath,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = r.CreateSubstitution.Create()
|
||||||
|
if err != nil {
|
||||||
|
// return err if RecurseSubPackages is false
|
||||||
|
if !r.CreateSubstitution.RecurseSubPackages {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
// print error message and continue if RecurseSubPackages is true
|
||||||
|
fmt.Fprintf(w, "%s\n", err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(w, "created substitution %q\n", r.CreateSubstitution.Name)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CreateSubstitutionRunner) preRun(c *cobra.Command, args []string) {
|
||||||
|
r.CreateSubstitution.Name = args[1]
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,12 +7,13 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/ext"
|
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -62,6 +63,7 @@ openAPI:
|
|||||||
name: my-tag-setter
|
name: my-tag-setter
|
||||||
value: "1.7.9"
|
value: "1.7.9"
|
||||||
`,
|
`,
|
||||||
|
out: `created substitution "my-image-subst"`,
|
||||||
expectedOpenAPI: `
|
expectedOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -123,7 +125,7 @@ openAPI:
|
|||||||
- marker: ${my-tag-setter}
|
- marker: ${my-tag-setter}
|
||||||
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
|
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
|
||||||
`,
|
`,
|
||||||
err: "substitution with name my-image already exists",
|
err: `substitution with name "my-image" already exists`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "error if setter with same name exists",
|
name: "error if setter with same name exists",
|
||||||
@@ -140,7 +142,7 @@ openAPI:
|
|||||||
name: my-image
|
name: my-image
|
||||||
value: "nginx"
|
value: "nginx"
|
||||||
`,
|
`,
|
||||||
err: "setter with name my-image already exists, substitution and setter can't have same name",
|
err: `setter with name "my-image" already exists, substitution and setter can't have same name`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "substitution and create setters 1",
|
name: "substitution and create setters 1",
|
||||||
@@ -165,6 +167,7 @@ spec:
|
|||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
`,
|
`,
|
||||||
|
out: `created substitution "my-image-subst"`,
|
||||||
expectedOpenAPI: `
|
expectedOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -253,6 +256,7 @@ openAPI:
|
|||||||
- marker: ${my-tag-setter}
|
- marker: ${my-tag-setter}
|
||||||
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
|
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
|
||||||
`,
|
`,
|
||||||
|
out: `created substitution "my-nested-subst"`,
|
||||||
expectedOpenAPI: `
|
expectedOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -341,7 +345,7 @@ spec:
|
|||||||
substVal: prefix-1234
|
substVal: prefix-1234
|
||||||
|
|
||||||
`,
|
`,
|
||||||
err: "setters must have different name than the substitution: foo",
|
err: `setters must have different name than the substitution: foo`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i := range tests {
|
for i := range tests {
|
||||||
@@ -351,22 +355,18 @@ spec:
|
|||||||
openapi.ResetOpenAPI()
|
openapi.ResetOpenAPI()
|
||||||
defer openapi.ResetOpenAPI()
|
defer openapi.ResetOpenAPI()
|
||||||
|
|
||||||
f, err := ioutil.TempFile("", "k8s-cli-")
|
baseDir, err := ioutil.TempDir("", "")
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
defer os.Remove(f.Name())
|
defer os.RemoveAll(baseDir)
|
||||||
err = ioutil.WriteFile(f.Name(), []byte(test.inputOpenAPI), 0600)
|
f := filepath.Join(baseDir, "Krmfile")
|
||||||
|
err = ioutil.WriteFile(f, []byte(test.inputOpenAPI), 0600)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
old := ext.GetOpenAPIFile
|
|
||||||
defer func() { ext.GetOpenAPIFile = old }()
|
|
||||||
ext.GetOpenAPIFile = func(args []string) (s string, err error) {
|
|
||||||
return f.Name(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := ioutil.TempFile("", "k8s-cli-*.yaml")
|
r, err := ioutil.TempFile(baseDir, "k8s-cli-*.yaml")
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
@@ -379,7 +379,7 @@ spec:
|
|||||||
runner := commands.NewCreateSubstitutionRunner("")
|
runner := commands.NewCreateSubstitutionRunner("")
|
||||||
out := &bytes.Buffer{}
|
out := &bytes.Buffer{}
|
||||||
runner.Command.SetOut(out)
|
runner.Command.SetOut(out)
|
||||||
runner.Command.SetArgs(append([]string{r.Name()}, test.args...))
|
runner.Command.SetArgs(append([]string{baseDir}, test.args...))
|
||||||
err = runner.Command.Execute()
|
err = runner.Command.Execute()
|
||||||
|
|
||||||
if test.err != "" {
|
if test.err != "" {
|
||||||
@@ -393,7 +393,14 @@ spec:
|
|||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !assert.Equal(t, test.out, out.String()) {
|
expectedOut := strings.Replace(test.out, "${baseDir}", baseDir, -1)
|
||||||
|
expectedNormalized := strings.Replace(expectedOut, "\\", "/", -1)
|
||||||
|
// normalize path format for windows
|
||||||
|
actualNormalized := strings.Replace(
|
||||||
|
strings.Replace(out.String(), "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
|
||||||
|
if !assert.Contains(t, actualNormalized, expectedNormalized) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,7 +414,7 @@ spec:
|
|||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
actualOpenAPI, err := ioutil.ReadFile(f.Name())
|
actualOpenAPI, err := ioutil.ReadFile(f)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
@@ -419,3 +426,89 @@ spec:
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCreateSubstSubPackages(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
dataset string
|
||||||
|
packagePath string
|
||||||
|
args []string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "create-subst-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
args: []string{"image-tag", "--field-value", "mysql:1.7.9", "--pattern", "${image}:${tag}", "-R"},
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
created substitution "image-tag"
|
||||||
|
|
||||||
|
${baseDir}/mysql/storage/
|
||||||
|
created substitution "image-tag"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create-subst-top-level-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
packagePath: "mysql",
|
||||||
|
args: []string{"image-tag", "--field-value", "mysql:1.7.9", "--pattern", "${image}:${tag}"},
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
created substitution "image-tag"`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create-subst-nested-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
packagePath: "mysql/storage",
|
||||||
|
args: []string{"image-tag", "--field-value", "storage:1.7.9", "--pattern", "${image}:${tag}"},
|
||||||
|
expected: `${baseDir}/mysql/storage/
|
||||||
|
created substitution "image-tag"`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create-subst-already-exists",
|
||||||
|
dataset: "dataset-with-setters",
|
||||||
|
packagePath: "mysql",
|
||||||
|
args: []string{"image-tag", "--field-value", "mysql:1.7.9", "--pattern", "${image}:${tag}", "-R"},
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
substitution with name "image-tag" already exists
|
||||||
|
|
||||||
|
${baseDir}/mysql/nosetters/
|
||||||
|
created substitution "image-tag"
|
||||||
|
|
||||||
|
${baseDir}/mysql/storage/
|
||||||
|
created substitution "image-tag"`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i := range tests {
|
||||||
|
test := tests[i]
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
// reset the openAPI afterward
|
||||||
|
openapi.ResetOpenAPI()
|
||||||
|
defer openapi.ResetOpenAPI()
|
||||||
|
sourceDir := filepath.Join("test", "testdata", test.dataset)
|
||||||
|
baseDir, err := ioutil.TempDir("", "")
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
copyutil.CopyDir(sourceDir, baseDir)
|
||||||
|
defer os.RemoveAll(baseDir)
|
||||||
|
runner := commands.NewCreateSubstitutionRunner("")
|
||||||
|
actual := &bytes.Buffer{}
|
||||||
|
runner.Command.SetOut(actual)
|
||||||
|
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
|
||||||
|
err = runner.Command.Execute()
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize path format for windows
|
||||||
|
actualNormalized := strings.Replace(
|
||||||
|
strings.Replace(actual.String(), "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
|
||||||
|
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
|
||||||
|
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
|
||||||
|
if !assert.Equal(t, strings.TrimSpace(expectedNormalized), strings.TrimSpace(actualNormalized)) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,11 +4,14 @@
|
|||||||
package commands
|
package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/ext"
|
"sigs.k8s.io/kustomize/cmd/config/ext"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
||||||
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
|
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
|
||||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
|
||||||
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
|
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -24,6 +27,8 @@ func NewDeleteSetterRunner(parent string) *DeleteSetterRunner {
|
|||||||
PreRunE: r.preRunE,
|
PreRunE: r.preRunE,
|
||||||
RunE: r.runE,
|
RunE: r.runE,
|
||||||
}
|
}
|
||||||
|
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
|
||||||
|
"deletes setter recursively in all the nested subpackages")
|
||||||
fixDocs(parent, c)
|
fixDocs(parent, c)
|
||||||
r.Command = c
|
r.Command = c
|
||||||
|
|
||||||
@@ -35,9 +40,10 @@ func DeleteSetterCommand(parent string) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type DeleteSetterRunner struct {
|
type DeleteSetterRunner struct {
|
||||||
Command *cobra.Command
|
Command *cobra.Command
|
||||||
DeleteSetter settersutil.DeleterCreator
|
DeleteSetter settersutil.DeleterCreator
|
||||||
OpenAPIFile string
|
OpenAPIFile string
|
||||||
|
RecurseSubPackages bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *DeleteSetterRunner) preRunE(c *cobra.Command, args []string) error {
|
func (r *DeleteSetterRunner) preRunE(c *cobra.Command, args []string) error {
|
||||||
@@ -50,17 +56,49 @@ func (r *DeleteSetterRunner) preRunE(c *cobra.Command, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := openapi.AddSchemaFromFile(r.OpenAPIFile); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *DeleteSetterRunner) runE(c *cobra.Command, args []string) error {
|
func (r *DeleteSetterRunner) runE(c *cobra.Command, args []string) error {
|
||||||
return handleError(c, r.delete(c, args))
|
e := executeCmdOnPkgs{
|
||||||
|
needOpenAPI: true,
|
||||||
|
writer: c.OutOrStdout(),
|
||||||
|
rootPkgPath: args[0],
|
||||||
|
recurseSubPackages: r.RecurseSubPackages,
|
||||||
|
cmdRunner: r,
|
||||||
|
}
|
||||||
|
err := e.execute()
|
||||||
|
if err != nil {
|
||||||
|
return handleError(c, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *DeleteSetterRunner) delete(c *cobra.Command, args []string) error {
|
func (r *DeleteSetterRunner) executeCmd(w io.Writer, pkgPath string) error {
|
||||||
return r.DeleteSetter.Delete(r.OpenAPIFile, args[0])
|
openAPIFileName, err := ext.OpenAPIFileName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.DeleteSetter = settersutil.DeleterCreator{
|
||||||
|
Name: r.DeleteSetter.Name,
|
||||||
|
DefinitionPrefix: fieldmeta.SetterDefinitionPrefix,
|
||||||
|
RecurseSubPackages: r.RecurseSubPackages,
|
||||||
|
OpenAPIFileName: openAPIFileName,
|
||||||
|
OpenAPIPath: filepath.Join(pkgPath, openAPIFileName),
|
||||||
|
ResourcesPath: pkgPath,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = r.DeleteSetter.Delete()
|
||||||
|
if err != nil {
|
||||||
|
// return err if RecurseSubPackages is false
|
||||||
|
if !r.DeleteSetter.RecurseSubPackages {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
// print error message and continue if RecurseSubPackages is true
|
||||||
|
fmt.Fprintf(w, "%s\n", err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(w, "deleted setter %q\n", r.DeleteSetter.Name)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,13 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/ext"
|
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ openAPI:
|
|||||||
value: "3"
|
value: "3"
|
||||||
setBy: me
|
setBy: me
|
||||||
`,
|
`,
|
||||||
|
out: `deleted setter "replicas-setter"`,
|
||||||
expectedOpenAPI: `
|
expectedOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -95,6 +97,7 @@ openAPI:
|
|||||||
name: image
|
name: image
|
||||||
value: nginx
|
value: nginx
|
||||||
`,
|
`,
|
||||||
|
out: `deleted setter "replicas-setter"`,
|
||||||
expectedOpenAPI: `
|
expectedOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -158,6 +161,7 @@ spec:
|
|||||||
- "b"
|
- "b"
|
||||||
- "c"
|
- "c"
|
||||||
`,
|
`,
|
||||||
|
out: `deleted setter "list"`,
|
||||||
expectedResources: `
|
expectedResources: `
|
||||||
apiVersion: example.com/v1beta1
|
apiVersion: example.com/v1beta1
|
||||||
kind: Example1
|
kind: Example1
|
||||||
@@ -226,7 +230,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
replicas: 3 # {"$openapi" : "replicas-setter"}
|
replicas: 3 # {"$openapi" : "replicas-setter"}
|
||||||
`,
|
`,
|
||||||
err: `setter with name image does not exist`,
|
err: `setter "image" does not exist`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "delete setter used in substitution error",
|
name: "delete setter used in substitution error",
|
||||||
@@ -287,7 +291,7 @@ openAPI:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
`,
|
`,
|
||||||
err: `setter is used in substitution image, please delete the parent substitution first`,
|
err: `setter "image-name" is used in substitution "image", please delete the parent substitution first`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i := range tests {
|
for i := range tests {
|
||||||
@@ -297,24 +301,18 @@ kind: Deployment
|
|||||||
openapi.ResetOpenAPI()
|
openapi.ResetOpenAPI()
|
||||||
defer openapi.ResetOpenAPI()
|
defer openapi.ResetOpenAPI()
|
||||||
|
|
||||||
f, err := ioutil.TempFile("", "k8s-cli-")
|
baseDir, err := ioutil.TempDir("", "")
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
defer os.Remove(f.Name())
|
defer os.RemoveAll(baseDir)
|
||||||
|
f := filepath.Join(baseDir, "Krmfile")
|
||||||
err = ioutil.WriteFile(f.Name(), []byte(test.inputOpenAPI), 0600)
|
err = ioutil.WriteFile(f, []byte(test.inputOpenAPI), 0600)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
old := ext.GetOpenAPIFile
|
r, err := ioutil.TempFile(baseDir, "k8s-cli-*.yaml")
|
||||||
defer func() { ext.GetOpenAPIFile = old }()
|
|
||||||
ext.GetOpenAPIFile = func(args []string) (s string, err error) {
|
|
||||||
return f.Name(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := ioutil.TempFile("", "k8s-cli-*.yaml")
|
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
@@ -327,21 +325,29 @@ kind: Deployment
|
|||||||
runner := commands.NewDeleteSetterRunner("")
|
runner := commands.NewDeleteSetterRunner("")
|
||||||
out := &bytes.Buffer{}
|
out := &bytes.Buffer{}
|
||||||
runner.Command.SetOut(out)
|
runner.Command.SetOut(out)
|
||||||
runner.Command.SetArgs(append([]string{r.Name()}, test.args...))
|
runner.Command.SetArgs(append([]string{baseDir}, test.args...))
|
||||||
err = runner.Command.Execute()
|
err = runner.Command.Execute()
|
||||||
|
|
||||||
if test.err != "" {
|
if test.err != "" {
|
||||||
if !assert.NotNil(t, err) {
|
if !assert.NotNil(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
} else {
|
|
||||||
assert.Equal(t, err.Error(), test.err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
assert.Equal(t, test.err, err.Error())
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !assert.Equal(t, test.out, out.String()) {
|
// normalize path format for windows
|
||||||
|
actualNorm := strings.Replace(
|
||||||
|
strings.Replace(out.String(), "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
|
||||||
|
expectedOut := strings.Replace(test.out, "${baseDir}", baseDir, -1)
|
||||||
|
expectedNormalized := strings.Replace(expectedOut, "\\", "/", -1)
|
||||||
|
|
||||||
|
if !assert.Contains(t, strings.TrimSpace(actualNorm), expectedNormalized) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,7 +361,7 @@ kind: Deployment
|
|||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
actualOpenAPI, err := ioutil.ReadFile(f.Name())
|
actualOpenAPI, err := ioutil.ReadFile(f)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
@@ -367,3 +373,80 @@ kind: Deployment
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDeleteSetterSubPackages(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
dataset string
|
||||||
|
packagePath string
|
||||||
|
args []string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "delete-setter-recurse-subpackages",
|
||||||
|
dataset: "dataset-with-setters",
|
||||||
|
args: []string{"namespace", "-R"},
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
deleted setter "namespace"
|
||||||
|
|
||||||
|
${baseDir}/mysql/nosetters/
|
||||||
|
setter "namespace" does not exist
|
||||||
|
|
||||||
|
${baseDir}/mysql/storage/
|
||||||
|
deleted setter "namespace"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "delete-setter-top-level-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-with-setters",
|
||||||
|
packagePath: "mysql",
|
||||||
|
args: []string{"namespace"},
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
deleted setter "namespace"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "delete-setter-nested-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-with-setters",
|
||||||
|
packagePath: "mysql/storage",
|
||||||
|
args: []string{"namespace"},
|
||||||
|
expected: `${baseDir}/mysql/storage/
|
||||||
|
deleted setter "namespace"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i := range tests {
|
||||||
|
test := tests[i]
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
// reset the openAPI afterward
|
||||||
|
openapi.ResetOpenAPI()
|
||||||
|
defer openapi.ResetOpenAPI()
|
||||||
|
sourceDir := filepath.Join("test", "testdata", test.dataset)
|
||||||
|
baseDir, err := ioutil.TempDir("", "")
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
copyutil.CopyDir(sourceDir, baseDir)
|
||||||
|
//defer os.RemoveAll(baseDir)
|
||||||
|
runner := commands.NewDeleteSetterRunner("")
|
||||||
|
actual := &bytes.Buffer{}
|
||||||
|
runner.Command.SetOut(actual)
|
||||||
|
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
|
||||||
|
err = runner.Command.Execute()
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize path format for windows
|
||||||
|
actualNormalized := strings.Replace(
|
||||||
|
strings.Replace(actual.String(), "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
|
||||||
|
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
|
||||||
|
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
|
||||||
|
if !assert.Equal(t, expectedNormalized, actualNormalized) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,10 +4,13 @@
|
|||||||
package commands
|
package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/ext"
|
"sigs.k8s.io/kustomize/cmd/config/ext"
|
||||||
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
|
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
|
||||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
|
||||||
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
|
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -20,6 +23,8 @@ func NewDeleteSubstitutionRunner(parent string) *DeleteSubstitutionRunner {
|
|||||||
PreRunE: r.preRunE,
|
PreRunE: r.preRunE,
|
||||||
RunE: r.runE,
|
RunE: r.runE,
|
||||||
}
|
}
|
||||||
|
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
|
||||||
|
"deletes substitution recursively in all the nested subpackages")
|
||||||
fixDocs(parent, c)
|
fixDocs(parent, c)
|
||||||
r.Command = c
|
r.Command = c
|
||||||
|
|
||||||
@@ -34,6 +39,7 @@ type DeleteSubstitutionRunner struct {
|
|||||||
Command *cobra.Command
|
Command *cobra.Command
|
||||||
DeleteSubstitution settersutil.DeleterCreator
|
DeleteSubstitution settersutil.DeleterCreator
|
||||||
OpenAPIFile string
|
OpenAPIFile string
|
||||||
|
RecurseSubPackages bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *DeleteSubstitutionRunner) preRunE(c *cobra.Command, args []string) error {
|
func (r *DeleteSubstitutionRunner) preRunE(c *cobra.Command, args []string) error {
|
||||||
@@ -46,17 +52,49 @@ func (r *DeleteSubstitutionRunner) preRunE(c *cobra.Command, args []string) erro
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := openapi.AddSchemaFromFile(r.OpenAPIFile); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *DeleteSubstitutionRunner) runE(c *cobra.Command, args []string) error {
|
func (r *DeleteSubstitutionRunner) runE(c *cobra.Command, args []string) error {
|
||||||
return handleError(c, r.delete(c, args))
|
e := executeCmdOnPkgs{
|
||||||
|
needOpenAPI: true,
|
||||||
|
writer: c.OutOrStdout(),
|
||||||
|
rootPkgPath: args[0],
|
||||||
|
recurseSubPackages: r.RecurseSubPackages,
|
||||||
|
cmdRunner: r,
|
||||||
|
}
|
||||||
|
err := e.execute()
|
||||||
|
if err != nil {
|
||||||
|
return handleError(c, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *DeleteSubstitutionRunner) delete(c *cobra.Command, args []string) error {
|
func (r *DeleteSubstitutionRunner) executeCmd(w io.Writer, pkgPath string) error {
|
||||||
return r.DeleteSubstitution.Delete(r.OpenAPIFile, args[0])
|
openAPIFileName, err := ext.OpenAPIFileName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.DeleteSubstitution = settersutil.DeleterCreator{
|
||||||
|
Name: r.DeleteSubstitution.Name,
|
||||||
|
DefinitionPrefix: fieldmeta.SubstitutionDefinitionPrefix,
|
||||||
|
RecurseSubPackages: r.RecurseSubPackages,
|
||||||
|
OpenAPIFileName: openAPIFileName,
|
||||||
|
OpenAPIPath: filepath.Join(pkgPath, openAPIFileName),
|
||||||
|
ResourcesPath: pkgPath,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = r.DeleteSubstitution.Delete()
|
||||||
|
if err != nil {
|
||||||
|
// return err if RecurseSubPackages is false
|
||||||
|
if !r.DeleteSubstitution.RecurseSubPackages {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
// print error message and continue if RecurseSubPackages is true
|
||||||
|
fmt.Fprintf(w, "%s\n", err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(w, "deleted substitution %q\n", r.DeleteSubstitution.Name)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,13 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/ext"
|
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -79,6 +80,7 @@ spec:
|
|||||||
- name: sidecar
|
- name: sidecar
|
||||||
image: nginx:1.7.9 # {"$ref":"#/definitions/io.k8s.cli.substitutions.my.image"}
|
image: nginx:1.7.9 # {"$ref":"#/definitions/io.k8s.cli.substitutions.my.image"}
|
||||||
`,
|
`,
|
||||||
|
out: `deleted substitution "my.image"`,
|
||||||
expectedResources: `
|
expectedResources: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@@ -169,6 +171,7 @@ spec:
|
|||||||
- name: sidecar
|
- name: sidecar
|
||||||
image: nginx:1.7.9 # {"$openapi":"my-image-sub"}
|
image: nginx:1.7.9 # {"$openapi":"my-image-sub"}
|
||||||
`,
|
`,
|
||||||
|
out: `deleted substitution "my-image-sub"`,
|
||||||
expectedResources: `
|
expectedResources: `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@@ -297,7 +300,7 @@ openAPI:
|
|||||||
value: "3"
|
value: "3"
|
||||||
setBy: me
|
setBy: me
|
||||||
`,
|
`,
|
||||||
err: "substitution with name my-image-sub-not-present does not exist",
|
err: `substitution "my-image-sub-not-present" does not exist`,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -415,7 +418,7 @@ spec:
|
|||||||
- name: sidecar
|
- name: sidecar
|
||||||
image: nginx::1.7.9 # {"$openapi":"my-image-subst"}
|
image: nginx::1.7.9 # {"$openapi":"my-image-subst"}
|
||||||
`,
|
`,
|
||||||
err: "substitution is used in substitution my-nested-subst, please delete the parent substitution first",
|
err: `substitution "my-image-subst" is used in substitution "my-nested-subst", please delete the parent substitution first`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i := range tests {
|
for i := range tests {
|
||||||
@@ -425,24 +428,18 @@ spec:
|
|||||||
openapi.ResetOpenAPI()
|
openapi.ResetOpenAPI()
|
||||||
defer openapi.ResetOpenAPI()
|
defer openapi.ResetOpenAPI()
|
||||||
|
|
||||||
f, err := ioutil.TempFile("", "k8s-cli-")
|
baseDir, err := ioutil.TempDir("", "")
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
defer os.Remove(f.Name())
|
defer os.RemoveAll(baseDir)
|
||||||
|
f := filepath.Join(baseDir, "Krmfile")
|
||||||
err = ioutil.WriteFile(f.Name(), []byte(test.inputOpenAPI), 0600)
|
err = ioutil.WriteFile(f, []byte(test.inputOpenAPI), 0600)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
old := ext.GetOpenAPIFile
|
r, err := ioutil.TempFile(baseDir, "k8s-cli-*.yaml")
|
||||||
defer func() { ext.GetOpenAPIFile = old }()
|
|
||||||
ext.GetOpenAPIFile = func(args []string) (s string, err error) {
|
|
||||||
return f.Name(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := ioutil.TempFile("", "k8s-cli-*.yaml")
|
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
@@ -455,21 +452,38 @@ spec:
|
|||||||
runner := commands.NewDeleteSubstitutionRunner("")
|
runner := commands.NewDeleteSubstitutionRunner("")
|
||||||
out := &bytes.Buffer{}
|
out := &bytes.Buffer{}
|
||||||
runner.Command.SetOut(out)
|
runner.Command.SetOut(out)
|
||||||
runner.Command.SetArgs(append([]string{r.Name()}, test.args...))
|
runner.Command.SetArgs(append([]string{baseDir}, test.args...))
|
||||||
err = runner.Command.Execute()
|
err = runner.Command.Execute()
|
||||||
|
|
||||||
if test.err != "" {
|
if test.err != "" {
|
||||||
if !assert.NotNil(t, err) {
|
if !assert.NotNil(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
} else {
|
|
||||||
assert.Equal(t, err.Error(), test.err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
assert.Equal(t, test.err, err.Error())
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !assert.Equal(t, test.out, out.String()) {
|
// normalize path format for windows
|
||||||
|
actualNorm := strings.Replace(
|
||||||
|
strings.Replace(out.String(), "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
expectedOut := strings.Replace(test.out, "${baseDir}", baseDir, -1)
|
||||||
|
expectedNorm := strings.Replace(expectedOut, "\\", "/", -1)
|
||||||
|
|
||||||
|
if !assert.Contains(t, strings.TrimSpace(actualNorm), expectedNorm) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
actualOpenAPI, err := ioutil.ReadFile(f)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
if !assert.Equal(t,
|
||||||
|
strings.TrimSpace(test.expectedOpenAPI),
|
||||||
|
strings.TrimSpace(string(actualOpenAPI))) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,16 +494,74 @@ spec:
|
|||||||
if !assert.Equal(t,
|
if !assert.Equal(t,
|
||||||
strings.TrimSpace(test.expectedResources),
|
strings.TrimSpace(test.expectedResources),
|
||||||
strings.TrimSpace(string(actualResources))) {
|
strings.TrimSpace(string(actualResources))) {
|
||||||
return
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
})
|
||||||
actualOpenAPI, err := ioutil.ReadFile(f.Name())
|
}
|
||||||
if !assert.NoError(t, err) {
|
}
|
||||||
t.FailNow()
|
|
||||||
}
|
func TestDeleteSubstitutionSubPackages(t *testing.T) {
|
||||||
if !assert.Equal(t,
|
var tests = []struct {
|
||||||
strings.TrimSpace(test.expectedOpenAPI),
|
name string
|
||||||
strings.TrimSpace(string(actualOpenAPI))) {
|
dataset string
|
||||||
|
packagePath string
|
||||||
|
args []string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "delete-substitution-recurse-subpackages",
|
||||||
|
dataset: "dataset-with-setters",
|
||||||
|
args: []string{"image-tag", "-R"},
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
deleted substitution "image-tag"
|
||||||
|
|
||||||
|
${baseDir}/mysql/nosetters/
|
||||||
|
substitution "image-tag" does not exist
|
||||||
|
|
||||||
|
${baseDir}/mysql/storage/
|
||||||
|
substitution "image-tag" does not exist
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "delete-setter-top-level-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-with-setters",
|
||||||
|
packagePath: "mysql",
|
||||||
|
args: []string{"image-tag"},
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
deleted substitution "image-tag"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i := range tests {
|
||||||
|
test := tests[i]
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
// reset the openAPI afterward
|
||||||
|
openapi.ResetOpenAPI()
|
||||||
|
defer openapi.ResetOpenAPI()
|
||||||
|
sourceDir := filepath.Join("test", "testdata", test.dataset)
|
||||||
|
baseDir, err := ioutil.TempDir("", "")
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
copyutil.CopyDir(sourceDir, baseDir)
|
||||||
|
//defer os.RemoveAll(baseDir)
|
||||||
|
runner := commands.NewDeleteSubstitutionRunner("")
|
||||||
|
actual := &bytes.Buffer{}
|
||||||
|
runner.Command.SetOut(actual)
|
||||||
|
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
|
||||||
|
err = runner.Command.Execute()
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize path format for windows
|
||||||
|
actualNormalized := strings.Replace(
|
||||||
|
strings.Replace(actual.String(), "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
|
||||||
|
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
|
||||||
|
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
|
||||||
|
if !assert.Equal(t, expectedNormalized, actualNormalized) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -7,15 +7,14 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/olekukonko/tablewriter"
|
"github.com/olekukonko/tablewriter"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/ext"
|
"sigs.k8s.io/kustomize/cmd/config/ext"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
||||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
|
||||||
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
|
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
|
||||||
"sigs.k8s.io/kustomize/kyaml/pathutil"
|
|
||||||
"sigs.k8s.io/kustomize/kyaml/setters"
|
"sigs.k8s.io/kustomize/kyaml/setters"
|
||||||
"sigs.k8s.io/kustomize/kyaml/setters2"
|
"sigs.k8s.io/kustomize/kyaml/setters2"
|
||||||
)
|
)
|
||||||
@@ -36,6 +35,8 @@ func NewListSettersRunner(parent string) *ListSettersRunner {
|
|||||||
"output as github markdown")
|
"output as github markdown")
|
||||||
c.Flags().BoolVar(&r.IncludeSubst, "include-subst", false,
|
c.Flags().BoolVar(&r.IncludeSubst, "include-subst", false,
|
||||||
"include substitutions in the output")
|
"include substitutions in the output")
|
||||||
|
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", true,
|
||||||
|
"list setters recursively in all the nested subpackages")
|
||||||
fixDocs(parent, c)
|
fixDocs(parent, c)
|
||||||
r.Command = c
|
r.Command = c
|
||||||
return r
|
return r
|
||||||
@@ -46,11 +47,12 @@ func ListSettersCommand(parent string) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ListSettersRunner struct {
|
type ListSettersRunner struct {
|
||||||
Command *cobra.Command
|
Command *cobra.Command
|
||||||
Lookup setters.LookupSetters
|
Lookup setters.LookupSetters
|
||||||
List setters2.List
|
List setters2.List
|
||||||
Markdown bool
|
Markdown bool
|
||||||
IncludeSubst bool
|
IncludeSubst bool
|
||||||
|
RecurseSubPackages bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ListSettersRunner) preRunE(c *cobra.Command, args []string) error {
|
func (r *ListSettersRunner) preRunE(c *cobra.Command, args []string) error {
|
||||||
@@ -65,48 +67,50 @@ func (r *ListSettersRunner) preRunE(c *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
func (r *ListSettersRunner) runE(c *cobra.Command, args []string) error {
|
func (r *ListSettersRunner) runE(c *cobra.Command, args []string) error {
|
||||||
if setterVersion == "v2" {
|
if setterVersion == "v2" {
|
||||||
openAPIFileName, err := ext.OpenAPIFileName()
|
e := executeCmdOnPkgs{
|
||||||
if err != nil {
|
needOpenAPI: true,
|
||||||
return err
|
writer: c.OutOrStdout(),
|
||||||
|
rootPkgPath: args[0],
|
||||||
|
recurseSubPackages: r.RecurseSubPackages,
|
||||||
|
cmdRunner: r,
|
||||||
}
|
}
|
||||||
|
|
||||||
openAPIPaths, err := pathutil.SubDirsWithFile(args[0], openAPIFileName)
|
err := e.execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return handleError(c, err)
|
||||||
}
|
|
||||||
if len(openAPIPaths) == 0 {
|
|
||||||
return errors.Errorf("unable to find %s in %s", openAPIFileName, args[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
// list setters for all the subpackages with openAPI file paths
|
|
||||||
for _, openAPIPath := range openAPIPaths {
|
|
||||||
r.List = setters2.List{
|
|
||||||
Name: r.List.Name,
|
|
||||||
OpenAPIFileName: openAPIFileName,
|
|
||||||
}
|
|
||||||
resourcePath := strings.TrimSuffix(openAPIPath, openAPIFileName)
|
|
||||||
fmt.Fprintf(c.OutOrStdout(), "%s\n", resourcePath)
|
|
||||||
if err := r.ListSetters(c, openAPIPath, resourcePath); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if r.IncludeSubst {
|
|
||||||
if err := r.ListSubstitutions(c, openAPIPath); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return handleError(c, lookup(r.Lookup, c, args))
|
return handleError(c, lookup(r.Lookup, c, args))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ListSettersRunner) ListSetters(c *cobra.Command, openAPIPath, resourcePath string) error {
|
func (r *ListSettersRunner) executeCmd(w io.Writer, pkgPath string) error {
|
||||||
|
openAPIFileName, err := ext.OpenAPIFileName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.List = setters2.List{
|
||||||
|
Name: r.List.Name,
|
||||||
|
OpenAPIFileName: openAPIFileName,
|
||||||
|
}
|
||||||
|
openAPIPath := filepath.Join(pkgPath, openAPIFileName)
|
||||||
|
if err := r.ListSetters(w, openAPIPath, pkgPath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if r.IncludeSubst {
|
||||||
|
if err := r.ListSubstitutions(w, openAPIPath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ListSettersRunner) ListSetters(w io.Writer, openAPIPath, resourcePath string) error {
|
||||||
// use setters v2
|
// use setters v2
|
||||||
if err := r.List.ListSetters(openAPIPath, resourcePath); err != nil {
|
if err := r.List.ListSetters(openAPIPath, resourcePath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
table := newTable(c.OutOrStdout(), r.Markdown)
|
table := newTable(w, r.Markdown)
|
||||||
table.SetHeader([]string{"NAME", "VALUE", "SET BY", "DESCRIPTION", "COUNT", "REQUIRED"})
|
table.SetHeader([]string{"NAME", "VALUE", "SET BY", "DESCRIPTION", "COUNT", "REQUIRED"})
|
||||||
for i := range r.List.Setters {
|
for i := range r.List.Setters {
|
||||||
s := r.List.Setters[i]
|
s := r.List.Setters[i]
|
||||||
@@ -137,12 +141,12 @@ func (r *ListSettersRunner) ListSetters(c *cobra.Command, openAPIPath, resourceP
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ListSettersRunner) ListSubstitutions(c *cobra.Command, openAPIPath string) error {
|
func (r *ListSettersRunner) ListSubstitutions(w io.Writer, openAPIPath string) error {
|
||||||
// use setters v2
|
// use setters v2
|
||||||
if err := r.List.ListSubst(openAPIPath); err != nil {
|
if err := r.List.ListSubst(openAPIPath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
table := newTable(c.OutOrStdout(), r.Markdown)
|
table := newTable(w, r.Markdown)
|
||||||
b := tablewriter.Border{Top: true}
|
b := tablewriter.Border{Top: true}
|
||||||
table.SetBorders(b)
|
table.SetBorders(b)
|
||||||
|
|
||||||
|
|||||||
@@ -471,9 +471,11 @@ func TestListSettersSubPackages(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "list-replicas",
|
name: "list-replicas",
|
||||||
dataset: "dataset1",
|
dataset: "dataset-with-setters",
|
||||||
args: []string{"--include-subst"},
|
args: []string{"--include-subst"},
|
||||||
expected: `test/testdata/dataset1/mysql/
|
expected: `
|
||||||
|
|
||||||
|
test/testdata/dataset-with-setters/mysql/
|
||||||
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
|
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
|
||||||
image mysql 1 No
|
image mysql 1 No
|
||||||
namespace myspace 1 No
|
namespace myspace 1 No
|
||||||
@@ -481,11 +483,26 @@ func TestListSettersSubPackages(t *testing.T) {
|
|||||||
--------------- ----------------- --------------
|
--------------- ----------------- --------------
|
||||||
SUBSTITUTION PATTERN REFERENCES
|
SUBSTITUTION PATTERN REFERENCES
|
||||||
image-tag ${image}:${tag} [image,tag]
|
image-tag ${image}:${tag} [image,tag]
|
||||||
test/testdata/dataset1/mysql/nosetters/
|
|
||||||
|
test/testdata/dataset-with-setters/mysql/nosetters/
|
||||||
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
|
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
|
||||||
test/testdata/dataset1/mysql/storage/
|
|
||||||
|
test/testdata/dataset-with-setters/mysql/storage/
|
||||||
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
|
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
|
||||||
namespace myspace 1 No
|
namespace myspace 1 No
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "list-replicas",
|
||||||
|
dataset: "dataset-with-setters/mysql",
|
||||||
|
args: []string{"--recurse-subpackages=false"},
|
||||||
|
expected: `
|
||||||
|
|
||||||
|
test/testdata/dataset-with-setters/mysql/
|
||||||
|
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
|
||||||
|
image mysql 1 No
|
||||||
|
namespace myspace 1 No
|
||||||
|
tag 1.7.9 1 No
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -509,7 +526,7 @@ test/testdata/dataset1/mysql/storage/
|
|||||||
// normalize path format for windows
|
// normalize path format for windows
|
||||||
actualNormalized := strings.Replace(actual.String(), "\\", "/", -1)
|
actualNormalized := strings.Replace(actual.String(), "\\", "/", -1)
|
||||||
|
|
||||||
if !assert.Equal(t, test.expected, actualNormalized) {
|
if !assert.Equal(t, strings.TrimSpace(test.expected), strings.TrimSpace(actualNormalized)) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ package commands
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/olekukonko/tablewriter"
|
"github.com/olekukonko/tablewriter"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@@ -39,6 +41,8 @@ func NewSetRunner(parent string) *SetRunner {
|
|||||||
"annotate the field with a description of its value")
|
"annotate the field with a description of its value")
|
||||||
c.Flags().StringVar(&setterVersion, "version", "",
|
c.Flags().StringVar(&setterVersion, "version", "",
|
||||||
"use this version of the setter format")
|
"use this version of the setter format")
|
||||||
|
c.Flags().BoolVarP(&r.Set.RecurseSubPackages, "recurse-subpackages", "R", false,
|
||||||
|
"sets recursively in all the nested subpackages")
|
||||||
c.Flags().MarkHidden("version")
|
c.Flags().MarkHidden("version")
|
||||||
|
|
||||||
return r
|
return r
|
||||||
@@ -126,15 +130,23 @@ func (r *SetRunner) preRunE(c *cobra.Command, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *SetRunner) runE(c *cobra.Command, args []string) error {
|
func (r *SetRunner) runE(c *cobra.Command, args []string) error {
|
||||||
if setterVersion == "v2" {
|
if setterVersion == "v2" {
|
||||||
count, err := r.Set.Set(r.OpenAPIFile, args[0])
|
e := executeCmdOnPkgs{
|
||||||
fmt.Fprintf(c.OutOrStdout(), "set %d fields\n", count)
|
needOpenAPI: true,
|
||||||
return handleError(c, err)
|
writer: c.OutOrStdout(),
|
||||||
|
rootPkgPath: args[0],
|
||||||
|
recurseSubPackages: r.Set.RecurseSubPackages,
|
||||||
|
cmdRunner: r,
|
||||||
|
}
|
||||||
|
err := e.execute()
|
||||||
|
if err != nil {
|
||||||
|
return handleError(c, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
if len(args) > 2 || c.Flag("values").Changed {
|
if len(args) > 2 || c.Flag("values").Changed {
|
||||||
return handleError(c, r.perform(c, args))
|
return handleError(c, r.perform(c, args))
|
||||||
@@ -142,6 +154,38 @@ func (r *SetRunner) runE(c *cobra.Command, args []string) error {
|
|||||||
return handleError(c, lookup(r.Lookup, c, args))
|
return handleError(c, lookup(r.Lookup, c, args))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *SetRunner) executeCmd(w io.Writer, pkgPath string) error {
|
||||||
|
openAPIFileName, err := ext.OpenAPIFileName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.Set = settersutil.FieldSetter{
|
||||||
|
Name: r.Set.Name,
|
||||||
|
Value: r.Set.Value,
|
||||||
|
ListValues: r.Set.ListValues,
|
||||||
|
Description: r.Set.Description,
|
||||||
|
SetBy: r.Set.SetBy,
|
||||||
|
Count: 0,
|
||||||
|
OpenAPIPath: filepath.Join(pkgPath, openAPIFileName),
|
||||||
|
OpenAPIFileName: openAPIFileName,
|
||||||
|
ResourcesPath: pkgPath,
|
||||||
|
RecurseSubPackages: r.Set.RecurseSubPackages,
|
||||||
|
}
|
||||||
|
count, err := r.Set.Set()
|
||||||
|
if err != nil {
|
||||||
|
// return err if RecurseSubPackages is false
|
||||||
|
if !r.Set.RecurseSubPackages {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
// print error message and continue if RecurseSubPackages is true
|
||||||
|
fmt.Fprintf(w, "%s\n", err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(w, "set %d field(s)\n", count)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func lookup(l setters.LookupSetters, c *cobra.Command, args []string) error {
|
func lookup(l setters.LookupSetters, c *cobra.Command, args []string) error {
|
||||||
// lookup the setters
|
// lookup the setters
|
||||||
err := kio.Pipeline{
|
err := kio.Pipeline{
|
||||||
|
|||||||
@@ -7,12 +7,13 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/ext"
|
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ func TestSetCommand(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "set replicas",
|
name: "set replicas",
|
||||||
args: []string{"replicas", "4", "--description", "hi there", "--set-by", "pw"},
|
args: []string{"replicas", "4", "--description", "hi there", "--set-by", "pw"},
|
||||||
out: "set 1 fields\n",
|
out: "set 1 field(s)\n",
|
||||||
inputOpenAPI: `
|
inputOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -126,7 +127,7 @@ spec:
|
|||||||
{
|
{
|
||||||
name: "set replicas no description",
|
name: "set replicas no description",
|
||||||
args: []string{"replicas", "4"},
|
args: []string{"replicas", "4"},
|
||||||
out: "set 1 fields\n",
|
out: "set 1 field(s)\n",
|
||||||
inputOpenAPI: `
|
inputOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -174,7 +175,7 @@ spec:
|
|||||||
{
|
{
|
||||||
name: "set image with value",
|
name: "set image with value",
|
||||||
args: []string{"tag", "1.8.1"},
|
args: []string{"tag", "1.8.1"},
|
||||||
out: "set 1 fields\n",
|
out: "set 1 field(s)\n",
|
||||||
inputOpenAPI: `
|
inputOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -509,7 +510,7 @@ list in body should have at most 2 items`,
|
|||||||
{
|
{
|
||||||
name: "set replicas with value set by flag",
|
name: "set replicas with value set by flag",
|
||||||
args: []string{"replicas", "--values", "4", "--description", "hi there"},
|
args: []string{"replicas", "--values", "4", "--description", "hi there"},
|
||||||
out: "set 1 fields\n",
|
out: "set 1 field(s)\n",
|
||||||
inputOpenAPI: `
|
inputOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -605,7 +606,7 @@ spec:
|
|||||||
{
|
{
|
||||||
name: "openAPI list values set by flag success",
|
name: "openAPI list values set by flag success",
|
||||||
args: []string{"list", "--values", "10", "--values", "11"},
|
args: []string{"list", "--values", "10", "--values", "11"},
|
||||||
out: "set 1 fields\n",
|
out: "set 1 field(s)\n",
|
||||||
inputOpenAPI: `
|
inputOpenAPI: `
|
||||||
kind: Kptfile
|
kind: Kptfile
|
||||||
openAPI:
|
openAPI:
|
||||||
@@ -709,7 +710,7 @@ list in body should have at most 2 items`,
|
|||||||
{
|
{
|
||||||
name: "nested substitution",
|
name: "nested substitution",
|
||||||
args: []string{"my-image-setter", "ubuntu"},
|
args: []string{"my-image-setter", "ubuntu"},
|
||||||
out: "set 2 fields\n",
|
out: "set 2 field(s)\n",
|
||||||
inputOpenAPI: `
|
inputOpenAPI: `
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: Example
|
kind: Example
|
||||||
@@ -1013,22 +1014,19 @@ spec:
|
|||||||
openapi.ResetOpenAPI()
|
openapi.ResetOpenAPI()
|
||||||
defer openapi.ResetOpenAPI()
|
defer openapi.ResetOpenAPI()
|
||||||
|
|
||||||
f, err := ioutil.TempFile("", "k8s-cli-")
|
baseDir, err := ioutil.TempDir("", "")
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
defer os.Remove(f.Name())
|
defer os.RemoveAll(baseDir)
|
||||||
err = ioutil.WriteFile(f.Name(), []byte(test.inputOpenAPI), 0600)
|
|
||||||
|
f := filepath.Join(baseDir, "Krmfile")
|
||||||
|
err = ioutil.WriteFile(f, []byte(test.inputOpenAPI), 0600)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
old := ext.GetOpenAPIFile
|
|
||||||
defer func() { ext.GetOpenAPIFile = old }()
|
|
||||||
ext.GetOpenAPIFile = func(args []string) (s string, err error) {
|
|
||||||
return f.Name(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := ioutil.TempFile("", "k8s-cli-*.yaml")
|
r, err := ioutil.TempFile(baseDir, "k8s-cli-*.yaml")
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
@@ -1041,7 +1039,7 @@ spec:
|
|||||||
runner := commands.NewSetRunner("")
|
runner := commands.NewSetRunner("")
|
||||||
out := &bytes.Buffer{}
|
out := &bytes.Buffer{}
|
||||||
runner.Command.SetOut(out)
|
runner.Command.SetOut(out)
|
||||||
runner.Command.SetArgs(append([]string{r.Name()}, test.args...))
|
runner.Command.SetArgs(append([]string{baseDir}, test.args...))
|
||||||
err = runner.Command.Execute()
|
err = runner.Command.Execute()
|
||||||
if test.errMsg != "" {
|
if test.errMsg != "" {
|
||||||
if !assert.NotNil(t, err) {
|
if !assert.NotNil(t, err) {
|
||||||
@@ -1056,7 +1054,7 @@ spec:
|
|||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
if test.errMsg == "" && !assert.Equal(t, test.out, out.String()) {
|
if test.errMsg == "" && !assert.Contains(t, out.String(), strings.TrimSpace(test.out)) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1070,7 +1068,7 @@ spec:
|
|||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
actualOpenAPI, err := ioutil.ReadFile(f.Name())
|
actualOpenAPI, err := ioutil.ReadFile(f)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
@@ -1082,3 +1080,82 @@ spec:
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetSubPackages(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
dataset string
|
||||||
|
packagePath string
|
||||||
|
args []string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "set-recurse-subpackages",
|
||||||
|
dataset: "dataset-with-setters",
|
||||||
|
args: []string{"namespace", "otherspace", "-R"},
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
set 1 field(s)
|
||||||
|
|
||||||
|
${baseDir}/mysql/nosetters/
|
||||||
|
setter "namespace" is not found
|
||||||
|
|
||||||
|
${baseDir}/mysql/storage/
|
||||||
|
set 1 field(s)
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "set-top-level-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-with-setters",
|
||||||
|
packagePath: "mysql",
|
||||||
|
args: []string{"namespace", "otherspace"},
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
set 1 field(s)
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "set-nested-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-with-setters",
|
||||||
|
packagePath: "mysql/storage",
|
||||||
|
args: []string{"namespace", "otherspace"},
|
||||||
|
expected: `${baseDir}/mysql/storage/
|
||||||
|
set 1 field(s)
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i := range tests {
|
||||||
|
test := tests[i]
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
// reset the openAPI afterward
|
||||||
|
openapi.ResetOpenAPI()
|
||||||
|
defer openapi.ResetOpenAPI()
|
||||||
|
sourceDir := filepath.Join("test", "testdata", test.dataset)
|
||||||
|
baseDir, err := ioutil.TempDir("", "")
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
copyutil.CopyDir(sourceDir, baseDir)
|
||||||
|
defer os.RemoveAll(baseDir)
|
||||||
|
runner := commands.NewSetRunner("")
|
||||||
|
actual := &bytes.Buffer{}
|
||||||
|
runner.Command.SetOut(actual)
|
||||||
|
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
|
||||||
|
err = runner.Command.Execute()
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize path format for windows
|
||||||
|
actualNormalized := strings.Replace(
|
||||||
|
strings.Replace(actual.String(), "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
|
||||||
|
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
|
||||||
|
expectedNormalized := strings.Replace(
|
||||||
|
strings.Replace(expected, "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
if !assert.Equal(t, strings.TrimSpace(expectedNormalized), strings.TrimSpace(actualNormalized)) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ items:
|
|||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: mysql-deployment
|
name: mysql-deployment
|
||||||
namespace: myspace # {"$openapi":"namespace"}
|
namespace: myspace
|
||||||
annotations:
|
annotations:
|
||||||
config.kubernetes.io/index: '0'
|
config.kubernetes.io/index: '0'
|
||||||
config.kubernetes.io/path: 'config/mysql-deployment_deployment.yaml'
|
config.kubernetes.io/path: 'config/mysql-deployment_deployment.yaml'
|
||||||
@@ -192,7 +192,7 @@ items:
|
|||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: mysql
|
- name: mysql
|
||||||
image: mysql:1.7.9 # {"$openapi":"image-tag"}
|
image: mysql:1.7.9
|
||||||
- apiVersion: apps/v1
|
- apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -212,7 +212,7 @@ items:
|
|||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: storage-deployment
|
name: storage-deployment
|
||||||
namespace: myspace # {"$openapi":"namespace"}
|
namespace: myspace
|
||||||
annotations:
|
annotations:
|
||||||
config.kubernetes.io/index: '0'
|
config.kubernetes.io/index: '0'
|
||||||
config.kubernetes.io/path: 'config/storage-deployment_deployment.yaml'
|
config.kubernetes.io/path: 'config/storage-deployment_deployment.yaml'
|
||||||
|
|||||||
@@ -5,9 +5,11 @@ package commands
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"sigs.k8s.io/kustomize/cmd/config/ext"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
||||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||||
"sigs.k8s.io/kustomize/kyaml/sets"
|
"sigs.k8s.io/kustomize/kyaml/sets"
|
||||||
@@ -17,18 +19,18 @@ import (
|
|||||||
func GetCountRunner(name string) *CountRunner {
|
func GetCountRunner(name string) *CountRunner {
|
||||||
r := &CountRunner{}
|
r := &CountRunner{}
|
||||||
c := &cobra.Command{
|
c := &cobra.Command{
|
||||||
Use: "count DIR...",
|
Use: "count [DIR]",
|
||||||
|
Args: cobra.MaximumNArgs(1),
|
||||||
Short: commands.CountShort,
|
Short: commands.CountShort,
|
||||||
Long: commands.CountLong,
|
Long: commands.CountLong,
|
||||||
Example: commands.CountExamples,
|
Example: commands.CountExamples,
|
||||||
RunE: r.runE,
|
RunE: r.runE,
|
||||||
}
|
}
|
||||||
fixDocs(name, c)
|
fixDocs(name, c)
|
||||||
c.Flags().BoolVar(&r.IncludeSubpackages, "include-subpackages", true,
|
|
||||||
"also print resources from subpackages.")
|
|
||||||
c.Flags().BoolVar(&r.Kind, "kind", true,
|
c.Flags().BoolVar(&r.Kind, "kind", true,
|
||||||
"count resources by kind.")
|
"count resources by kind.")
|
||||||
|
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", true,
|
||||||
|
"prints count of resources recursively in all the nested subpackages")
|
||||||
r.Command = c
|
r.Command = c
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
@@ -42,20 +44,56 @@ type CountRunner struct {
|
|||||||
IncludeSubpackages bool
|
IncludeSubpackages bool
|
||||||
Kind bool
|
Kind bool
|
||||||
Command *cobra.Command
|
Command *cobra.Command
|
||||||
|
RecurseSubPackages bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *CountRunner) runE(c *cobra.Command, args []string) error {
|
func (r *CountRunner) runE(c *cobra.Command, args []string) error {
|
||||||
var inputs []kio.Reader
|
if len(args) == 0 {
|
||||||
for _, a := range args {
|
input := &kio.ByteReader{Reader: c.InOrStdin()}
|
||||||
inputs = append(inputs, kio.LocalPackageReader{
|
|
||||||
PackagePath: a,
|
return handleError(c, kio.Pipeline{
|
||||||
IncludeSubpackages: r.IncludeSubpackages,
|
Inputs: []kio.Reader{input},
|
||||||
})
|
Outputs: r.out(c.OutOrStdout()),
|
||||||
}
|
}.Execute())
|
||||||
if len(inputs) == 0 {
|
|
||||||
inputs = append(inputs, &kio.ByteReader{Reader: c.InOrStdin()})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e := executeCmdOnPkgs{
|
||||||
|
writer: c.OutOrStdout(),
|
||||||
|
needOpenAPI: false,
|
||||||
|
recurseSubPackages: r.RecurseSubPackages,
|
||||||
|
cmdRunner: r,
|
||||||
|
rootPkgPath: args[0],
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CountRunner) executeCmd(w io.Writer, pkgPath string) error {
|
||||||
|
openAPIFileName, err := ext.OpenAPIFileName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: openAPIFileName}
|
||||||
|
|
||||||
|
err = kio.Pipeline{
|
||||||
|
Inputs: []kio.Reader{input},
|
||||||
|
Outputs: r.out(w),
|
||||||
|
}.Execute()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
// return err if there is only package
|
||||||
|
if !r.RecurseSubPackages {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
// print error message and continue if there are multiple packages to annotate
|
||||||
|
fmt.Fprintf(w, "%s\n", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CountRunner) out(w io.Writer) []kio.Writer {
|
||||||
var out []kio.Writer
|
var out []kio.Writer
|
||||||
if r.Kind {
|
if r.Kind {
|
||||||
out = append(out, kio.WriterFunc(func(nodes []*yaml.RNode) error {
|
out = append(out, kio.WriterFunc(func(nodes []*yaml.RNode) error {
|
||||||
@@ -69,20 +107,15 @@ func (r *CountRunner) runE(c *cobra.Command, args []string) error {
|
|||||||
order := k.List()
|
order := k.List()
|
||||||
sort.Strings(order)
|
sort.Strings(order)
|
||||||
for _, k := range order {
|
for _, k := range order {
|
||||||
fmt.Fprintf(c.OutOrStdout(), "%s: %d\n", k, count[k])
|
fmt.Fprintf(w, "%s: %d\n", k, count[k])
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
out = append(out, kio.WriterFunc(func(nodes []*yaml.RNode) error {
|
out = append(out, kio.WriterFunc(func(nodes []*yaml.RNode) error {
|
||||||
fmt.Fprintf(c.OutOrStdout(), "%d\n", len(nodes))
|
fmt.Fprintf(w, "%d\n", len(nodes))
|
||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
return handleError(c, kio.Pipeline{
|
return out
|
||||||
Inputs: inputs,
|
|
||||||
Outputs: out,
|
|
||||||
}.Execute())
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,13 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCountCommand_files(t *testing.T) {
|
func TestCountCommand_files(t *testing.T) {
|
||||||
@@ -67,7 +70,80 @@ spec:
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !assert.Equal(t, "Deployment: 2\nService: 1\n", b.String()) {
|
if !assert.Contains(t, b.String(), "Deployment: 2\nService: 1\n") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCountSubPackages(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
dataset string
|
||||||
|
packagePath string
|
||||||
|
args []string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "count-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
Deployment: 1
|
||||||
|
|
||||||
|
${baseDir}/mysql/storage/
|
||||||
|
Deployment: 1
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "count-top-level-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
args: []string{"-R=false"},
|
||||||
|
packagePath: "mysql",
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
Deployment: 1
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "count-nested-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
packagePath: "mysql/storage",
|
||||||
|
args: []string{"-R=false"},
|
||||||
|
expected: `${baseDir}/mysql/storage/
|
||||||
|
Deployment: 1
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i := range tests {
|
||||||
|
test := tests[i]
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
// reset the openAPI afterward
|
||||||
|
openapi.ResetOpenAPI()
|
||||||
|
defer openapi.ResetOpenAPI()
|
||||||
|
sourceDir := filepath.Join("test", "testdata", test.dataset)
|
||||||
|
baseDir, err := ioutil.TempDir("", "")
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
copyutil.CopyDir(sourceDir, baseDir)
|
||||||
|
defer os.RemoveAll(baseDir)
|
||||||
|
runner := commands.GetCountRunner("")
|
||||||
|
actual := &bytes.Buffer{}
|
||||||
|
runner.Command.SetOut(actual)
|
||||||
|
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
|
||||||
|
err = runner.Command.Execute()
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize path format for windows
|
||||||
|
actualNormalized := strings.Replace(
|
||||||
|
strings.Replace(actual.String(), "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
|
||||||
|
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
|
||||||
|
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
|
||||||
|
if !assert.Equal(t, expectedNormalized, actualNormalized) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,11 @@
|
|||||||
package commands
|
package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"sigs.k8s.io/kustomize/cmd/config/ext"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
||||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||||
"sigs.k8s.io/kustomize/kyaml/kio/filters"
|
"sigs.k8s.io/kustomize/kyaml/kio/filters"
|
||||||
@@ -33,6 +37,8 @@ formatting substitution verbs {'%n': 'metadata.name', '%s': 'metadata.namespace'
|
|||||||
`if true, override existing filepath annotations.`)
|
`if true, override existing filepath annotations.`)
|
||||||
c.Flags().BoolVar(&r.UseSchema, "use-schema", false,
|
c.Flags().BoolVar(&r.UseSchema, "use-schema", false,
|
||||||
`if true, uses openapi resource schema to format resources.`)
|
`if true, uses openapi resource schema to format resources.`)
|
||||||
|
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
|
||||||
|
"formats resource files recursively in all the nested subpackages")
|
||||||
r.Command = c
|
r.Command = c
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
@@ -43,12 +49,13 @@ func FmtCommand(name string) *cobra.Command {
|
|||||||
|
|
||||||
// FmtRunner contains the run function
|
// FmtRunner contains the run function
|
||||||
type FmtRunner struct {
|
type FmtRunner struct {
|
||||||
Command *cobra.Command
|
Command *cobra.Command
|
||||||
FilenamePattern string
|
FilenamePattern string
|
||||||
SetFilenames bool
|
SetFilenames bool
|
||||||
KeepAnnotations bool
|
KeepAnnotations bool
|
||||||
Override bool
|
Override bool
|
||||||
UseSchema bool
|
UseSchema bool
|
||||||
|
RecurseSubPackages bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *FmtRunner) preRunE(c *cobra.Command, args []string) error {
|
func (r *FmtRunner) preRunE(c *cobra.Command, args []string) error {
|
||||||
@@ -59,17 +66,6 @@ func (r *FmtRunner) preRunE(c *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *FmtRunner) runE(c *cobra.Command, args []string) error {
|
func (r *FmtRunner) runE(c *cobra.Command, args []string) error {
|
||||||
f := []kio.Filter{filters.FormatFilter{
|
|
||||||
UseSchema: r.UseSchema,
|
|
||||||
}}
|
|
||||||
|
|
||||||
// format with file names
|
|
||||||
if r.SetFilenames {
|
|
||||||
f = append(f, &filters.FileSetter{
|
|
||||||
FilenamePattern: r.FilenamePattern,
|
|
||||||
Override: r.Override,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// format stdin if there are no args
|
// format stdin if there are no args
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
@@ -79,20 +75,64 @@ func (r *FmtRunner) runE(c *cobra.Command, args []string) error {
|
|||||||
KeepReaderAnnotations: r.KeepAnnotations,
|
KeepReaderAnnotations: r.KeepAnnotations,
|
||||||
}
|
}
|
||||||
return handleError(c, kio.Pipeline{
|
return handleError(c, kio.Pipeline{
|
||||||
Inputs: []kio.Reader{rw}, Filters: f, Outputs: []kio.Writer{rw}}.Execute())
|
Inputs: []kio.Reader{rw}, Filters: r.fmtFilters(), Outputs: []kio.Writer{rw}}.Execute())
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range args {
|
for _, rootPkgPath := range args {
|
||||||
path := args[i]
|
e := executeCmdOnPkgs{
|
||||||
rw := &kio.LocalPackageReadWriter{
|
writer: c.OutOrStdout(),
|
||||||
NoDeleteFiles: true,
|
needOpenAPI: false,
|
||||||
PackagePath: path,
|
recurseSubPackages: r.RecurseSubPackages,
|
||||||
KeepReaderAnnotations: r.KeepAnnotations}
|
cmdRunner: r,
|
||||||
err := kio.Pipeline{
|
rootPkgPath: rootPkgPath,
|
||||||
Inputs: []kio.Reader{rw}, Filters: f, Outputs: []kio.Writer{rw}}.Execute()
|
}
|
||||||
|
|
||||||
|
err := e.execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleError(c, err)
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *FmtRunner) executeCmd(w io.Writer, pkgPath string) error {
|
||||||
|
openAPIFileName, err := ext.OpenAPIFileName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
rw := &kio.LocalPackageReadWriter{
|
||||||
|
NoDeleteFiles: true,
|
||||||
|
PackagePath: pkgPath,
|
||||||
|
KeepReaderAnnotations: r.KeepAnnotations, PackageFileName: openAPIFileName}
|
||||||
|
err = kio.Pipeline{
|
||||||
|
Inputs: []kio.Reader{rw}, Filters: r.fmtFilters(), Outputs: []kio.Writer{rw}}.Execute()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
// return err if RecurseSubPackages is false
|
||||||
|
if !r.RecurseSubPackages {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
// print error message and continue if RecurseSubPackages is true
|
||||||
|
fmt.Fprintf(w, "%s\n", err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Fprint(w, "formatted resource files in the package\n")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FmtRunner) fmtFilters() []kio.Filter {
|
||||||
|
fmtFilters := []kio.Filter{filters.FormatFilter{
|
||||||
|
UseSchema: r.UseSchema,
|
||||||
|
}}
|
||||||
|
|
||||||
|
// format with file names
|
||||||
|
if r.SetFilenames {
|
||||||
|
fmtFilters = append(fmtFilters, &filters.FileSetter{
|
||||||
|
FilenamePattern: r.FilenamePattern,
|
||||||
|
Override: r.Override,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return fmtFilters
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,12 +7,15 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||||
"sigs.k8s.io/kustomize/kyaml/kio/filters/testyaml"
|
"sigs.k8s.io/kustomize/kyaml/kio/filters/testyaml"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||||
"sigs.k8s.io/kustomize/kyaml/testutil"
|
"sigs.k8s.io/kustomize/kyaml/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -163,3 +166,78 @@ func TestCmd_failFileContents(t *testing.T) {
|
|||||||
// expect an error
|
// expect an error
|
||||||
assert.EqualError(t, err, "yaml: line 1: did not find expected node content")
|
assert.EqualError(t, err, "yaml: line 1: did not find expected node content")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFmtSubPackages(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
dataset string
|
||||||
|
packagePath string
|
||||||
|
args []string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "fmt-recurse-subpackages",
|
||||||
|
dataset: "dataset-with-setters",
|
||||||
|
args: []string{"-R"},
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
formatted resource files in the package
|
||||||
|
|
||||||
|
${baseDir}/mysql/nosetters/
|
||||||
|
formatted resource files in the package
|
||||||
|
|
||||||
|
${baseDir}/mysql/storage/
|
||||||
|
formatted resource files in the package
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fmt-top-level-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
packagePath: "mysql",
|
||||||
|
expected: `${baseDir}/mysql/
|
||||||
|
formatted resource files in the package
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fmt-nested-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
packagePath: "mysql/storage",
|
||||||
|
expected: `${baseDir}/mysql/storage/
|
||||||
|
formatted resource files in the package
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i := range tests {
|
||||||
|
test := tests[i]
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
// reset the openAPI afterward
|
||||||
|
openapi.ResetOpenAPI()
|
||||||
|
defer openapi.ResetOpenAPI()
|
||||||
|
sourceDir := filepath.Join("test", "testdata", test.dataset)
|
||||||
|
baseDir, err := ioutil.TempDir("", "")
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
copyutil.CopyDir(sourceDir, baseDir)
|
||||||
|
defer os.RemoveAll(baseDir)
|
||||||
|
runner := commands.GetFmtRunner("")
|
||||||
|
actual := &bytes.Buffer{}
|
||||||
|
runner.Command.SetOut(actual)
|
||||||
|
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
|
||||||
|
err = runner.Command.Execute()
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize path format for windows
|
||||||
|
actualNormalized := strings.Replace(
|
||||||
|
strings.Replace(actual.String(), "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
|
||||||
|
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
|
||||||
|
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
|
||||||
|
if !assert.Equal(t, strings.TrimSpace(expectedNormalized), strings.TrimSpace(actualNormalized)) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ package commands
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
|
"sigs.k8s.io/kustomize/cmd/config/ext"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
||||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||||
"sigs.k8s.io/kustomize/kyaml/kio/filters"
|
"sigs.k8s.io/kustomize/kyaml/kio/filters"
|
||||||
@@ -18,22 +20,21 @@ import (
|
|||||||
func GetGrepRunner(name string) *GrepRunner {
|
func GetGrepRunner(name string) *GrepRunner {
|
||||||
r := &GrepRunner{}
|
r := &GrepRunner{}
|
||||||
c := &cobra.Command{
|
c := &cobra.Command{
|
||||||
Use: "grep QUERY [DIR]...",
|
Use: "grep QUERY [DIR]",
|
||||||
Short: commands.GrepShort,
|
Short: commands.GrepShort,
|
||||||
Long: commands.GrepLong,
|
Long: commands.GrepLong,
|
||||||
Example: commands.GrepExamples,
|
Example: commands.GrepExamples,
|
||||||
PreRunE: r.preRunE,
|
PreRunE: r.preRunE,
|
||||||
RunE: r.runE,
|
RunE: r.runE,
|
||||||
Args: cobra.MinimumNArgs(1),
|
Args: cobra.MaximumNArgs(2),
|
||||||
}
|
}
|
||||||
fixDocs(name, c)
|
fixDocs(name, c)
|
||||||
c.Flags().BoolVar(&r.IncludeSubpackages, "include-subpackages", true,
|
|
||||||
"also print resources from subpackages.")
|
|
||||||
c.Flags().BoolVar(&r.KeepAnnotations, "annotate", true,
|
c.Flags().BoolVar(&r.KeepAnnotations, "annotate", true,
|
||||||
"annotate resources with their file origins.")
|
"annotate resources with their file origins.")
|
||||||
c.Flags().BoolVarP(&r.InvertMatch, "invert-match", "", false,
|
c.Flags().BoolVarP(&r.InvertMatch, "invert-match", "", false,
|
||||||
"Selected Resources are those not matching any of the specified patterns..")
|
"Selected Resources are those not matching any of the specified patterns..")
|
||||||
|
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", true,
|
||||||
|
"also print resources recursively in all the nested subpackages")
|
||||||
r.Command = c
|
r.Command = c
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
@@ -44,11 +45,11 @@ func GrepCommand(name string) *cobra.Command {
|
|||||||
|
|
||||||
// GrepRunner contains the run function
|
// GrepRunner contains the run function
|
||||||
type GrepRunner struct {
|
type GrepRunner struct {
|
||||||
IncludeSubpackages bool
|
KeepAnnotations bool
|
||||||
KeepAnnotations bool
|
Command *cobra.Command
|
||||||
Command *cobra.Command
|
|
||||||
filters.GrepFilter
|
filters.GrepFilter
|
||||||
Format bool
|
Format bool
|
||||||
|
RecurseSubPackages bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *GrepRunner) preRunE(c *cobra.Command, args []string) error {
|
func (r *GrepRunner) preRunE(c *cobra.Command, args []string) error {
|
||||||
@@ -101,25 +102,57 @@ func (r *GrepRunner) preRunE(c *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *GrepRunner) runE(c *cobra.Command, args []string) error {
|
func (r *GrepRunner) runE(c *cobra.Command, args []string) error {
|
||||||
var filters = []kio.Filter{r.GrepFilter}
|
if len(args) == 1 {
|
||||||
|
input := &kio.ByteReader{Reader: c.InOrStdin()}
|
||||||
var inputs []kio.Reader
|
return handleError(c, kio.Pipeline{
|
||||||
for _, a := range args[1:] {
|
Inputs: []kio.Reader{input},
|
||||||
inputs = append(inputs, kio.LocalPackageReader{
|
Filters: []kio.Filter{r.GrepFilter},
|
||||||
PackagePath: a,
|
Outputs: []kio.Writer{kio.ByteWriter{
|
||||||
IncludeSubpackages: r.IncludeSubpackages,
|
Writer: c.OutOrStdout(),
|
||||||
})
|
KeepReaderAnnotations: r.KeepAnnotations,
|
||||||
}
|
}},
|
||||||
if len(inputs) == 0 {
|
}.Execute())
|
||||||
inputs = append(inputs, &kio.ByteReader{Reader: c.InOrStdin()})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return handleError(c, kio.Pipeline{
|
e := executeCmdOnPkgs{
|
||||||
Inputs: inputs,
|
writer: c.OutOrStdout(),
|
||||||
Filters: filters,
|
needOpenAPI: false,
|
||||||
|
recurseSubPackages: r.RecurseSubPackages,
|
||||||
|
cmdRunner: r,
|
||||||
|
rootPkgPath: args[1],
|
||||||
|
skipPkgPathPrint: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.execute()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GrepRunner) executeCmd(w io.Writer, pkgPath string) error {
|
||||||
|
openAPIFileName, err := ext.OpenAPIFileName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: openAPIFileName}
|
||||||
|
|
||||||
|
err = kio.Pipeline{
|
||||||
|
Inputs: []kio.Reader{input},
|
||||||
|
Filters: []kio.Filter{r.GrepFilter},
|
||||||
Outputs: []kio.Writer{kio.ByteWriter{
|
Outputs: []kio.Writer{kio.ByteWriter{
|
||||||
Writer: c.OutOrStdout(),
|
Writer: w,
|
||||||
KeepReaderAnnotations: r.KeepAnnotations,
|
KeepReaderAnnotations: r.KeepAnnotations,
|
||||||
}},
|
}},
|
||||||
}.Execute())
|
}.Execute()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
// return err if there is only package
|
||||||
|
if !r.RecurseSubPackages {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
// print error message and continue if there are multiple packages to annotate
|
||||||
|
fmt.Fprintf(w, "%s\n", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "---")
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,12 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestGrepCommand_files verifies grep reads the files and filters them
|
// TestGrepCommand_files verifies grep reads the files and filters them
|
||||||
@@ -68,7 +70,7 @@ spec:
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !assert.Equal(t, `kind: Deployment
|
if !assert.Contains(t, b.String(), `kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
app: nginx2
|
app: nginx2
|
||||||
@@ -90,7 +92,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
selector:
|
selector:
|
||||||
app: nginx
|
app: nginx
|
||||||
`, b.String()) {
|
`) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,7 +138,7 @@ spec:
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !assert.Equal(t, `kind: Deployment
|
if !assert.Contains(t, b.String(), `kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
app: nginx2
|
app: nginx2
|
||||||
@@ -156,7 +158,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
selector:
|
selector:
|
||||||
app: nginx
|
app: nginx
|
||||||
`, b.String()) {
|
`) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -250,7 +252,7 @@ spec:
|
|||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !assert.Equal(t, `kind: Deployment
|
if !assert.Contains(t, b.String(), `kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
app: nginx1.7
|
app: nginx1.7
|
||||||
@@ -264,7 +266,142 @@ spec:
|
|||||||
containers:
|
containers:
|
||||||
- name: nginx
|
- name: nginx
|
||||||
image: nginx:1.7.9
|
image: nginx:1.7.9
|
||||||
`, b.String()) {
|
`) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGrepSubPackages(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
dataset string
|
||||||
|
packagePath string
|
||||||
|
args []string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "grep-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
args: []string{"kind=Deployment"},
|
||||||
|
expected: `# Copyright 2019 The Kubernetes Authors.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
namespace: myspace
|
||||||
|
name: mysql-deployment
|
||||||
|
annotations:
|
||||||
|
config.kubernetes.io/index: '0'
|
||||||
|
config.kubernetes.io/path: 'deployment.yaml'
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: mysql
|
||||||
|
image: mysql:1.7.9
|
||||||
|
---
|
||||||
|
# Copyright 2019 The Kubernetes Authors.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
namespace: myspace
|
||||||
|
name: storage-deployment
|
||||||
|
annotations:
|
||||||
|
config.kubernetes.io/index: '0'
|
||||||
|
config.kubernetes.io/path: 'deployment.yaml'
|
||||||
|
spec:
|
||||||
|
replicas: 4
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: storage
|
||||||
|
image: storage:1.7.7
|
||||||
|
---`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "grep-top-level-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
args: []string{"kind=Deployment", "-R=false"},
|
||||||
|
packagePath: "mysql",
|
||||||
|
expected: `# Copyright 2019 The Kubernetes Authors.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
namespace: myspace
|
||||||
|
name: mysql-deployment
|
||||||
|
annotations:
|
||||||
|
config.kubernetes.io/index: '0'
|
||||||
|
config.kubernetes.io/path: 'deployment.yaml'
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: mysql
|
||||||
|
image: mysql:1.7.9
|
||||||
|
---`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "grep-nested-pkg-no-recurse-subpackages",
|
||||||
|
dataset: "dataset-without-setters",
|
||||||
|
packagePath: "mysql/storage",
|
||||||
|
args: []string{"kind=Deployment", "-R=false"},
|
||||||
|
expected: `# Copyright 2019 The Kubernetes Authors.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
namespace: myspace
|
||||||
|
name: storage-deployment
|
||||||
|
annotations:
|
||||||
|
config.kubernetes.io/index: '0'
|
||||||
|
config.kubernetes.io/path: 'deployment.yaml'
|
||||||
|
spec:
|
||||||
|
replicas: 4
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: storage
|
||||||
|
image: storage:1.7.7
|
||||||
|
---`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i := range tests {
|
||||||
|
test := tests[i]
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
sourceDir := filepath.Join("test", "testdata", test.dataset)
|
||||||
|
baseDir, err := ioutil.TempDir("", "")
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
copyutil.CopyDir(sourceDir, baseDir)
|
||||||
|
defer os.RemoveAll(baseDir)
|
||||||
|
runner := commands.GetGrepRunner("")
|
||||||
|
actual := &bytes.Buffer{}
|
||||||
|
runner.Command.SetOut(actual)
|
||||||
|
runner.Command.SetArgs(append(test.args, filepath.Join(baseDir, test.packagePath)))
|
||||||
|
err = runner.Command.Execute()
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize path format for windows
|
||||||
|
actualNormalized := strings.Replace(
|
||||||
|
strings.Replace(actual.String(), "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
|
||||||
|
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
|
||||||
|
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
|
||||||
|
if !assert.Equal(t, expectedNormalized, actualNormalized) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,11 +9,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
|
||||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||||
"sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil"
|
"sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil"
|
||||||
"sigs.k8s.io/kustomize/kyaml/runfn"
|
"sigs.k8s.io/kustomize/kyaml/runfn"
|
||||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
|
|
||||||
|
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetCatRunner returns a RunFnRunner.
|
// GetCatRunner returns a RunFnRunner.
|
||||||
@@ -60,11 +62,14 @@ func GetRunFnRunner(name string) *RunFnRunner {
|
|||||||
|
|
||||||
r.Command.Flags().BoolVar(
|
r.Command.Flags().BoolVar(
|
||||||
&r.Network, "network", false, "enable network access for functions that declare it")
|
&r.Network, "network", false, "enable network access for functions that declare it")
|
||||||
r.Command.Flags().StringVar(
|
|
||||||
&r.NetworkName, "network-name", "bridge", "the docker network to run the container in")
|
|
||||||
r.Command.Flags().StringArrayVar(
|
r.Command.Flags().StringArrayVar(
|
||||||
&r.Mounts, "mount", []string{},
|
&r.Mounts, "mount", []string{},
|
||||||
"a list of storage options read from the filesystem")
|
"a list of storage options read from the filesystem")
|
||||||
|
r.Command.Flags().BoolVar(
|
||||||
|
&r.LogSteps, "log-steps", false, "log steps to stderr")
|
||||||
|
r.Command.Flags().StringArrayVarP(
|
||||||
|
&r.Env, "env", "e", []string{},
|
||||||
|
"a list of environment variables to be used by functions")
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,8 +94,9 @@ type RunFnRunner struct {
|
|||||||
RunFns runfn.RunFns
|
RunFns runfn.RunFns
|
||||||
ResultsDir string
|
ResultsDir string
|
||||||
Network bool
|
Network bool
|
||||||
NetworkName string
|
|
||||||
Mounts []string
|
Mounts []string
|
||||||
|
LogSteps bool
|
||||||
|
Env []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RunFnRunner) runE(c *cobra.Command, args []string) error {
|
func (r *RunFnRunner) runE(c *cobra.Command, args []string) error {
|
||||||
@@ -99,7 +105,7 @@ func (r *RunFnRunner) runE(c *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
// getContainerFunctions parses the commandline flags and arguments into explicit
|
// getContainerFunctions parses the commandline flags and arguments into explicit
|
||||||
// Functions to run.
|
// Functions to run.
|
||||||
func (r *RunFnRunner) getContainerFunctions(c *cobra.Command, args, dataItems []string) (
|
func (r *RunFnRunner) getContainerFunctions(c *cobra.Command, dataItems []string) (
|
||||||
[]*yaml.RNode, error) {
|
[]*yaml.RNode, error) {
|
||||||
|
|
||||||
if r.Image == "" && r.StarPath == "" && r.ExecPath == "" && r.StarURL == "" {
|
if r.Image == "" && r.StarPath == "" && r.ExecPath == "" && r.StarURL == "" {
|
||||||
@@ -124,8 +130,8 @@ func (r *RunFnRunner) getContainerFunctions(c *cobra.Command, args, dataItems []
|
|||||||
}
|
}
|
||||||
if r.Network {
|
if r.Network {
|
||||||
err = fn.PipeE(
|
err = fn.PipeE(
|
||||||
yaml.LookupCreate(yaml.MappingNode, "container", "network"),
|
yaml.Lookup("container"),
|
||||||
yaml.SetField("required", yaml.NewScalarRNode("true")))
|
yaml.SetField("network", yaml.NewScalarRNode("true")))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -193,7 +199,7 @@ data: {}
|
|||||||
}
|
}
|
||||||
err = rc.PipeE(
|
err = rc.PipeE(
|
||||||
yaml.LookupCreate(yaml.MappingNode, "metadata", "annotations"),
|
yaml.LookupCreate(yaml.MappingNode, "metadata", "annotations"),
|
||||||
yaml.SetField("config.kubernetes.io/function", yaml.NewScalarRNode(value)))
|
yaml.SetField(runtimeutil.FunctionAnnotationKey, yaml.NewScalarRNode(value)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -267,7 +273,7 @@ func (r *RunFnRunner) preRunE(c *cobra.Command, args []string) error {
|
|||||||
return errors.Errorf("0 or 1 arguments supported, function arguments go after '--'")
|
return errors.Errorf("0 or 1 arguments supported, function arguments go after '--'")
|
||||||
}
|
}
|
||||||
|
|
||||||
fns, err := r.getContainerFunctions(c, args, dataItems)
|
fns, err := r.getContainerFunctions(c, dataItems)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -300,11 +306,12 @@ func (r *RunFnRunner) preRunE(c *cobra.Command, args []string) error {
|
|||||||
Input: input,
|
Input: input,
|
||||||
Path: path,
|
Path: path,
|
||||||
Network: r.Network,
|
Network: r.Network,
|
||||||
NetworkName: r.NetworkName,
|
|
||||||
EnableStarlark: r.EnableStar,
|
EnableStarlark: r.EnableStar,
|
||||||
EnableExec: r.EnableExec,
|
EnableExec: r.EnableExec,
|
||||||
StorageMounts: storageMounts,
|
StorageMounts: storageMounts,
|
||||||
ResultsDir: r.ResultsDir,
|
ResultsDir: r.ResultsDir,
|
||||||
|
LogSteps: r.LogSteps,
|
||||||
|
Env: r.Env,
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't consider args for the function
|
// don't consider args for the function
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/kyaml/runfn"
|
"sigs.k8s.io/kustomize/kyaml/runfn"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -28,7 +29,6 @@ func TestRunFnCommand_preRunE(t *testing.T) {
|
|||||||
output io.Writer
|
output io.Writer
|
||||||
functionPaths []string
|
functionPaths []string
|
||||||
network bool
|
network bool
|
||||||
networkName string
|
|
||||||
mount []string
|
mount []string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@@ -94,34 +94,32 @@ apiVersion: v1
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "network enabled",
|
name: "network enabled",
|
||||||
args: []string{"run", "dir", "--image", "foo:bar", "--network"},
|
args: []string{"run", "dir", "--image", "foo:bar", "--network"},
|
||||||
path: "dir",
|
path: "dir",
|
||||||
network: true,
|
network: true,
|
||||||
networkName: "bridge",
|
|
||||||
expected: `
|
expected: `
|
||||||
metadata:
|
metadata:
|
||||||
name: function-input
|
name: function-input
|
||||||
annotations:
|
annotations:
|
||||||
config.kubernetes.io/function: |
|
config.kubernetes.io/function: |
|
||||||
container: {image: 'foo:bar', network: {required: true}}
|
container: {image: 'foo:bar', network: true}
|
||||||
data: {}
|
data: {}
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "with network name",
|
name: "with network name",
|
||||||
args: []string{"run", "dir", "--image", "foo:bar", "--network", "--network-name", "foo"},
|
args: []string{"run", "dir", "--image", "foo:bar", "--network"},
|
||||||
path: "dir",
|
path: "dir",
|
||||||
network: true,
|
network: true,
|
||||||
networkName: "foo",
|
|
||||||
expected: `
|
expected: `
|
||||||
metadata:
|
metadata:
|
||||||
name: function-input
|
name: function-input
|
||||||
annotations:
|
annotations:
|
||||||
config.kubernetes.io/function: |
|
config.kubernetes.io/function: |
|
||||||
container: {image: 'foo:bar', network: {required: true}}
|
container: {image: 'foo:bar', network: true}
|
||||||
data: {}
|
data: {}
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
@@ -201,8 +199,8 @@ apiVersion: v1
|
|||||||
path: "dir",
|
path: "dir",
|
||||||
expectedStruct: &runfn.RunFns{
|
expectedStruct: &runfn.RunFns{
|
||||||
Path: "dir",
|
Path: "dir",
|
||||||
NetworkName: "bridge",
|
|
||||||
EnableStarlark: true,
|
EnableStarlark: true,
|
||||||
|
Env: []string{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -253,9 +251,9 @@ apiVersion: v1
|
|||||||
args: []string{"run", "dir", "--results-dir", "foo/", "--image", "foo:bar", "--", "a=b", "c=d", "e=f"},
|
args: []string{"run", "dir", "--results-dir", "foo/", "--image", "foo:bar", "--", "a=b", "c=d", "e=f"},
|
||||||
path: "dir",
|
path: "dir",
|
||||||
expectedStruct: &runfn.RunFns{
|
expectedStruct: &runfn.RunFns{
|
||||||
Path: "dir",
|
Path: "dir",
|
||||||
NetworkName: "bridge",
|
ResultsDir: "foo/",
|
||||||
ResultsDir: "foo/",
|
Env: []string{},
|
||||||
},
|
},
|
||||||
expected: `
|
expected: `
|
||||||
metadata:
|
metadata:
|
||||||
@@ -283,6 +281,25 @@ apiVersion: v1
|
|||||||
args: []string{"run", "dir", "--image", "foo:bar", "--", "a=b", "c", "e=f"},
|
args: []string{"run", "dir", "--image", "foo:bar", "--", "a=b", "c", "e=f"},
|
||||||
err: "must have keys and values separated by",
|
err: "must have keys and values separated by",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "log steps",
|
||||||
|
args: []string{"run", "dir", "--log-steps"},
|
||||||
|
path: "dir",
|
||||||
|
expectedStruct: &runfn.RunFns{
|
||||||
|
Path: "dir",
|
||||||
|
LogSteps: true,
|
||||||
|
Env: []string{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "envs",
|
||||||
|
args: []string{"run", "dir", "--env", "FOO=BAR", "-e", "BAR"},
|
||||||
|
path: "dir",
|
||||||
|
expectedStruct: &runfn.RunFns{
|
||||||
|
Path: "dir",
|
||||||
|
Env: []string{"FOO=BAR", "BAR"},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range tests {
|
for i := range tests {
|
||||||
@@ -338,9 +355,6 @@ apiVersion: v1
|
|||||||
if !assert.Equal(t, tt.network, r.RunFns.Network) {
|
if !assert.Equal(t, tt.network, r.RunFns.Network) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
if !assert.Equal(t, tt.networkName, r.RunFns.NetworkName) {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if !assert.Equal(t, false, r.RunFns.Network) {
|
if !assert.Equal(t, false, r.RunFns.Network) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
@@ -385,5 +399,4 @@ apiVersion: v1
|
|||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
6
cmd/config/internal/commands/test/testdata/dataset-without-setters/mysql/Krmfile
vendored
Normal file
6
cmd/config/internal/commands/test/testdata/dataset-without-setters/mysql/Krmfile
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
apiVersion: krm.dev/v1alpha1
|
||||||
|
kind: Krmfile
|
||||||
|
metadata:
|
||||||
|
name: mysql
|
||||||
|
packageMetadata:
|
||||||
|
shortDescription: sample description
|
||||||
15
cmd/config/internal/commands/test/testdata/dataset-without-setters/mysql/deployment.yaml
vendored
Normal file
15
cmd/config/internal/commands/test/testdata/dataset-without-setters/mysql/deployment.yaml
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2019 The Kubernetes Authors.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
namespace: myspace
|
||||||
|
name: mysql-deployment
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: mysql
|
||||||
|
image: mysql:1.7.9
|
||||||
6
cmd/config/internal/commands/test/testdata/dataset-without-setters/mysql/storage/Krmfile
vendored
Normal file
6
cmd/config/internal/commands/test/testdata/dataset-without-setters/mysql/storage/Krmfile
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
apiVersion: krm.dev/v1alpha1
|
||||||
|
kind: Krmfile
|
||||||
|
metadata:
|
||||||
|
name: storage
|
||||||
|
packageMetadata:
|
||||||
|
shortDescription: sample description
|
||||||
15
cmd/config/internal/commands/test/testdata/dataset-without-setters/mysql/storage/deployment.yaml
vendored
Normal file
15
cmd/config/internal/commands/test/testdata/dataset-without-setters/mysql/storage/deployment.yaml
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2019 The Kubernetes Authors.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
namespace: myspace
|
||||||
|
name: storage-deployment
|
||||||
|
spec:
|
||||||
|
replicas: 4
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: storage
|
||||||
|
image: storage:1.7.7
|
||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"sigs.k8s.io/kustomize/cmd/config/ext"
|
||||||
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
||||||
"sigs.k8s.io/kustomize/kyaml/kio/filters"
|
"sigs.k8s.io/kustomize/kyaml/kio/filters"
|
||||||
|
|
||||||
@@ -26,8 +27,6 @@ func GetTreeRunner(name string) *TreeRunner {
|
|||||||
Args: cobra.MaximumNArgs(1),
|
Args: cobra.MaximumNArgs(1),
|
||||||
}
|
}
|
||||||
fixDocs(name, c)
|
fixDocs(name, c)
|
||||||
c.Flags().BoolVar(&r.IncludeSubpackages, "include-subpackages", true,
|
|
||||||
"also print resources from subpackages.")
|
|
||||||
|
|
||||||
// TODO(pwittrock): Figure out if these are the right things to expose, and consider making it
|
// TODO(pwittrock): Figure out if these are the right things to expose, and consider making it
|
||||||
// a list of options instead of individual flags
|
// a list of options instead of individual flags
|
||||||
@@ -59,29 +58,33 @@ func TreeCommand(name string) *cobra.Command {
|
|||||||
|
|
||||||
// TreeRunner contains the run function
|
// TreeRunner contains the run function
|
||||||
type TreeRunner struct {
|
type TreeRunner struct {
|
||||||
IncludeSubpackages bool
|
Command *cobra.Command
|
||||||
Command *cobra.Command
|
name bool
|
||||||
name bool
|
resources bool
|
||||||
resources bool
|
ports bool
|
||||||
ports bool
|
images bool
|
||||||
images bool
|
replicas bool
|
||||||
replicas bool
|
all bool
|
||||||
all bool
|
env bool
|
||||||
env bool
|
args bool
|
||||||
args bool
|
cmd bool
|
||||||
cmd bool
|
fields []string
|
||||||
fields []string
|
includeLocal bool
|
||||||
includeLocal bool
|
excludeNonLocal bool
|
||||||
excludeNonLocal bool
|
structure string
|
||||||
structure string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *TreeRunner) runE(c *cobra.Command, args []string) error {
|
func (r *TreeRunner) runE(c *cobra.Command, args []string) error {
|
||||||
var input kio.Reader
|
var input kio.Reader
|
||||||
var root = "."
|
var root = "."
|
||||||
|
openAPIFileName, err := ext.OpenAPIFileName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
matchFilesGlob := append([]string{openAPIFileName}, kio.DefaultMatch...)
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
root = filepath.Clean(args[0])
|
root = filepath.Clean(args[0])
|
||||||
input = kio.LocalPackageReader{PackagePath: args[0]}
|
input = kio.LocalPackageReader{PackagePath: args[0], MatchFilesGlob: matchFilesGlob}
|
||||||
} else {
|
} else {
|
||||||
input = &kio.ByteReader{Reader: c.InOrStdin()}
|
input = &kio.ByteReader{Reader: c.InOrStdin()}
|
||||||
}
|
}
|
||||||
@@ -156,10 +159,12 @@ func (r *TreeRunner) runE(c *cobra.Command, args []string) error {
|
|||||||
Inputs: []kio.Reader{input},
|
Inputs: []kio.Reader{input},
|
||||||
Filters: fltrs,
|
Filters: fltrs,
|
||||||
Outputs: []kio.Writer{kio.TreeWriter{
|
Outputs: []kio.Writer{kio.TreeWriter{
|
||||||
Root: root,
|
Root: root,
|
||||||
Writer: c.OutOrStdout(),
|
Writer: c.OutOrStdout(),
|
||||||
Fields: fields,
|
Fields: fields,
|
||||||
Structure: kio.TreeStructure(r.structure)}},
|
Structure: kio.TreeStructure(r.structure),
|
||||||
|
OpenAPIFileName: openAPIFileName,
|
||||||
|
}},
|
||||||
}.Execute())
|
}.Execute())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,6 +90,109 @@ spec:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTreeCommand_subpkgs(t *testing.T) {
|
||||||
|
d, err := ioutil.TempDir("", "kustomize-tree-test")
|
||||||
|
defer os.RemoveAll(d)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.MkdirAll(filepath.Join(d, "subpkg"), 0700)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ioutil.WriteFile(filepath.Join(d, "f1.yaml"), []byte(`
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Abstraction
|
||||||
|
metadata:
|
||||||
|
name: foo
|
||||||
|
configFn:
|
||||||
|
container:
|
||||||
|
image: gcr.io/example/reconciler:v1
|
||||||
|
annotations:
|
||||||
|
config.kubernetes.io/local-config: "true"
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
---
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx2
|
||||||
|
name: foo
|
||||||
|
annotations:
|
||||||
|
app: nginx2
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
---
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: foo
|
||||||
|
annotations:
|
||||||
|
app: nginx
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: nginx
|
||||||
|
`), 0600)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = ioutil.WriteFile(filepath.Join(d, "subpkg", "f2.yaml"), []byte(`kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
name: bar
|
||||||
|
annotations:
|
||||||
|
app: nginx
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
`), 0600)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ioutil.WriteFile(filepath.Join(d, "Krmfile"), []byte(`apiVersion: kpt.dev/v1alpha1
|
||||||
|
kind: Krmfile
|
||||||
|
metadata:
|
||||||
|
name: mainpkg
|
||||||
|
openAPI:
|
||||||
|
definitions:
|
||||||
|
`), 0600)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = ioutil.WriteFile(filepath.Join(d, "subpkg", "Krmfile"), []byte(`apiVersion: kpt.dev/v1alpha1
|
||||||
|
kind: Krmfile
|
||||||
|
metadata:
|
||||||
|
name: subpkg
|
||||||
|
openAPI:
|
||||||
|
definitions:
|
||||||
|
`), 0600)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// fmt the files
|
||||||
|
b := &bytes.Buffer{}
|
||||||
|
r := commands.GetTreeRunner("")
|
||||||
|
r.Command.SetArgs([]string{d})
|
||||||
|
r.Command.SetOut(b)
|
||||||
|
if !assert.NoError(t, r.Command.Execute()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !assert.Equal(t, fmt.Sprintf(`%s
|
||||||
|
├── [Krmfile] Krmfile mainpkg
|
||||||
|
├── [f1.yaml] Deployment foo
|
||||||
|
├── [f1.yaml] Service foo
|
||||||
|
└── Pkg: subpkg
|
||||||
|
├── [Krmfile] Krmfile subpkg
|
||||||
|
└── [f2.yaml] Deployment bar
|
||||||
|
`, d), b.String()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestTreeCommand_stdin(t *testing.T) {
|
func TestTreeCommand_stdin(t *testing.T) {
|
||||||
// fmt the files
|
// fmt the files
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
|
|||||||
@@ -5,13 +5,91 @@ package commands
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-errors/errors"
|
"github.com/go-errors/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"sigs.k8s.io/kustomize/cmd/config/ext"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/pathutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// cmdRunner interface holds executeCmd definition which executes respective command's
|
||||||
|
// implementation on single package
|
||||||
|
type cmdRunner interface {
|
||||||
|
executeCmd(w io.Writer, pkgPath string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// executeCmdOnPkgs struct holds the parameters necessary to
|
||||||
|
// execute the filter command on packages in rootPkgPath
|
||||||
|
type executeCmdOnPkgs struct {
|
||||||
|
rootPkgPath string
|
||||||
|
recurseSubPackages bool
|
||||||
|
needOpenAPI bool
|
||||||
|
cmdRunner cmdRunner
|
||||||
|
writer io.Writer
|
||||||
|
skipPkgPathPrint bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// executeCmdOnPkgs takes the function definition for a command to be executed on single package, applies that definition
|
||||||
|
// recursively on all the subpackages present in rootPkgPath if recurseSubPackages is true, else applies the command on rootPkgPath only
|
||||||
|
func (e executeCmdOnPkgs) execute() error {
|
||||||
|
openAPIFileName, err := ext.OpenAPIFileName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pkgsPaths, err := pathutil.DirsWithFile(e.rootPkgPath, openAPIFileName, e.recurseSubPackages)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(pkgsPaths) == 0 {
|
||||||
|
// at this point, there are no openAPI files in the rootPkgPath
|
||||||
|
if e.needOpenAPI {
|
||||||
|
// few executions need openAPI file to be present(ex: setters commands), if true throw an error
|
||||||
|
return errors.Errorf("unable to find %q in package %q", openAPIFileName, e.rootPkgPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add root path for commands which doesn't need openAPI(ex: annotate, fmt)
|
||||||
|
pkgsPaths = []string{e.rootPkgPath}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range pkgsPaths {
|
||||||
|
pkgPath := pkgsPaths[i]
|
||||||
|
// Add schema present in openAPI file for current package
|
||||||
|
if e.needOpenAPI {
|
||||||
|
if err := openapi.AddSchemaFromFile(filepath.Join(pkgPath, openAPIFileName)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !e.skipPkgPathPrint {
|
||||||
|
fmt.Fprintf(e.writer, "%s/\n", pkgPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := e.cmdRunner.executeCmd(e.writer, pkgPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if i != len(pkgsPaths)-1 {
|
||||||
|
fmt.Fprint(e.writer, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete schema present in openAPI file for current package
|
||||||
|
if e.needOpenAPI {
|
||||||
|
if err := openapi.DeleteSchemaInFile(filepath.Join(pkgPath, openAPIFileName)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// parseFieldPath parse a flag value into a field path
|
// parseFieldPath parse a flag value into a field path
|
||||||
func parseFieldPath(path string) ([]string, error) {
|
func parseFieldPath(path string) ([]string, error) {
|
||||||
// fixup '\.' so we don't split on it
|
// fixup '\.' so we don't split on it
|
||||||
|
|||||||
184
cmd/config/internal/commands/util_test.go
Normal file
184
cmd/config/internal/commands/util_test.go
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
// Copyright 2019 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestExecuteCmdOnPkgs(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
recurse bool
|
||||||
|
pkgPath string
|
||||||
|
needOpenAPI bool
|
||||||
|
errMsg string
|
||||||
|
expectedOut string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "need_Krmfile_error",
|
||||||
|
recurse: true,
|
||||||
|
needOpenAPI: true,
|
||||||
|
pkgPath: "subpkg1/subdir1",
|
||||||
|
errMsg: `unable to find "Krmfile" in package`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Krmfile_not_needed_no_err",
|
||||||
|
recurse: true,
|
||||||
|
needOpenAPI: false,
|
||||||
|
pkgPath: "subpkg1/subdir1",
|
||||||
|
expectedOut: `${baseDir}/subpkg1/subdir1/
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "executeCmd_returns_error",
|
||||||
|
recurse: true,
|
||||||
|
needOpenAPI: false,
|
||||||
|
pkgPath: "subpkg4",
|
||||||
|
expectedOut: `${baseDir}/subpkg4/
|
||||||
|
`,
|
||||||
|
errMsg: `this command returns an error if package has error.txt file`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "executeCmd_prints_pkgpaths",
|
||||||
|
recurse: true,
|
||||||
|
needOpenAPI: false,
|
||||||
|
pkgPath: "subpkg2",
|
||||||
|
expectedOut: `${baseDir}/subpkg2/
|
||||||
|
|
||||||
|
${baseDir}/subpkg2/subpkg3/
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
dir, err := ioutil.TempDir("", "")
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
err = createTestDirStructure(dir)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range tests {
|
||||||
|
test := tests[i]
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
actual := &bytes.Buffer{}
|
||||||
|
r := &TestRunner{}
|
||||||
|
e := executeCmdOnPkgs{
|
||||||
|
needOpenAPI: test.needOpenAPI,
|
||||||
|
writer: actual,
|
||||||
|
rootPkgPath: filepath.Join(dir, test.pkgPath),
|
||||||
|
recurseSubPackages: test.recurse,
|
||||||
|
cmdRunner: r,
|
||||||
|
}
|
||||||
|
err := e.execute()
|
||||||
|
if test.errMsg == "" {
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !assert.Error(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
if !assert.Contains(t, err.Error(), test.errMsg) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize path format for windows
|
||||||
|
actualNormalized := strings.Replace(
|
||||||
|
strings.Replace(actual.String(), "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
|
||||||
|
expected := strings.Replace(test.expectedOut, "${baseDir}", dir+"/", -1)
|
||||||
|
expectedNormalized := strings.Replace(
|
||||||
|
strings.Replace(expected, "\\", "/", -1),
|
||||||
|
"//", "/", -1)
|
||||||
|
if !assert.Equal(t, expectedNormalized, actualNormalized) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func createTestDirStructure(dir string) error {
|
||||||
|
/*
|
||||||
|
Adds the folders to the input dir with following structure
|
||||||
|
dir
|
||||||
|
├── subpkg1
|
||||||
|
│ ├── Krmfile
|
||||||
|
│ └── subdir1
|
||||||
|
├── subpkg4
|
||||||
|
│ ├── Krmfile
|
||||||
|
│ └── error.txt
|
||||||
|
└── subpkg2
|
||||||
|
├── subpkg3
|
||||||
|
│ ├── Krmfile
|
||||||
|
│ └── subdir2
|
||||||
|
└── Krmfile
|
||||||
|
*/
|
||||||
|
err := os.MkdirAll(filepath.Join(dir, "subpkg1/subdir1"), 0777|os.ModeDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = os.MkdirAll(filepath.Join(dir, "subpkg2/subpkg3/subdir2"), 0777|os.ModeDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = os.MkdirAll(filepath.Join(dir, "subpkg4"), 0777|os.ModeDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = ioutil.WriteFile(filepath.Join(dir, "subpkg1", "Krmfile"), []byte(""), 0777)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = ioutil.WriteFile(filepath.Join(dir, "subpkg2", "Krmfile"), []byte(""), 0777)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = ioutil.WriteFile(filepath.Join(dir, "subpkg2/subpkg3", "Krmfile"), []byte(""), 0777)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = ioutil.WriteFile(filepath.Join(dir, "subpkg4", "error.txt"), []byte(""), 0777)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = ioutil.WriteFile(filepath.Join(dir, "subpkg4", "Krmfile"), []byte(""), 0777)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = ioutil.WriteFile(filepath.Join(dir, "Krmfile"), []byte(""), 0777)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type TestRunner struct{}
|
||||||
|
|
||||||
|
func (r *TestRunner) executeCmd(w io.Writer, pkgPath string) error {
|
||||||
|
children, err := ioutil.ReadDir(pkgPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, child := range children {
|
||||||
|
if child.Name() == "error.txt" {
|
||||||
|
return errors.Errorf("this command returns an error if package has error.txt file")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# 使用 kustomize 对 helm chart s进行修改
|
# 使用 kustomize 对 helm charts 进行修改
|
||||||
|
|
||||||
[last mile]: https://testingclouds.wordpress.com/2018/07/20/844/
|
[last mile]: https://testingclouds.wordpress.com/2018/07/20/844/
|
||||||
[stable chart]: https://github.com/helm/charts/tree/master/stable
|
[stable chart]: https://github.com/helm/charts/tree/master/stable
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ go 1.14
|
|||||||
require (
|
require (
|
||||||
k8s.io/apimachinery v0.18.3
|
k8s.io/apimachinery v0.18.3
|
||||||
sigs.k8s.io/application v0.8.2
|
sigs.k8s.io/application v0.8.2
|
||||||
sigs.k8s.io/kustomize/kyaml v0.6.1
|
sigs.k8s.io/kustomize/kyaml v0.7.1
|
||||||
sigs.k8s.io/yaml v1.2.0
|
sigs.k8s.io/yaml v1.2.0
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -559,8 +559,8 @@ sigs.k8s.io/application v0.8.2 h1:XB7C33f7eW+1MbCJXoZa0+nP+R+S/VbAvYfCd3ufP1I=
|
|||||||
sigs.k8s.io/application v0.8.2/go.mod h1:Mv+ht9RE/QNtITYCzRbt3XTIN6t6so6cInmiyg6wOIg=
|
sigs.k8s.io/application v0.8.2/go.mod h1:Mv+ht9RE/QNtITYCzRbt3XTIN6t6so6cInmiyg6wOIg=
|
||||||
sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9NPsg=
|
sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9NPsg=
|
||||||
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
|
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.6.1 h1:mwffj5vt3MPdbWV3fZnnwol8SO7sUoGdgejBlvseyak=
|
sigs.k8s.io/kustomize/kyaml v0.7.1 h1:Ih6SJPvfKYfZaIFWUa2YAyg/0ZSTpA3LFjR/hv7+8ao=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.6.1/go.mod h1:bEzbO5pN9OvlEeCLvFHo8Pu7SA26Herc2m60UeWZBdI=
|
sigs.k8s.io/kustomize/kyaml v0.7.1/go.mod h1:ne3F9JPhW2wrVaLslxBsEe6MQJQ9YK5rUutrdhBWXwI=
|
||||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
||||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
|
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
|
||||||
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU=
|
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU=
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ module sigs.k8s.io/kustomize/functions/examples/injection-tshirt-sizes
|
|||||||
|
|
||||||
go 1.14
|
go 1.14
|
||||||
|
|
||||||
require sigs.k8s.io/kustomize/kyaml v0.6.1
|
require sigs.k8s.io/kustomize/kyaml v0.7.1
|
||||||
|
|||||||
@@ -217,6 +217,8 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR
|
|||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
|
||||||
|
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@@ -263,5 +265,5 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo=
|
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.6.1 h1:mwffj5vt3MPdbWV3fZnnwol8SO7sUoGdgejBlvseyak=
|
sigs.k8s.io/kustomize/kyaml v0.7.1 h1:Ih6SJPvfKYfZaIFWUa2YAyg/0ZSTpA3LFjR/hv7+8ao=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.6.1/go.mod h1:bEzbO5pN9OvlEeCLvFHo8Pu7SA26Herc2m60UeWZBdI=
|
sigs.k8s.io/kustomize/kyaml v0.7.1/go.mod h1:ne3F9JPhW2wrVaLslxBsEe6MQJQ9YK5rUutrdhBWXwI=
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ module sigs.k8s.io/kustomize/functions/examples/template-go-nginx
|
|||||||
|
|
||||||
go 1.14
|
go 1.14
|
||||||
|
|
||||||
require sigs.k8s.io/kustomize/kyaml v0.6.1
|
require sigs.k8s.io/kustomize/kyaml v0.7.1
|
||||||
|
|||||||
@@ -218,6 +218,8 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR
|
|||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
|
||||||
|
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@@ -264,5 +266,5 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo=
|
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.6.1 h1:mwffj5vt3MPdbWV3fZnnwol8SO7sUoGdgejBlvseyak=
|
sigs.k8s.io/kustomize/kyaml v0.7.1 h1:Ih6SJPvfKYfZaIFWUa2YAyg/0ZSTpA3LFjR/hv7+8ao=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.6.1/go.mod h1:bEzbO5pN9OvlEeCLvFHo8Pu7SA26Herc2m60UeWZBdI=
|
sigs.k8s.io/kustomize/kyaml v0.7.1/go.mod h1:ne3F9JPhW2wrVaLslxBsEe6MQJQ9YK5rUutrdhBWXwI=
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ go 1.14
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/instrumenta/kubeval v0.0.0-20190918223246-8d013ec9fc56
|
github.com/instrumenta/kubeval v0.0.0-20190918223246-8d013ec9fc56
|
||||||
sigs.k8s.io/kustomize/kyaml v0.6.1
|
sigs.k8s.io/kustomize/kyaml v0.7.1
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -244,6 +244,8 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR
|
|||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
|
||||||
|
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@@ -294,7 +296,7 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo=
|
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.6.1 h1:mwffj5vt3MPdbWV3fZnnwol8SO7sUoGdgejBlvseyak=
|
sigs.k8s.io/kustomize/kyaml v0.7.1 h1:Ih6SJPvfKYfZaIFWUa2YAyg/0ZSTpA3LFjR/hv7+8ao=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.6.1/go.mod h1:bEzbO5pN9OvlEeCLvFHo8Pu7SA26Herc2m60UeWZBdI=
|
sigs.k8s.io/kustomize/kyaml v0.7.1/go.mod h1:ne3F9JPhW2wrVaLslxBsEe6MQJQ9YK5rUutrdhBWXwI=
|
||||||
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
||||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ module sigs.k8s.io/kustomize/functions/examples/validator-resource-requests
|
|||||||
|
|
||||||
go 1.14
|
go 1.14
|
||||||
|
|
||||||
require sigs.k8s.io/kustomize/kyaml v0.6.1
|
require sigs.k8s.io/kustomize/kyaml v0.7.1
|
||||||
|
|||||||
@@ -211,6 +211,8 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR
|
|||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
|
||||||
|
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@@ -257,5 +259,5 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo=
|
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.6.1 h1:mwffj5vt3MPdbWV3fZnnwol8SO7sUoGdgejBlvseyak=
|
sigs.k8s.io/kustomize/kyaml v0.7.1 h1:Ih6SJPvfKYfZaIFWUa2YAyg/0ZSTpA3LFjR/hv7+8ao=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.6.1/go.mod h1:bEzbO5pN9OvlEeCLvFHo8Pu7SA26Herc2m60UeWZBdI=
|
sigs.k8s.io/kustomize/kyaml v0.7.1/go.mod h1:ne3F9JPhW2wrVaLslxBsEe6MQJQ9YK5rUutrdhBWXwI=
|
||||||
|
|||||||
@@ -8,17 +8,11 @@ require (
|
|||||||
github.com/spf13/cobra v1.0.0
|
github.com/spf13/cobra v1.0.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
k8s.io/client-go v0.17.3
|
k8s.io/client-go v0.17.3
|
||||||
sigs.k8s.io/kustomize/api v0.5.1
|
sigs.k8s.io/kustomize/api v0.6.2
|
||||||
sigs.k8s.io/kustomize/cmd/config v0.5.0
|
sigs.k8s.io/kustomize/cmd/config v0.8.1
|
||||||
sigs.k8s.io/yaml v1.2.0
|
sigs.k8s.io/yaml v1.2.0
|
||||||
)
|
)
|
||||||
|
|
||||||
replace (
|
|
||||||
sigs.k8s.io/kustomize/api v0.5.1 => ../api
|
|
||||||
sigs.k8s.io/kustomize/cmd/config v0.5.0 => ../cmd/config
|
|
||||||
sigs.k8s.io/kustomize/kyaml => ../kyaml
|
|
||||||
)
|
|
||||||
|
|
||||||
exclude (
|
exclude (
|
||||||
github.com/russross/blackfriday v2.0.0+incompatible
|
github.com/russross/blackfriday v2.0.0+incompatible
|
||||||
sigs.k8s.io/kustomize/api v0.2.0
|
sigs.k8s.io/kustomize/api v0.2.0
|
||||||
|
|||||||
@@ -358,6 +358,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
|||||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||||
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
|
||||||
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||||
github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
|
github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
@@ -627,6 +629,7 @@ golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtn
|
|||||||
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@@ -742,12 +745,18 @@ modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
|
|||||||
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
|
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
|
||||||
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
|
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
|
||||||
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
|
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
|
||||||
sigs.k8s.io/cli-utils v0.19.0 h1:lAoR5okhSV/dIusodaQp5VbDpHMcKnvjqKYHU+AB3a4=
|
sigs.k8s.io/cli-utils v0.20.2 h1:jNMu4ExtvFXlmKqZMDJqySqK55vGtVRqoLht6eIMffw=
|
||||||
sigs.k8s.io/cli-utils v0.19.0/go.mod h1:B7KdqkSkHNIUn3cFbaR4aKUZMKtr+Benboi1w/HW/Fg=
|
sigs.k8s.io/cli-utils v0.20.2/go.mod h1:uT5cVxMrOoRplL8umtrJx5R51ZWsIKD7lQfPtot80uA=
|
||||||
sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9NPsg=
|
sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9NPsg=
|
||||||
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
|
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
|
||||||
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
|
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
|
||||||
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
|
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
|
||||||
|
sigs.k8s.io/kustomize/api v0.6.2 h1:qZzMiyllvwBv6KQ8V3VsF452INpDW4eWEHOfyeKvkHw=
|
||||||
|
sigs.k8s.io/kustomize/api v0.6.2/go.mod h1:OL467fU5FuolXnIPUqhBLSXUUD00/IBjHs+dBdAS75E=
|
||||||
|
sigs.k8s.io/kustomize/cmd/config v0.8.1 h1:VURvPtiIBfzJ1lp5K0Oj6iHLobhbI6HJR1lECuuUJE8=
|
||||||
|
sigs.k8s.io/kustomize/cmd/config v0.8.1/go.mod h1:6+jNbGFOfz2fTq4NoLJcCp7A9JIgwtzq5wP5j1kCi6o=
|
||||||
|
sigs.k8s.io/kustomize/kyaml v0.8.1 h1:5GRanVGU6+iq3ERTiQD9VIfyGByFVB4z4GthP8NkRYE=
|
||||||
|
sigs.k8s.io/kustomize/kyaml v0.8.1/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
|
||||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
||||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
|
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
|
||||||
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=
|
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=
|
||||||
|
|||||||
@@ -81,6 +81,11 @@ func newCmdAddConfigMap(
|
|||||||
"from-env-file",
|
"from-env-file",
|
||||||
"",
|
"",
|
||||||
"Specify the path to a file to read lines of key=val pairs to create a configmap (i.e. a Docker .env file).")
|
"Specify the path to a file to read lines of key=val pairs to create a configmap (i.e. a Docker .env file).")
|
||||||
|
cmd.Flags().BoolVar(
|
||||||
|
&flags.DisableNameSuffixHash,
|
||||||
|
"disableNameSuffixHash",
|
||||||
|
false,
|
||||||
|
"Disable the name suffix for the configmap")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -126,4 +131,9 @@ func mergeFlagsIntoCmArgs(args *types.ConfigMapArgs, flags flagsAndArgs) {
|
|||||||
args.EnvSources = append(
|
args.EnvSources = append(
|
||||||
args.EnvSources, flags.EnvFileSource)
|
args.EnvSources, flags.EnvFileSource)
|
||||||
}
|
}
|
||||||
|
if flags.DisableNameSuffixHash {
|
||||||
|
args.Options = &types.GeneratorOptions{
|
||||||
|
DisableNameSuffixHash: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ type flagsAndArgs struct {
|
|||||||
Type string
|
Type string
|
||||||
// Namespace of secret
|
// Namespace of secret
|
||||||
Namespace string
|
Namespace string
|
||||||
|
// Disable name suffix
|
||||||
|
DisableNameSuffixHash bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates required fields are set to support structured generation.
|
// Validate validates required fields are set to support structured generation.
|
||||||
|
|||||||
@@ -91,6 +91,11 @@ func newCmdAddSecret(
|
|||||||
"namespace",
|
"namespace",
|
||||||
"",
|
"",
|
||||||
"Specify the namespace of the secret")
|
"Specify the namespace of the secret")
|
||||||
|
cmd.Flags().BoolVar(
|
||||||
|
&flags.DisableNameSuffixHash,
|
||||||
|
"disableNameSuffixHash",
|
||||||
|
false,
|
||||||
|
"Disable the name suffix for the secret")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -139,4 +144,9 @@ func mergeFlagsIntoGeneratorArgs(args *types.GeneratorArgs, flags flagsAndArgs)
|
|||||||
args.EnvSources = append(
|
args.EnvSources = append(
|
||||||
args.EnvSources, flags.EnvFileSource)
|
args.EnvSources, flags.EnvFileSource)
|
||||||
}
|
}
|
||||||
|
if flags.DisableNameSuffixHash {
|
||||||
|
args.Options = &types.GeneratorOptions{
|
||||||
|
DisableNameSuffixHash: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,3 +114,14 @@ func TestMergeFlagsIntoSecretArgs_EnvSource(t *testing.T) {
|
|||||||
t.Fatalf("expected env2")
|
t.Fatalf("expected env2")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMergeFlagsIntoSecretArgs_DisableNameSuffixHash(t *testing.T) {
|
||||||
|
k := &types.Kustomization{}
|
||||||
|
args := findOrMakeSecretArgs(k, "foo", "bar", "forbidden")
|
||||||
|
mergeFlagsIntoGeneratorArgs(
|
||||||
|
&args.GeneratorArgs,
|
||||||
|
flagsAndArgs{DisableNameSuffixHash: true})
|
||||||
|
if k.SecretGenerator[0].Options.DisableNameSuffixHash != true {
|
||||||
|
t.Fatalf("expected true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -39,5 +39,6 @@ func RunFix(fSys filesys.FileSystem) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m.FixKustomizationPreMarshalling()
|
||||||
return mf.Write(m)
|
return mf.Write(m)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
"sigs.k8s.io/kustomize/api/filesys"
|
"sigs.k8s.io/kustomize/api/filesys"
|
||||||
testutils_test "sigs.k8s.io/kustomize/kustomize/v3/internal/commands/testutils"
|
testutils_test "sigs.k8s.io/kustomize/kustomize/v3/internal/commands/testutils"
|
||||||
)
|
)
|
||||||
@@ -31,3 +32,104 @@ func TestFix(t *testing.T) {
|
|||||||
t.Errorf("expected kind in kustomization")
|
t.Errorf("expected kind in kustomization")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFixOutdatedPatchesFieldTitle(t *testing.T) {
|
||||||
|
kustomizationContentWithOutdatedPatchesFieldTitle := []byte(`
|
||||||
|
patchesJson6902:
|
||||||
|
- path: patch1.yaml
|
||||||
|
target:
|
||||||
|
kind: Service
|
||||||
|
- path: patch2.yaml
|
||||||
|
target:
|
||||||
|
group: apps
|
||||||
|
kind: Deployment
|
||||||
|
version: v1
|
||||||
|
`)
|
||||||
|
|
||||||
|
expected := []byte(`
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
patches:
|
||||||
|
- path: patch1.yaml
|
||||||
|
target:
|
||||||
|
kind: Service
|
||||||
|
- path: patch2.yaml
|
||||||
|
target:
|
||||||
|
group: apps
|
||||||
|
kind: Deployment
|
||||||
|
version: v1
|
||||||
|
`)
|
||||||
|
fSys := filesys.MakeFsInMemory()
|
||||||
|
testutils_test.WriteTestKustomizationWith(fSys, kustomizationContentWithOutdatedPatchesFieldTitle)
|
||||||
|
cmd := NewCmdFix(fSys)
|
||||||
|
err := cmd.RunE(cmd, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected cmd error: %v", err)
|
||||||
|
}
|
||||||
|
content, err := testutils_test.ReadTestKustomization(fSys)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected read error: %v", err)
|
||||||
|
}
|
||||||
|
if !strings.Contains(string(content), "apiVersion: ") {
|
||||||
|
t.Errorf("expected apiVersion in kustomization")
|
||||||
|
}
|
||||||
|
if !strings.Contains(string(content), "kind: Kustomization") {
|
||||||
|
t.Errorf("expected kind in kustomization")
|
||||||
|
}
|
||||||
|
|
||||||
|
if diff := cmp.Diff(expected, content); diff != "" {
|
||||||
|
t.Errorf("Mismatch (-expected, +actual):\n%s", diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRenameAndKeepOutdatedPatchesField(t *testing.T) {
|
||||||
|
kustomizationContentWithOutdatedPatchesFieldTitle := []byte(`
|
||||||
|
patchesJson6902:
|
||||||
|
- path: patch1.yaml
|
||||||
|
target:
|
||||||
|
kind: Deployment
|
||||||
|
patches:
|
||||||
|
- path: patch2.yaml
|
||||||
|
target:
|
||||||
|
kind: Deployment
|
||||||
|
- path: patch3.yaml
|
||||||
|
target:
|
||||||
|
kind: Service
|
||||||
|
`)
|
||||||
|
|
||||||
|
expected := []byte(`
|
||||||
|
patches:
|
||||||
|
- path: patch2.yaml
|
||||||
|
target:
|
||||||
|
kind: Deployment
|
||||||
|
- path: patch3.yaml
|
||||||
|
target:
|
||||||
|
kind: Service
|
||||||
|
- path: patch1.yaml
|
||||||
|
target:
|
||||||
|
kind: Deployment
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
`)
|
||||||
|
fSys := filesys.MakeFsInMemory()
|
||||||
|
testutils_test.WriteTestKustomizationWith(fSys, kustomizationContentWithOutdatedPatchesFieldTitle)
|
||||||
|
cmd := NewCmdFix(fSys)
|
||||||
|
err := cmd.RunE(cmd, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected cmd error: %v", err)
|
||||||
|
}
|
||||||
|
content, err := testutils_test.ReadTestKustomization(fSys)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected read error: %v", err)
|
||||||
|
}
|
||||||
|
if !strings.Contains(string(content), "apiVersion: ") {
|
||||||
|
t.Errorf("expected apiVersion in kustomization")
|
||||||
|
}
|
||||||
|
if !strings.Contains(string(content), "kind: Kustomization") {
|
||||||
|
t.Errorf("expected kind in kustomization")
|
||||||
|
}
|
||||||
|
|
||||||
|
if diff := cmp.Diff(expected, content); diff != "" {
|
||||||
|
t.Errorf("Mismatch (-expected, +actual):\n%s", diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -145,6 +145,47 @@ func TestSetImage(t *testing.T) {
|
|||||||
" newTag: my-tag2",
|
" newTag: my-tag2",
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
description: "override file with patch",
|
||||||
|
given: given{
|
||||||
|
args: []string{"image1=foo.bar.foo:8800/foo/image1:foo-bar"},
|
||||||
|
infileImages: []string{
|
||||||
|
"images:",
|
||||||
|
"- name: image1",
|
||||||
|
" newName: my-image1",
|
||||||
|
" newTag: my-tag",
|
||||||
|
"- name: image2",
|
||||||
|
" newName: my-image2",
|
||||||
|
" newTag: my-tag2",
|
||||||
|
"patchesJson6902:",
|
||||||
|
"- patch: |-",
|
||||||
|
" - op: remove",
|
||||||
|
" path: /spec/selector",
|
||||||
|
" target:",
|
||||||
|
" kind: Service",
|
||||||
|
" name: foo",
|
||||||
|
" version: v1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: expected{
|
||||||
|
fileOutput: []string{
|
||||||
|
"images:",
|
||||||
|
"- name: image1",
|
||||||
|
" newName: foo.bar.foo:8800/foo/image1",
|
||||||
|
" newTag: foo-bar",
|
||||||
|
"- name: image2",
|
||||||
|
" newName: my-image2",
|
||||||
|
" newTag: my-tag2",
|
||||||
|
"patchesJson6902:",
|
||||||
|
"- patch: |-",
|
||||||
|
" - op: remove",
|
||||||
|
" path: /spec/selector",
|
||||||
|
" target:",
|
||||||
|
" kind: Service",
|
||||||
|
" name: foo",
|
||||||
|
" version: v1",
|
||||||
|
}},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
description: "override new tag and new name with just a new tag",
|
description: "override new tag and new name with just a new tag",
|
||||||
given: given{
|
given: given{
|
||||||
|
|||||||
@@ -170,7 +170,6 @@ func (mf *kustomizationFile) Write(kustomization *types.Kustomization) error {
|
|||||||
if kustomization == nil {
|
if kustomization == nil {
|
||||||
return errors.New("util: kustomization file arg is nil")
|
return errors.New("util: kustomization file arg is nil")
|
||||||
}
|
}
|
||||||
kustomization.FixKustomizationPreMarshalling()
|
|
||||||
data, err := mf.marshal(kustomization)
|
data, err := mf.marshal(kustomization)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -338,103 +338,6 @@ kind: Kustomization
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRenameAndKeepOutdatedPatchesField(t *testing.T) {
|
|
||||||
kustomizationContentWithOutdatedPatchesFieldTitle := []byte(`
|
|
||||||
patchesJson6902:
|
|
||||||
- path: patch1.yaml
|
|
||||||
target:
|
|
||||||
kind: Deployment
|
|
||||||
patches:
|
|
||||||
- path: patch2.yaml
|
|
||||||
target:
|
|
||||||
kind: Deployment
|
|
||||||
- path: patch3.yaml
|
|
||||||
target:
|
|
||||||
kind: Service
|
|
||||||
`)
|
|
||||||
|
|
||||||
expected := []byte(`
|
|
||||||
patches:
|
|
||||||
- path: patch2.yaml
|
|
||||||
target:
|
|
||||||
kind: Deployment
|
|
||||||
- path: patch3.yaml
|
|
||||||
target:
|
|
||||||
kind: Service
|
|
||||||
- path: patch1.yaml
|
|
||||||
target:
|
|
||||||
kind: Deployment
|
|
||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
||||||
kind: Kustomization
|
|
||||||
`)
|
|
||||||
fSys := filesys.MakeFsInMemory()
|
|
||||||
testutils_test.WriteTestKustomizationWith(fSys, kustomizationContentWithOutdatedPatchesFieldTitle)
|
|
||||||
mf, err := NewKustomizationFile(fSys)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unexpected Error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
kustomization, err := mf.Read()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unexpected Error: %v", err)
|
|
||||||
}
|
|
||||||
if err = mf.Write(kustomization); err != nil {
|
|
||||||
t.Fatalf("Unexpected Error: %v", err)
|
|
||||||
}
|
|
||||||
bytes, _ := fSys.ReadFile(mf.path)
|
|
||||||
|
|
||||||
if diff := cmp.Diff(expected, bytes); diff != "" {
|
|
||||||
t.Errorf("Mismatch (-expected, +actual):\n%s", diff)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFixOutdatedPatchesFieldTitle(t *testing.T) {
|
|
||||||
kustomizationContentWithOutdatedPatchesFieldTitle := []byte(`
|
|
||||||
patchesJson6902:
|
|
||||||
- path: patch1.yaml
|
|
||||||
target:
|
|
||||||
kind: Service
|
|
||||||
- path: patch2.yaml
|
|
||||||
target:
|
|
||||||
group: apps
|
|
||||||
kind: Deployment
|
|
||||||
version: v1
|
|
||||||
`)
|
|
||||||
|
|
||||||
expected := []byte(`
|
|
||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
||||||
kind: Kustomization
|
|
||||||
patches:
|
|
||||||
- path: patch1.yaml
|
|
||||||
target:
|
|
||||||
kind: Service
|
|
||||||
- path: patch2.yaml
|
|
||||||
target:
|
|
||||||
group: apps
|
|
||||||
kind: Deployment
|
|
||||||
version: v1
|
|
||||||
`)
|
|
||||||
fSys := filesys.MakeFsInMemory()
|
|
||||||
testutils_test.WriteTestKustomizationWith(fSys, kustomizationContentWithOutdatedPatchesFieldTitle)
|
|
||||||
mf, err := NewKustomizationFile(fSys)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unexpected Error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
kustomization, err := mf.Read()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unexpected Error: %v", err)
|
|
||||||
}
|
|
||||||
if err = mf.Write(kustomization); err != nil {
|
|
||||||
t.Fatalf("Unexpected Error: %v", err)
|
|
||||||
}
|
|
||||||
bytes, _ := fSys.ReadFile(mf.path)
|
|
||||||
|
|
||||||
if diff := cmp.Diff(expected, bytes); diff != "" {
|
|
||||||
t.Errorf("Mismatch (-expected, +actual):\n%s", diff)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnknownFieldInKustomization(t *testing.T) {
|
func TestUnknownFieldInKustomization(t *testing.T) {
|
||||||
kContent := []byte(`
|
kContent := []byte(`
|
||||||
foo:
|
foo:
|
||||||
|
|||||||
10
kyaml/ext/ext.go
Normal file
10
kyaml/ext/ext.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
// Copyright 2019 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package ext
|
||||||
|
|
||||||
|
// GetIgnoreFileName returns the name for ignore files in
|
||||||
|
// packages. It can be overridden by tools using this library.
|
||||||
|
var GetIgnoreFileName = func() string {
|
||||||
|
return ".krmignore"
|
||||||
|
}
|
||||||
@@ -154,13 +154,17 @@ func (c *Filter) setupExec() {
|
|||||||
|
|
||||||
// getArgs returns the command + args to run to spawn the container
|
// getArgs returns the command + args to run to spawn the container
|
||||||
func (c *Filter) getCommand() (string, []string) {
|
func (c *Filter) getCommand() (string, []string) {
|
||||||
|
network := runtimeutil.NetworkNameNone
|
||||||
|
if c.ContainerSpec.Network {
|
||||||
|
network = runtimeutil.NetworkNameHost
|
||||||
|
}
|
||||||
// run the container using docker. this is simpler than using the docker
|
// run the container using docker. this is simpler than using the docker
|
||||||
// libraries, and ensures things like auth work the same as if the container
|
// libraries, and ensures things like auth work the same as if the container
|
||||||
// was run from the cli.
|
// was run from the cli.
|
||||||
args := []string{"run",
|
args := []string{"run",
|
||||||
"--rm", // delete the container afterward
|
"--rm", // delete the container afterward
|
||||||
"-i", "-a", "STDIN", "-a", "STDOUT", "-a", "STDERR", // attach stdin, stdout, stderr
|
"-i", "-a", "STDIN", "-a", "STDOUT", "-a", "STDERR", // attach stdin, stdout, stderr
|
||||||
"--network", string(c.ContainerSpec.Network.Name),
|
"--network", string(network),
|
||||||
|
|
||||||
// added security options
|
// added security options
|
||||||
"--user", c.User.String(),
|
"--user", c.User.String(),
|
||||||
@@ -186,10 +190,5 @@ func NewContainer(spec runtimeutil.ContainerSpec) Filter {
|
|||||||
f.ContainerSpec.User = runtimeutil.UserNobody
|
f.ContainerSpec.User = runtimeutil.UserNobody
|
||||||
}
|
}
|
||||||
|
|
||||||
// default network name is none
|
|
||||||
if f.ContainerSpec.Network.Name == "" {
|
|
||||||
f.ContainerSpec.Network.Name = runtimeutil.NetworkNameNone
|
|
||||||
}
|
|
||||||
|
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,17 +55,15 @@ metadata:
|
|||||||
"run",
|
"run",
|
||||||
"--rm",
|
"--rm",
|
||||||
"-i", "-a", "STDIN", "-a", "STDOUT", "-a", "STDERR",
|
"-i", "-a", "STDIN", "-a", "STDOUT", "-a", "STDERR",
|
||||||
"--network", "test-1",
|
"--network", "host",
|
||||||
"--user", "nobody",
|
"--user", "nobody",
|
||||||
"--security-opt=no-new-privileges",
|
"--security-opt=no-new-privileges",
|
||||||
},
|
},
|
||||||
instance: NewContainer(
|
instance: NewContainer(
|
||||||
runtimeutil.ContainerSpec{
|
runtimeutil.ContainerSpec{
|
||||||
Image: "example.com:version",
|
Image: "example.com:version",
|
||||||
Network: runtimeutil.ContainerNetwork{
|
Network: true,
|
||||||
Name: "test-1",
|
User: "nobody",
|
||||||
},
|
|
||||||
User: "nobody",
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ const (
|
|||||||
type ContainerNetworkName string
|
type ContainerNetworkName string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
NetworkNameNone ContainerNetworkName = "none"
|
NetworkNameNone ContainerNetworkName = "none"
|
||||||
NetworkNameEmpty ContainerNetworkName = ""
|
NetworkNameHost ContainerNetworkName = "host"
|
||||||
)
|
)
|
||||||
const defaultEnvValue string = "true"
|
const defaultEnvValue string = "true"
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ type ContainerSpec struct {
|
|||||||
Image string `json:"image,omitempty" yaml:"image,omitempty"`
|
Image string `json:"image,omitempty" yaml:"image,omitempty"`
|
||||||
|
|
||||||
// Network defines network specific configuration
|
// Network defines network specific configuration
|
||||||
Network ContainerNetwork `json:"network,omitempty" yaml:"network,omitempty"`
|
Network bool `json:"network,omitempty" yaml:"network,omitempty"`
|
||||||
|
|
||||||
// Mounts are the storage or directories to mount into the container
|
// Mounts are the storage or directories to mount into the container
|
||||||
StorageMounts []StorageMount `json:"mounts,omitempty" yaml:"mounts,omitempty"`
|
StorageMounts []StorageMount `json:"mounts,omitempty" yaml:"mounts,omitempty"`
|
||||||
@@ -178,15 +178,6 @@ type ContainerSpec struct {
|
|||||||
Env []string `json:"envs,omitempty" yaml:"envs,omitempty"`
|
Env []string `json:"envs,omitempty" yaml:"envs,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerNetwork
|
|
||||||
type ContainerNetwork struct {
|
|
||||||
// Required specifies that function requires a network
|
|
||||||
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
|
|
||||||
|
|
||||||
// Name is the name of the network to use from a container
|
|
||||||
Name ContainerNetworkName `json:"name,omitempty" yaml:"name,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// StarlarkSpec defines how to run a function as a starlark program
|
// StarlarkSpec defines how to run a function as a starlark program
|
||||||
type StarlarkSpec struct {
|
type StarlarkSpec struct {
|
||||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||||
@@ -237,7 +228,6 @@ func GetFunctionSpec(n *yaml.RNode) *FunctionSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if fn := getFunctionSpecFromAnnotation(n, meta); fn != nil {
|
if fn := getFunctionSpecFromAnnotation(n, meta); fn != nil {
|
||||||
fn.Container.Network.Name = NetworkNameEmpty
|
|
||||||
fn.StorageMounts = []StorageMount{}
|
fn.StorageMounts = []StorageMount{}
|
||||||
return fn
|
return fn
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1208,14 +1208,12 @@ metadata:
|
|||||||
config.kubernetes.io/function: |-
|
config.kubernetes.io/function: |-
|
||||||
container:
|
container:
|
||||||
image: foo:v1.0.0
|
image: foo:v1.0.0
|
||||||
network:
|
network: true
|
||||||
required: true
|
|
||||||
`,
|
`,
|
||||||
expectedFn: `
|
expectedFn: `
|
||||||
container:
|
container:
|
||||||
image: foo:v1.0.0
|
image: foo:v1.0.0
|
||||||
network:
|
network: true
|
||||||
required: true
|
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1324,8 +1322,7 @@ metadata:
|
|||||||
configFn:
|
configFn:
|
||||||
container:
|
container:
|
||||||
image: gcr.io/kustomize-functions/example-tshirt:v0.1.0
|
image: gcr.io/kustomize-functions/example-tshirt:v0.1.0
|
||||||
network:
|
network: true
|
||||||
required: true
|
|
||||||
`,
|
`,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
@@ -1337,8 +1334,7 @@ metadata:
|
|||||||
configFn:
|
configFn:
|
||||||
container:
|
container:
|
||||||
image: gcr.io/kustomize-functions/example-tshirt:v0.1.0
|
image: gcr.io/kustomize-functions/example-tshirt:v0.1.0
|
||||||
network:
|
network: false
|
||||||
required: false
|
|
||||||
`,
|
`,
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
@@ -1363,8 +1359,7 @@ metadata:
|
|||||||
config.kubernetes.io/function: |
|
config.kubernetes.io/function: |
|
||||||
container:
|
container:
|
||||||
image: gcr.io/kustomize-functions/example-tshirt:v0.1.0
|
image: gcr.io/kustomize-functions/example-tshirt:v0.1.0
|
||||||
network:
|
network: true
|
||||||
required: true
|
|
||||||
`,
|
`,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
@@ -1376,7 +1371,7 @@ metadata:
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
fn := GetFunctionSpec(cfg)
|
fn := GetFunctionSpec(cfg)
|
||||||
assert.Equal(t, tc.required, fn.Container.Network.Required)
|
assert.Equal(t, tc.required, fn.Container.Network)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ require (
|
|||||||
github.com/go-openapi/spec v0.19.5
|
github.com/go-openapi/spec v0.19.5
|
||||||
github.com/go-openapi/strfmt v0.19.5
|
github.com/go-openapi/strfmt v0.19.5
|
||||||
github.com/go-openapi/validate v0.19.8
|
github.com/go-openapi/validate v0.19.8
|
||||||
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00
|
||||||
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d
|
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d
|
||||||
github.com/sergi/go-diff v1.1.0
|
github.com/sergi/go-diff v1.1.0
|
||||||
github.com/spf13/cobra v1.0.0
|
github.com/spf13/cobra v1.0.0
|
||||||
|
|||||||
@@ -145,6 +145,8 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
|
|||||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||||
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
|
||||||
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/paulmach/orb v0.1.3/go.mod h1:VFlX/8C+IQ1p6FTRRKzKoOPJnvEtA5G0Veuqwbu//Vk=
|
github.com/paulmach/orb v0.1.3/go.mod h1:VFlX/8C+IQ1p6FTRRKzKoOPJnvEtA5G0Veuqwbu//Vk=
|
||||||
|
|||||||
100
kyaml/kio/ignorefilesmatcher.go
Normal file
100
kyaml/kio/ignorefilesmatcher.go
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
// Copyright 2019 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package kio
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/monochromegane/go-gitignore"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/ext"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ignoreFilesMatcher handles `.krmignore` files, which allows for ignoring
|
||||||
|
// files or folders in a package. The format of this file is a subset of the
|
||||||
|
// gitignore format, with recursive patterns (like a/**/c) not supported. If a
|
||||||
|
// file or folder matches any of the patterns in the .krmignore file for the
|
||||||
|
// package, it will be excluded.
|
||||||
|
//
|
||||||
|
// It works as follows:
|
||||||
|
//
|
||||||
|
// * It will look for .krmignore file in the top folder and on the top level
|
||||||
|
// of any subpackages. Subpackages are defined by the presence of a Krmfile
|
||||||
|
// in the folder.
|
||||||
|
// * `.krmignore` files only cover files and folders for the package in which
|
||||||
|
// it is defined. So ignore patterns defined in a parent package does not
|
||||||
|
// affect which files are ignored from a subpackage.
|
||||||
|
// * An ignore pattern can not ignore a subpackage. So even if the parent
|
||||||
|
// package contains a pattern that ignores the directory foo, if foo is a
|
||||||
|
// subpackage, it will still be included if the IncludeSubpackages property
|
||||||
|
// is set to true
|
||||||
|
type ignoreFilesMatcher struct {
|
||||||
|
matchers []matcher
|
||||||
|
}
|
||||||
|
|
||||||
|
// readIgnoreFile checks whether there is a .krmignore file in the path, and
|
||||||
|
// if it is, reads it in and turns it into a matcher. If we can't find a file,
|
||||||
|
// we just add a matcher that match nothing.
|
||||||
|
func (i *ignoreFilesMatcher) readIgnoreFile(path string) error {
|
||||||
|
i.verifyPath(path)
|
||||||
|
m, err := gitignore.NewGitIgnore(filepath.Join(path, ext.GetIgnoreFileName()))
|
||||||
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
i.matchers = append(i.matchers, matcher{
|
||||||
|
matcher: gitignore.DummyIgnoreMatcher(false),
|
||||||
|
basePath: path,
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
i.matchers = append(i.matchers, matcher{
|
||||||
|
matcher: m,
|
||||||
|
basePath: path,
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// verifyPath checks whether the top matcher on the stack
|
||||||
|
// is correct for the provided filepath. Matchers are removed once
|
||||||
|
// we encounter a filepath that is not a subpath of the basepath for
|
||||||
|
// the matcher.
|
||||||
|
func (i *ignoreFilesMatcher) verifyPath(path string) {
|
||||||
|
for j := len(i.matchers) - 1; j >= 0; j-- {
|
||||||
|
matcher := i.matchers[j]
|
||||||
|
if strings.HasPrefix(path, matcher.basePath) || path == matcher.basePath {
|
||||||
|
i.matchers = i.matchers[:j+1]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// matchFile checks whether the file given by the provided path matches
|
||||||
|
// any of the patterns in the .krmignore file for the package.
|
||||||
|
func (i *ignoreFilesMatcher) matchFile(path string) bool {
|
||||||
|
if len(i.matchers) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
i.verifyPath(filepath.Dir(path))
|
||||||
|
return i.matchers[len(i.matchers)-1].matcher.Match(path, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// matchFile checks whether the directory given by the provided path matches
|
||||||
|
// any of the patterns in the .krmignore file for the package.
|
||||||
|
func (i *ignoreFilesMatcher) matchDir(path string) bool {
|
||||||
|
if len(i.matchers) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
i.verifyPath(path)
|
||||||
|
return i.matchers[len(i.matchers)-1].matcher.Match(path, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// matcher wraps the gitignore matcher and the path to the folder
|
||||||
|
// where the file was found.
|
||||||
|
type matcher struct {
|
||||||
|
matcher gitignore.IgnoreMatcher
|
||||||
|
|
||||||
|
basePath string
|
||||||
|
}
|
||||||
249
kyaml/kio/ignorefilesmatcher_test.go
Normal file
249
kyaml/kio/ignorefilesmatcher_test.go
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
// Copyright 2019 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package kio
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIgnoreFilesMatcher_readIgnoreFile(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
writeIgnoreFile bool
|
||||||
|
isMatch bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "has .krmignore file",
|
||||||
|
writeIgnoreFile: true,
|
||||||
|
isMatch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no .krmignore file",
|
||||||
|
writeIgnoreFile: false,
|
||||||
|
isMatch: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range testCases {
|
||||||
|
test := testCases[i]
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
dir, err := ioutil.TempDir("", "kyaml-test")
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
assert.FailNow(t, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if test.writeIgnoreFile {
|
||||||
|
ignoreFilePath := filepath.Join(dir, ".krmignore")
|
||||||
|
err = ioutil.WriteFile(ignoreFilePath, []byte(`
|
||||||
|
testfile.yaml
|
||||||
|
`), 0600)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
assert.FailNow(t, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
testFilePath := filepath.Join(dir, "testfile.yaml")
|
||||||
|
err = ioutil.WriteFile(testFilePath, []byte{}, 0600)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
assert.FailNow(t, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
ignoreFilesMatcher := ignoreFilesMatcher{}
|
||||||
|
err = ignoreFilesMatcher.readIgnoreFile(dir)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
assert.Equal(t, test.isMatch, ignoreFilesMatcher.matchFile(testFilePath))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
readFileA = []byte(`
|
||||||
|
a: a
|
||||||
|
---
|
||||||
|
c: c
|
||||||
|
`)
|
||||||
|
readFileB = []byte(`
|
||||||
|
b: b
|
||||||
|
`)
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLocalPackageReader_Read_ignoreFile(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
directories []string
|
||||||
|
files map[string][]byte
|
||||||
|
expected []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "ignore file",
|
||||||
|
directories: []string{
|
||||||
|
filepath.Join("a", "b"),
|
||||||
|
filepath.Join("a", "c"),
|
||||||
|
},
|
||||||
|
files: map[string][]byte{
|
||||||
|
filepath.Join("pkgFile"): {},
|
||||||
|
filepath.Join("a", "b", "a_test.yaml"): readFileA,
|
||||||
|
filepath.Join("a", "c", "c_test.yaml"): readFileB,
|
||||||
|
filepath.Join(".krmignore"): []byte(`
|
||||||
|
a/c/c_test.yaml
|
||||||
|
`,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
`a: a`,
|
||||||
|
`c: c`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ignore folder",
|
||||||
|
directories: []string{
|
||||||
|
filepath.Join("a", "b"),
|
||||||
|
filepath.Join("a", "c"),
|
||||||
|
},
|
||||||
|
files: map[string][]byte{
|
||||||
|
filepath.Join("pkgFile"): {},
|
||||||
|
filepath.Join("a", "b", "a_test.yaml"): readFileA,
|
||||||
|
filepath.Join("a", "c", "c_test.yaml"): readFileB,
|
||||||
|
filepath.Join(".krmignore"): []byte(`
|
||||||
|
a/c
|
||||||
|
`,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
`a: a`,
|
||||||
|
`c: c`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "krmignore file in subpackage",
|
||||||
|
directories: []string{
|
||||||
|
filepath.Join("a", "c"),
|
||||||
|
},
|
||||||
|
files: map[string][]byte{
|
||||||
|
filepath.Join("pkgFile"): {},
|
||||||
|
filepath.Join("a", "c", "a_test.yaml"): readFileA,
|
||||||
|
filepath.Join("a", "c", "c_test.yaml"): readFileB,
|
||||||
|
filepath.Join(".krmignore"): []byte(`
|
||||||
|
d/e/f.yaml
|
||||||
|
`,
|
||||||
|
),
|
||||||
|
filepath.Join("a", "c", "pkgFile"): {},
|
||||||
|
filepath.Join("a", "c", ".krmignore"): []byte(`
|
||||||
|
a_test.yaml
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
`b: b`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "krmignore files does not affect subpackages",
|
||||||
|
directories: []string{
|
||||||
|
filepath.Join("a", "c"),
|
||||||
|
},
|
||||||
|
files: map[string][]byte{
|
||||||
|
filepath.Join("pkgFile"): {},
|
||||||
|
filepath.Join("a", "c", "a_test.yaml"): readFileA,
|
||||||
|
filepath.Join("a", "c", "c_test.yaml"): readFileB,
|
||||||
|
filepath.Join(".krmignore"): []byte(`
|
||||||
|
a/c/c_test.yaml
|
||||||
|
`,
|
||||||
|
),
|
||||||
|
filepath.Join("a", "c", "pkgFile"): {},
|
||||||
|
filepath.Join("a", "c", ".krmignore"): []byte(`
|
||||||
|
a_test.yaml
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
`b: b`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "handles a combination of packages and directories",
|
||||||
|
directories: []string{
|
||||||
|
filepath.Join("a"),
|
||||||
|
filepath.Join("d", "e"),
|
||||||
|
filepath.Join("f"),
|
||||||
|
},
|
||||||
|
files: map[string][]byte{
|
||||||
|
filepath.Join("pkgFile"): {},
|
||||||
|
filepath.Join("d", "pkgFile"): {},
|
||||||
|
filepath.Join("d", "e", "pkgFile"): {},
|
||||||
|
filepath.Join("f", "pkgFile"): {},
|
||||||
|
filepath.Join("manifest.yaml"): []byte(`root: root`),
|
||||||
|
filepath.Join("a", "manifest.yaml"): []byte(`a: a`),
|
||||||
|
filepath.Join("d", "manifest.yaml"): []byte(`d: d`),
|
||||||
|
filepath.Join("d", "e", "manifest.yaml"): []byte(`e: e`),
|
||||||
|
filepath.Join("f", "manifest.yaml"): []byte(`f: f`),
|
||||||
|
filepath.Join("d", ".krmignore"): []byte(`
|
||||||
|
manifest.yaml
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
`a: a`,
|
||||||
|
`e: e`,
|
||||||
|
`f: f`,
|
||||||
|
`root: root`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ignore file can exclude subpackages",
|
||||||
|
directories: []string{
|
||||||
|
filepath.Join("a"),
|
||||||
|
},
|
||||||
|
files: map[string][]byte{
|
||||||
|
filepath.Join("pkgFile"): {},
|
||||||
|
filepath.Join("a", "pkgFile"): {},
|
||||||
|
filepath.Join("manifest.yaml"): []byte(`root: root`),
|
||||||
|
filepath.Join("a", "manifest.yaml"): []byte(`a: a`),
|
||||||
|
filepath.Join(".krmignore"): []byte(`
|
||||||
|
a
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
`root: root`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range testCases {
|
||||||
|
test := testCases[i]
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
s := SetupDirectories(t, test.directories...)
|
||||||
|
defer s.Clean()
|
||||||
|
for path, content := range test.files {
|
||||||
|
s.WriteFile(t, path, content)
|
||||||
|
}
|
||||||
|
|
||||||
|
// empty path
|
||||||
|
rfr := LocalPackageReader{
|
||||||
|
PackagePath: s.Root,
|
||||||
|
IncludeSubpackages: true,
|
||||||
|
PackageFileName: "pkgFile",
|
||||||
|
OmitReaderAnnotations: true,
|
||||||
|
}
|
||||||
|
nodes, err := rfr.Read()
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
assert.FailNow(t, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if !assert.Len(t, nodes, len(test.expected)) {
|
||||||
|
assert.FailNow(t, "wrong number items")
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, node := range nodes {
|
||||||
|
val, err := node.String()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
want := strings.ReplaceAll(test.expected[i], "${SEP}", string(filepath.Separator))
|
||||||
|
assert.Equal(t, strings.TrimSpace(want), strings.TrimSpace(val))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -80,6 +80,7 @@ func (r *LocalPackageReadWriter) Read() ([]*yaml.RNode, error) {
|
|||||||
IncludeSubpackages: r.IncludeSubpackages,
|
IncludeSubpackages: r.IncludeSubpackages,
|
||||||
ErrorIfNonResources: r.ErrorIfNonResources,
|
ErrorIfNonResources: r.ErrorIfNonResources,
|
||||||
SetAnnotations: r.SetAnnotations,
|
SetAnnotations: r.SetAnnotations,
|
||||||
|
PackageFileName: r.PackageFileName,
|
||||||
}.Read()
|
}.Read()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err)
|
return nil, errors.Wrap(err)
|
||||||
@@ -184,8 +185,13 @@ func (r LocalPackageReader) Read() ([]*yaml.RNode, error) {
|
|||||||
|
|
||||||
var operand ResourceNodeSlice
|
var operand ResourceNodeSlice
|
||||||
var pathRelativeTo string
|
var pathRelativeTo string
|
||||||
r.PackagePath = filepath.Clean(r.PackagePath)
|
var err error
|
||||||
err := filepath.Walk(r.PackagePath, func(
|
ignoreFilesMatcher := &ignoreFilesMatcher{}
|
||||||
|
r.PackagePath, err = filepath.Abs(r.PackagePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err)
|
||||||
|
}
|
||||||
|
err = filepath.Walk(r.PackagePath, func(
|
||||||
path string, info os.FileInfo, err error) error {
|
path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err)
|
return errors.Wrap(err)
|
||||||
@@ -194,9 +200,10 @@ func (r LocalPackageReader) Read() ([]*yaml.RNode, error) {
|
|||||||
// is this the user specified path?
|
// is this the user specified path?
|
||||||
if path == r.PackagePath {
|
if path == r.PackagePath {
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
// skip the root package directory
|
// skip the root package directory, but check for a
|
||||||
|
// .krmignore file first.
|
||||||
pathRelativeTo = r.PackagePath
|
pathRelativeTo = r.PackagePath
|
||||||
return nil
|
return ignoreFilesMatcher.readIgnoreFile(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// user specified path is a file rather than a directory.
|
// user specified path is a file rather than a directory.
|
||||||
@@ -206,9 +213,9 @@ func (r LocalPackageReader) Read() ([]*yaml.RNode, error) {
|
|||||||
|
|
||||||
// check if we should skip the directory or file
|
// check if we should skip the directory or file
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
return r.ShouldSkipDir(path)
|
return r.shouldSkipDir(path, ignoreFilesMatcher)
|
||||||
}
|
}
|
||||||
if match, err := r.ShouldSkipFile(info); err != nil {
|
if match, err := r.shouldSkipFile(path, ignoreFilesMatcher); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if !match {
|
} else if !match {
|
||||||
// skip this file
|
// skip this file
|
||||||
@@ -250,11 +257,16 @@ func (r *LocalPackageReader) readFile(path string, _ os.FileInfo) ([]*yaml.RNode
|
|||||||
return rr.Read()
|
return rr.Read()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShouldSkipFile returns true if the file should be skipped
|
// shouldSkipFile returns true if the file should be skipped
|
||||||
func (r *LocalPackageReader) ShouldSkipFile(info os.FileInfo) (bool, error) {
|
func (r *LocalPackageReader) shouldSkipFile(path string, matcher *ignoreFilesMatcher) (bool, error) {
|
||||||
|
// check if the file is covered by a .krmignore file.
|
||||||
|
if matcher.matchFile(path) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
// check if the files are in scope
|
// check if the files are in scope
|
||||||
for _, g := range r.MatchFilesGlob {
|
for _, g := range r.MatchFilesGlob {
|
||||||
if match, err := filepath.Match(g, info.Name()); err != nil {
|
if match, err := filepath.Match(g, filepath.Base(path)); err != nil {
|
||||||
return false, errors.Wrap(err)
|
return false, errors.Wrap(err)
|
||||||
} else if match {
|
} else if match {
|
||||||
return true, nil
|
return true, nil
|
||||||
@@ -273,8 +285,12 @@ func (r *LocalPackageReader) initReaderAnnotations(path string, _ os.FileInfo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShouldSkipDir returns a filepath.SkipDir if the directory should be skipped
|
// shouldSkipDir returns a filepath.SkipDir if the directory should be skipped
|
||||||
func (r *LocalPackageReader) ShouldSkipDir(path string) error {
|
func (r *LocalPackageReader) shouldSkipDir(path string, matcher *ignoreFilesMatcher) error {
|
||||||
|
if matcher.matchDir(path) {
|
||||||
|
return filepath.SkipDir
|
||||||
|
}
|
||||||
|
|
||||||
if r.PackageFileName == "" {
|
if r.PackageFileName == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -288,5 +304,5 @@ func (r *LocalPackageReader) ShouldSkipDir(path string) error {
|
|||||||
if !r.IncludeSubpackages {
|
if !r.IncludeSubpackages {
|
||||||
return filepath.SkipDir
|
return filepath.SkipDir
|
||||||
}
|
}
|
||||||
return nil
|
return matcher.readIgnoreFile(path)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,59 +4,14 @@
|
|||||||
package kio_test
|
package kio_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
. "sigs.k8s.io/kustomize/kyaml/kio"
|
. "sigs.k8s.io/kustomize/kyaml/kio"
|
||||||
// "sigs.k8s.io/kustomize/kyaml/testutil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// setup creates directories and files for testing
|
|
||||||
type setup struct {
|
|
||||||
// root is the tmp directory
|
|
||||||
root string
|
|
||||||
}
|
|
||||||
|
|
||||||
// setupDirectories creates directories for reading test configuration from
|
|
||||||
func setupDirectories(t *testing.T, dirs ...string) setup {
|
|
||||||
d, err := ioutil.TempDir("", "kyaml-test")
|
|
||||||
if !assert.NoError(t, err) {
|
|
||||||
assert.FailNow(t, err.Error())
|
|
||||||
}
|
|
||||||
err = os.Chdir(d)
|
|
||||||
if !assert.NoError(t, err) {
|
|
||||||
assert.FailNow(t, err.Error())
|
|
||||||
}
|
|
||||||
for _, s := range dirs {
|
|
||||||
err = os.MkdirAll(s, 0700)
|
|
||||||
if !assert.NoError(t, err) {
|
|
||||||
assert.FailNow(t, err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return setup{root: d}
|
|
||||||
}
|
|
||||||
|
|
||||||
// writeFile writes a file under the test directory
|
|
||||||
func (s setup) writeFile(t *testing.T, path string, value []byte) {
|
|
||||||
err := os.MkdirAll(filepath.Dir(filepath.Join(s.root, path)), 0700)
|
|
||||||
if !assert.NoError(t, err) {
|
|
||||||
assert.FailNow(t, err.Error())
|
|
||||||
}
|
|
||||||
err = ioutil.WriteFile(filepath.Join(s.root, path), value, 0600)
|
|
||||||
if !assert.NoError(t, err) {
|
|
||||||
assert.FailNow(t, err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// clean deletes the test config
|
|
||||||
func (s setup) clean() {
|
|
||||||
os.RemoveAll(s.root)
|
|
||||||
}
|
|
||||||
|
|
||||||
var readFileA = []byte(`---
|
var readFileA = []byte(`---
|
||||||
a: b #first
|
a: b #first
|
||||||
---
|
---
|
||||||
@@ -94,18 +49,18 @@ func TestLocalPackageReader_Read_empty(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLocalPackageReader_Read_pkg(t *testing.T) {
|
func TestLocalPackageReader_Read_pkg(t *testing.T) {
|
||||||
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
||||||
defer s.clean()
|
defer s.Clean()
|
||||||
s.writeFile(t, filepath.Join("a_test.yaml"), readFileA)
|
s.WriteFile(t, filepath.Join("a_test.yaml"), readFileA)
|
||||||
s.writeFile(t, filepath.Join("b_test.yaml"), readFileB)
|
s.WriteFile(t, filepath.Join("b_test.yaml"), readFileB)
|
||||||
s.writeFile(t, filepath.Join("c_test.yaml"), readFileC)
|
s.WriteFile(t, filepath.Join("c_test.yaml"), readFileC)
|
||||||
s.writeFile(t, filepath.Join("d_test.yaml"), readFileD)
|
s.WriteFile(t, filepath.Join("d_test.yaml"), readFileD)
|
||||||
|
|
||||||
paths := []struct {
|
paths := []struct {
|
||||||
path string
|
path string
|
||||||
}{
|
}{
|
||||||
{path: "./"},
|
{path: "./"},
|
||||||
{path: s.root},
|
{path: s.Root},
|
||||||
}
|
}
|
||||||
for _, p := range paths {
|
for _, p := range paths {
|
||||||
rfr := LocalPackageReader{PackagePath: p.path}
|
rfr := LocalPackageReader{PackagePath: p.path}
|
||||||
@@ -167,13 +122,13 @@ metadata:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLocalPackageReader_Read_JSON(t *testing.T) {
|
func TestLocalPackageReader_Read_JSON(t *testing.T) {
|
||||||
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
||||||
defer s.clean()
|
defer s.Clean()
|
||||||
|
|
||||||
s.writeFile(t, filepath.Join("a_test.json"), []byte(`{
|
s.WriteFile(t, filepath.Join("a_test.json"), []byte(`{
|
||||||
"a": "b"
|
"a": "b"
|
||||||
}`))
|
}`))
|
||||||
s.writeFile(t, filepath.Join("b_test.json"), []byte(`{
|
s.WriteFile(t, filepath.Join("b_test.json"), []byte(`{
|
||||||
"e": "f",
|
"e": "f",
|
||||||
"g": {
|
"g": {
|
||||||
"h": ["i", "j"]
|
"h": ["i", "j"]
|
||||||
@@ -184,7 +139,7 @@ func TestLocalPackageReader_Read_JSON(t *testing.T) {
|
|||||||
path string
|
path string
|
||||||
}{
|
}{
|
||||||
{path: "./"},
|
{path: "./"},
|
||||||
{path: s.root},
|
{path: s.Root},
|
||||||
}
|
}
|
||||||
for _, p := range paths {
|
for _, p := range paths {
|
||||||
rfr := LocalPackageReader{PackagePath: p.path, MatchFilesGlob: []string{"*.json"}}
|
rfr := LocalPackageReader{PackagePath: p.path, MatchFilesGlob: []string{"*.json"}}
|
||||||
@@ -217,16 +172,16 @@ func TestLocalPackageReader_Read_JSON(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLocalPackageReader_Read_file(t *testing.T) {
|
func TestLocalPackageReader_Read_file(t *testing.T) {
|
||||||
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
||||||
defer s.clean()
|
defer s.Clean()
|
||||||
s.writeFile(t, filepath.Join("a_test.yaml"), readFileA)
|
s.WriteFile(t, filepath.Join("a_test.yaml"), readFileA)
|
||||||
s.writeFile(t, filepath.Join("b_test.yaml"), readFileB)
|
s.WriteFile(t, filepath.Join("b_test.yaml"), readFileB)
|
||||||
|
|
||||||
paths := []struct {
|
paths := []struct {
|
||||||
path string
|
path string
|
||||||
}{
|
}{
|
||||||
{path: "./"},
|
{path: "./"},
|
||||||
{path: s.root},
|
{path: s.Root},
|
||||||
}
|
}
|
||||||
for _, p := range paths {
|
for _, p := range paths {
|
||||||
rfr := LocalPackageReader{PackagePath: filepath.Join(p.path, "a_test.yaml")}
|
rfr := LocalPackageReader{PackagePath: filepath.Join(p.path, "a_test.yaml")}
|
||||||
@@ -265,16 +220,16 @@ metadata:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLocalPackageReader_Read_pkgOmitAnnotations(t *testing.T) {
|
func TestLocalPackageReader_Read_pkgOmitAnnotations(t *testing.T) {
|
||||||
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
||||||
defer s.clean()
|
defer s.Clean()
|
||||||
s.writeFile(t, filepath.Join("a_test.yaml"), readFileA)
|
s.WriteFile(t, filepath.Join("a_test.yaml"), readFileA)
|
||||||
s.writeFile(t, filepath.Join("b_test.yaml"), readFileB)
|
s.WriteFile(t, filepath.Join("b_test.yaml"), readFileB)
|
||||||
|
|
||||||
paths := []struct {
|
paths := []struct {
|
||||||
path string
|
path string
|
||||||
}{
|
}{
|
||||||
{path: "./"},
|
{path: "./"},
|
||||||
{path: s.root},
|
{path: s.Root},
|
||||||
}
|
}
|
||||||
for _, p := range paths {
|
for _, p := range paths {
|
||||||
// empty path
|
// empty path
|
||||||
@@ -313,16 +268,16 @@ g:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLocalPackageReader_Read_nestedDirs(t *testing.T) {
|
func TestLocalPackageReader_Read_nestedDirs(t *testing.T) {
|
||||||
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
||||||
defer s.clean()
|
defer s.Clean()
|
||||||
s.writeFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
|
s.WriteFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
|
||||||
s.writeFile(t, filepath.Join("a", "b", "b_test.yaml"), readFileB)
|
s.WriteFile(t, filepath.Join("a", "b", "b_test.yaml"), readFileB)
|
||||||
|
|
||||||
paths := []struct {
|
paths := []struct {
|
||||||
path string
|
path string
|
||||||
}{
|
}{
|
||||||
{path: "./"},
|
{path: "./"},
|
||||||
{path: s.root},
|
{path: s.Root},
|
||||||
}
|
}
|
||||||
for _, p := range paths {
|
for _, p := range paths {
|
||||||
// empty path
|
// empty path
|
||||||
@@ -374,13 +329,13 @@ metadata:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLocalPackageReader_Read_matchRegex(t *testing.T) {
|
func TestLocalPackageReader_Read_matchRegex(t *testing.T) {
|
||||||
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
||||||
defer s.clean()
|
defer s.Clean()
|
||||||
s.writeFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
|
s.WriteFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
|
||||||
s.writeFile(t, filepath.Join("a", "b", "b_test.yaml"), readFileB)
|
s.WriteFile(t, filepath.Join("a", "b", "b_test.yaml"), readFileB)
|
||||||
|
|
||||||
// empty path
|
// empty path
|
||||||
rfr := LocalPackageReader{PackagePath: s.root, MatchFilesGlob: []string{`a*.yaml`}}
|
rfr := LocalPackageReader{PackagePath: s.Root, MatchFilesGlob: []string{`a*.yaml`}}
|
||||||
nodes, err := rfr.Read()
|
nodes, err := rfr.Read()
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
assert.FailNow(t, err.Error())
|
assert.FailNow(t, err.Error())
|
||||||
@@ -414,14 +369,14 @@ metadata:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLocalPackageReader_Read_skipSubpackage(t *testing.T) {
|
func TestLocalPackageReader_Read_skipSubpackage(t *testing.T) {
|
||||||
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
||||||
defer s.clean()
|
defer s.Clean()
|
||||||
s.writeFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
|
s.WriteFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
|
||||||
s.writeFile(t, filepath.Join("a", "c", "c_test.yaml"), readFileB)
|
s.WriteFile(t, filepath.Join("a", "c", "c_test.yaml"), readFileB)
|
||||||
s.writeFile(t, filepath.Join("a", "c", "pkgFile"), pkgFile)
|
s.WriteFile(t, filepath.Join("a", "c", "pkgFile"), pkgFile)
|
||||||
|
|
||||||
// empty path
|
// empty path
|
||||||
rfr := LocalPackageReader{PackagePath: s.root, PackageFileName: "pkgFile"}
|
rfr := LocalPackageReader{PackagePath: s.Root, PackageFileName: "pkgFile"}
|
||||||
nodes, err := rfr.Read()
|
nodes, err := rfr.Read()
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
assert.FailNow(t, err.Error())
|
assert.FailNow(t, err.Error())
|
||||||
@@ -455,14 +410,14 @@ metadata:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLocalPackageReader_Read_includeSubpackage(t *testing.T) {
|
func TestLocalPackageReader_Read_includeSubpackage(t *testing.T) {
|
||||||
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
||||||
defer s.clean()
|
defer s.Clean()
|
||||||
s.writeFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
|
s.WriteFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
|
||||||
s.writeFile(t, filepath.Join("a", "c", "c_test.yaml"), readFileB)
|
s.WriteFile(t, filepath.Join("a", "c", "c_test.yaml"), readFileB)
|
||||||
s.writeFile(t, filepath.Join("a", "c", "pkgFile"), pkgFile)
|
s.WriteFile(t, filepath.Join("a", "c", "pkgFile"), pkgFile)
|
||||||
|
|
||||||
// empty path
|
// empty path
|
||||||
rfr := LocalPackageReader{PackagePath: s.root, IncludeSubpackages: true, PackageFileName: "pkgFile"}
|
rfr := LocalPackageReader{PackagePath: s.Root, IncludeSubpackages: true, PackageFileName: "pkgFile"}
|
||||||
nodes, err := rfr.Read()
|
nodes, err := rfr.Read()
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
assert.FailNow(t, err.Error())
|
assert.FailNow(t, err.Error())
|
||||||
|
|||||||
55
kyaml/kio/testing.go
Normal file
55
kyaml/kio/testing.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
// Copyright 2019 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package kio
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Setup creates directories and files for testing
|
||||||
|
type Setup struct {
|
||||||
|
// root is the tmp directory
|
||||||
|
Root string
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupDirectories creates directories for reading test configuration from
|
||||||
|
func SetupDirectories(t *testing.T, dirs ...string) Setup {
|
||||||
|
d, err := ioutil.TempDir("", "kyaml-test")
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
assert.FailNow(t, err.Error())
|
||||||
|
}
|
||||||
|
err = os.Chdir(d)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
assert.FailNow(t, err.Error())
|
||||||
|
}
|
||||||
|
for _, s := range dirs {
|
||||||
|
err = os.MkdirAll(s, 0700)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
assert.FailNow(t, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Setup{Root: d}
|
||||||
|
}
|
||||||
|
|
||||||
|
// writeFile writes a file under the test directory
|
||||||
|
func (s Setup) WriteFile(t *testing.T, path string, value []byte) {
|
||||||
|
err := os.MkdirAll(filepath.Dir(filepath.Join(s.Root, path)), 0700)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
assert.FailNow(t, err.Error())
|
||||||
|
}
|
||||||
|
err = ioutil.WriteFile(filepath.Join(s.Root, path), value, 0600)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
assert.FailNow(t, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean deletes the test config
|
||||||
|
func (s Setup) Clean() {
|
||||||
|
os.RemoveAll(s.Root)
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ package kio
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -33,10 +34,11 @@ var GraphStructures = []string{string(TreeStructureGraph), string(TreeStructureP
|
|||||||
// TODO(pwittrock): test this package better. it is lower-risk since it is only
|
// TODO(pwittrock): test this package better. it is lower-risk since it is only
|
||||||
// used for printing rather than updating or editing.
|
// used for printing rather than updating or editing.
|
||||||
type TreeWriter struct {
|
type TreeWriter struct {
|
||||||
Writer io.Writer
|
Writer io.Writer
|
||||||
Root string
|
Root string
|
||||||
Fields []TreeWriterField
|
Fields []TreeWriterField
|
||||||
Structure TreeStructure
|
Structure TreeStructure
|
||||||
|
OpenAPIFileName string
|
||||||
}
|
}
|
||||||
|
|
||||||
// TreeWriterField configures a Resource field to be included in the tree
|
// TreeWriterField configures a Resource field to be included in the tree
|
||||||
@@ -72,7 +74,7 @@ func (p TreeWriter) packageStructure(nodes []*yaml.RNode) error {
|
|||||||
// create a new branch for the package
|
// create a new branch for the package
|
||||||
createOk := pkg != "." // special edge case logic for tree on current working dir
|
createOk := pkg != "." // special edge case logic for tree on current working dir
|
||||||
if createOk {
|
if createOk {
|
||||||
branch = branch.AddBranch(pkg)
|
branch = branch.AddBranch(branchName(p.Root, pkg, p.OpenAPIFileName))
|
||||||
}
|
}
|
||||||
|
|
||||||
// cache the branch for this package
|
// cache the branch for this package
|
||||||
@@ -91,6 +93,19 @@ func (p TreeWriter) packageStructure(nodes []*yaml.RNode) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// branchName takes the root directory and relative path to the directory
|
||||||
|
// and returns the branch name
|
||||||
|
func branchName(root, dirRelPath, openAPIFileName string) string {
|
||||||
|
name := filepath.Base(dirRelPath)
|
||||||
|
_, err := os.Stat(filepath.Join(root, dirRelPath, openAPIFileName))
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
|
// add Pkg: prefix indicating that it is a separate package as it has
|
||||||
|
// openAPIFile
|
||||||
|
return fmt.Sprintf("Pkg: %s", name)
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
// Write writes the ascii tree to p.Writer
|
// Write writes the ascii tree to p.Writer
|
||||||
func (p TreeWriter) Write(nodes []*yaml.RNode) error {
|
func (p TreeWriter) Write(nodes []*yaml.RNode) error {
|
||||||
switch p.Structure {
|
switch p.Structure {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ package kio_test
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -76,9 +75,9 @@ spec:
|
|||||||
└── foo-package
|
└── foo-package
|
||||||
├── [f1.yaml] Deployment default/foo
|
├── [f1.yaml] Deployment default/foo
|
||||||
├── [f1.yaml] Service default/foo
|
├── [f1.yaml] Service default/foo
|
||||||
└── foo-package%s3
|
└── 3
|
||||||
└── [f3.yaml] Deployment default/foo
|
└── [f3.yaml] Deployment default/foo
|
||||||
`, string(filepath.Separator)), out.String()) {
|
`), out.String()) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user