Compare commits

..

52 Commits

Author SHA1 Message Date
Morten Torkildsen
90ae506183 update go.mod for release 2020-06-01 12:30:30 -07:00
Morten Torkildsen
093409d7b6 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-06-01 12:30:07 -07:00
Morten Torkildsen
d8769008ca update go.mod for release 2020-05-21 17:34:24 -07:00
Morten Torkildsen
b4456d2c24 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-05-21 17:34:03 -07:00
Morten Torkildsen
4f68f47e05 Merge pull request #2518 from mortent/release-cmd/config-v0.1
Merge master into release-cmd/config-v0.1
2020-05-21 15:43:49 -07:00
Morten Torkildsen
722e91a5c4 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-05-21 15:34:04 -07:00
Phillip Wittrock
1086764c17 update go.mod for release 2020-05-14 15:13:54 -07:00
Phillip Wittrock
d94ef43a85 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-05-14 15:11:26 -07:00
Phillip Wittrock
83dfa0b9f1 update go.mod for release 2020-05-08 08:48:32 -07:00
Phillip Wittrock
89953ec908 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-05-08 08:43:58 -07:00
Phillip Wittrock
e465ee9e9a update go.mod for release 2020-05-07 13:51:47 -07:00
Phillip Wittrock
1008933b21 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-05-07 13:51:33 -07:00
jregan
4246f79874 update go.mod for release 2020-04-30 17:04:01 -07:00
jregan
a28dd97871 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-04-30 16:36:10 -07:00
Phillip Wittrock
8de94ba96c update go.mod for release 2020-04-22 12:11:42 -07:00
Phillip Wittrock
deb55a9f15 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-04-22 12:11:19 -07:00
Phillip Wittrock
bf721a3fdd update go.mod for release 2020-04-17 09:51:31 -07:00
Phillip Wittrock
7d968fa80e Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-04-17 09:51:26 -07:00
Phillip Wittrock
fd6207b1c3 update go.mod for release 2020-04-02 11:31:23 -07:00
Phillip Wittrock
cbe85f482d Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-04-02 11:31:14 -07:00
Phillip Wittrock
a1c7330331 update go.mod for release 2020-03-28 08:34:06 -07:00
Phillip Wittrock
08ceab40dd Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-03-28 08:34:01 -07:00
Phillip Wittrock
f8fb00cb13 update go.mod for release 2020-03-23 12:08:52 -07:00
Phillip Wittrock
8a1c841420 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-03-23 12:08:31 -07:00
Phillip Wittrock
730d1f2473 update go.mod for release 2020-03-06 09:29:07 -08:00
Phillip Wittrock
29d1a37858 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-03-06 09:29:02 -08:00
Phillip Wittrock
c467f48bf2 update go.mod for release 2020-02-27 12:21:10 -08:00
Phillip Wittrock
054f56ceaf Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-02-27 12:21:05 -08:00
Phillip Wittrock
d5a107074d update go.mod for release 2020-02-21 10:18:34 -08:00
Phillip Wittrock
d8bd6db880 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2020-02-21 10:18:15 -08:00
Phillip Wittrock
d27135e3a3 update go.mod for release 2020-02-19 15:00:57 -08:00
Phillip Wittrock
282b1fa49a Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2020-02-19 15:00:38 -08:00
Phillip Wittrock
584eb236fd update go.mod for release 2020-02-05 17:46:10 -08:00
Phillip Wittrock
31a193f60f Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2020-02-05 17:46:04 -08:00
Phillip Wittrock
bf17b244e5 update go.mod for release 2020-01-16 16:24:55 -08:00
Phillip Wittrock
8338299529 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2020-01-16 16:24:35 -08:00
Phillip Wittrock
7adf7eb271 update go.mod for release 2020-01-15 18:10:02 -08:00
Phillip Wittrock
06b091b175 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2020-01-15 18:09:55 -08:00
Phillip Wittrock
bf03669e94 update go.mod for release 2020-01-13 12:49:07 -08:00
Phillip Wittrock
7f52c814a8 release cmd/config
Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0
2020-01-13 12:47:01 -08:00
Phillip Wittrock
d5aac922d9 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2020-01-10 16:38:39 -08:00
Phillip Wittrock
9a62d866f3 update go.mod for release 2020-01-09 17:02:34 -08:00
Phillip Wittrock
b2812838bf release cmd/config 0.0.6
Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0
2020-01-09 17:02:08 -08:00
Phillip Wittrock
e59e477702 update go.mod for release 2020-01-03 10:01:16 -08:00
Phillip Wittrock
4264ad0ad4 release cmd/config 0.0.5 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2020-01-03 10:01:06 -08:00
Phillip Wittrock
2554cd00eb update go.mod for release 2020-01-02 09:02:06 -08:00
Phillip Wittrock
383244cd63 Release cmd/config 0.0.4
Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0
2020-01-02 09:01:56 -08:00
Phillip Wittrock
b9da33afd4 update go.mod for release 2019-12-20 09:44:25 -08:00
Phillip Wittrock
23e339b86c Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2019-12-20 09:44:21 -08:00
Phillip Wittrock
9555009df8 update go.mod for release 2019-12-16 14:21:02 -08:00
Phillip Wittrock
91a10c560c Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2019-12-16 14:20:58 -08:00
Phillip Wittrock
780cb19c4d drop replace 2019-12-13 13:50:17 -08:00
11931 changed files with 17093 additions and 875501 deletions

2
.gitignore vendored
View File

@@ -19,5 +19,3 @@
# macOS
*.DS_store
.bin

View File

@@ -14,8 +14,11 @@ all: verify-kustomize
verify-kustomize: \
lint-kustomize \
test-unit-kustomize-all \
test-examples-kustomize-against-HEAD \
test-examples-kustomize-against-3.6.1
test-examples-kustomize-against-HEAD
# TODO: restore test-examples-kustomize-against-3.5.5 \
# once it works. Likely have to fix and release 3.6
# test-examples-kustomize-against-3.5.4 no longer works because
# the examples tests features not in 3.5.4
# The following target referenced by a file in
# https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/kustomize
@@ -24,7 +27,6 @@ prow-presubmit-check: \
lint-kustomize \
test-unit-kustomize-all \
test-examples-kustomize-against-HEAD \
test-examples-kustomize-against-3.6.1 \
test-unit-cmd-all \
test-go-mod
@@ -196,7 +198,7 @@ build-kustomize-api: $(builtinplugins)
.PHONY: test-unit-kustomize-api
test-unit-kustomize-api: build-kustomize-api
cd api; go test ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222"
cd api; go test ./...
.PHONY: test-unit-kustomize-plugins
test-unit-kustomize-plugins:
@@ -233,10 +235,10 @@ test-examples-kustomize-against-HEAD: $(MYGOBIN)/kustomize $(MYGOBIN)/mdrip
./hack/testExamplesAgainstKustomize.sh HEAD
.PHONY:
test-examples-kustomize-against-3.6.1: $(MYGOBIN)/mdrip
test-examples-kustomize-against-3.5.4: $(MYGOBIN)/mdrip
( \
set -e; \
tag=v3.6.1; \
tag=v3.5.4; \
/bin/rm -f $(MYGOBIN)/kustomize; \
echo "Installing kustomize $$tag."; \
GO111MODULE=on go get sigs.k8s.io/kustomize/kustomize/v3@$${tag}; \
@@ -245,6 +247,20 @@ test-examples-kustomize-against-3.6.1: $(MYGOBIN)/mdrip
cd kustomize; go install .; \
)
.PHONY:
test-examples-kustomize-against-3.5.5: $(MYGOBIN)/mdrip
( \
set -e; \
tag=v3.5.5; \
/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.
# This is for testing an example plugin that
# uses kubeval for validation.

View File

@@ -16,9 +16,9 @@ inspired by [DAM].
[![Go Report Card](https://goreportcard.com/badge/github.com/kubernetes-sigs/kustomize)](https://goreportcard.com/report/github.com/kubernetes-sigs/kustomize)
Download a binary from the [release page], or see
these [instructions](https://kubernetes-sigs.github.io/kustomize/installation/).
these [instructions](docs/INSTALL.md).
Browse the [docs](https://kubernetes-sigs.github.io/kustomize/) or jump right into the
Browse the [docs](docs) or jump right into the
tested [examples](examples).
## kubectl integration
@@ -132,8 +132,20 @@ The YAML can be directly [applied] to a cluster:
## Community
- [file a bug](https://kubernetes-sigs.github.io/kustomize/contributing/bugs/) instructions
- [contribute a feature](https://kubernetes-sigs.github.io/kustomize/contributing/features/) instructions
To file bugs please read [this](docs/bugs.md).
Before working on an implementation, please
* Read the [eschewed feature list].
* File an issue describing
how the new feature would behave
and label it [kind/feature].
### Other communication channels
- [Slack]
- [Mailing List]
- General kubernetes [community page]
### Code of conduct
@@ -142,27 +154,32 @@ is governed by the [Kubernetes Code of Conduct].
[`make`]: https://www.gnu.org/software/make
[`sed`]: https://www.gnu.org/software/sed
[DAM]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#declarative-application-management
[DAM]: docs/glossary.md#declarative-application-management
[KEP]: https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/0008-kustomize.md
[Kubernetes Code of Conduct]: code-of-conduct.md
[applied]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#apply
[base]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#base
[declarative configuration]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#declarative-application-management
[Mailing List]: https://groups.google.com/forum/#!forum/kubernetes-sig-cli
[Slack]: https://kubernetes.slack.com/messages/sig-cli
[applied]: docs/glossary.md#apply
[base]: docs/glossary.md#base
[community page]: http://kubernetes.io/community/
[declarative configuration]: docs/glossary.md#declarative-application-management
[eschewed feature list]: docs/eschewedFeatures.md
[imageBase]: docs/images/base.jpg
[imageOverlay]: docs/images/overlay.jpg
[kind/feature]: /../../labels/kind%2Ffeature
[kubectl announcement]: https://kubernetes.io/blog/2019/03/25/kubernetes-1-14-release-announcement
[kubectl book]: https://kubectl.docs.kubernetes.io/pages/app_customization/introduction.html
[kubernetes documentation]: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/
[kubernetes style]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#kubernetes-style-object
[kustomization]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#kustomization
[overlay]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#overlay
[overlays]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#overlay
[release page]: https://github.com/kubernetes-sigs/kustomize/releases
[resource]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#resource
[resources]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#resource
[kubernetes style]: docs/glossary.md#kubernetes-style-object
[kustomization]: docs/glossary.md#kustomization
[overlay]: docs/glossary.md#overlay
[overlays]: docs/glossary.md#overlay
[release page]: /../../releases
[resource]: docs/glossary.md#resource
[resources]: docs/glossary.md#resource
[sig-cli]: https://github.com/kubernetes/community/blob/master/sig-cli/README.md
[variant]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#variant
[variants]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#variant
[v2.0.3]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v2.0.3
[v2.1.0]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v2.1.0
[workflows]: https://kubernetes-sigs.github.io/kustomize/guides
[variant]: docs/glossary.md#variant
[variants]: docs/glossary.md#variant
[v2.0.3]: /../../releases/tag/v2.0.3
[v2.1.0]: /../../releases/tag/v2.1.0
[workflows]: docs/workflows.md

View File

@@ -29,7 +29,7 @@ func (p *AnnotationsTransformerPlugin) Transform(m resmap.ResMap) error {
err := filtersutil.ApplyToJSON(annotations.Filter{
Annotations: p.Annotations,
FsSlice: p.FieldSpecs,
}, r)
}, r.Kunstructured)
if err != nil {
return err
}

View File

@@ -29,7 +29,7 @@ func (p *LabelTransformerPlugin) Transform(m resmap.ResMap) error {
err := filtersutil.ApplyToJSON(labels.Filter{
Labels: p.Labels,
FsSlice: p.FieldSpecs,
}, r)
}, r.Kunstructured)
if err != nil {
return err
}

View File

@@ -51,7 +51,7 @@ func (p *NamespaceTransformerPlugin) Transform(m resmap.ResMap) error {
err := filtersutil.ApplyToJSON(namespace.Filter{
Namespace: p.Namespace,
FsSlice: p.FieldSpecs,
}, r)
}, r.Kunstructured)
if err != nil {
return err
}

View File

@@ -101,7 +101,7 @@ func (p *PatchJson6902TransformerPlugin) Transform(m resmap.ResMap) error {
} else {
return filtersutil.ApplyToJSON(patchjson6902.Filter{
Patch: p.JsonOp,
}, obj)
}, obj.Kunstructured)
}
}

View File

@@ -4,8 +4,11 @@
package builtins
import (
"encoding/json"
"fmt"
kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
"sigs.k8s.io/kustomize/api/filters/patchstrategicmerge"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
@@ -74,7 +77,7 @@ func (p *PatchStrategicMergeTransformerPlugin) Transform(m resmap.ResMap) error
return err
}
if !p.YAMLSupport {
err = target.Patch(patch.Copy())
err = target.Patch(patch.Kunstructured)
if err != nil {
return err
}
@@ -87,22 +90,28 @@ func (p *PatchStrategicMergeTransformerPlugin) Transform(m resmap.ResMap) error
}
}
} else {
patchCopy := patch.DeepCopy()
patchCopy.SetName(target.GetName())
patchCopy.SetNamespace(target.GetNamespace())
patchCopy.SetGvk(target.GetGvk())
node, err := filtersutil.GetRNode(patchCopy)
node, err := getRNode(patch)
if err != nil {
return err
}
err = filtersutil.ApplyToJSON(patchstrategicmerge.Filter{
Patch: node,
}, target)
}, target.Kunstructured)
}
}
return nil
}
//TODO: Remove this once the next version of kyaml is released which
// exposes GetRNode from the filutersutil package.
func getRNode(k json.Marshaler) (*kyaml.RNode, error) {
j, err := k.MarshalJSON()
if err != nil {
return nil, err
}
return kyaml.Parse(string(j))
}
func NewPatchStrategicMergeTransformerPlugin() resmap.TransformerPlugin {
return &PatchStrategicMergeTransformerPlugin{}
}

View File

@@ -115,7 +115,7 @@ func (p *PatchTransformerPlugin) transformStrategicMerge(m resmap.ResMap, patch
// use the legacy implementation or the kyaml-based solution.
func (p *PatchTransformerPlugin) applySMPatch(resource, patch *resource.Resource) error {
if !p.YAMLSupport {
return resource.Patch(patch.Copy())
return resource.Patch(patch.Kunstructured)
} else {
node, err := filtersutil.GetRNode(patch)
if err != nil {
@@ -123,7 +123,7 @@ func (p *PatchTransformerPlugin) applySMPatch(resource, patch *resource.Resource
}
return filtersutil.ApplyToJSON(patchstrategicmerge.Filter{
Patch: node,
}, resource)
}, resource.Kunstructured)
}
}
@@ -165,7 +165,7 @@ func (p *PatchTransformerPlugin) applyJson6902Patch(resource *resource.Resource,
} else {
return filtersutil.ApplyToJSON(patchjson6902.Filter{
Patch: p.Patch,
}, resource)
}, resource.Kunstructured)
}
}

View File

@@ -121,13 +121,13 @@ func (p *ValueAddTransformerPlugin) Transform(m resmap.ResMap) (err error) {
if t.FieldPath == types.MetadataNamespacePath {
err = filtersutil.ApplyToJSON(namespace.Filter{
Namespace: p.Value,
}, res)
}, res.Kunstructured)
} else {
err = filtersutil.ApplyToJSON(valueadd.Filter{
Value: p.Value,
FieldPath: t.FieldPath,
FilePathPosition: t.FilePathPosition,
}, res)
}, res.Kunstructured)
}
if err != nil {
return err

View File

@@ -31,86 +31,6 @@ apiVersion: apps/v1
metadata:
name: yourDeploy
kind: Deployment
`,
},
"container patch": {
input: `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
containers:
- name: foo1
- name: foo2
- name: foo3
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
containers:
- name: foo0
`),
expected: `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
containers:
- name: foo1
- name: foo2
- name: foo3
- name: foo0
`,
},
"volumes patch": {
input: `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
volumes:
- name: foo1
- name: foo2
- name: foo3
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
volumes:
- name: foo0
`),
expected: `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
volumes:
- name: foo1
- name: foo2
- name: foo3
- name: foo0
`,
},
"nested patch": {

View File

@@ -1,6 +1,6 @@
module sigs.k8s.io/kustomize/api
go 1.14
go 1.13
require (
github.com/evanphx/json-patch v4.5.0+incompatible
@@ -11,11 +11,11 @@ require (
github.com/stretchr/testify v1.4.0
github.com/yujunz/go-getter v1.4.1-lite
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff
gopkg.in/yaml.v2 v2.3.0
gopkg.in/yaml.v2 v2.2.8
k8s.io/api v0.17.0
k8s.io/apimachinery v0.17.0
k8s.io/client-go v0.17.0
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a
sigs.k8s.io/kustomize/kyaml v0.3.4
sigs.k8s.io/kustomize/kyaml v0.1.11
sigs.k8s.io/yaml v1.2.0
)

View File

@@ -104,6 +104,7 @@ github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
@@ -166,6 +167,7 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -279,6 +281,7 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
@@ -340,7 +343,6 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d h1:K6eOUihrFLdZjZnA4XlRp864fmWXv9YTIk7VPLhRacA=
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d/go.mod h1:7DPO4domFU579Ga6E61sB9VFNaniPVwJP5C4bBCu3wA=
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
@@ -371,6 +373,7 @@ github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
@@ -424,7 +427,6 @@ go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.starlark.net v0.0.0-20190528202925-30ae18b8564f/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg=
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
@@ -464,6 +466,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/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-20190923162816-aa69164e4478/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/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -490,6 +493,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 h1:rOhMmluY6kLMhdnrivzec6lLgaVbMHMn2ISQXJeJ5EM=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c h1:Vco5b+cuG5NNfORVxZy6bYZQ7rsigisU1WQFkvQ0L5E=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -549,11 +553,12 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2 h1:XZx7nhd5GMaZpmDaEHFVafUZC7ya0fuo7cSJ3UCKYmM=
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -580,9 +585,10 @@ 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/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/kustomize/kyaml v0.3.4 h1:RhxnabYltv4mdD5+I7pIaJtae+eaTn4TiZqPT7K+C7A=
sigs.k8s.io/kustomize/kyaml v0.3.4/go.mod h1:XJL84E6sOFeNrQ7CADiemc1B0EjIxHo3OhW4o1aJYNw=
sigs.k8s.io/kustomize/kyaml v0.1.11 h1:/VvWxVIgH5gG1K4A7trgbyLgO3tRBiAWNhLFVU1HEmo=
sigs.k8s.io/kustomize/kyaml v0.1.11/go.mod h1:72/rLkSi+L/pHM1oCjwrf3ClU+tH5kZQvvdLSqIHwWU=
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/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=

View File

@@ -41,33 +41,33 @@ type Loader interface {
// Kunstructured allows manipulation of k8s objects
// that do not have Golang structs.
type Kunstructured interface {
Copy() Kunstructured
GetAnnotations() map[string]string
GetBool(path string) (bool, error)
GetFieldValue(string) (interface{}, error)
GetFloat64(path string) (float64, error)
GetGvk() resid.Gvk
GetInt64(path string) (int64, error)
GetKind() string
GetLabels() map[string]string
GetMap(path string) (map[string]interface{}, error)
GetName() string
GetSlice(path string) ([]interface{}, error)
GetString(string) (string, error)
GetStringMap(path string) (map[string]string, error)
GetStringSlice(string) ([]string, error)
Map() map[string]interface{}
MarshalJSON() ([]byte, error)
MatchesAnnotationSelector(selector string) (bool, error)
MatchesLabelSelector(selector string) (bool, error)
Patch(Kunstructured) error
SetAnnotations(map[string]string)
SetGvk(resid.Gvk)
SetLabels(map[string]string)
SetMap(map[string]interface{})
Copy() Kunstructured
GetFieldValue(string) (interface{}, error)
GetString(string) (string, error)
GetStringSlice(string) ([]string, error)
GetBool(path string) (bool, error)
GetFloat64(path string) (float64, error)
GetInt64(path string) (int64, error)
GetSlice(path string) ([]interface{}, error)
GetStringMap(path string) (map[string]string, error)
GetMap(path string) (map[string]interface{}, error)
MarshalJSON() ([]byte, error)
UnmarshalJSON([]byte) error
GetGvk() resid.Gvk
SetGvk(resid.Gvk)
GetKind() string
GetName() string
SetName(string)
SetNamespace(string)
UnmarshalJSON([]byte) error
GetLabels() map[string]string
SetLabels(map[string]string)
GetAnnotations() map[string]string
SetAnnotations(map[string]string)
MatchesLabelSelector(selector string) (bool, error)
MatchesAnnotationSelector(selector string) (bool, error)
Patch(Kunstructured) error
}
// KunstructuredFactory makes instances of Kunstructured.

View File

@@ -1,4 +1,4 @@
FROM golang:1.14 AS build
FROM golang:1.11 AS build
ARG GO111MODULE=on

View File

@@ -159,31 +159,40 @@ func main() {
}
}
query := []byte(`{ "query":{ "match_all":{} } }`)
it := idx.IterateQuery(query, 10000, 60*time.Second)
seedDocs := make(crawler.CrawlSeed, 0)
// get all the documents in the index
getSeedDocsFunc := func() {
query := []byte(`{ "query":{ "match_all":{} } }`)
it := idx.IterateQuery(query, 10000, 60*time.Second)
for it.Next() {
for _, hit := range it.Value().Hits.Hits {
seedDocs = append(seedDocs, hit.Document.Document.Copy())
}
}
if err := it.Err(); err != nil {
log.Fatalf("getSeedDocsFunc Error iterating: %v\n", err)
}
}
switch mode {
case CrawlIndexAndGithub:
getSeedDocsFunc()
crawlers := []crawler.Crawler{ghCrawlerConstructor("", "")}
crawler.CrawlFromSeedIterator(ctx, it, crawlers, docConverter, indexFunc, seen)
crawler.CrawlFromSeed(ctx, seedDocs, crawlers, docConverter, indexFunc, seen)
crawler.CrawlGithub(ctx, crawlers, docConverter, indexFunc, seen)
case CrawlIndex:
getSeedDocsFunc()
crawlers := []crawler.Crawler{ghCrawlerConstructor("", "")}
crawler.CrawlFromSeedIterator(ctx, it, crawlers, docConverter, indexFunc, seen)
crawler.CrawlFromSeed(ctx, seedDocs, crawlers, docConverter, indexFunc, seen)
case CrawlGithub:
crawlers := []crawler.Crawler{ghCrawlerConstructor("", "")}
// add all the documents in the index into seen.
// this greatly reduces the time overhead of CrawlGithub.
for it.Next() {
for _, hit := range it.Value().Hits.Hits {
d := hit.Document.Document
seen.Set(d.ID(), d.FileType)
}
getSeedDocsFunc()
for _, d := range seedDocs {
seen[d.ID()] = d.FileType
}
if err := it.Err(); err != nil {
log.Fatalf("Error iterating the index: %v\n", err)
}
crawler.CrawlGithub(ctx, crawlers, docConverter, indexFunc, seen)
case CrawlUser:
if *githubUserPtr == "" {

View File

@@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: elasticsearch
spec:
selector:
custom-resource: v1alpha1.ESCluster
custom-resource-name: esbasic
custom-resource-namespace: default
es/data: "true"
using: escluster.Cluster
ports:
- protocol: "TCP"
port: 9200
type: LoadBalancer
loadBalancerIP: ""

View File

@@ -213,36 +213,21 @@ func doCrawl(ctx context.Context, docsPtr *CrawlSeed, crawlers []Crawler, conv C
logger.Printf("\t%d documents cannot be converted but still were inserted or updated in the index\n", convErrCount)
}
// CrawlFromSeedIterator iterates all the documents in the index and call CrawlFromSeed for each document.
func CrawlFromSeedIterator(ctx context.Context, it *index.KustomizeIterator, crawlers []Crawler,
conv Converter, indx IndexFunc, seen utils.SeenMap) {
docCount := 0
for it.Next() {
for _, hit := range it.Value().Hits.Hits {
docCount++
logger.Printf("updating document %d from seed\n", docCount)
singleSeed := CrawlSeed{&(hit.Document.Document)}
CrawlFromSeed(ctx, singleSeed, crawlers, conv, indx, seen)
}
}
if err := it.Err(); err != nil {
log.Fatalf("Error iterating the index: %v\n", err)
}
}
// CrawlFromSeed updates all the documents in seed, and crawls all the new
// documents referred in the seed.
func CrawlFromSeed(ctx context.Context, seed CrawlSeed, crawlers []Crawler,
conv Converter, indx IndexFunc, seen utils.SeenMap) {
// stack tracks the documents directly referred in the seed.
// stack tracks the documents directly referred in other documents.
stack := make(CrawlSeed, 0)
// Exploit seed to update bulk of corpus.
logger.Printf("updating %d documents from seed\n", len(seed))
// each unique document in seed will be crawled once.
doCrawl(ctx, &seed, crawlers, conv, indx, seen, &stack, true, false)
logger.Printf("crawling %d new documents referred by doc\n", len(stack))
// Traverse any new documents added while updating corpus.
logger.Printf("crawling %d new documents found in the seed\n", len(stack))
// While crawling each document in stack, the documents directly referred in the document
// will be added into stack.
// After this statement is done, stack will become empty.
@@ -312,6 +297,8 @@ func CrawlGithubRunner(ctx context.Context, output chan<- CrawledDocument,
// CrawlGithub crawls all the kustomization files on Github.
func CrawlGithub(ctx context.Context, crawlers []Crawler, conv Converter,
indx IndexFunc, seen utils.SeenMap) {
// stack tracks the documents directly referred in other documents.
stack := make(CrawlSeed, 0)
// ch is channel where all the crawlers sends the crawled documents to.
ch := make(chan CrawledDocument, 1<<10)
@@ -337,20 +324,7 @@ func CrawlGithub(ctx context.Context, crawlers []Crawler, conv Converter,
"%v could not match any crawler", cdoc))
continue
}
// stack tracks the documents directly referred in the document.
stack := make(CrawlSeed, 0)
addBranches(cdoc, match, indx, seen, &stack)
if len(stack) > 0 {
// here the documents referred in a kustomization file are crawled separately,
// to avoid accumulating all the referred documents into a single gigantic
// mem-inentive stack.
logger.Printf("crawling the %d new documents referred in doc %d",
len(stack), docCount)
doCrawl(ctx, &stack, crawlers, conv, indx, seen, &stack, false, true)
}
}
}()
@@ -362,4 +336,9 @@ func CrawlGithub(ctx context.Context, crawlers []Crawler, conv Converter,
}
close(ch)
wg.Wait()
// Handle deps of newly discovered documents.
logger.Printf("crawling the %d new documents referred by other documents",
len(stack))
doCrawl(ctx, &stack, crawlers, conv, indx, seen, &stack, false, true)
}

View File

@@ -82,15 +82,14 @@ func (gc githubCrawler) Crawl(ctx context.Context,
ranges := []RangeWithin{
RangeWithin{
start: uint64(0),
end: githubMaxFileSize,
},
start: uint64(0),
end: githubMaxFileSize,
},
}
errs := make(multiError, 0)
for len(ranges) > 0 {
logger.Printf("Current ranges: %v (len: %d)\n", ranges, len(ranges))
tailRange := ranges[len(ranges)-1]
tailRange := ranges[len(ranges) - 1]
ranges = ranges[:(len(ranges) - 1)]
reProcessQueryRanges, err := gc.CrawlSingleRange(ctx, output, seen, tailRange.start, tailRange.end)
if err != nil {
@@ -152,15 +151,7 @@ func (gc githubCrawler) CrawlSingleRange(ctx context.Context,
}
queryResult.Add(rangeResult)
if reProcessQuery {
// if the size of a range is 0, such as [245, 245], and reProcessQuery is true,
// it means that there are more than 1000 results for the query range.
// Reprocessing the query range will not help because the GitHub Search API
// only provides up to 1,000 results for each search.
if RangeSizes(query).Size() == 0 {
logger.Printf("range size is 0 includes more than 1000 results: %s", query)
} else {
reProcessQueryRanges = append(reProcessQueryRanges, RangeSizes(query))
}
reProcessQueryRanges = append(reProcessQueryRanges, RangeSizes(query))
}
}

View File

@@ -225,7 +225,3 @@ type RangeWithin struct {
func (r RangeWithin) RangeString() string {
return fmt.Sprintf("%d..%d", r.start, r.end)
}
func (r RangeWithin) Size() uint64 {
return r.end - r.start
}

View File

@@ -1,6 +1,6 @@
module sigs.k8s.io/kustomize/api/internal/crawl
go 1.14
go 1.13
require (
github.com/elastic/go-elasticsearch/v6 v6.8.5

View File

@@ -490,10 +490,9 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/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-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -515,7 +514,7 @@ 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/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=
sigs.k8s.io/kustomize/kyaml v0.3.4/go.mod h1:XJL84E6sOFeNrQ7CADiemc1B0EjIxHo3OhW4o1aJYNw=
sigs.k8s.io/kustomize/kyaml v0.1.11/go.mod h1:72/rLkSi+L/pHM1oCjwrf3ClU+tH5kZQvvdLSqIHwWU=
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/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=

View File

@@ -1,37 +1,21 @@
package utils
import "sync"
type SeenMap map[string]string
type SeenMap struct {
data map[string]string
lock sync.RWMutex
}
// TODO: add lock to avoid race condition
func (seen SeenMap) Seen(item string) bool {
seen.lock.RLock()
_, ok := seen.data[item]
seen.lock.RUnlock()
_, ok := seen[item]
return ok
}
func (seen SeenMap) Set(k, v string) {
seen.lock.Lock()
seen.data[k] = v
seen.lock.Unlock()
seen[k] = v
}
// The caller should make sure that key is in the map.
func (seen SeenMap) Value(k string) string {
seen.lock.RLock()
v := seen.data[k]
seen.lock.RUnlock()
return v
return seen[k]
}
func NewSeenMap() SeenMap {
return SeenMap{
data: make(map[string]string),
lock: sync.RWMutex{},
}
return make(map[string]string)
}

View File

@@ -33,7 +33,6 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error {
cmd := exec.Command(
gitProgram,
"clone",
"--depth=1",
repoSpec.CloneSpec(),
repoSpec.Dir.String())
out, err := cmd.CombinedOutput()
@@ -45,23 +44,10 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error {
repoSpec.CloneSpec(), repoSpec.Dir.String())
}
cmd = exec.Command(
gitProgram,
"fetch",
"--depth=1",
"origin",
repoSpec.Ref)
cmd.Dir = repoSpec.Dir.String()
out, err = cmd.CombinedOutput()
if err != nil {
log.Printf("Error fetching ref: %s", out)
return errors.Wrapf(err, "trouble fetching %s", repoSpec.Ref)
}
cmd = exec.Command(
gitProgram,
"checkout",
"FETCH_HEAD")
repoSpec.Ref)
cmd.Dir = repoSpec.Dir.String()
out, err = cmd.CombinedOutput()
if err != nil {

View File

@@ -9,17 +9,22 @@ import (
"io/ioutil"
"os"
"os/exec"
"strconv"
"strings"
"github.com/google/shlex"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/yaml"
)
const (
idAnnotation = "kustomize.config.k8s.io/id"
HashAnnotation = "kustomize.config.k8s.io/needs-hash"
BehaviorAnnotation = "kustomize.config.k8s.io/behavior"
tmpConfigFilePrefix = "kust-plugin-config-"
)
@@ -109,12 +114,12 @@ func (p *ExecPlugin) Generate() (resmap.ResMap, error) {
if err != nil {
return nil, err
}
return utils.UpdateResourceOptions(rm)
return p.UpdateResourceOptions(rm)
}
func (p *ExecPlugin) Transform(rm resmap.ResMap) error {
// add ResIds as annotations to all objects so that we can add them back
inputRM, err := utils.GetResMapWithIDAnnotation(rm)
inputRM, err := p.getResMapWithIdAnnotation(rm)
if err != nil {
return err
}
@@ -132,7 +137,7 @@ func (p *ExecPlugin) Transform(rm resmap.ResMap) error {
}
// update the original ResMap based on the output
return utils.UpdateResMapValues(p.path, p.h, output, rm)
return p.updateResMapValues(output, rm)
}
// invokePlugin writes plugin config to a temp file, then
@@ -179,3 +184,91 @@ func (p *ExecPlugin) getEnv() []string {
"KUSTOMIZE_PLUGIN_CONFIG_ROOT="+p.h.Loader().Root())
return env
}
// Returns a new copy of the given ResMap with the ResIds annotated in each Resource
func (p *ExecPlugin) getResMapWithIdAnnotation(rm resmap.ResMap) (resmap.ResMap, error) {
inputRM := rm.DeepCopy()
for _, r := range inputRM.Resources() {
idString, err := yaml.Marshal(r.CurId())
if err != nil {
return nil, err
}
annotations := r.GetAnnotations()
if annotations == nil {
annotations = make(map[string]string)
}
annotations[idAnnotation] = string(idString)
r.SetAnnotations(annotations)
}
return inputRM, nil
}
// updateResMapValues updates the Resource value in the given ResMap
// with the emitted Resource values in output.
func (p *ExecPlugin) updateResMapValues(output []byte, rm resmap.ResMap) error {
outputRM, err := p.h.ResmapFactory().NewResMapFromBytes(output)
if err != nil {
return err
}
for _, r := range outputRM.Resources() {
// for each emitted Resource, find the matching Resource in the original ResMap
// using its id
annotations := r.GetAnnotations()
idString, ok := annotations[idAnnotation]
if !ok {
return fmt.Errorf("the transformer %s should not remove annotation %s",
p.path, idAnnotation)
}
id := resid.ResId{}
err := yaml.Unmarshal([]byte(idString), &id)
if err != nil {
return err
}
res, err := rm.GetByCurrentId(id)
if err != nil {
return fmt.Errorf("unable to find unique match to %s", id.String())
}
// remove the annotation set by Kustomize to track the resource
delete(annotations, idAnnotation)
if len(annotations) == 0 {
annotations = nil
}
r.SetAnnotations(annotations)
// update the ResMap resource value with the transformed object
res.Kunstructured = r.Kunstructured
}
return nil
}
// updateResourceOptions updates the generator options for each resource in the
// given ResMap based on plugin provided annotations.
func (p *ExecPlugin) UpdateResourceOptions(rm resmap.ResMap) (resmap.ResMap, error) {
for _, r := range rm.Resources() {
// Disable name hashing by default and require plugin to explicitly
// request it for each resource.
annotations := r.GetAnnotations()
behavior := annotations[BehaviorAnnotation]
var needsHash bool
if val, ok := annotations[HashAnnotation]; ok {
b, err := strconv.ParseBool(val)
if err != nil {
return nil, fmt.Errorf(
"the annotation %q contains an invalid value (%q)",
HashAnnotation, val)
}
needsHash = b
}
delete(annotations, HashAnnotation)
delete(annotations, BehaviorAnnotation)
if len(annotations) == 0 {
annotations = nil
}
r.SetAnnotations(annotations)
r.SetOptions(types.NewGenArgs(
&types.GeneratorArgs{
Behavior: behavior,
Options: &types.GeneratorOptions{DisableNameSuffixHash: !needsHash}}))
}
return rm, nil
}

View File

@@ -4,6 +4,7 @@
package execplugin_test
import (
"fmt"
"strings"
"testing"
@@ -16,6 +17,7 @@ import (
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
)
func TestExecPluginConfig(t *testing.T) {
@@ -89,3 +91,107 @@ metadata:
t.Fatalf("unexpected arg array: %#v", p.Args())
}
}
func makeConfigMap(rf *resource.Factory, name, behavior string, hashValue *string) *resource.Resource {
r := rf.FromMap(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{"name": name},
})
annotations := map[string]string{}
if behavior != "" {
annotations[BehaviorAnnotation] = behavior
}
if hashValue != nil {
annotations[HashAnnotation] = *hashValue
}
if len(annotations) > 0 {
r.SetAnnotations(annotations)
}
return r
}
func makeConfigMapOptions(rf *resource.Factory, name, behavior string, disableHash bool) *resource.Resource {
return rf.FromMapAndOption(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{"name": name},
}, &types.GeneratorArgs{
Behavior: behavior,
Options: &types.GeneratorOptions{DisableNameSuffixHash: disableHash}})
}
func strptr(s string) *string {
return &s
}
func TestUpdateResourceOptions(t *testing.T) {
p := NewExecPlugin("")
if err := p.ErrIfNotExecutable(); err == nil {
t.Fatalf("expected unexecutable error")
}
rf := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
in := resmap.New()
expected := resmap.New()
cases := []struct {
behavior string
needsHash bool
hashValue *string
}{
{hashValue: strptr("false")},
{hashValue: strptr("true"), needsHash: true},
{behavior: "replace"},
{behavior: "merge"},
{behavior: "create"},
{behavior: "nonsense"},
{behavior: "merge", hashValue: strptr("false")},
{behavior: "merge", hashValue: strptr("true"), needsHash: true},
}
for i, c := range cases {
name := fmt.Sprintf("test%d", i)
in.Append(makeConfigMap(rf, name, c.behavior, c.hashValue))
expected.Append(makeConfigMapOptions(rf, name, c.behavior, !c.needsHash))
}
actual, err := p.UpdateResourceOptions(in)
if err != nil {
t.Fatalf("unexpected error: %v", err.Error())
}
for i, a := range expected.Resources() {
b := actual.GetByIndex(i)
if b == nil {
t.Fatalf("resource %d missing from processed map", i)
}
if !a.Equals(b) {
t.Errorf("expected %v got %v", a, b)
}
if a.NeedHashSuffix() != b.NeedHashSuffix() {
t.Errorf("")
}
if a.Behavior() != b.Behavior() {
t.Errorf("expected %v got %v", a.Behavior(), b.Behavior())
}
}
}
func TestUpdateResourceOptionsWithInvalidHashAnnotationValues(t *testing.T) {
p := NewExecPlugin("")
if err := p.ErrIfNotExecutable(); err == nil {
t.Fatalf("expected unexecutable error")
}
rf := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
cases := []string{
"",
"FaLsE",
"TrUe",
"potato",
}
for i, c := range cases {
name := fmt.Sprintf("test%d", i)
in := resmap.New()
in.Append(makeConfigMap(rf, name, "", &c))
_, err := p.UpdateResourceOptions(in)
if err == nil {
t.Errorf("expected error from value %q", c)
}
}
}

View File

@@ -1,197 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package fnplugin
import (
"bytes"
"fmt"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil"
"sigs.k8s.io/kustomize/kyaml/runfn"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// FnPlugin is the struct to hold function information
type FnPlugin struct {
// Function runner
runFns runfn.RunFns
// Plugin configuration data.
cfg []byte
// Plugin name cache for error output
pluginName string
// PluginHelpers
h *resmap.PluginHelpers
}
func bytesToRNode(yml []byte) (*yaml.RNode, error) {
rnode, err := yaml.Parse(string(yml))
if err != nil {
return nil, err
}
return rnode, nil
}
func resourceToRNode(res *resource.Resource) (*yaml.RNode, error) {
yml, err := res.AsYAML()
if err != nil {
return nil, err
}
return bytesToRNode(yml)
}
// GetFunctionSpec return function spec is there is. Otherwise return nil
func GetFunctionSpec(res *resource.Resource) *runtimeutil.FunctionSpec {
rnode, err := resourceToRNode(res)
if err != nil {
return nil
}
return runtimeutil.GetFunctionSpec(rnode)
}
func toStorageMounts(mounts []string) []runtimeutil.StorageMount {
var sms []runtimeutil.StorageMount
for _, mount := range mounts {
sms = append(sms, runtimeutil.StringToStorageMount(mount))
}
return sms
}
// NewFnPlugin creates a FnPlugin struct
func NewFnPlugin(o *types.FnPluginLoadingOptions) *FnPlugin {
return &FnPlugin{
runFns: runfn.RunFns{
Functions: []*yaml.RNode{},
Network: o.Network,
NetworkName: o.NetworkName,
EnableStarlark: o.EnableStar,
EnableExec: o.EnableExec,
StorageMounts: toStorageMounts(o.Mounts),
},
}
}
// Cfg returns function config
func (p *FnPlugin) Cfg() []byte {
return p.cfg
}
// Config is called by kustomize to pass-in config information
func (p *FnPlugin) Config(h *resmap.PluginHelpers, config []byte) error {
p.h = h
p.cfg = config
fn, err := bytesToRNode(p.cfg)
if err != nil {
return err
}
meta, err := fn.GetMeta()
if err != nil {
return err
}
p.pluginName = fmt.Sprintf("api: %s, kind: %s, name: %s",
meta.APIVersion, meta.Kind, meta.Name)
return nil
}
// Generate is called when run as generator
func (p *FnPlugin) Generate() (resmap.ResMap, error) {
output, err := p.invokePlugin(nil)
if err != nil {
return nil, err
}
rm, err := p.h.ResmapFactory().NewResMapFromBytes(output)
if err != nil {
return nil, err
}
return utils.UpdateResourceOptions(rm)
}
// Transform is called when run as transformer
func (p *FnPlugin) Transform(rm resmap.ResMap) error {
// add ResIds as annotations to all objects so that we can add them back
inputRM, err := utils.GetResMapWithIDAnnotation(rm)
if err != nil {
return err
}
// encode the ResMap so it can be fed to the plugin
resources, err := inputRM.AsYaml()
if err != nil {
return err
}
// invoke the plugin with resources as the input
output, err := p.invokePlugin(resources)
if err != nil {
return fmt.Errorf("%v %s", err, string(output))
}
// update the original ResMap based on the output
return utils.UpdateResMapValues(p.pluginName, p.h, output, rm)
}
func injectAnnotation(input *yaml.RNode, k, v string) error {
err := input.PipeE(yaml.SetAnnotation(k, v))
if err != nil {
return err
}
return nil
}
// invokePlugin uses Function runner to run function as plugin
func (p *FnPlugin) invokePlugin(input []byte) ([]byte, error) {
// get function config rnode
functionConfig, err := bytesToRNode(p.cfg)
if err != nil {
return nil, err
}
// This annotation will let kustomize ingnore this item in output
err = injectAnnotation(functionConfig, "config.kubernetes.io/local-config", "true")
if err != nil {
return nil, err
}
// we need to add config as input for generators. Some of them don't work with FunctionConfig
// and in addition kio.Pipeline won't create anything if there are no objects
// see https://github.com/kubernetes-sigs/kustomize/blob/master/kyaml/kio/kio.go#L93
// Since we added `local-config` annotation so it will be ignored in generator output
// TODO(donnyxia): This is actually not used by generator and only used to bypass a kio limitation.
// Need better solution.
if input == nil {
yaml, err := functionConfig.String()
if err != nil {
return nil, err
}
input = []byte(yaml)
}
// Configure and Execute Fn. We don't need to convert resources to ResourceList here
// because function runtime will do that. See kyaml/fn/runtime/runtimeutil/runtimeutil.go
var ouputBuffer bytes.Buffer
p.runFns.Input = bytes.NewReader(input)
p.runFns.Functions = append(p.runFns.Functions, functionConfig)
p.runFns.Output = &ouputBuffer
err = p.runFns.Execute()
if err != nil {
return nil, errors.Wrap(
err, "couldn't execute function")
}
return ouputBuffer.Bytes(), nil
}

View File

@@ -16,7 +16,6 @@ import (
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers"
"sigs.k8s.io/kustomize/api/internal/plugins/execplugin"
"sigs.k8s.io/kustomize/api/internal/plugins/fnplugin"
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/resid"
@@ -117,7 +116,7 @@ func (l *Loader) loadAndConfigurePlugin(
if isBuiltinPlugin(res) {
switch l.pc.BpLoadingOptions {
case types.BploLoadFromFileSys:
c, err = l.loadPlugin(res)
c, err = l.loadPlugin(res.OrgId())
case types.BploUseStaticallyLinked:
// Instead of looking for and loading a .so file,
// instantiate the plugin from a generated factory
@@ -132,7 +131,7 @@ func (l *Loader) loadAndConfigurePlugin(
} else {
switch l.pc.PluginRestrictions {
case types.PluginRestrictionsNone:
c, err = l.loadPlugin(res)
c, err = l.loadPlugin(res.OrgId())
case types.PluginRestrictionsBuiltinsOnly:
err = types.NewErrOnlyBuiltinPluginsAllowed(res.OrgId().Kind)
default:
@@ -167,15 +166,7 @@ func (l *Loader) makeBuiltinPlugin(r resid.Gvk) (resmap.Configurable, error) {
return nil, errors.Errorf("unable to load builtin %s", r)
}
func (l *Loader) loadPlugin(res *resource.Resource) (resmap.Configurable, error) {
spec := fnplugin.GetFunctionSpec(res)
if spec != nil {
return fnplugin.NewFnPlugin(&l.pc.FnpLoadingOptions), nil
}
return l.loadExecOrGoPlugin(res.OrgId())
}
func (l *Loader) loadExecOrGoPlugin(resId resid.ResId) (resmap.Configurable, error) {
func (l *Loader) loadPlugin(resId resid.ResId) (resmap.Configurable, error) {
// First try to load the plugin as an executable.
p := execplugin.NewExecPlugin(l.absolutePluginPath(resId))
err := p.ErrIfNotExecutable()

View File

@@ -4,25 +4,13 @@
package utils
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strconv"
"time"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/yaml"
)
const (
idAnnotation = "kustomize.config.k8s.io/id"
HashAnnotation = "kustomize.config.k8s.io/needs-hash"
BehaviorAnnotation = "kustomize.config.k8s.io/behavior"
)
func GoBin() string {
@@ -125,91 +113,3 @@ func FileExists(path string) bool {
}
return true
}
// GetResMapWithIDAnnotation returns a new copy of the given ResMap with the ResIds annotated in each Resource
func GetResMapWithIDAnnotation(rm resmap.ResMap) (resmap.ResMap, error) {
inputRM := rm.DeepCopy()
for _, r := range inputRM.Resources() {
idString, err := yaml.Marshal(r.CurId())
if err != nil {
return nil, err
}
annotations := r.GetAnnotations()
if annotations == nil {
annotations = make(map[string]string)
}
annotations[idAnnotation] = string(idString)
r.SetAnnotations(annotations)
}
return inputRM, nil
}
// UpdateResMapValues updates the Resource value in the given ResMap
// with the emitted Resource values in output.
func UpdateResMapValues(pluginName string, h *resmap.PluginHelpers, output []byte, rm resmap.ResMap) error {
outputRM, err := h.ResmapFactory().NewResMapFromBytes(output)
if err != nil {
return err
}
for _, r := range outputRM.Resources() {
// for each emitted Resource, find the matching Resource in the original ResMap
// using its id
annotations := r.GetAnnotations()
idString, ok := annotations[idAnnotation]
if !ok {
return fmt.Errorf("the transformer %s should not remove annotation %s",
pluginName, idAnnotation)
}
id := resid.ResId{}
err := yaml.Unmarshal([]byte(idString), &id)
if err != nil {
return err
}
res, err := rm.GetByCurrentId(id)
if err != nil {
return fmt.Errorf("unable to find unique match to %s", id.String())
}
// remove the annotation set by Kustomize to track the resource
delete(annotations, idAnnotation)
if len(annotations) == 0 {
annotations = nil
}
r.SetAnnotations(annotations)
// update the resource value with the transformed object
res.ResetPrimaryData(r)
}
return nil
}
// UpdateResourceOptions updates the generator options for each resource in the
// given ResMap based on plugin provided annotations.
func UpdateResourceOptions(rm resmap.ResMap) (resmap.ResMap, error) {
for _, r := range rm.Resources() {
// Disable name hashing by default and require plugin to explicitly
// request it for each resource.
annotations := r.GetAnnotations()
behavior := annotations[BehaviorAnnotation]
var needsHash bool
if val, ok := annotations[HashAnnotation]; ok {
b, err := strconv.ParseBool(val)
if err != nil {
return nil, fmt.Errorf(
"the annotation %q contains an invalid value (%q)",
HashAnnotation, val)
}
needsHash = b
}
delete(annotations, HashAnnotation)
delete(annotations, BehaviorAnnotation)
if len(annotations) == 0 {
annotations = nil
}
r.SetAnnotations(annotations)
r.SetOptions(types.NewGenArgs(
&types.GeneratorArgs{
Behavior: behavior,
Options: &types.GeneratorOptions{DisableNameSuffixHash: !needsHash}}))
}
return rm, nil
}

View File

@@ -4,17 +4,12 @@
package utils
import (
"fmt"
"path/filepath"
"strings"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
)
func TestDeterminePluginSrcRoot(t *testing.T) {
@@ -29,99 +24,3 @@ func TestDeterminePluginSrcRoot(t *testing.T) {
t.Errorf("expected suffix '%s' in '%s'", konfig.RelPluginHome, actual)
}
}
func makeConfigMap(rf *resource.Factory, name, behavior string, hashValue *string) *resource.Resource {
r := rf.FromMap(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{"name": name},
})
annotations := map[string]string{}
if behavior != "" {
annotations[BehaviorAnnotation] = behavior
}
if hashValue != nil {
annotations[HashAnnotation] = *hashValue
}
if len(annotations) > 0 {
r.SetAnnotations(annotations)
}
return r
}
func makeConfigMapOptions(rf *resource.Factory, name, behavior string, disableHash bool) *resource.Resource {
return rf.FromMapAndOption(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{"name": name},
}, &types.GeneratorArgs{
Behavior: behavior,
Options: &types.GeneratorOptions{DisableNameSuffixHash: disableHash}})
}
func strptr(s string) *string {
return &s
}
func TestUpdateResourceOptions(t *testing.T) {
rf := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
in := resmap.New()
expected := resmap.New()
cases := []struct {
behavior string
needsHash bool
hashValue *string
}{
{hashValue: strptr("false")},
{hashValue: strptr("true"), needsHash: true},
{behavior: "replace"},
{behavior: "merge"},
{behavior: "create"},
{behavior: "nonsense"},
{behavior: "merge", hashValue: strptr("false")},
{behavior: "merge", hashValue: strptr("true"), needsHash: true},
}
for i, c := range cases {
name := fmt.Sprintf("test%d", i)
in.Append(makeConfigMap(rf, name, c.behavior, c.hashValue))
expected.Append(makeConfigMapOptions(rf, name, c.behavior, !c.needsHash))
}
actual, err := UpdateResourceOptions(in)
if err != nil {
t.Fatalf("unexpected error: %v", err.Error())
}
for i, a := range expected.Resources() {
b := actual.GetByIndex(i)
if b == nil {
t.Fatalf("resource %d missing from processed map", i)
}
if !a.Equals(b) {
t.Errorf("expected %v got %v", a, b)
}
if a.NeedHashSuffix() != b.NeedHashSuffix() {
t.Errorf("")
}
if a.Behavior() != b.Behavior() {
t.Errorf("expected %v got %v", a.Behavior(), b.Behavior())
}
}
}
func TestUpdateResourceOptionsWithInvalidHashAnnotationValues(t *testing.T) {
rf := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
cases := []string{
"",
"FaLsE",
"TrUe",
"potato",
}
for i, c := range cases {
name := fmt.Sprintf("test%d", i)
in := resmap.New()
in.Append(makeConfigMap(rf, name, "", &c))
_, err := UpdateResourceOptions(in)
if err == nil {
t.Errorf("expected error from value %q", c)
}
}
}

View File

@@ -166,21 +166,11 @@ func (kt *KustTarget) addHashesToNames(
// not yet fixed.
func (kt *KustTarget) AccumulateTarget() (
ra *accumulator.ResAccumulator, err error) {
return kt.accumulateTarget(accumulator.MakeEmptyAccumulator())
}
// ra should be empty when this KustTarget is a Kustomization, or the ra of the parent if this KustTarget is a Component
// (or empty if the Component does not have a parent).
func (kt *KustTarget) accumulateTarget(ra *accumulator.ResAccumulator) (
resRa *accumulator.ResAccumulator, err error) {
ra, err = kt.accumulateResources(ra, kt.kustomization.Resources)
ra = accumulator.MakeEmptyAccumulator()
err = kt.accumulateResources(ra, kt.kustomization.Resources)
if err != nil {
return nil, errors.Wrap(err, "accumulating resources")
}
ra, err = kt.accumulateComponents(ra, kt.kustomization.Components)
if err != nil {
return nil, errors.Wrap(err, "accumulating components")
}
tConfig, err := builtinconfig.MakeTransformerConfig(
kt.ldr, kt.kustomization.Configurations)
if err != nil {
@@ -209,10 +199,6 @@ func (kt *KustTarget) accumulateTarget(ra *accumulator.ResAccumulator) (
if err != nil {
return nil, err
}
err = kt.runValidators(ra)
if err != nil {
return nil, err
}
err = ra.MergeVars(kt.kustomization.Vars)
if err != nil {
return nil, errors.Wrapf(
@@ -249,7 +235,7 @@ func (kt *KustTarget) runGenerators(
func (kt *KustTarget) configureExternalGenerators() ([]resmap.Generator, error) {
ra := accumulator.MakeEmptyAccumulator()
ra, err := kt.accumulateResources(ra, kt.kustomization.Generators)
err := kt.accumulateResources(ra, kt.kustomization.Generators)
if err != nil {
return nil, err
}
@@ -264,7 +250,7 @@ func (kt *KustTarget) runTransformers(ra *accumulator.ResAccumulator) error {
return err
}
r = append(r, lts...)
lts, err = kt.configureExternalTransformers(kt.kustomization.Transformers)
lts, err = kt.configureExternalTransformers()
if err != nil {
return err
}
@@ -273,132 +259,56 @@ func (kt *KustTarget) runTransformers(ra *accumulator.ResAccumulator) error {
return ra.Transform(t)
}
func (kt *KustTarget) configureExternalTransformers(transformers []string) ([]resmap.Transformer, error) {
func (kt *KustTarget) configureExternalTransformers() ([]resmap.Transformer, error) {
ra := accumulator.MakeEmptyAccumulator()
ra, err := kt.accumulateResources(ra, transformers)
err := kt.accumulateResources(ra, kt.kustomization.Transformers)
if err != nil {
return nil, err
}
return kt.pLdr.LoadTransformers(kt.ldr, kt.validator, ra.ResMap())
}
func (kt *KustTarget) runValidators(ra *accumulator.ResAccumulator) error {
validators, err := kt.configureExternalTransformers(kt.kustomization.Validators)
if err != nil {
return err
}
for _, v := range validators {
// Validators shouldn't modify the resource map
orignal := ra.ResMap().DeepCopy()
err = v.Transform(ra.ResMap())
if err != nil {
return err
}
new := ra.ResMap().DeepCopy()
kt.removeValidatedByLabel(new)
if err = orignal.ErrorIfNotEqualSets(new); err != nil {
return fmt.Errorf("validator shouldn't modify the resource map: %v", err)
}
}
return nil
}
func (kt *KustTarget) removeValidatedByLabel(rm resmap.ResMap) {
resources := rm.Resources()
for _, r := range resources {
labels := r.GetLabels()
if _, found := labels[konfig.ValidatedByLabelKey]; !found {
continue
}
delete(labels, konfig.ValidatedByLabelKey)
if len(labels) == 0 {
r.SetLabels(nil)
} else {
r.SetLabels(labels)
}
}
}
// accumulateResources fills the given resourceAccumulator
// with resources read from the given list of paths.
func (kt *KustTarget) accumulateResources(
ra *accumulator.ResAccumulator, paths []string) (*accumulator.ResAccumulator, error) {
ra *accumulator.ResAccumulator, paths []string) error {
for _, path := range paths {
// try loading resource as file then as base (directory or git repository)
if errF := kt.accumulateFile(ra, path); errF != nil {
ldr, errL := kt.ldr.New(path)
if errL != nil {
return nil, fmt.Errorf("accumulateFile %q, loader.New %q", errF, errL)
return fmt.Errorf("accumulateFile %q, loader.New %q", errF, errL)
}
var errD error
ra, errD = kt.accumulateDirectory(ra, ldr, false)
errD := kt.accumulateDirectory(ra, ldr)
if errD != nil {
return nil, fmt.Errorf("accumulateFile %q, accumulateDirector: %q", errF, errD)
return fmt.Errorf("accumulateFile %q, accumulateDirector: %q", errF, errD)
}
}
}
return ra, nil
}
// accumulateResources fills the given resourceAccumulator
// with resources read from the given list of paths.
func (kt *KustTarget) accumulateComponents(
ra *accumulator.ResAccumulator, paths []string) (*accumulator.ResAccumulator, error) {
for _, path := range paths {
// Components always refer to directories
ldr, errL := kt.ldr.New(path)
if errL != nil {
return nil, fmt.Errorf("loader.New %q", errL)
}
var errD error
ra, errD = kt.accumulateDirectory(ra, ldr, true)
if errD != nil {
return nil, fmt.Errorf("accumulateDirectory: %q", errD)
}
}
return ra, nil
return nil
}
func (kt *KustTarget) accumulateDirectory(
ra *accumulator.ResAccumulator, ldr ifc.Loader, isComponent bool) (*accumulator.ResAccumulator, error) {
ra *accumulator.ResAccumulator, ldr ifc.Loader) error {
defer ldr.Cleanup()
subKt := NewKustTarget(
ldr, kt.validator, kt.rFactory, kt.tFactory, kt.pLdr)
err := subKt.Load()
if err != nil {
return nil, errors.Wrapf(
return errors.Wrapf(
err, "couldn't make target for path '%s'", ldr.Root())
}
if isComponent && subKt.kustomization.Kind != types.ComponentKind {
return nil, fmt.Errorf(
"expected kind '%s' for path '%s' but got '%s'", types.ComponentKind, ldr.Root(), subKt.kustomization.Kind)
} else if !isComponent && subKt.kustomization.Kind == types.ComponentKind {
return nil, fmt.Errorf(
"expected kind != '%s' for path '%s'", types.ComponentKind, ldr.Root())
}
var subRa *accumulator.ResAccumulator
if isComponent {
// Components don't create a new accumulator: the kustomization directives are added to the current accumulator
subRa, err = subKt.accumulateTarget(ra)
ra = accumulator.MakeEmptyAccumulator()
} else {
// Child Kustomizations create a new accumulator which resolves their kustomization directives, which will later
// be merged into the current accumulator.
subRa, err = subKt.AccumulateTarget()
}
subRa, err := subKt.AccumulateTarget()
if err != nil {
return nil, errors.Wrapf(
return errors.Wrapf(
err, "recursed accumulation of path '%s'", ldr.Root())
}
err = ra.MergeAccumulator(subRa)
if err != nil {
return nil, errors.Wrapf(
return errors.Wrapf(
err, "recursed merging from path '%s'", ldr.Root())
}
return ra, nil
return nil
}
func (kt *KustTarget) accumulateFile(

View File

@@ -21,11 +21,6 @@ nameReference:
- path: spec/scaleTargetRef/name
kind: HorizontalPodAutoscaler
- kind: StatefulSet
fieldSpecs:
- path: spec/scaleTargetRef/name
kind: HorizontalPodAutoscaler
- kind: ConfigMap
version: v1
fieldSpecs:
@@ -252,10 +247,6 @@ nameReference:
kind: Role
- path: rules/resourceNames
kind: ClusterRole
- path: spec/template/spec/containers/env/valueFrom/secretKeyRef/name
kind: Service
group: serving.knative.dev
version: v1
- kind: Service
version: v1

View File

@@ -30,13 +30,4 @@ const (
// A program name, for use in help, finding the XDG_CONFIG_DIR, etc.
ProgramName = "kustomize"
// Label key that indicates the resources are built from Kustomize
ManagedbyLabelKey = "app.kubernetes.io/managed-by"
// An environment variable to turn on/off adding the ManagedByLabelKey
EnableManagedbyLabelEnv = "KUSTOMIZE_ENABLE_MANAGEDBY_LABEL"
// Label key that indicates the resources are validated by a validator
ValidatedByLabelKey = "validated-by"
)

View File

@@ -292,7 +292,8 @@ metadata:
---
apiVersion: v1
data:
nonsense: "Lorem ipsum dolor sit amet, consectetur\nadipiscing elit, sed do eiusmod tempor\nincididunt ut labore et dolore magna aliqua. \n"
nonsense: "Lorem ipsum dolor sit amet, consectetur\nadipiscing elit, sed do eiusmod
tempor\nincididunt ut labore et dolore magna aliqua. \n"
kind: ConfigMap
metadata:
annotations:

View File

@@ -132,54 +132,6 @@ spec:
`)
}
func TestTinyOverlay(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("base", `
namePrefix: a-
resources:
- deployment.yaml
`)
th.WriteF("base/deployment.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeployment
spec:
template:
spec:
containers:
- image: whatever
`)
th.WriteK("overlay", `
namePrefix: b-
resources:
- ../base
patchesStrategicMerge:
- depPatch.yaml
`)
th.WriteF("overlay/depPatch.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeployment
spec:
replicas: 999
`)
m := th.Run("overlay", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: b-a-myDeployment
spec:
replicas: 999
template:
spec:
containers:
- image: whatever
`)
}
func writeSmallBase(th kusttest_test.Harness) {
th.WriteK("/app/base", `
namePrefix: a-

View File

@@ -1,670 +0,0 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package krusty_test
import (
"fmt"
"strings"
"testing"
"sigs.k8s.io/kustomize/api/konfig"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
type FileGen func(kusttest_test.Harness)
func writeC(path string, content string) FileGen {
return func(th kusttest_test.Harness) {
th.WriteC(path, content)
}
}
func writeF(path string, content string) FileGen {
return func(th kusttest_test.Harness) {
th.WriteF(path, content)
}
}
func writeK(path string, content string) FileGen {
return func(th kusttest_test.Harness) {
th.WriteK(path, content)
}
}
func writeTestBase(th kusttest_test.Harness) {
th.WriteK("/app/base", `
resources:
- deploy.yaml
configMapGenerator:
- name: my-configmap
literals:
- testValue=1
- otherValue=10
`)
th.WriteF("/app/base/deploy.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: storefront
spec:
replicas: 1
`)
}
func writeTestComponent(th kusttest_test.Harness) {
th.WriteC("/app/comp", `
namePrefix: comp-
replicas:
- name: storefront
count: 3
resources:
- stub.yaml
configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- testValue=2
- compValue=5
`)
th.WriteF("/app/comp/stub.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: stub
spec:
replicas: 1
`)
}
func writeOverlayProd(th kusttest_test.Harness) {
th.WriteK("/app/prod", `
resources:
- ../base
- db
components:
- ../comp
`)
writeDB(th)
}
func writeDB(th kusttest_test.Harness) {
deployment("db", "/app/prod/db")(th)
}
func deployment(name string, path string) FileGen {
return writeF(path, fmt.Sprintf(`
apiVersion: v1
kind: Deployment
metadata:
name: %s
spec:
type: Logical
`, name))
}
func TestComponent(t *testing.T) {
testCases := map[string]struct {
input []FileGen
runPath string
expectedOutput string
}{
// Components are inserted into the resource hierarchy as the parent of those
// resources that come before it in the resources list of the parent Kustomization.
"basic-component": {
input: []FileGen{writeTestBase, writeTestComponent, writeOverlayProd},
runPath: "/app/prod",
expectedOutput: `
apiVersion: v1
kind: Deployment
metadata:
name: comp-storefront
spec:
replicas: 3
---
apiVersion: v1
data:
compValue: "5"
otherValue: "10"
testValue: "2"
kind: ConfigMap
metadata:
annotations: {}
labels: {}
name: comp-my-configmap-ct5bgtbccd
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-db
spec:
type: Logical
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-stub
spec:
replicas: 1
`,
},
"multiple-components": {
input: []FileGen{writeTestBase, writeTestComponent, writeDB,
writeC("/app/additionalcomp", `
configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- otherValue=9
`),
writeK("/app/prod", `
resources:
- ../base
- db
components:
- ../comp
- ../additionalcomp
`),
},
runPath: "/app/prod",
expectedOutput: `
apiVersion: v1
kind: Deployment
metadata:
name: comp-storefront
spec:
replicas: 3
---
apiVersion: v1
data:
compValue: "5"
otherValue: "9"
testValue: "2"
kind: ConfigMap
metadata:
annotations: {}
labels: {}
name: comp-my-configmap-dgf97tmg6h
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-db
spec:
type: Logical
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-stub
spec:
replicas: 1
`,
},
"nested-components": {
input: []FileGen{writeTestBase, writeTestComponent, writeDB,
writeC("/app/additionalcomp", `
components:
- ../comp
configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- otherValue=9
`),
writeK("/app/prod", `
resources:
- ../base
- db
components:
- ../additionalcomp
`),
},
runPath: "/app/prod",
expectedOutput: `
apiVersion: v1
kind: Deployment
metadata:
name: comp-storefront
spec:
replicas: 3
---
apiVersion: v1
data:
compValue: "5"
otherValue: "9"
testValue: "2"
kind: ConfigMap
metadata:
annotations: {}
labels: {}
name: comp-my-configmap-dgf97tmg6h
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-db
spec:
type: Logical
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-stub
spec:
replicas: 1
`,
},
// If a component sets a name prefix on a base, then that base can also be separately included
// without being affected by the component in another branch of the resource tree
"basic-component-with-repeated-base": {
input: []FileGen{writeTestBase, writeTestComponent, writeOverlayProd,
writeK("/app/repeated", `
resources:
- ../base
- ../prod
`),
},
runPath: "/app/repeated",
expectedOutput: `
apiVersion: v1
kind: Deployment
metadata:
name: storefront
spec:
replicas: 1
---
apiVersion: v1
data:
otherValue: "10"
testValue: "1"
kind: ConfigMap
metadata:
name: my-configmap-7k9t4h74f8
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-storefront
spec:
replicas: 3
---
apiVersion: v1
data:
compValue: "5"
otherValue: "10"
testValue: "2"
kind: ConfigMap
metadata:
annotations: {}
labels: {}
name: comp-my-configmap-ct5bgtbccd
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-db
spec:
type: Logical
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-stub
spec:
replicas: 1
`,
},
"applying-component-directly-should-be-same-as-kustomization": {
input: []FileGen{writeTestBase, writeTestComponent,
writeC("/app/direct-component", `
resources:
- ../base
configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- compValue=5
- testValue=2
`),
},
runPath: "/app/direct-component",
expectedOutput: `
apiVersion: v1
kind: Deployment
metadata:
name: storefront
spec:
replicas: 1
---
apiVersion: v1
data:
compValue: "5"
otherValue: "10"
testValue: "2"
kind: ConfigMap
metadata:
annotations: {}
labels: {}
name: my-configmap-96dt22k28h
`,
},
"missing-optional-component-api-version": {
input: []FileGen{writeTestBase, writeOverlayProd,
writeF("/app/comp/"+konfig.DefaultKustomizationFileName(), `
kind: Component
configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- otherValue=9
`),
},
runPath: "/app/prod",
expectedOutput: `
apiVersion: v1
kind: Deployment
metadata:
name: storefront
spec:
replicas: 1
---
apiVersion: v1
data:
otherValue: "9"
testValue: "1"
kind: ConfigMap
metadata:
annotations: {}
labels: {}
name: my-configmap-72cfg2mg5d
---
apiVersion: v1
kind: Deployment
metadata:
name: db
spec:
type: Logical
`,
},
// See how nameSuffix "-b" is also added to the resources included by "comp-a" because they are in the
// accumulator when "comp-b" is accumulated. In practice we could use simple Kustomizations for this example.
"components-can-add-the-same-base-if-the-first-renames-resources": {
input: []FileGen{writeTestBase,
deployment("proxy", "/app/comp-a/proxy.yaml"),
writeC("/app/comp-a", `
resources:
- ../base
nameSuffix: "-a"
`),
writeC("/app/comp-b", `
resources:
- ../base
nameSuffix: "-b"
`),
writeK("/app/prod", `
components:
- ../comp-a
- ../comp-b`),
},
runPath: "/app/prod",
expectedOutput: `
apiVersion: v1
kind: Deployment
metadata:
name: storefront-a-b
spec:
replicas: 1
---
apiVersion: v1
data:
otherValue: "10"
testValue: "1"
kind: ConfigMap
metadata:
name: my-configmap-a-b-tfb7c5t69m
---
apiVersion: v1
kind: Deployment
metadata:
name: storefront-b
spec:
replicas: 1
---
apiVersion: v1
data:
otherValue: "10"
testValue: "1"
kind: ConfigMap
metadata:
name: my-configmap-b-8h7b8862bb
`,
},
"multiple-bases-can-add-the-same-component-if-it-doesn-not-define-named-entities": {
input: []FileGen{
writeC("/app/comp", `
namespace: prod
`),
writeK("/app/base-a", `
resources:
- proxy.yaml
components:
- ../comp
`),
deployment("proxy-a", "/app/base-a/proxy.yaml"),
writeK("/app/base-b", `
resources:
- proxy.yaml
components:
- ../comp
`),
deployment("proxy-b", "/app/base-b/proxy.yaml"),
writeK("/app/prod", `
resources:
- proxy.yaml
- ../base-a
- ../base-b
`),
deployment("proxy-prod", "/app/prod/proxy.yaml"),
},
runPath: "/app/prod",
// Note that the namepsace has not been applied to proxy-prod because it was not in scope when the
// component was applied
expectedOutput: `
apiVersion: v1
kind: Deployment
metadata:
name: proxy-prod
spec:
type: Logical
---
apiVersion: v1
kind: Deployment
metadata:
name: proxy-a
namespace: prod
spec:
type: Logical
---
apiVersion: v1
kind: Deployment
metadata:
name: proxy-b
namespace: prod
spec:
type: Logical
`,
},
}
for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {
th := kusttest_test.MakeHarness(t)
for _, f := range tc.input {
f(th)
}
m := th.Run(tc.runPath, th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, tc.expectedOutput)
})
}
}
func TestComponentErrors(t *testing.T) {
testCases := map[string]struct {
input []FileGen
runPath string
expectedError string
}{
"components-cannot-be-added-to-resources": {
input: []FileGen{writeTestBase, writeTestComponent,
writeK("/app/compinres", `
resources:
- ../base
- ../comp
`),
},
runPath: "app/compinres",
expectedError: "expected kind != 'Component' for path '/app/comp'",
},
"kustomizations-cannot-be-added-to-components": {
input: []FileGen{writeTestBase, writeTestComponent,
writeK("/app/kustincomponents", `
components:
- ../base
- ../comp
`),
},
runPath: "/app/kustincomponents",
expectedError: "accumulating components: accumulateDirectory: \"expected kind 'Component' for path " +
"'/app/base' but got 'Kustomization'",
},
"files-cannot-be-added-to-components-list": {
input: []FileGen{writeTestBase,
writeF("/app/filesincomponents/stub.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: stub
spec:
replicas: 1
`),
writeK("/app/filesincomponents", `
components:
- stub.yaml
- ../comp
`),
},
runPath: "/app/filesincomponents",
expectedError: "'/app/filesincomponents/stub.yaml' must be a directory to be a root",
},
"invalid-component-api-version": {
input: []FileGen{writeTestBase, writeOverlayProd,
writeF("/app/comp/"+konfig.DefaultKustomizationFileName(), `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Component
configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- otherValue=9
`),
},
runPath: "/app/prod",
expectedError: "apiVersion for Component should be kustomize.config.k8s.io/v1alpha1",
},
"components-cannot-add-the-same-resource": {
input: []FileGen{writeTestBase,
writeC("/app/comp-a", `
resources:
- proxy.yaml
`),
deployment("proxy", "/app/comp-a/proxy.yaml"),
writeC("/app/comp-b", `
resources:
- proxy.yaml
`),
deployment("proxy", "/app/comp-b/proxy.yaml"),
writeK("/app/prod", `
resources:
- ../base
components:
- ../comp-a
- ../comp-b`),
},
runPath: "/app/prod",
expectedError: "may not add resource with an already registered id: ~G_v1_Deployment|~X|proxy",
},
"components-cannot-add-the-same-base": {
input: []FileGen{writeTestBase,
deployment("proxy", "/app/comp-a/proxy.yaml"),
writeC("/app/comp-a", `
resources:
- ../base
`),
writeC("/app/comp-b", `
resources:
- ../base
`),
writeK("/app/prod", `
components:
- ../comp-a
- ../comp-b`),
},
runPath: "/app/prod",
expectedError: "may not add resource with an already registered id: ~G_v1_Deployment|~X|storefront",
},
"components-cannot-add-bases-containing-the-same-resource": {
input: []FileGen{writeTestBase,
writeC("/app/comp-a", `
resources:
- ../base-a
`),
writeK("/app/base-a", `
resources:
- proxy.yaml
`),
deployment("proxy", "/app/base-a/proxy.yaml"),
writeC("/app/comp-b", `
resources:
- ../base-b
`),
writeK("/app/base-b", `
resources:
- proxy.yaml
`),
deployment("proxy", "/app/base-b/proxy.yaml"),
writeK("/app/prod", `
resources:
- ../base
components:
- ../comp-a
- ../comp-b`),
},
runPath: "/app/prod",
expectedError: "may not add resource with an already registered id: ~G_v1_Deployment|~X|proxy",
},
}
for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {
th := kusttest_test.MakeHarness(t)
for _, f := range tc.input {
f(th)
}
err := th.RunWithErr(tc.runPath, th.MakeDefaultOptions())
if err == nil || !strings.Contains(err.Error(), tc.expectedError) {
t.Fatalf("unexpected error: %s", err)
}
})
}
}

View File

@@ -85,7 +85,8 @@ metadata:
---
apiVersion: v1
data:
druid_segmentCache_locations: '[{"path": "var/druid/segment-cache", "maxSize": 32000000000, "freeSpacePercent": 1.0}]'
druid_segmentCache_locations: '[{"path": "var/druid/segment-cache", "maxSize":
32000000000, "freeSpacePercent": 1.0}]'
v2: '[{"path": "var/druid/segment-cache"}]'
kind: ConfigMap
metadata:

View File

@@ -11,7 +11,7 @@ import (
func makeCommonFileForExtendedPatchTest(th kusttest_test.Harness) {
th.WriteF("/app/base/deployment.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: nginx
@@ -36,7 +36,7 @@ spec:
name: configmap-in-base
name: configmap-in-base
---
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: busybox
@@ -101,7 +101,7 @@ patches:
name: busybox
`)
th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: busybox
@@ -110,7 +110,7 @@ metadata:
`)
m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
@@ -135,7 +135,7 @@ spec:
name: configmap-in-base
name: configmap-in-base
---
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
annotations:
@@ -203,7 +203,7 @@ patches:
kind: Deployment
`)
th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: busybox
@@ -212,7 +212,7 @@ metadata:
`)
m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
annotations:
@@ -239,7 +239,7 @@ spec:
name: configmap-in-base
name: configmap-in-base
---
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
annotations:
@@ -305,7 +305,7 @@ patches:
labelSelector: app=nginx
`)
th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: nginx
@@ -314,7 +314,7 @@ metadata:
`)
m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
annotations:
@@ -341,7 +341,7 @@ spec:
name: configmap-in-base
name: configmap-in-base
---
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
@@ -408,7 +408,7 @@ patches:
kind: Deployment
`)
th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: busybox
@@ -417,7 +417,7 @@ metadata:
`)
m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
@@ -442,7 +442,7 @@ spec:
name: configmap-in-base
name: configmap-in-base
---
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
annotations:
@@ -509,7 +509,7 @@ patches:
labelSelector: app=busybox
`)
th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: busybox
@@ -518,7 +518,7 @@ metadata:
`)
m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
@@ -543,7 +543,7 @@ spec:
name: configmap-in-base
name: configmap-in-base
---
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
annotations:
@@ -612,7 +612,7 @@ patches:
labelSelector: app=busybox
`)
th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: busybox
@@ -621,7 +621,7 @@ metadata:
`)
m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
@@ -646,7 +646,7 @@ spec:
name: configmap-in-base
name: configmap-in-base
---
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
annotations:
@@ -714,7 +714,7 @@ patches:
labelSelector: app=busybox
`)
th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: busybox
@@ -723,7 +723,7 @@ metadata:
`)
m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
@@ -748,7 +748,7 @@ spec:
name: configmap-in-base
name: configmap-in-base
---
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
annotations:
@@ -814,7 +814,7 @@ patches:
name: no-match
`)
th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: busybox
@@ -823,7 +823,7 @@ metadata:
`)
m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
@@ -848,7 +848,7 @@ spec:
name: configmap-in-base
name: configmap-in-base
---
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
@@ -910,7 +910,7 @@ patches:
- path: patch.yaml
`)
th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: busybox
@@ -919,7 +919,7 @@ metadata:
`)
m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
@@ -944,7 +944,7 @@ spec:
name: configmap-in-base
name: configmap-in-base
---
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
annotations:
@@ -1014,7 +1014,7 @@ patches:
kind: Job
`)
th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: busybox
@@ -1023,7 +1023,7 @@ metadata:
`)
m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
@@ -1048,7 +1048,7 @@ spec:
name: configmap-in-base
name: configmap-in-base
---
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
@@ -1116,7 +1116,7 @@ patches:
kind: Deployment
`)
th.WriteF("/app/base/patch1.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: busybox
@@ -1124,7 +1124,7 @@ metadata:
new-key-from-patch1: new-value
`)
th.WriteF("/app/base/patch2.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: busybox
@@ -1133,7 +1133,7 @@ metadata:
`)
m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
@@ -1158,7 +1158,7 @@ spec:
name: configmap-in-base
name: configmap-in-base
---
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
annotations:

View File

@@ -1,466 +0,0 @@
package krusty_test
import (
"os/exec"
"testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
func TestFnExecGenerator(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("/app", `
resources:
- short_secret.yaml
generators:
- gener.yaml
`)
// Create some additional resource just to make sure everything is added
th.WriteF("/app/short_secret.yaml", `
apiVersion: v1
kind: Secret
metadata:
labels:
airshipit.org/ephemeral-user-data: "true"
name: node1-bmc-secret
type: Opaque
stringData:
userData: |
bootcmd:
- mkdir /mnt/vda
`)
th.WriteF("/app/gener.yaml", `
kind: executable
metadata:
name: demo
annotations:
config.kubernetes.io/function: |
exec:
path: ./fnplugin_test/fnexectest.sh
spec:
`)
o := th.MakeOptionsPluginsEnabled()
o.PluginConfig.FnpLoadingOptions.EnableExec = true
m := th.Run("/app", o)
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Secret
metadata:
labels:
airshipit.org/ephemeral-user-data: "true"
name: node1-bmc-secret
stringData:
userData: |
bootcmd:
- mkdir /mnt/vda
type: Opaque
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
config.kubernetes.io/path: deployment_nginx.yaml
tshirt-size: small
labels:
app: nginx
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
`)
}
func skipIfNoDocker(t *testing.T) {
if _, err := exec.LookPath("docker"); err != nil {
t.Skip("skipping because docker binary wasn't found in PATH")
}
}
func TestFnContainerGenerator(t *testing.T) {
skipIfNoDocker(t)
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("/app", `
resources:
- short_secret.yaml
generators:
- gener.yaml
`)
// Create generator config
th.WriteF("/app/gener.yaml", `
apiVersion: examples.config.kubernetes.io/v1beta1
kind: CockroachDB
metadata:
name: demo
annotations:
config.kubernetes.io/function: |
container:
image: gcr.io/kustomize-functions/example-cockroachdb:v0.1.0
spec:
replicas: 3
`)
// Create some additional resource just to make sure everything is added
th.WriteF("/app/short_secret.yaml", `
apiVersion: v1
kind: Secret
metadata:
labels:
airshipit.org/ephemeral-user-data: "true"
name: node1-bmc-secret
type: Opaque
stringData:
userData: |
bootcmd:
- mkdir /mnt/vda
`)
m := th.Run("/app", th.MakeOptionsPluginsEnabled())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Secret
metadata:
labels:
airshipit.org/ephemeral-user-data: "true"
name: node1-bmc-secret
stringData:
userData: |
bootcmd:
- mkdir /mnt/vda
type: Opaque
---
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
annotations:
config.kubernetes.io/path: config/demo-budget_poddisruptionbudget.yaml
labels:
app: cockroachdb
name: demo
name: demo-budget
spec:
minAvailable: 67%
selector:
matchLabels:
app: cockroachdb
name: demo
---
apiVersion: v1
kind: Service
metadata:
annotations:
config.kubernetes.io/path: config/demo-public_service.yaml
labels:
app: cockroachdb
name: demo
name: demo-public
spec:
ports:
- name: grpc
port: 26257
targetPort: 26257
- name: http
port: 8080
targetPort: 8080
selector:
app: cockroachdb
name: demo
---
apiVersion: v1
kind: Service
metadata:
annotations:
config.kubernetes.io/path: config/demo_service.yaml
prometheus.io/path: _status/vars
prometheus.io/port: "8080"
prometheus.io/scrape: "true"
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
labels:
app: cockroachdb
name: demo
name: demo
spec:
clusterIP: None
ports:
- name: grpc
port: 26257
targetPort: 26257
- name: http
port: 8080
targetPort: 8080
selector:
app: cockroachdb
name: demo
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
annotations:
config.kubernetes.io/path: config/demo_statefulset.yaml
labels:
app: cockroachdb
name: demo
name: demo
spec:
replicas: 3
selector:
matchLabels:
app: cockroachdb
name: demo
serviceName: demo
template:
metadata:
labels:
app: cockroachdb
name: demo
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- cockroachdb
topologyKey: kubernetes.io/hostname
weight: 100
containers:
- command:
- /bin/bash
- -ecx
- |
# The use of qualified `+"`hostname -f`"+` is crucial:
# Other nodes aren't able to look up the unqualified hostname.
CRARGS=("start" "--logtostderr" "--insecure" "--host" "$(hostname -f)" "--http-host" "0.0.0.0")
# We only want to initialize a new cluster (by omitting the join flag)
# if we're sure that we're the first node (i.e. index 0) and that
# there aren't any other nodes running as part of the cluster that
# this is supposed to be a part of (which indicates that a cluster
# already exists and we should make sure not to create a new one).
# It's fine to run without --join on a restart if there aren't any
# other nodes.
if [ ! "$(hostname)" == "cockroachdb-0" ] || [ -e "/cockroach/cockroach-data/cluster_exists_marker" ]
then
# We don't join cockroachdb in order to avoid a node attempting
# to join itself, which currently doesn't work
# (https://github.com/cockroachdb/cockroach/issues/9625).
CRARGS+=("--join" "cockroachdb-public")
fi
exec /cockroach/cockroach ${CRARGS[*]}
image: cockroachdb/cockroach:v1.1.0
imagePullPolicy: IfNotPresent
name: demo
ports:
- containerPort: 26257
name: grpc
- containerPort: 8080
name: http
volumeMounts:
- mountPath: /cockroach/cockroach-data
name: datadir
initContainers:
- args:
- -on-start=/on-start.sh
- -service=cockroachdb
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: cockroachdb/cockroach-k8s-init:0.1
imagePullPolicy: IfNotPresent
name: bootstrap
volumeMounts:
- mountPath: /cockroach/cockroach-data
name: datadir
terminationGracePeriodSeconds: 60
volumes:
- name: datadir
persistentVolumeClaim:
claimName: datadir
volumeClaimTemplates:
- metadata:
name: datadir
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
`)
}
func TestFnContainerTransformer(t *testing.T) {
skipIfNoDocker(t)
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("/app", `
resources:
- data.yaml
transformers:
- transf1.yaml
- transf2.yaml
`)
th.WriteF("/app/data.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
annotations:
tshirt-size: small # this injects the resource reservations
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
`)
// This transformer should add resource reservations based on annotation in data.yaml
// See https://github.com/kubernetes-sigs/kustomize/tree/master/functions/examples/injection-tshirt-sizes
th.WriteF("/app/transf1.yaml", `
apiVersion: examples.config.kubernetes.io/v1beta1
kind: Validator
metadata:
name: valid
annotations:
config.kubernetes.io/function: |-
container:
image: gcr.io/kustomize-functions/example-tshirt:v0.2.0
`)
// This transformer will check resources without and won't do any changes
// See https://github.com/kubernetes-sigs/kustomize/tree/master/functions/examples/validator-kubeval
th.WriteF("/app/transf2.yaml", `
apiVersion: examples.config.kubernetes.io/v1beta1
kind: Kubeval
metadata:
name: validate
annotations:
config.kubernetes.io/function: |
container:
image: gcr.io/kustomize-functions/example-validator-kubeval:v0.1.0
spec:
strict: true
ignoreMissingSchemas: true
# TODO: Update this to use network/volumes features.
# Relevant issues:
# - https://github.com/kubernetes-sigs/kustomize/issues/1901
# - https://github.com/kubernetes-sigs/kustomize/issues/1902
kubernetesVersion: "1.16.0"
schemaLocation: "file:///schemas"
`)
m := th.Run("/app", th.MakeOptionsPluginsEnabled())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
config.kubernetes.io/path: deployment_nginx.yaml
tshirt-size: small
labels:
app: nginx
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
resources:
requests:
cpu: 200m
memory: 50M
`)
}
func TestFnContainerTransformerWithConfig(t *testing.T) {
skipIfNoDocker(t)
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("/app", `
resources:
- data1.yaml
- data2.yaml
transformers:
- label_namespace.yaml
`)
th.WriteF("/app/data1.yaml", `apiVersion: v1
kind: Namespace
metadata:
name: my-namespace
`)
th.WriteF("/app/data2.yaml", `apiVersion: v1
kind: Namespace
metadata:
name: another-namespace
`)
th.WriteF("/app/label_namespace.yaml", `apiVersion: v1
kind: ConfigMap
metadata:
name: label_namespace
annotations:
config.kubernetes.io/function: |-
container:
image: gcr.io/kpt-functions/label-namespace@sha256:4f030738d6d25a207641ca517916431517578bd0eb8d98a8bde04e3bb9315dcd
data:
label_name: my-ns-name
label_value: function-test
`)
m := th.Run("/app", th.MakeOptionsPluginsEnabled())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Namespace
metadata:
annotations:
config.kubernetes.io/path: namespace_my-namespace.yaml
labels:
my-ns-name: function-test
name: my-namespace
---
apiVersion: v1
kind: Namespace
metadata:
annotations:
config.kubernetes.io/path: namespace_another-namespace.yaml
labels:
my-ns-name: function-test
name: another-namespace
`)
}

View File

@@ -1,24 +0,0 @@
#!/bin/sh
cat <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
annotations:
tshirt-size: small # this injects the resource reservations
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
EOF

View File

@@ -56,7 +56,7 @@ spec:
app: nginx
`)
th.WriteF("/app/base/deployment.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: nginx
@@ -92,7 +92,7 @@ spec:
org: example.com
team: foo
---
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
annotations:
@@ -173,7 +173,7 @@ secretGenerator:
- password=somepw
`)
th.WriteF("/app/deployment.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: nginx
@@ -218,7 +218,7 @@ func TestBaseWithGeneratorsAlone(t *testing.T) {
makeBaseWithGenerators(th)
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
annotations:
@@ -308,7 +308,7 @@ func TestMergeAndReplaceGenerators(t *testing.T) {
th := kusttest_test.MakeHarness(t)
makeBaseWithGenerators(th)
th.WriteF("/overlay/deployment.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: nginx
@@ -351,7 +351,7 @@ secretGenerator:
`)
m := th.Run("/overlay", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
annotations:

View File

@@ -4,8 +4,6 @@
package krusty
import (
"fmt"
"sigs.k8s.io/kustomize/api/builtins"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/internal/k8sdeps/transformer"
@@ -13,9 +11,7 @@ import (
"sigs.k8s.io/kustomize/api/internal/target"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/k8sdeps/validator"
"sigs.k8s.io/kustomize/api/konfig"
fLdr "sigs.k8s.io/kustomize/api/loader"
"sigs.k8s.io/kustomize/api/provenance"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
@@ -82,15 +78,5 @@ func (b *Kustomizer) Run(path string) (resmap.ResMap, error) {
if b.options.DoLegacyResourceSort {
builtins.NewLegacyOrderTransformerPlugin().Transform(m)
}
if b.options.AddManagedbyLabel {
t := builtins.LabelTransformerPlugin{
Labels: map[string]string{konfig.ManagedbyLabelKey: fmt.Sprintf("kustomize-%s", provenance.GetProvenance().Version)},
FieldSpecs: []types.FieldSpec{{
Path: "metadata/labels",
CreateIfNotPresent: true,
}},
}
t.Transform(m)
}
return m, nil
}

View File

@@ -1,43 +0,0 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package krusty_test
import (
"testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
func TestAddManagedbyLabel(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("/app/service.yaml", `
apiVersion: v1
kind: Service
metadata:
name: myService
spec:
ports:
- port: 7002
`)
th.WriteK("/app", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- service.yaml
`)
options := th.MakeDefaultOptions()
options.AddManagedbyLabel = true
m := th.Run("/app", options)
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/managed-by: kustomize-v444.333.222
name: myService
spec:
ports:
- port: 7002
`)
}

View File

@@ -10,184 +10,6 @@ import (
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
func TestSimpleMultiplePatches(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("base", `
namePrefix: b-
commonLabels:
team: foo
resources:
- deployment.yaml
- service.yaml
configMapGenerator:
- name: configmap-in-base
literals:
- foo=bar
`)
th.WriteF("base/deployment.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
template:
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: nginx-persistent-storage
mountPath: /tmp/ps
- name: sidecar
image: sidecar:latest
volumes:
- name: nginx-persistent-storage
emptyDir: {}
- configMap:
name: configmap-in-base
name: configmap-in-base
`)
th.WriteF("base/service.yaml", `
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- port: 80
`)
th.WriteK("overlay", `
namePrefix: a-
commonLabels:
env: staging
patchesStrategicMerge:
- deployment-patch1.yaml
- deployment-patch2.yaml
resources:
- ../base
configMapGenerator:
- name: configmap-in-overlay
literals:
- hello=world
`)
th.WriteF("overlay/deployment-patch1.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
template:
spec:
containers:
- name: nginx
image: nginx:latest
env:
- name: ENVKEY
value: ENVVALUE
volumes:
- name: nginx-persistent-storage
emptyDir: null
gcePersistentDisk:
pdName: nginx-persistent-storage
- configMap:
name: configmap-in-overlay
name: configmap-in-overlay
`)
th.WriteF("overlay/deployment-patch2.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
template:
spec:
containers:
- name: nginx
env:
- name: ANOTHERENV
value: FOO
volumes:
- name: nginx-persistent-storage
`)
m := th.Run("overlay", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
env: staging
team: foo
name: a-b-nginx
spec:
selector:
matchLabels:
env: staging
team: foo
template:
metadata:
labels:
env: staging
team: foo
spec:
containers:
- env:
- name: ANOTHERENV
value: FOO
- name: ENVKEY
value: ENVVALUE
image: nginx:latest
name: nginx
volumeMounts:
- mountPath: /tmp/ps
name: nginx-persistent-storage
- image: sidecar:latest
name: sidecar
volumes:
- gcePersistentDisk:
pdName: nginx-persistent-storage
name: nginx-persistent-storage
- configMap:
name: a-configmap-in-overlay-ffm9hf78mc
name: configmap-in-overlay
- configMap:
name: a-b-configmap-in-base-fm96mhk4dt
name: configmap-in-base
---
apiVersion: v1
kind: Service
metadata:
labels:
env: staging
team: foo
name: a-b-nginx
spec:
ports:
- port: 80
selector:
env: staging
team: foo
---
apiVersion: v1
data:
foo: bar
kind: ConfigMap
metadata:
labels:
env: staging
team: foo
name: a-b-configmap-in-base-fm96mhk4dt
---
apiVersion: v1
data:
hello: world
kind: ConfigMap
metadata:
labels:
env: staging
name: a-configmap-in-overlay-ffm9hf78mc
`)
}
func makeCommonFileForMultiplePatchTest(th kusttest_test.Harness) {
th.WriteK("/app/base", `
apiVersion: kustomize.config.k8s.io/v1beta1
@@ -208,7 +30,7 @@ configMapGenerator:
- foo=bar
`)
th.WriteF("/app/base/deployment.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: nginx
@@ -270,7 +92,7 @@ func TestMultiplePatchesNoConflict(t *testing.T) {
th := kusttest_test.MakeHarness(t)
makeCommonFileForMultiplePatchTest(th)
th.WriteF("/app/overlay/staging/deployment-patch1.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: nginx
@@ -293,7 +115,7 @@ spec:
name: configmap-in-overlay
`)
th.WriteF("/app/overlay/staging/deployment-patch2.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: nginx
@@ -310,7 +132,7 @@ spec:
`)
m := th.Run("/app/overlay/staging", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
annotations:
@@ -411,7 +233,7 @@ func TestMultiplePatchesWithConflict(t *testing.T) {
th := kusttest_test.MakeHarness(t)
makeCommonFileForMultiplePatchTest(th)
th.WriteF("/app/overlay/staging/deployment-patch1.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: nginx
@@ -433,7 +255,7 @@ spec:
name: configmap-in-overlay
`)
th.WriteF("/app/overlay/staging/deployment-patch2.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: nginx
@@ -457,7 +279,7 @@ spec:
}
func TestMultiplePatchesWithOnePatchDeleteDirective(t *testing.T) {
additivePatch := `apiVersion: apps/v1
additivePatch := `apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: nginx
@@ -470,7 +292,7 @@ spec:
- name: SOME_NAME
value: somevalue
`
deletePatch := `apiVersion: apps/v1
deletePatch := `apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: nginx
@@ -506,7 +328,7 @@ spec:
th.WriteF("/app/overlay/staging/deployment-patch1.yaml", c.patch1)
th.WriteF("/app/overlay/staging/deployment-patch2.yaml", c.patch2)
m := th.Run("/app/overlay/staging", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `apiVersion: apps/v1
th.AssertActualEqualsExpected(m, `apiVersion: apps/v1beta2
kind: Deployment
metadata:
annotations:
@@ -601,7 +423,7 @@ func TestMultiplePatchesBothWithPatchDeleteDirective(t *testing.T) {
th := kusttest_test.MakeHarness(t)
makeCommonFileForMultiplePatchTest(th)
th.WriteF("/app/overlay/staging/deployment-patch1.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: nginx
@@ -613,7 +435,7 @@ spec:
name: sidecar
`)
th.WriteF("/app/overlay/staging/deployment-patch2.yaml", `
apiVersion: apps/v1
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: nginx

View File

@@ -18,11 +18,6 @@ type Options struct {
// order as specified by the kustomization file(s).
DoLegacyResourceSort bool
// When true, a label
// app.kubernetes.io/managed-by: kustomize-<version>
// is added to all the resources in the build out.
AddManagedbyLabel bool
// Restrictions on what can be loaded from the file system.
// See type definition.
LoadRestrictions types.LoadRestrictions

View File

@@ -844,7 +844,8 @@ spec:
- -namespace=${POD_NAMESPACE}
- -certs-dir=/cockroach-certs
- -type=node
- -addresses=localhost,127.0.0.1,${POD_IP},$(hostname -f),$(hostname -f|cut -f 1-2 -d '.'),dev-base-cockroachdb-public
- -addresses=localhost,127.0.0.1,${POD_IP},$(hostname -f),$(hostname -f|cut
-f 1-2 -d '.'),dev-base-cockroachdb-public
- -symlink-ca-from=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
env:
- name: POD_IP

View File

@@ -532,7 +532,7 @@ func (m *resWrangler) ErrorIfNotEqualSets(other ResMap) error {
for _, r1 := range m.rList {
id := r1.CurId()
others := m2.GetMatchingResourcesByCurrentId(id.Equals)
if len(others) == 0 {
if len(others) < 0 {
return fmt.Errorf(
"id in self missing from other; id: %s", id)
}

View File

@@ -669,12 +669,7 @@ func TestErrorIfNotEqualSets(t *testing.T) {
t.Fatalf("%v should not equal %v %v", m1, m2, err)
}
m3 := resmaptest_test.NewRmBuilder(t, rf).AddR(r2).ResMap()
if err := m2.ErrorIfNotEqualSets(m3); err == nil {
t.Fatalf("%v should not equal %v %v", m2, m3, err)
}
m3 = resmaptest_test.NewRmBuilder(t, rf).Add(
m3 := resmaptest_test.NewRmBuilder(t, rf).Add(
map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",

View File

@@ -69,10 +69,10 @@ func (rf *Factory) makeOne(
o = types.NewGenArgs(nil)
}
r := &Resource{
kunStr: u,
options: o,
Kunstructured: u,
options: o,
}
return r.setOriginalName(r.kunStr.GetName()).setOriginalNs(r.GetNamespace())
return r.setOriginalName(r.GetName()).setOriginalNs(r.GetNamespace())
}
// SliceFromPatches returns a slice of resources given a patch path

View File

@@ -1,7 +1,7 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// Package resource implements representations of k8s API resources.
// Package resource implements representations of k8s API resources as "unstructured" objects.
package resource
import (
@@ -14,57 +14,10 @@ import (
"sigs.k8s.io/yaml"
)
// Resource is a representation of a Kubernetes Resource Model object paired
// with metadata used by kustomize.
//
// At time of writing Resource is changing from being based on an object
// sitting behind
//
// sigs.k8s.io/kustomize/api/ifc.Unstructured
//
// to being based on an instance of
//
// sigs.k8s.io/kustomize/kyaml/yaml.RNode
//
// Ultimately, use of the Resource struct in kustomize should be entirely
// replaced by instances of RNode for direct use in kyaml, with all metadata
// stored directly in the RNodes as short-lived annotations, to be deleted
// before final output as part of a final filtration step. Using annotations
// will allow pipelined KRM Config Functions to share metadata that would
// otherwise be hidden in kustomize-only structures.
//
// ifc.Unstructured is an interface hiding an instance of
// sigs.k8s.io/kustomize/api/k8sdeps/kunstruct.UnstructAdapter
// which in turn adapts an instance of
// k8s.io/apimachinery/pkg/apis/meta/v1/unstructured
// to the ifc.Unstructured interface. This latter code handles
// mutations in the old code.
//
// The rule in kustomize development has been
// api/
// k8sdeps/ ifc/ krusty/ theRest/
//
// 1) Depend on k8s.io/ only via sigs.k8s.io/kustomize/api/k8sdeps.
//
// 2) Instances created in k8sdeps/ can only be injected into theRest/
// behind interfaces defined in ifc/, arranged by a small bit of code
// in krusty/. Nothing in theRest/ can import k8sdeps/.
//
// This was to allow for importing kustomize code into kubectl, which also
// depends on k8s.io/apimachinery, albeit via a strange, old arrangement
// predating Go modules. The idea was to copy the k8sdeps/ tree into kubectl
// via a large PR, and depend on the rest via vendoring (and a small copy of
// krusty/ code). Over 2019, however, kubectl underwent large code changes
// including a switch to Go modules, and an attempt to extract it from the
// k8s repo, and this made large kustomize integration PRs hard to get through
// code review.
//
// The new plan is to eliminate k8sdeps/ entirely, along with its k8s.io/
// dependence, switch to kyaml, and thus allow kustomize to be imported into
// kubectl via normal Go module imports.
//
// Resource is map representation of a Kubernetes API resource object
// paired with a GenerationBehavior.
type Resource struct {
kunStr ifc.Kunstructured
ifc.Kunstructured
originalName string
originalNs string
options *types.GenArgs
@@ -74,118 +27,6 @@ type Resource struct {
nameSuffixes []string
}
func (r *Resource) ResetPrimaryData(incoming *Resource) {
r.kunStr = incoming.kunStr.Copy()
}
func (r *Resource) GetAnnotations() map[string]string {
return r.kunStr.GetAnnotations()
}
func (r *Resource) Copy() ifc.Kunstructured {
return r.kunStr.Copy()
}
func (r *Resource) GetBool(p string) (bool, error) {
return r.kunStr.GetBool(p)
}
func (r *Resource) GetFieldValue(f string) (interface{}, error) {
return r.kunStr.GetFieldValue(f)
}
func (r *Resource) GetFloat64(p string) (float64, error) {
return r.kunStr.GetFloat64(p)
}
func (r *Resource) GetGvk() resid.Gvk {
return r.kunStr.GetGvk()
}
func (r *Resource) GetInt64(p string) (int64, error) {
return r.kunStr.GetInt64(p)
}
func (r *Resource) GetKind() string {
return r.kunStr.GetKind()
}
func (r *Resource) GetLabels() map[string]string {
return r.kunStr.GetLabels()
}
func (r *Resource) GetMap(p string) (map[string]interface{}, error) {
return r.kunStr.GetMap(p)
}
func (r *Resource) GetName() string {
return r.kunStr.GetName()
}
func (r *Resource) GetSlice(p string) ([]interface{}, error) {
return r.kunStr.GetSlice(p)
}
func (r *Resource) GetString(p string) (string, error) {
return r.kunStr.GetString(p)
}
func (r *Resource) GetStringMap(p string) (map[string]string, error) {
return r.kunStr.GetStringMap(p)
}
func (r *Resource) GetStringSlice(p string) ([]string, error) {
return r.kunStr.GetStringSlice(p)
}
func (r *Resource) Map() map[string]interface{} {
return r.kunStr.Map()
}
func (r *Resource) MarshalJSON() ([]byte, error) {
return r.kunStr.MarshalJSON()
}
func (r *Resource) MatchesLabelSelector(selector string) (bool, error) {
return r.kunStr.MatchesLabelSelector(selector)
}
func (r *Resource) MatchesAnnotationSelector(selector string) (bool, error) {
return r.kunStr.MatchesAnnotationSelector(selector)
}
func (r *Resource) Patch(other ifc.Kunstructured) error {
return r.kunStr.Patch(other)
}
func (r *Resource) SetAnnotations(m map[string]string) {
r.kunStr.SetAnnotations(m)
}
func (r *Resource) SetGvk(gvk resid.Gvk) {
r.kunStr.SetGvk(gvk)
}
func (r *Resource) SetLabels(m map[string]string) {
r.kunStr.SetLabels(m)
}
func (r *Resource) SetMap(m map[string]interface{}) {
r.kunStr.SetMap(m)
}
func (r *Resource) SetName(n string) {
r.kunStr.SetName(n)
}
func (r *Resource) SetNamespace(n string) {
r.kunStr.SetNamespace(n)
}
func (r *Resource) UnmarshalJSON(s []byte) error {
return r.kunStr.UnmarshalJSON(s)
}
// ResCtx is an interface describing the contextual added
// kept kustomize in the context of each Resource object.
// Currently mainly the name prefix and name suffix are added.
@@ -205,7 +46,7 @@ type ResCtxMatcher func(ResCtx) bool
// DeepCopy returns a new copy of resource
func (r *Resource) DeepCopy() *Resource {
rc := &Resource{
kunStr: r.kunStr.Copy(),
Kunstructured: r.Kunstructured.Copy(),
}
rc.copyOtherFields(r)
return rc
@@ -213,11 +54,11 @@ func (r *Resource) DeepCopy() *Resource {
// Replace performs replace with other resource.
func (r *Resource) Replace(other *Resource) {
r.kunStr.SetLabels(mergeStringMaps(other.kunStr.GetLabels(), r.kunStr.GetLabels()))
r.kunStr.SetAnnotations(
mergeStringMaps(other.kunStr.GetAnnotations(), r.kunStr.GetAnnotations()))
r.kunStr.SetName(other.GetName())
r.kunStr.SetNamespace(other.GetNamespace())
r.SetLabels(mergeStringMaps(other.GetLabels(), r.GetLabels()))
r.SetAnnotations(
mergeStringMaps(other.GetAnnotations(), r.GetAnnotations()))
r.SetName(other.GetName())
r.SetNamespace(other.GetNamespace())
r.copyOtherFields(other)
}
@@ -233,7 +74,7 @@ func (r *Resource) copyOtherFields(other *Resource) {
func (r *Resource) Equals(o *Resource) bool {
return r.ReferencesEqual(o) &&
reflect.DeepEqual(r.kunStr, o.kunStr)
reflect.DeepEqual(r.Kunstructured, o.Kunstructured)
}
func (r *Resource) ReferencesEqual(o *Resource) bool {
@@ -252,13 +93,13 @@ func (r *Resource) ReferencesEqual(o *Resource) bool {
}
func (r *Resource) KunstructEqual(o *Resource) bool {
return reflect.DeepEqual(r.kunStr, o.kunStr)
return reflect.DeepEqual(r.Kunstructured, o.Kunstructured)
}
// Merge performs merge with other resource.
func (r *Resource) Merge(other *Resource) {
r.Replace(other)
mergeConfigmap(r.kunStr.Map(), other.Map(), r.Map())
mergeConfigmap(r.Map(), other.Map(), r.Map())
}
func (r *Resource) copyRefBy() []resid.ResId {
@@ -384,7 +225,7 @@ func (r *Resource) setOriginalNs(n string) *Resource {
// String returns resource as JSON.
func (r *Resource) String() string {
bs, err := r.kunStr.MarshalJSON()
bs, err := r.MarshalJSON()
if err != nil {
return "<" + err.Error() + ">"
}
@@ -394,7 +235,7 @@ func (r *Resource) String() string {
// AsYAML returns the resource in Yaml form.
// Easier to read than JSON.
func (r *Resource) AsYAML() ([]byte, error) {
json, err := r.kunStr.MarshalJSON()
json, err := r.MarshalJSON()
if err != nil {
return nil, err
}
@@ -419,7 +260,7 @@ func (r *Resource) NeedHashSuffix() bool {
// GetNamespace returns the namespace the resource thinks it's in.
func (r *Resource) GetNamespace() string {
namespace, _ := r.kunStr.GetString("metadata.namespace")
namespace, _ := r.GetString("metadata.namespace")
// if err, namespace is empty, so no need to check.
return namespace
}
@@ -429,7 +270,7 @@ func (r *Resource) GetNamespace() string {
// TODO: compute this once and save it in the resource.
func (r *Resource) OrgId() resid.ResId {
return resid.NewResIdWithNamespace(
r.kunStr.GetGvk(), r.GetOriginalName(), r.GetOriginalNs())
r.GetGvk(), r.GetOriginalName(), r.GetOriginalNs())
}
// CurId returns a ResId for the resource using the
@@ -437,7 +278,7 @@ func (r *Resource) OrgId() resid.ResId {
// This should be unique in any ResMap.
func (r *Resource) CurId() resid.ResId {
return resid.NewResIdWithNamespace(
r.kunStr.GetGvk(), r.kunStr.GetName(), r.GetNamespace())
r.GetGvk(), r.GetName(), r.GetNamespace())
}
// GetRefBy returns the ResIds that referred to current resource

View File

@@ -52,16 +52,6 @@ kind: Kustomization
`+content))
}
func (th Harness) WriteC(path string, content string) {
th.fSys.WriteFile(
filepath.Join(
path,
konfig.DefaultKustomizationFileName()), []byte(`
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
`+content))
}
func (th Harness) WriteF(path string, content string) {
th.fSys.WriteFile(path, []byte(content))
}

View File

@@ -6,8 +6,6 @@ package types
const (
KustomizationVersion = "kustomize.config.k8s.io/v1beta1"
KustomizationKind = "Kustomization"
ComponentVersion = "kustomize.config.k8s.io/v1alpha1"
ComponentKind = "Component"
MetadataNamespacePath = "metadata/namespace"
)
@@ -75,14 +73,10 @@ type Kustomization struct {
//
// Resources specifies relative paths to files holding YAML representations
// of kubernetes API objects, or specifications of other kustomizations
// of kubernetes API objects, or specifcations of other kustomizations
// via relative paths, absolute paths, or URLs.
Resources []string `json:"resources,omitempty" yaml:"resources,omitempty"`
// Components specifies relative paths to specifications of other Components
// via relative paths, absolute paths, or URLs.
Components []string `json:"components,omitempty" yaml:"components,omitempty"`
// Crds specifies relative paths to Custom Resource Definition files.
// This allows custom resources to be recognized as operands, making
// it possible to add them to the Resources list.
@@ -124,9 +118,6 @@ type Kustomization struct {
// Transformers is a list of files containing transformers
Transformers []string `json:"transformers,omitempty" yaml:"transformers,omitempty"`
// Validators is a list of files containing validators
Validators []string `json:"validators,omitempty" yaml:"validators,omitempty"`
// Inventory appends an object that contains the record
// of all other objects, which can be used in apply, prune and delete
Inventory *Inventory `json:"inventory,omitempty" yaml:"inventory,omitempty"`
@@ -137,31 +128,23 @@ type Kustomization struct {
// moving content of deprecated fields to newer
// fields.
func (k *Kustomization) FixKustomizationPostUnmarshalling() {
if k.APIVersion == "" {
k.APIVersion = KustomizationVersion
}
if k.Kind == "" {
k.Kind = KustomizationKind
}
if k.APIVersion == "" {
if k.Kind == ComponentKind {
k.APIVersion = ComponentVersion
} else {
k.APIVersion = KustomizationVersion
}
}
k.Resources = append(k.Resources, k.Bases...)
k.Bases = nil
}
func (k *Kustomization) EnforceFields() []string {
var errs []string
if k.Kind != "" && k.Kind != KustomizationKind && k.Kind != ComponentKind {
errs = append(errs, "kind should be "+KustomizationKind+" or "+ComponentKind)
if k.APIVersion != "" && k.APIVersion != KustomizationVersion {
errs = append(errs, "apiVersion should be "+KustomizationVersion)
}
requiredVersion := KustomizationVersion
if k.Kind == ComponentKind {
requiredVersion = ComponentVersion
}
if k.APIVersion != "" && k.APIVersion != requiredVersion {
errs = append(errs, "apiVersion for "+k.Kind+" should be "+requiredVersion)
if k.Kind != "" && k.Kind != KustomizationKind {
errs = append(errs, "kind should be "+KustomizationKind)
}
return errs
}

View File

@@ -29,7 +29,4 @@ type PluginConfig struct {
// BpLoadingOptions distinguishes builtin plugin behaviors.
BpLoadingOptions BuiltinPluginLoadingOptions
// FnpLoadingOptions sets the way function-based plugin behaviors.
FnpLoadingOptions FnPluginLoadingOptions
}

View File

@@ -41,16 +41,3 @@ const (
// to generate static code.
BploLoadFromFileSys
)
// FnPluginLoadingOptions set way functions-based pluing are restricted
type FnPluginLoadingOptions struct {
// Allow to run executables
EnableExec bool
// Allow to run starlark
EnableStar bool
// Allow container access to network
Network bool
NetworkName string
// list of mounts
Mounts []string
}

View File

@@ -6,7 +6,7 @@
GOBIN := $(shell go env GOPATH)/bin
build:
go build -v -o $(GOBIN)/kubectl-krm ./kubectl-krm
go build -v -o $(GOBIN)/config .
all: generate build license fix vet fmt test lint tidy

View File

@@ -6,7 +6,7 @@ of development of the kyaml package and as a reference implementation for using
## Docs
All documentation is also built directly into the `config` command group using
`kustomize help cfg`.
`kustomize help config`.
- [tutorials](docs/tutorials)
- [commands](docs/commands)

View File

@@ -1,32 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package configcobra
import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
)
func GetCfg(name string) *cobra.Command {
cmd := &cobra.Command{
Use: "cfg",
Short: "Commands for reading and writing configuration.",
}
cmd.AddCommand(commands.AnnotateCommand(name))
cmd.AddCommand(commands.CatCommand(name))
cmd.AddCommand(commands.CountCommand(name))
cmd.AddCommand(commands.CreateSetterCommand(name))
cmd.AddCommand(commands.CreateSubstitutionCommand(name))
cmd.AddCommand(commands.FmtCommand(name))
cmd.AddCommand(commands.GrepCommand(name))
cmd.AddCommand(commands.InitCommand(name))
cmd.AddCommand(commands.ListSettersCommand(name))
cmd.AddCommand(commands.MergeCommand(name))
cmd.AddCommand(commands.Merge3Command(name))
cmd.AddCommand(commands.SetCommand(name))
cmd.AddCommand(commands.TreeCommand(name))
return cmd
}

View File

@@ -6,12 +6,43 @@
package configcobra
import (
"strings"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/api"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/tutorials"
"sigs.k8s.io/kustomize/kyaml/commandutil"
)
var root = &cobra.Command{
Use: "config",
Short: "[Alpha] Utilities for working with Resource Configuration.",
Long: `[Alpha] Utilities for working with Resource Configuration.
Tutorials:
Run 'kustomize help config tutorial-TUTORIAL'
$ kustomize help config tutorials-command-basics
Command Documentation:
Run 'kustomize help config CMD'
$ kustomize help config tree
Advanced Documentation Topics:
Run 'kustomize help config docs-TOPIC'
$ kustomize help config docs-merge
$ kustomize help config docs-merge3
$ kustomize help config docs-fn
$ kustomize help config docs-io-annotations
`,
}
// Export commands publicly for composition
var (
Annotate = commands.AnnotateCommand
@@ -19,14 +50,12 @@ var (
Count = commands.CountCommand
CreateSetter = commands.CreateSetterCommand
CreateSubstitution = commands.CreateSubstitutionCommand
DeleteSetter = commands.DeleteSetterCommand
Fmt = commands.FmtCommand
Grep = commands.GrepCommand
Init = commands.InitCommand
ListSetters = commands.ListSettersCommand
Merge = commands.MergeCommand
Merge3 = commands.Merge3Command
RunFn = commands.RunCommand
RunFn = commands.RunFnCommand
Set = commands.SetCommand
Sink = commands.SinkCommand
Source = commands.SourceCommand
@@ -38,16 +67,50 @@ var (
ExitOnError = &commands.ExitOnError
)
// AddCommands adds the cfg, fn and live commands to kustomize.
func AddCommands(root *cobra.Command, name string) *cobra.Command {
// NewConfigCommand returns a new *cobra.Command for the config command group. This may
// be embedded into other go binaries as a way of packaging the "config" command as part
// of another binary.
//
// name is substituted into the built-in documentation for each sub-command as the command
// invocation prefix -- e.g. if the result is embedded in kustomize, then name should be
// "kustomize" and the built-in docs will display "kustomize config" in the examples.
//
func NewConfigCommand(name string) *cobra.Command {
// config command is alpha
root.Version = "v0.0.0"
// Only populate the command if Alpha commands are enabled.
if !commandutil.GetAlphaEnabled() {
// return the command because other subcommands are added to it
root.Short = "[Alpha] To enable set KUSTOMIZE_ENABLE_ALPHA_COMMANDS=true"
root.Long = "[Alpha] To enable set KUSTOMIZE_ENABLE_ALPHA_COMMANDS=true"
root.Example = ""
return root
}
root.PersistentFlags().BoolVar(&commands.StackOnError, "stack-trace", false,
"print a stack-trace on failure")
name = strings.TrimSpace(name + " config")
commands.ExitOnError = true
root.AddCommand(commands.AnnotateCommand(name))
root.AddCommand(commands.GrepCommand(name))
root.AddCommand(commands.TreeCommand(name))
root.AddCommand(commands.CatCommand(name))
root.AddCommand(commands.FmtCommand(name))
root.AddCommand(commands.MergeCommand(name))
root.AddCommand(commands.Merge3Command(name))
root.AddCommand(commands.CountCommand(name))
root.AddCommand(commands.RunFnCommand(name))
root.AddCommand(commands.XArgsCommand())
root.AddCommand(commands.WrapCommand())
root.PersistentFlags().BoolVar(StackOnError, "stack-trace", false,
"print a stack-trace on error")
root.AddCommand(GetCfg(name))
root.AddCommand(GetFn(name))
root.AddCommand(GetLive(name))
root.AddCommand(commands.SetCommand(name))
root.AddCommand(commands.ListSettersCommand(name))
root.AddCommand(commands.CreateSetterCommand(name))
root.AddCommand(commands.CreateSubstitutionCommand(name))
root.AddCommand(commands.SinkCommand(name))
root.AddCommand(commands.SourceCommand(name))
root.AddCommand(&cobra.Command{
Use: "docs-merge",

View File

@@ -11,14 +11,15 @@ import (
"sigs.k8s.io/kustomize/kyaml/commandutil"
)
// ExampleAddCommands demonstrates how to embed the config command as a command inside
// ExampleNewConfigCommand demonstrates how to embed the config command as a command inside
// another group.
func ExampleAddCommands() {
func ExampleNewConfigCommand() {
// enable the config commands
os.Setenv(commandutil.EnableAlphaCommmandsEnvName, "true")
_ = configcobra.AddCommands(&cobra.Command{
var root = &cobra.Command{
Use: "my-cmd",
Short: "My command.",
Long: `My command.`,
}, "my-cmd")
}
root.AddCommand(configcobra.NewConfigCommand("my-cmd"))
}

View File

@@ -1,24 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package configcobra
import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
)
func GetFn(name string) *cobra.Command {
cmd := &cobra.Command{
Use: "fn",
Short: "Commands for running functions against configuration.",
}
cmd.AddCommand(commands.RunCommand(name))
cmd.AddCommand(commands.SinkCommand(name))
cmd.AddCommand(commands.SourceCommand(name))
cmd.AddCommand(commands.WrapCommand())
cmd.AddCommand(commands.XArgsCommand())
return cmd
}

View File

@@ -1,89 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package configcobra
import (
"flag"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/discovery"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/kubectl/pkg/cmd/util"
"sigs.k8s.io/cli-utils/cmd/apply"
"sigs.k8s.io/cli-utils/cmd/destroy"
"sigs.k8s.io/cli-utils/cmd/diff"
"sigs.k8s.io/cli-utils/cmd/initcmd"
"sigs.k8s.io/cli-utils/cmd/preview"
"sigs.k8s.io/cli-utils/pkg/util/factory"
)
func GetLive(name string) *cobra.Command {
cmd := &cobra.Command{
Use: "live",
Short: "Commands for reading and writing resources to a cluster.",
}
ioStreams := genericclioptions.IOStreams{
In: cmd.InOrStdin(),
Out: cmd.OutOrStdout(),
ErrOut: cmd.ErrOrStderr(),
}
flags := cmd.PersistentFlags()
kubeConfigFlags := genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag()
kubeConfigFlags.AddFlags(flags)
userAgentKubeConfigFlags := &UserAgentKubeConfigFlags{
Delegate: kubeConfigFlags,
UserAgent: "kustomize",
}
matchVersionKubeConfigFlags := util.NewMatchVersionFlags(
&factory.CachingRESTClientGetter{
Delegate: userAgentKubeConfigFlags,
},
)
matchVersionKubeConfigFlags.AddFlags(cmd.PersistentFlags())
cmd.PersistentFlags().AddGoFlagSet(flag.CommandLine)
f := util.NewFactory(matchVersionKubeConfigFlags)
applyCmd := apply.ApplyCommand(f, ioStreams)
_ = applyCmd.Flags().MarkHidden("no-prune")
cmd.AddCommand(
applyCmd,
initcmd.NewCmdInit(ioStreams),
preview.NewCmdPreview(f, ioStreams),
diff.NewCmdDiff(f, ioStreams),
destroy.NewCmdDestroy(f, ioStreams))
return cmd
}
type UserAgentKubeConfigFlags struct {
Delegate genericclioptions.RESTClientGetter
UserAgent string
}
func (u *UserAgentKubeConfigFlags) ToRESTConfig() (*rest.Config, error) {
clientConfig, err := u.Delegate.ToRESTConfig()
if err != nil {
return nil, err
}
if u.UserAgent != "" {
clientConfig.UserAgent = u.UserAgent
}
return clientConfig, nil
}
func (u *UserAgentKubeConfigFlags) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) {
return u.Delegate.ToDiscoveryClient()
}
func (u *UserAgentKubeConfigFlags) ToRESTMapper() (meta.RESTMapper, error) {
return u.Delegate.ToRESTMapper()
}
func (u *UserAgentKubeConfigFlags) ToRawKubeConfigLoader() clientcmd.ClientConfig {
return u.Delegate.ToRawKubeConfigLoader()
}

View File

@@ -1,7 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
//go:generate $GOBIN/mdtogo docs/api-conventions internal/generateddocs/api --full=true --license=none
//go:generate $GOBIN/mdtogo docs/tutorials internal/generateddocs/tutorials --full=true --license=none
//go:generate $GOBIN/mdtogo docs/commands internal/generateddocs/commands --license=none
package config

View File

@@ -7,7 +7,7 @@ containers that can be chained together as part of a configuration management pi
The end result of such a pipeline are fully rendered configurations that can then be
applied to a control plane (e.g. Using kubectl apply for Kubernetes control plane).
As such, although this document references Kubernetes Resource Model and API conventions,
it is completely decoupled from Kubernetes API machinery and does not depend on any
it is completely decoupled from Kuberentes API machinery and does not depend on any
in-cluster components.
This document references terms described in [Kubernetes API Conventions][1].
@@ -33,7 +33,7 @@ _Configuration functions_ enable shift-left practices (client-side) through:
Performing these on the client rather than the server enables:
- Configuration to be reviewed prior to being sent to the API server
- Configuration to be validated as part of the CI/CD pipeline
- Configuration to be validated as part of the CI?CD pipeline
- Configuration for Resources to validated holistically rather than individually
per-Resource
- e.g. ensure the `Service.selector` and `Deployment.spec.template` labels

View File

@@ -11,8 +11,8 @@
### Examples
kustomize cfg annotate my-dir/ --kv foo=bar
kustomize config annotate my-dir/ --kv foo=bar
kustomize cfg annotate my-dir/ --kv foo=bar --kv a=b
kustomize config annotate my-dir/ --kv foo=bar --kv a=b
kustomize cfg annotate my-dir/ --kv foo=bar --kind Deployment --name foo
kustomize config annotate my-dir/ --kv foo=bar --kind Deployment --name foo

View File

@@ -12,10 +12,10 @@
### Examples
# print Resource config from a directory
kustomize cfg cat my-dir/
kustomize config cat my-dir/
# wrap Resource config from a directory in an ResourceList
kustomize cfg cat my-dir/ --wrap-kind ResourceList --wrap-version config.kubernetes.io/v1alpha1 --function-config fn.yaml
kustomize config cat my-dir/ --wrap-kind ResourceList --wrap-version config.kubernetes.io/v1alpha1 --function-config fn.yaml
# unwrap Resource config from a directory in an ResourceList
... | kustomize cfg cat
... | kustomize config cat

View File

@@ -12,4 +12,4 @@
### Examples
# print Resource counts from a directory
kustomize cfg count my-dir/
kustomize config count my-dir/

View File

@@ -38,7 +38,7 @@ Create a custom setter for a Resource field by inlining OpenAPI as comments.
**Create a new setter:**
# create a setter for ports
$ kustomize cfg set create DIR/ http-port 8080 --type "integer" --field "port"
$ kustomize config set create DIR/ http-port 8080 --type "integer" --field "port"
Resources fields with a field name matching `--field` and field value matching `VALUE` will
have a line comment added marking this field as settable.
@@ -63,7 +63,7 @@ Create a custom setter for a Resource field by inlining OpenAPI as comments.
Users may not set the field value using the `set` command:
# change the http-port value to 8081
$ kustomize cfg set DIR/ http-port 8081
$ kustomize config set DIR/ http-port 8081
### Using default values
@@ -75,7 +75,7 @@ The default values for a setter may be:
A setter may be for a substring of a full field:
$ kustomize cfg set create DIR/ image-tag v1.0.01 --type "string" --field "image"
$ kustomize config set create DIR/ image-tag v1.0.01 --type "string" --field "image"
image: gcr.io/example/app:v1.0.1 # # {"type":"string","x-kustomize":{"partialFieldSetters":[{"name":"image-tag","value":"v1.0.1"}]}}
@@ -84,10 +84,10 @@ A single field value may have multiple setters applied to it for different parts
### Examples
# create a setter for port fields matching "8080"
kustomize cfg create-setter DIR/ port 8080 --type "integer" --field port \
kustomize config create-setter DIR/ port 8080 --type "integer" --field port \
--description "default port used by the app"
# create a setter for a substring of a field rather than the full field -- e.g. only the
# image tag, not the full image
kustomize cfg create-setter DIR/ image-tag v1.0.1 --type "string" \
kustomize config create-setter DIR/ image-tag v1.0.1 --type "string" \
--field image --description "current stable release"

View File

@@ -32,13 +32,13 @@ field paths.
### Examples
# format file1.yaml and file2.yml
kustomize cfg fmt file1.yaml file2.yml
kustomize config fmt file1.yaml file2.yml
# format all *.yaml and *.yml recursively traversing directories
kustomize cfg fmt my-dir/
kustomize config fmt my-dir/
# format kubectl output
kubectl get -o yaml deployments | kustomize cfg fmt
kubectl get -o yaml deployments | kustomize config fmt
# format kustomize output
kustomize build | kustomize cfg fmt
kustomize build | kustomize config fmt

View File

@@ -19,13 +19,13 @@
### Examples
# find Deployment Resources
kustomize cfg grep "kind=Deployment" my-dir/
kustomize config grep "kind=Deployment" my-dir/
# find Resources named nginx
kustomize cfg grep "metadata.name=nginx" my-dir/
kustomize config grep "metadata.name=nginx" my-dir/
# use tree to display matching Resources
kustomize cfg grep "metadata.name=nginx" my-dir/ | kustomize cfg tree
kustomize config grep "metadata.name=nginx" my-dir/ | kustomize config tree
# look for Resources matching a specific container image
kustomize cfg grep "spec.template.spec.containers[name=nginx].image=nginx:1\.7\.9" my-dir/ | kustomize cfg tree
kustomize config grep "spec.template.spec.containers[name=nginx].image=nginx:1\.7\.9" my-dir/ | kustomize config tree

View File

@@ -1,18 +0,0 @@
## init
[Alpha] Initialize a directory with a Krmfile.
### Synopsis
[Alpha] Initialize a directory with a Krmfile.
DIR:
Path to local directory.
### Examples
# create a Krmfile in the local directory
kustomize cfg init
# create a Krmfile in my-dir/
kustomize cfg init my-dir/

View File

@@ -18,6 +18,6 @@ List setters for Resources.
Show setters:
$ kustomize cfg list-setters DIR/
$ config list-setters DIR/
NAME DESCRIPTION VALUE TYPE COUNT SETBY
name-prefix '' PREFIX string 2

View File

@@ -17,8 +17,8 @@ earlier are lower-precedence (the destination).
For information on merge rules, run:
kustomize cfg docs merge
kustomize config docs merge
### Examples
cat resources_and_patches.yaml | kustomize cfg merge > merged_resources.yaml
cat resources_and_patches.yaml | kustomize config merge > merged_resources.yaml

View File

@@ -16,8 +16,8 @@ to the Resource in the DEST_DIR.
For information on merge rules, run:
kustomize cfg docs-merge3
kustomize config docs-merge3
### Examples
kustomize cfg merge3 --ancestor a/ --from b/ --to c/
kustomize config merge3 --ancestor a/ --from b/ --to c/

View File

@@ -40,14 +40,14 @@ order they appear in the file).
spec:
configField: configValue
In the preceding example, 'kustomize fn run example/' would identify the function by
In the preceding example, 'kustomize config run example/' would identify the function by
the metadata.annotations.[config.kubernetes.io/function] field. It would then write all Resources in the directory to
a container stdin (running the gcr.io/example/examplefunction:v1.0.1 image). It
would then write the container stdout back to example/, replacing the directory
file contents.
See `kustomize help cfg docs-fn` for more details on writing functions.
See `kustomize help config docs-fn` for more details on writing functions.
### Examples
kustomize fn run example/
kustomize config run example/

View File

@@ -29,7 +29,7 @@ the configuration as comments.
To print the possible setters for the Resources in a directory, run
`list-setters` on a directory -- e.g. `kustomize cfg list-setters DIR/`.
`list-setters` on a directory -- e.g. `kustomize config list-setters DIR/`.
#### Tips
@@ -39,7 +39,7 @@ To print the possible setters for the Resources in a directory, run
The description and setBy fields are left unmodified unless specified with flags.
To create a custom setter for a field see: `kustomize help cfg create-setter`
To create a custom setter for a field see: `kustomize help config create-setter`
### Examples
@@ -48,12 +48,12 @@ To create a custom setter for a field see: `kustomize help cfg create-setter`
# DIR/resources.yaml
...
metadata:
name: PREFIX-app1 # {"type":"string","x-kustomize":{"setter":[{"name":"name-prefix","value":"PREFIX"}]}}
name: PREFIX-app1 # {"type":"string","x-kustomize":{"partialFieldSetters":[{"name":"name-prefix","value":"PREFIX"}]}}
...
---
...
metadata:
name: PREFIX-app2 # {"type":"string","x-kustomize":{"setter":[{"name":"name-prefix","value":"PREFIX"}]}}
name: PREFIX-app2 # {"type":"string","x-kustomize":{"partialFieldSetters":[{"name":"name-prefix","value":"PREFIX"}]}}
...
List setters: Show the possible setters
@@ -64,7 +64,7 @@ To create a custom setter for a field see: `kustomize help cfg create-setter`
Perform set: set a new value, owner and description
$ kustomize cfg set DIR/ name-prefix "test" --description "test environment" --set-by "dev"
$ kustomize config set DIR/ name-prefix "test" --description "test environment" --set-by "dev"
set 2 values
List setters: Show the new values
@@ -78,10 +78,10 @@ To create a custom setter for a field see: `kustomize help cfg create-setter`
# DIR/resources.yaml
...
metadata:
name: test-app1 # {"description":"test environment","type":"string","x-kustomize":{"setBy":"dev","setter":[{"name":"name-prefix","value":"test"}]}}
name: test-app1 # {"description":"test environment","type":"string","x-kustomize":{"setBy":"dev","partialFieldSetters":[{"name":"name-prefix","value":"test"}]}}
...
---
...
metadata:
name: test-app2 # {"description":"test environment","type":"string","x-kustomize":{"setBy":"dev","setter":[{"name":"name-prefix","value":"test"}]}}
name: test-app2 # {"description":"test environment","type":"string","x-kustomize":{"setBy":"dev","partialFieldSetters":[{"name":"name-prefix","value":"test"}]}}
...

View File

@@ -6,7 +6,7 @@
[Alpha] Implement a Sink by writing input to a local directory.
kustomize fn sink [DIR]
kustomize config sink [DIR]
DIR:
Path to local directory. If unspecified, sink will write to stdout as if it were a single file.
@@ -15,4 +15,4 @@
### Examples
kustomize fn source DIR/ | your-function | kustomize fn sink DIR/
kustomize config source DIR/ | your-function | kustomize config sink DIR/

View File

@@ -6,7 +6,7 @@
[Alpha] Implement a Source by reading a local directory.
kustomize fn source DIR...
kustomize config source DIR...
DIR:
One or more paths to local directories. Contents from directories will be concatenated.
@@ -17,6 +17,6 @@
### Examples
# emity configuration directory as input source to a function
kustomize fn source DIR/
kustomize config source DIR/
kustomize fn source DIR/ | your-function | kustomize fn sink DIR/
kustomize config source DIR/ | your-function | kustomize config sink DIR/

View File

@@ -6,7 +6,7 @@
[Alpha] Display Resource structure from a directory or stdin.
kustomize cfg tree may be used to print Resources in a directory or cluster, preserving structure
kustomize config tree may be used to print Resources in a directory or cluster, preserving structure
Args:
@@ -15,38 +15,38 @@ Args:
Resource fields may be printed as part of the Resources by specifying the fields as flags.
kustomize cfg tree has build-in support for printing common fields, such as replicas, container images,
kustomize config tree has build-in support for printing common fields, such as replicas, container images,
container names, etc.
kustomize cfg tree supports printing arbitrary fields using the '--field' flag.
kustomize config tree supports printing arbitrary fields using the '--field' flag.
By default, kustomize cfg tree uses Resource graph structure if any relationships between resources (ownerReferences)
By default, kustomize config tree uses Resource graph structure if any relationships between resources (ownerReferences)
are detected, as is typically the case when printing from a cluster. Otherwise, directory graph structure is used. The
graph structure can also be selected explicitly using the '--graph-structure' flag.
### Examples
# print Resources using directory structure
kustomize cfg tree my-dir/
kustomize config tree my-dir/
# print replicas, container name, and container image and fields for Resources
kustomize cfg tree my-dir --replicas --image --name
kustomize config tree my-dir --replicas --image --name
# print all common Resource fields
kustomize cfg tree my-dir/ --all
kustomize config tree my-dir/ --all
# print the "foo"" annotation
kustomize cfg tree my-dir/ --field "metadata.annotations.foo"
kustomize config tree my-dir/ --field "metadata.annotations.foo"
# print the "foo"" annotation
kubectl get all -o yaml | kustomize cfg tree \
kubectl get all -o yaml | kustomize config tree \
--field="status.conditions[type=Completed].status"
# print live Resources from a cluster using owners for graph structure
kubectl get all -o yaml | kustomize cfg tree --replicas --name --image
kubectl get all -o yaml | kustomize config tree --replicas --name --image
# print live Resources with status condition fields
kubectl get all -o yaml | kustomize cfg tree \
kubectl get all -o yaml | kustomize config tree \
--name --image --replicas \
--field="status.conditions[type=Completed].status" \
--field="status.conditions[type=Complete].status" \

View File

@@ -2,7 +2,7 @@
### Synopsis
`kustomize cfg` provides tools for working with local configuration directories.
`kustomize config` provides tools for working with local configuration directories.
First fetch a bundle of configuration to your local file system from the
Kubernetes examples repository.
@@ -14,7 +14,7 @@
`tree` can be used to summarize the collection of Resources in a directory:
$ kustomize cfg tree mysql-wordpress-pd/
$ kustomize config tree mysql-wordpress-pd/
mysql-wordpress-pd
├── [gce-volumes.yaml] v1.PersistentVolume wordpress-pv-1
├── [gce-volumes.yaml] v1.PersistentVolume wordpress-pv-2
@@ -31,7 +31,7 @@
supported fields, and may also print arbitrary values using the `--field` flag to specify a field
path.
$ kustomize cfg tree mysql-wordpress-pd/ --name --image --replicas --ports
$ kustomize config tree mysql-wordpress-pd/ --name --image --replicas --ports
mysql-wordpress-pd
├── [gce-volumes.yaml] PersistentVolume wordpress-pv-1
├── [gce-volumes.yaml] PersistentVolume wordpress-pv-2
@@ -60,7 +60,7 @@
to build the tree structure.
kubectl apply -R -f cockroachdb/
kubectl get all -o yaml | kustomize cfg tree --graph-structure owners --name --image --replicas
kubectl get all -o yaml | kustomize config tree --graph-structure owners --name --image --replicas
.
├── [Resource] Deployment wp/wordpress
│   ├── spec.replicas: 1
@@ -84,7 +84,7 @@
### `cat` -- view the full collection of Resources
$ kustomize cfg cat mysql-wordpress-pd/
$ kustomize config cat mysql-wordpress-pd/
apiVersion: v1
kind: PersistentVolume
metadata:
@@ -111,7 +111,7 @@
`fmt` formats the Resource Configuration by applying a consistent style, including
ordering of fields and indentation.
$ kustomize cfg fmt mysql-wordpress-pd/
$ kustomize config fmt mysql-wordpress-pd/
Run `git diff` and see the changes that have been applied.
@@ -120,7 +120,7 @@
`grep` prints Resources matching some field value. The Resources are annotated with their
file source so they can be piped to other commands without losing this information.
$ kustomize cfg grep "metadata.name=wordpress" wordpress/
$ kustomize config grep "metadata.name=wordpress" wordpress/
apiVersion: v1
kind: Service
metadata:
@@ -142,7 +142,7 @@
- list elements may be indexed by a field value using list[field=value]
- '.' as part of a key or value may be escaped as '\.'
$ kustomize cfg grep "spec.status.spec.containers[name=nginx].image=mysql:5\.6" wordpress/
$ kustomize config grep "spec.status.spec.containers[name=nginx].image=mysql:5\.6" wordpress/
apiVersion: apps/v1 # for k8s versions before 1.9.0 use apps/v1beta2 and before 1.8.0 use extensions/v1beta1
kind: Deployment
metadata:
@@ -163,7 +163,7 @@
`grep` may be used with kubectl to search for Resources in a cluster matching a value.
kubectl get all -o yaml | kustomize cfg grep "spec.replicas>0" | kustomize cfg tree --replicas
kubectl get all -o yaml | kustomize config grep "spec.replicas>0" | kustomize config tree --replicas
.
└──
├── [.] Deployment wp/wordpress
@@ -179,7 +179,7 @@
If there is an error parsing the Resource configuration, kustomize will print an error with the file.
$ kustomize cfg grep "spec.template.spec.containers[name=\.*].resources.limits.cpu>1.0" ./staging/ | kustomize cfg tree --name --resources
$ kustomize config grep "spec.template.spec.containers[name=\.*].resources.limits.cpu>1.0" ./staging/ | kustomize config tree --name --resources
Error: staging/persistent-volume-provisioning/quobyte/quobyte-admin-secret.yaml: [0]: yaml: unmarshal errors:
line 13: mapping key "type" already defined at line 9
@@ -192,7 +192,7 @@
When developing -- to get a stack trace for where an error was encountered,
use the `--stack-trace` flag:
$ kustomize cfg grep "spec.template.spec.containers[name=\.*].resources.limits.cpu>1.0" ./staging/ --stack-trace
$ kustomize config grep "spec.template.spec.containers[name=\.*].resources.limits.cpu>1.0" ./staging/ --stack-trace
go/src/sigs.k8s.io/kustomize/kyaml/yaml/types.go:260 (0x4d35c86)
(*RNode).GetMeta: return m, errors.Wrap(err)
go/src/sigs.k8s.io/kustomize/kyaml/kio/byteio_reader.go:130 (0x4d3e099)
@@ -206,7 +206,7 @@
Query for `replicas`:
$ kustomize cfg grep "spec.replicas>5" ./ | kustomize cfg tree --replicas
$ kustomize config grep "spec.replicas>5" ./ | kustomize config tree --replicas
.
├── staging/sysdig-cloud
│   └── [sysdig-rc.yaml] ReplicationController sysdig-agent
@@ -217,7 +217,7 @@
Query for `resource.limits`
$ kustomize cfg grep "spec.template.spec.containers[name=\.*].resources.limits.memory>0" ./ | kustomize cfg tree --resources
$ kustomize config grep "spec.template.spec.containers[name=\.*].resources.limits.memory>0" ./ | kustomize config tree --resources
.
├── cassandra
│   └── [cassandra-statefulset.yaml] StatefulSet cassandra
@@ -246,7 +246,7 @@
Find Resources that have an image specified, but the image doesn't have a tag:
$ kustomize cfg grep "spec.template.spec.containers[name=\.*].name=\.*" ./ | kustomize cfg grep "spec.template.spec.containers[name=\.*].image=\.*:\.*" -v | kustomize cfg tree --image --name
$ kustomize config grep "spec.template.spec.containers[name=\.*].name=\.*" ./ | kustomize config grep "spec.template.spec.containers[name=\.*].image=\.*:\.*" -v | kustomize config tree --image --name
.
├── staging/newrelic
│   ├── [newrelic-daemonset.yaml] DaemonSet newrelic-agent

View File

@@ -25,13 +25,13 @@
cd template-heredoc-cockroachdb/
# view the Resources
kustomize cfg tree local-resource/ --name --image --replicas
kustomize config tree local-resource/ --name --image --replicas
# run the function
kustomize fn run local-resource/
kustomize config run local-resource/
# view the generated Resources
kustomize cfg tree local-resource/ --name --image --replicas
kustomize config tree local-resource/ --name --image --replicas
`run` generated the directory ` local-resource/config` containing the generated
Resources.
@@ -45,7 +45,7 @@
but keep the fields that you manually added to the generated Resource configuration.
# run the function
kustomize fn run local-resource/
kustomize config run local-resource/
`run` facilitates a non-destructive *smart templating* approach that allows templating
to be composed with manual modifications directly to the template output, as well as
@@ -70,13 +70,13 @@
cd template-go-nginx/
# view the Resources
kustomize cfg tree local-resource/ --name --image --replicas
kustomize config tree local-resource/ --name --image --replicas
# run the function
kustomize fn run local-resource/
kustomize config run local-resource/
# view the generated Resources
kustomize cfg tree local-resource/ --name --image --replicas
kustomize config tree local-resource/ --name --image --replicas
`run` generated the directory ` local-resource/config` containing the generated
Resources. this time it put the configuration in a single file rather than multiple
@@ -92,7 +92,7 @@
but keep the fields that you manually added to the generated Resource configuration.
# run the function
kustomize fn run local-resource/
kustomize config run local-resource/
Just like in the preceding section, the function is implemented using a non-destructive
approach which merges the generated Resources into previously generated instances.
@@ -112,7 +112,7 @@
directory, and invoke `run` on the `local-resource/` directory.
# run the function
kustomize fn run local-resource/
kustomize config run local-resource/
cpu-requests missing for a container in Deployment nginx (example-use.yaml [1])
Error: exit status 1
Usage:
@@ -124,7 +124,7 @@
and print the name of the file + Resource index. Edit the file and uncomment the resources,
then re-run the functions.
kustomize fn run local-resource/
kustomize config run local-resource/
The validation now passes.
@@ -139,7 +139,7 @@
directory, and invoke `run` on the `local-resource/` directory.
# print the resources
kustomize cfg tree local-resource --resources --name
kustomize config tree local-resource --resources --name
local-resource
├── [example-use.yaml] Validator
└── [example-use.yaml] Deployment nginx
@@ -148,10 +148,10 @@
└── name: nginx
# run the functions
kustomize fn run local-resource/
kustomize config run local-resource/
# print the new resources
kustomize cfg tree local-resource --resources --name
kustomize config tree local-resource --resources --name
├── [example-use.yaml] Validator
└── [example-use.yaml] Deployment nginx
└── spec.template.spec.containers
@@ -163,8 +163,8 @@
Change the `tshirt-size` annotation from `medium` to `small` and re-run the functions.
kustomize fn run local-resource/
kustomize cfg tree local-resource/
kustomize config run local-resource/
kustomize config tree local-resource/
local-resource
├── [example-use.yaml] Validator
└── [example-use.yaml] Deployment nginx

View File

@@ -3,12 +3,10 @@
package ext
import (
"path/filepath"
)
import "path/filepath"
// GetOpenAPIFile returns the path to the file containing supplementary OpenAPI definitions.
// Maybe be overridden to configure which file to read OpenAPI definitions from.
var GetOpenAPIFile = func(args []string) (string, error) {
return filepath.Join(args[0], "Krmfile"), nil
return filepath.Join(args[0], "kustomization"), nil
}

View File

@@ -9,5 +9,4 @@ set -e
: "${kyaml_patch?Need to source VERSIONS}"
go mod edit -dropreplace=sigs.k8s.io/kustomize/kyaml@v0.0.0
go mod edit -dropreplace=sigs.k8s.io/kustomize/kyaml@v0.1.13
go mod edit -require=sigs.k8s.io/kustomize/kyaml@v$kyaml_major.$kyaml_minor.$kyaml_patch

View File

@@ -1,6 +1,6 @@
module sigs.k8s.io/kustomize/cmd/config
go 1.14
go 1.13
require (
github.com/go-errors/errors v1.0.1
@@ -10,27 +10,6 @@ require (
github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.4.0
k8s.io/apimachinery v0.17.3
k8s.io/cli-runtime v0.17.3
k8s.io/client-go v0.17.3
k8s.io/kubectl v0.0.0-20191219154910-1528d4eea6dd
sigs.k8s.io/cli-utils v0.12.0
// TODO: Fix this -- this should depend on v0.0.0 and be replaced (below),
// however the cli-runtime dependency causes `go mod` to set this as the
// dependency.
k8s.io/apimachinery v0.17.0
sigs.k8s.io/kustomize/kyaml v0.1.13 // Don't change this!
)
// TODO: Fix this -- we sould only depend on v0.0.0 and replace that one.
//
// This line is managed by the release script -- releasing/releasemodule.sh
// Pinning to a released version of kyaml will invalidate the e2e tests used to
// test kyaml changes as the e2e tests will run against the pinned version, not
// the HEAD.
//
// releasing/releasemodule.sh will remove this line and set the require version
// to the kyaml version specified in releasing/VERSIONS
replace (
sigs.k8s.io/kustomize/kyaml v0.0.0 => ../../kyaml
sigs.k8s.io/kustomize/kyaml v0.1.13 => ../../kyaml
)

View File

@@ -1,20 +1,6 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
github.com/360EntSecGroup-Skylar/excelize v1.4.1/go.mod h1:vnax29X2usfl7HHkBrX5EvSCJcmH3dT9luvxzu8iGAE=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU=
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
@@ -36,66 +22,32 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8=
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0 h1:w3NnFcKR5241cfmQU5ZZAsf0xcpId6mWOupTvJlUX2U=
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustmop/soup v1.1.2-0.20190516214245-38228baa104e/go.mod h1:CgNC6SGbT+Xb8wGGvzilttZL1mc5sQ/5KkcxsZttMIk=
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M=
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
@@ -104,10 +56,7 @@ github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/zapr v0.1.0 h1:h+WVe9j6HAA01niTJPA/kKH0i7e0rLZBCwauQFcRE54=
github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
@@ -161,7 +110,6 @@ github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tF
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
github.com/go-openapi/validate v0.19.8 h1:YFzsdWIDfVuLvIOF+ZmKjVg1MbPJ1QgY9PihMwei1ys=
github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
@@ -172,22 +120,12 @@ github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09Vjb
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8=
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
@@ -195,56 +133,30 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk=
github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.3.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
@@ -253,9 +165,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -264,54 +173,34 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
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/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
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/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.4.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/paulmach/orb v0.1.3/go.mod h1:VFlX/8C+IQ1p6FTRRKzKoOPJnvEtA5G0Veuqwbu//Vk=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -319,53 +208,35 @@ github.com/posener/complete/v2 v2.0.1-alpha.12 h1:0wvkuDfHb5vSZlNBYgpEH4XQHpF46M
github.com/posener/complete/v2 v2.0.1-alpha.12/go.mod h1://JlL91cS2JV7rOl6LVHrRqBXoBUecJu3ILQPgbJiMQ=
github.com/posener/script v1.0.4 h1:nSuXW5ZdmFnQIueLB2s0qvs4oNsUloM1Zydzh75v42w=
github.com/posener/script v1.0.4/go.mod h1:Rg3ijooqulo05aGLyGsHoLmIOUzHUVK19WVgrYBPU/E=
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d h1:K6eOUihrFLdZjZnA4XlRp864fmWXv9YTIk7VPLhRacA=
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d/go.mod h1:7DPO4domFU579Ga6E61sB9VFNaniPVwJP5C4bBCu3wA=
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -378,120 +249,68 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8=
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI=
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.2 h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA=
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.starlark.net v0.0.0-20190528202925-30ae18b8564f/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg=
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/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/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/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-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
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-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180117170059-2c42eef0765b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c h1:Vco5b+cuG5NNfORVxZy6bYZQ7rsigisU1WQFkvQ0L5E=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20171227012246-e19ae1496984/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -499,138 +318,39 @@ golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/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-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
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.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.0.0/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2 h1:XZx7nhd5GMaZpmDaEHFVafUZC7ya0fuo7cSJ3UCKYmM=
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
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=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/api v0.0.0-20190918155943-95b840bb6a1f/go.mod h1:uWuOHnjmNrtQomJrvEBg0c0HRNyQ+8KTEERVsK0PW48=
k8s.io/api v0.0.0-20191214185829-ca1d04f8b0d3/go.mod h1:itOjKREfmUTvcjantxOsyYU5mbFsU7qUnyUuRfF5+5M=
k8s.io/api v0.17.2/go.mod h1:BS9fjjLc4CMuqfSO8vgbHPKMt5+SF0ET6u/RVDihTo4=
k8s.io/api v0.17.3 h1:XAm3PZp3wnEdzekNkcmj/9Y1zdmQYJ1I4GKSBBZ8aG0=
k8s.io/api v0.17.3/go.mod h1:YZ0OTkuw7ipbe305fMpIdf3GLXZKRigjtZaV5gzC2J0=
k8s.io/apiextensions-apiserver v0.0.0-20190918161926-8f644eb6e783/go.mod h1:xvae1SZB3E17UpV59AWc271W/Ph25N+bjPyR63X6tPY=
k8s.io/apiextensions-apiserver v0.17.2 h1:cP579D2hSZNuO/rZj9XFRzwJNYb41DbNANJb6Kolpss=
k8s.io/apiextensions-apiserver v0.17.2/go.mod h1:4KdMpjkEjjDI2pPfBA15OscyNldHWdBCfsWMDWAmSTs=
k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655/go.mod h1:nL6pwRT8NgfF8TT68DBI8uEePRt89cSvoXUVqbkWHq4=
k8s.io/apimachinery v0.0.0-20191214185652-442f8fb2f03a/go.mod h1:Ng1IY8TS7sC44KJxT/WUR6qFRfWwahYYYpNXyYRKOCY=
k8s.io/apimachinery v0.0.0-20191216025728-0ee8b4573e3a/go.mod h1:Ng1IY8TS7sC44KJxT/WUR6qFRfWwahYYYpNXyYRKOCY=
k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
k8s.io/apimachinery v0.17.3 h1:f+uZV6rm4/tHE7xXgLyToprg6xWairaClGVkm2t8omg=
k8s.io/apimachinery v0.17.3/go.mod h1:gxLnyZcGNdZTCLnq3fgzyg2A5BVCHTNDFrw8AmuJ+0g=
k8s.io/apiserver v0.0.0-20190918160949-bfa5e2e684ad/go.mod h1:XPCXEwhjaFN29a8NldXA901ElnKeKLrLtREO9ZhFyhg=
k8s.io/apiserver v0.17.2/go.mod h1:lBmw/TtQdtxvrTk0e2cgtOxHizXI+d0mmGQURIHQZlo=
k8s.io/cli-runtime v0.0.0-20191214191754-e6dc6d5c8724/go.mod h1:wzlq80lvjgHW9if6MlE4OIGC86MDKsy5jtl9nxz/IYY=
k8s.io/cli-runtime v0.17.2/go.mod h1:aa8t9ziyQdbkuizkNLAw3qe3srSyWh9zlSB7zTqRNPI=
k8s.io/cli-runtime v0.17.3 h1:0ZlDdJgJBKsu77trRUynNiWsRuAvAVPBNaQfnt/1qtc=
k8s.io/cli-runtime v0.17.3/go.mod h1:X7idckYphH4SZflgNpOOViSxetiMj6xI0viMAjM81TA=
k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90/go.mod h1:J69/JveO6XESwVgG53q3Uz5OSfgsv4uxpScmmyYOOlk=
k8s.io/client-go v0.0.0-20191214190045-a32a6f7a3052/go.mod h1:tAaoc/sYuIL0+njJefSAmE28CIcxyaFV4kbIujBlY2s=
k8s.io/client-go v0.0.0-20191219150334-0b8da7416048/go.mod h1:ZEe8ZASDUAuqVGJ+UN0ka0PfaR+b6a6E1PGsSNZRui8=
k8s.io/client-go v0.17.2/go.mod h1:QAzRgsa0C2xl4/eVpeVAZMvikCn8Nm81yqVx3Kk9XYI=
k8s.io/client-go v0.17.3 h1:deUna1Ksx05XeESH6XGCyONNFfiQmDdqeqUvicvP6nU=
k8s.io/client-go v0.17.3/go.mod h1:cLXlTMtWHkuK4tD360KpWz2gG2KtdWEr/OT02i3emRQ=
k8s.io/code-generator v0.0.0-20190912054826-cd179ad6a269/go.mod h1:V5BD6M4CyaN5m+VthcclXWsVcT1Hu+glwa1bi3MIsyE=
k8s.io/code-generator v0.0.0-20191214185510-0b9b3c99f9f2/go.mod h1:BjGKcoq1MRUmcssvHiSxodCco1T6nVIt4YeCT5CMSao=
k8s.io/code-generator v0.17.2/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
k8s.io/component-base v0.0.0-20190918160511-547f6c5d7090/go.mod h1:933PBGtQFJky3TEwYx4aEPZ4IxqhWh3R6DCmzqIn1hA=
k8s.io/component-base v0.0.0-20191214190519-d868452632e2/go.mod h1:wupxkh1T/oUDqyTtcIjiEfpbmIHGm8By/vqpSKC6z8c=
k8s.io/component-base v0.17.2 h1:0XHf+cerTvL9I5Xwn9v+0jmqzGAZI7zNydv4tL6Cw6A=
k8s.io/component-base v0.17.2/go.mod h1:zMPW3g5aH7cHJpKYQ/ZsGMcgbsA/VyhEugF3QT1awLs=
k8s.io/apimachinery v0.17.0 h1:xRBnuie9rXcPxUkDizUsGvPf1cnlZCFu210op7J7LJo=
k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kubectl v0.0.0-20191219154910-1528d4eea6dd h1:nZX5+wEqTu/EBIYjrZlFOA63z4+Zcy96lDkCZPU9a9c=
k8s.io/kubectl v0.0.0-20191219154910-1528d4eea6dd/go.mod h1:9ehGcuUGjXVZh0qbYSB0vvofQw2JQe6c6cO0k4wu/Oo=
k8s.io/metrics v0.0.0-20191214191643-6b1944c9f765/go.mod h1:5V7rewilItwK0cz4nomU0b3XCcees2Ka5EBYWS1HBeM=
k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo=
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
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/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
sigs.k8s.io/cli-utils v0.12.0 h1:+CvYwQAEtKvcx/NaUVF9rDKvY91VwJj+i7D2lWBMYc0=
sigs.k8s.io/cli-utils v0.12.0/go.mod h1:H35YA5iJIM7EVNgqDTjX2dgt4wE23zmnXOTSTlyD+PE=
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/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
sigs.k8s.io/kustomize/kyaml v0.1.4 h1:cDG2u7v6CTAZmWKzCjk0hKG7AIN+2mCHx2ifwPbvKrs=
sigs.k8s.io/kustomize/kyaml v0.1.4/go.mod h1:461i94nj0h0ylJ6w83jLkR4SqqVhn1iY6fjD0JSTQeE=
sigs.k8s.io/kustomize/kyaml v0.1.13 h1:EQ2+kUPmlUvBQ62Icxst3gtD09GLNW4PjtJspxkCmpc=
sigs.k8s.io/kustomize/kyaml v0.1.13/go.mod h1:72/rLkSi+L/pHM1oCjwrf3ClU+tH5kZQvvdLSqIHwWU=
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 v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU=
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=
sigs.k8s.io/testing_frameworks v0.1.2 h1:vK0+tvjF0BZ/RYFeZ1E6BYBwHJJXhjuZ3TdsEKH+UQM=
sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI=

View File

@@ -50,8 +50,6 @@ func NewCreateSetterRunner(parent string) *CreateSetterRunner {
set.Flags().MarkHidden("partial")
set.Flags().StringVar(&setterVersion, "version", "",
"use this version of the setter format")
set.Flags().BoolVar(&r.CreateSetter.Required, "required", false,
"indicates that this setter must be set by package consumer before live apply/preview")
set.Flags().StringVar(&r.CreateSetter.SchemaPath, "schema-path", "",
`openAPI schema file path for setter constraints -- file content `+
`e.g. {"type": "string", "maxLength": 15, "enum": ["allowedValue1", "allowedValue2"]}`)
@@ -93,9 +91,7 @@ func (r *CreateSetterRunner) preRunE(c *cobra.Command, args []string) error {
}
if setterVersion == "" {
if len(args) == 2 && r.Set.SetPartialField.Type == "array" && c.Flag("field").Changed {
setterVersion = "v2"
} else if len(args) < 2 || !c.Flag("value").Changed && len(args) < 3 {
if len(args) < 2 || !c.Flag("value").Changed && len(args) < 3 {
setterVersion = "v1"
} else if err := initSetterVersion(c, args); err != nil {
return err
@@ -128,12 +124,6 @@ func (r *CreateSetterRunner) preRunE(c *cobra.Command, args []string) error {
r.CreateSetter.Description = r.Set.SetPartialField.Description
r.CreateSetter.SetBy = r.Set.SetPartialField.SetBy
r.CreateSetter.Type = r.Set.SetPartialField.Type
if r.CreateSetter.Type == "array" {
if !c.Flag("field").Changed {
return errors.Errorf("field flag must be set for array type setters")
}
}
}
return nil
}

View File

@@ -65,44 +65,6 @@ spec:
replicas: 3 # {"$openapi":"replicas"}
`,
},
{
name: "add replicas no match",
args: []string{"replicas", "3", "--description", "hello world", "--set-by", "me"},
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
foo: 2
`,
inputOpenAPI: `
apiVersion: v1alpha1
kind: Example
`,
expectedOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.replicas:
description: hello world
x-k8s-cli:
setter:
name: replicas
value: "3"
setBy: me
`,
expectedResources: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
foo: 2
`,
},
{
name: "error if substitution with same name exists",
args: []string{"my-image", "3", "--description", "hello world", "--set-by", "me"},
@@ -167,140 +129,15 @@ spec:
},
{
name: "list values with schema",
args: []string{"list", "--description", "hello world", "--set-by", "me", "--type", "array", "--field", "spec.list"},
schema: `{"maxItems": 3, "type": "array", "items": {"type": "string"}}`,
input: `
apiVersion: example.com/v1beta1
kind: Example1
spec:
list:
- "a"
- "b"
- "c"
---
apiVersion: example.com/v1beta1
kind: Example2
spec:
list:
- "a"
- "b"
- "c"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: myspace
spec:
replicas: 3
template:
spec:
containers:
- name: sidecar
image: nginx:1.7.9
- name: nginx
image: otherspace/nginx:1.7.9
`,
inputOpenAPI: `
apiVersion: v1alpha1
kind: Example
`,
expectedOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.list:
items:
type: string
maxItems: 3
type: array
description: hello world
x-k8s-cli:
setter:
name: list
value: ""
listValues:
- a
- b
- c
setBy: me
`,
expectedResources: `
apiVersion: example.com/v1beta1
kind: Example1
spec:
list: # {"$openapi":"list"}
- "a"
- "b"
- "c"
---
apiVersion: example.com/v1beta1
kind: Example2
spec:
list: # {"$openapi":"list"}
- "a"
- "b"
- "c"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: myspace
spec:
replicas: 3
template:
spec:
containers:
- name: sidecar
image: nginx:1.7.9
- name: nginx
image: otherspace/nginx:1.7.9
`,
},
{
name: "error list path with different values",
args: []string{"list", "--description", "hello world", "--set-by", "me", "--type", "array", "--field", "spec.list"},
schema: `{"maxItems": 3, "type": "array", "items": {"type": "string"}}`,
input: `
apiVersion: example.com/v1beta1
kind: Example
spec:
list:
- "a"
- "b"
- "c"
---
apiVersion: example.com/v1beta1
kind: Example
spec:
list:
- "c"
- "d"
`,
inputOpenAPI: `
apiVersion: v1alpha1
kind: Example
`,
err: `setters can only be created for fields with same values, encountered different ` +
`array values for specified field path: [c d], [a b c]`,
},
{
name: "list values error if field not set",
name: "add replicas with schema list values",
args: []string{"list", "a", "--description", "hello world", "--set-by", "me", "--type", "array"},
schema: `{"maxItems": 3, "type": "array", "items": {"type": "string"}}`,
schema: `{"maxItems": 2, "type": "array", "items": {"type": "string"}}`,
input: `
apiVersion: example.com/v1beta1
kind: Example
spec:
list:
- "a"
- "b"
- "c"
`,
inputOpenAPI: `
apiVersion: v1alpha1
@@ -314,28 +151,22 @@ openAPI:
io.k8s.cli.setters.list:
items:
type: string
maxItems: 3
maxItems: 2
type: array
description: hello world
x-k8s-cli:
setter:
name: list
listValues:
- a
- b
- c
value: a
setBy: me
`,
expectedResources: `
apiVersion: example.com/v1beta1
kind: Example
spec:
list: # {"$openapi":"list"}
- "a"
- "b"
- "c"
list:
- "a" # {"$openapi":"list"}
`,
err: `field flag must be set for array type setters`,
},
{
name: "add replicas with value set by flag",

View File

@@ -88,31 +88,16 @@ func (r *CreateSubstitutionRunner) preRunE(c *cobra.Command, args []string) erro
re := regexp.MustCompile(`\$\{([^}]*)\}`)
markers := re.FindAll([]byte(r.CreateSubstitution.Pattern), -1)
if len(markers) == 0 {
return errors.Errorf("unable to find setter or substitution names in pattern, " +
return errors.Errorf("unable to find setter names in pattern, " +
"setter names must be enclosed in ${}")
}
for _, marker := range markers {
name := strings.TrimSuffix(strings.TrimPrefix(string(marker), "${"), "}")
ref, err := spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SubstitutionDefinitionPrefix + name)
if err != nil {
return err
}
var markerRef string
subst, _ := openapi.Resolve(&ref)
// check if the substitution exists with the marker name or fall back to creating setter
// ref with the name
if subst != nil {
markerRef = fieldmeta.DefinitionsPrefix + fieldmeta.SubstitutionDefinitionPrefix + name
} else {
markerRef = fieldmeta.DefinitionsPrefix + fieldmeta.SetterDefinitionPrefix + name
}
ref := fieldmeta.DefinitionsPrefix + fieldmeta.SetterDefinitionPrefix +
strings.TrimSuffix(strings.TrimPrefix(string(marker), "${"), "}")
r.CreateSubstitution.Values = append(
r.CreateSubstitution.Values,
setters2.Value{Marker: string(marker), Ref: markerRef},
setters2.Value{Marker: string(marker), Ref: ref},
)
}

View File

@@ -149,16 +149,6 @@ apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.substitutions.my-image-subst:
x-k8s-cli:
substitution:
name: my-image-subst
pattern: something/${my-image-setter}::${my-tag-setter}/nginxotherthing
values:
- marker: ${my-image-setter}
ref: '#/definitions/io.k8s.cli.setters.my-image-setter'
- marker: ${my-tag-setter}
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
io.k8s.cli.setters.my-image-setter:
x-k8s-cli:
setter:
@@ -169,6 +159,16 @@ openAPI:
setter:
name: my-tag-setter
value: 1.7.9
io.k8s.cli.substitutions.my-image-subst:
x-k8s-cli:
substitution:
name: my-image-subst
pattern: something/${my-image-setter}::${my-tag-setter}/nginxotherthing
values:
- marker: ${my-image-setter}
ref: '#/definitions/io.k8s.cli.setters.my-image-setter'
- marker: ${my-tag-setter}
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
`,
expectedResources: `
apiVersion: apps/v1
@@ -186,228 +186,6 @@ spec:
image: sidecar:1.7.9
`,
},
{
name: "nested substitution",
args: []string{
"my-nested-subst", "--field-value", "something/nginx::1.7.9/nginxotherthing",
"--pattern", "something/${my-image-subst}/${my-other-setter}"},
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
spec:
containers:
- name: nginx
image: something/nginx::1.7.9/nginxotherthing
- name: sidecar
image: nginx::1.7.9 # {"$openapi":"my-image-subst"}
`,
inputOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.my-image-setter:
x-k8s-cli:
setter:
name: my-image-setter
value: nginx
io.k8s.cli.setters.my-tag-setter:
x-k8s-cli:
setter:
name: my-tag-setter
value: 1.7.9
io.k8s.cli.substitutions.my-image-subst:
x-k8s-cli:
substitution:
name: my-image-subst
pattern: ${my-image-setter}::${my-tag-setter}
values:
- marker: ${my-image-setter}
ref: '#/definitions/io.k8s.cli.setters.my-image-setter'
- marker: ${my-tag-setter}
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
`,
expectedOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.my-image-setter:
x-k8s-cli:
setter:
name: my-image-setter
value: nginx
io.k8s.cli.setters.my-tag-setter:
x-k8s-cli:
setter:
name: my-tag-setter
value: 1.7.9
io.k8s.cli.substitutions.my-image-subst:
x-k8s-cli:
substitution:
name: my-image-subst
pattern: ${my-image-setter}::${my-tag-setter}
values:
- marker: ${my-image-setter}
ref: '#/definitions/io.k8s.cli.setters.my-image-setter'
- marker: ${my-tag-setter}
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
io.k8s.cli.substitutions.my-nested-subst:
x-k8s-cli:
substitution:
name: my-nested-subst
pattern: something/${my-image-subst}/${my-other-setter}
values:
- marker: ${my-image-subst}
ref: '#/definitions/io.k8s.cli.substitutions.my-image-subst'
- marker: ${my-other-setter}
ref: '#/definitions/io.k8s.cli.setters.my-other-setter'
io.k8s.cli.setters.my-other-setter:
x-k8s-cli:
setter:
name: my-other-setter
value: nginxotherthing
`,
expectedResources: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
spec:
containers:
- name: nginx
image: something/nginx::1.7.9/nginxotherthing # {"$openapi":"my-nested-subst"}
- name: sidecar
image: nginx::1.7.9 # {"$openapi":"my-image-subst"}
`,
},
{
name: "nested cyclic substitution",
args: []string{"my-nested-subst", "--field-value", "something/nginx::1.7.9/nginxotherthing",
"--pattern", "something/${my-image-subst}/${my-other-setter}"},
inputOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.my-image-setter:
x-k8s-cli:
setter:
name: my-image-setter
value: nginx
io.k8s.cli.setters.my-tag-setter:
x-k8s-cli:
setter:
name: my-tag-setter
value: 1.7.9
io.k8s.cli.substitutions.my-image-subst:
x-k8s-cli:
substitution:
name: my-image-subst
pattern: ${my-nested-subst}::${my-tag-setter}
values:
- marker: ${my-nested-subst}
ref: '#/definitions/io.k8s.cli.substitutions.my-nested-subst'
- marker: ${my-tag-setter}
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
io.k8s.cli.setters.my-other-setter:
x-k8s-cli:
setter:
name: my-other-setter
value: nginxotherthing
io.k8s.cli.substitutions.my-nested-subst:
x-k8s-cli:
substitution:
name: my-nested-subst
pattern: something/${my-image-subst}/${my-other-setter}
values:
- marker: ${my-image-subst}
ref: '#/definitions/io.k8s.cli.substitutions.my-image-subst'
- marker: ${my-other-setter}
ref: '#/definitions/io.k8s.cli.setters.my-other-setter'
`,
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
spec:
containers:
- name: nginx
image: something/nginx::1.7.9/nginxotherthing # {"$openapi":"my-nested-subst"}
- name: sidecar
image: nginx::1.7.9 # {"$openapi":"my-image-subst"}
`,
expectedOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.my-image-setter:
x-k8s-cli:
setter:
name: my-image-setter
value: nginx
io.k8s.cli.setters.my-tag-setter:
x-k8s-cli:
setter:
name: my-tag-setter
value: 1.7.9
io.k8s.cli.substitutions.my-image-subst:
x-k8s-cli:
substitution:
name: my-image-subst
pattern: ${my-nested-subst}::${my-tag-setter}
values:
- marker: ${my-nested-subst}
ref: '#/definitions/io.k8s.cli.substitutions.my-nested-subst'
- marker: ${my-tag-setter}
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
io.k8s.cli.setters.my-other-setter:
x-k8s-cli:
setter:
name: my-other-setter
value: nginxotherthing
io.k8s.cli.substitutions.my-nested-subst:
x-k8s-cli:
substitution:
name: my-nested-subst
pattern: something/${my-image-subst}/${my-other-setter}
values:
- marker: ${my-image-subst}
ref: '#/definitions/io.k8s.cli.substitutions.my-image-subst'
- marker: ${my-other-setter}
ref: '#/definitions/io.k8s.cli.setters.my-other-setter'
`,
expectedResources: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
spec:
containers:
- name: nginx
image: something/nginx::1.7.9/nginxotherthing # {"$openapi":"my-nested-subst"}
- name: sidecar
image: nginx::1.7.9 # {"$openapi":"my-image-subst"}
`,
err: "cyclic substitution detected with name my-nested-subst",
},
}
for i := range tests {
test := tests[i]

View File

@@ -1,63 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package commands
import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
)
// NewDeleteRunner returns a command runner.
func NewDeleteSetterRunner(parent string) *DeleteSetterRunner {
r := &DeleteSetterRunner{}
c := &cobra.Command{
Use: "delete-setter DIR NAME",
Args: cobra.MinimumNArgs(2),
Short: "delete values on Resources fields.",
Long: "",
Example: "",
PreRunE: r.preRunE,
RunE: r.runE,
}
fixDocs(parent, c)
r.Command = c
return r
}
func DeleteSetterCommand(parent string) *cobra.Command {
return NewDeleteSetterRunner(parent).Command
}
type DeleteSetterRunner struct {
Command *cobra.Command
DeleteSetter settersutil.DeleterCreator
OpenAPIFile string
}
func (r *DeleteSetterRunner) preRunE(c *cobra.Command, args []string) error {
var err error
r.DeleteSetter.Name = args[1]
r.OpenAPIFile, err = ext.GetOpenAPIFile(args)
if err != nil {
return err
}
if err := openapi.AddSchemaFromFile(r.OpenAPIFile); err != nil {
return err
}
return nil
}
func (r *DeleteSetterRunner) runE(c *cobra.Command, args []string) error {
return handleError(c, r.delete(c, args))
}
func (r *DeleteSetterRunner) delete(c *cobra.Command, args []string) error {
return r.DeleteSetter.Delete(r.OpenAPIFile, args[0])
}

View File

@@ -1,302 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package commands_test
import (
"bytes"
"io/ioutil"
"os"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
"sigs.k8s.io/kustomize/kyaml/openapi"
)
func TestDeleteSetterCommand(t *testing.T) {
var tests = []struct {
name string
input string
args []string
schema string
out string
inputOpenAPI string
expectedOpenAPI string
expectedResources string
err string
}{
{
name: "delete replicas",
args: []string{"replicas", "hello world"},
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3 # {"$openapi" : "replicas"}}
`,
inputOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.replicas:
description: hello world
x-k8s-cli:
setter:
name: replicas
value: "3"
setBy: me
`,
expectedOpenAPI: `
apiVersion: v1alpha1
kind: Example
`,
expectedResources: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
`,
},
{
name: "delete only one setter",
args: []string{"replicas", "hello world"},
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3 # {"$openapi" : "replicas"}}
`,
inputOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.replicas:
description: hello world
x-k8s-cli:
setter:
name: replicas
value: "3"
setBy: me
io.k8s.cli.setters.image:
x-k8s-cli:
setter:
name: image
value: 1.0
`,
expectedOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.image:
x-k8s-cli:
setter:
name: image
value: 1.0
`,
expectedResources: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
`,
},
{
name: "delete non exist setter error",
args: []string{"image", "hello world"},
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3 # {"$openapi" : "replicas"}}
`,
inputOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.replicas:
description: hello world
x-k8s-cli:
setter:
name: replicas
value: "3"
setBy: me
`,
expectedOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.replicas:
description: hello world
x-k8s-cli:
setter:
name: replicas
value: "3"
setBy: me
`,
expectedResources: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3 # {"$openapi" : "replicas"}}
`,
err: `setter does not exist`,
},
{
name: "delete setter used in substitution error",
args: []string{"image-name", "hello world"},
input: `
apiVersion: apps/v1
kind: Deployment
`,
inputOpenAPI: `
openAPI:
definitions:
io.k8s.cli.setters.image-name:
x-k8s-cli:
setter:
name: image-name
value: "nginx"
io.k8s.cli.setters.image-tag:
x-k8s-cli:
setter:
name: image-tag
value: "1.8.1"
io.k8s.cli.substitutions.image:
x-k8s-cli:
substitution:
name: image
pattern: IMAGE_NAME:IMAGE_TAG
values:
- marker: "IMAGE_NAME"
ref: "#/definitions/io.k8s.cli.setters.image-name"
- marker: "IMAGE_TAG"
ref: "#/definitions/io.k8s.cli.setters.image-tag"
`,
expectedOpenAPI: `
openAPI:
definitions:
io.k8s.cli.setters.image-name:
x-k8s-cli:
setter:
name: image-name
value: "nginx"
io.k8s.cli.setters.image-tag:
x-k8s-cli:
setter:
name: image-tag
value: "1.8.1"
io.k8s.cli.substitutions.image:
x-k8s-cli:
substitution:
name: image
pattern: IMAGE_NAME:IMAGE_TAG
values:
- marker: "IMAGE_NAME"
ref: "#/definitions/io.k8s.cli.setters.image-name"
- marker: "IMAGE_TAG"
ref: "#/definitions/io.k8s.cli.setters.image-tag"
`,
expectedResources: `
apiVersion: apps/v1
kind: Deployment
`,
err: `setter is used in substitution image, please delete the substitution first`,
},
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
// reset the openAPI afterward
openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI()
f, err := ioutil.TempFile("", "k8s-cli-")
if !assert.NoError(t, err) {
t.FailNow()
}
defer os.Remove(f.Name())
err = ioutil.WriteFile(f.Name(), []byte(test.inputOpenAPI), 0600)
if !assert.NoError(t, err) {
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")
if !assert.NoError(t, err) {
t.FailNow()
}
defer os.Remove(r.Name())
err = ioutil.WriteFile(r.Name(), []byte(test.input), 0600)
if !assert.NoError(t, err) {
t.FailNow()
}
runner := commands.NewDeleteSetterRunner("")
out := &bytes.Buffer{}
runner.Command.SetOut(out)
runner.Command.SetArgs(append([]string{r.Name()}, test.args...))
err = runner.Command.Execute()
if test.err != "" {
if !assert.NotNil(t, err) {
t.FailNow()
} else {
assert.Equal(t, err.Error(), test.err)
return
}
}
if !assert.NoError(t, err) {
t.FailNow()
}
if !assert.Equal(t, test.out, out.String()) {
t.FailNow()
}
actualResources, err := ioutil.ReadFile(r.Name())
if !assert.NoError(t, err) {
t.FailNow()
}
if !assert.Equal(t,
strings.TrimSpace(test.expectedResources),
strings.TrimSpace(string(actualResources))) {
t.FailNow()
}
actualOpenAPI, err := ioutil.ReadFile(f.Name())
if !assert.NoError(t, err) {
t.FailNow()
}
if !assert.Equal(t,
strings.TrimSpace(test.expectedOpenAPI),
strings.TrimSpace(string(actualOpenAPI))) {
t.FailNow()
}
})
}
}

View File

@@ -1,60 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package commands
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/krmfile"
)
// GetInitRunner returns a command InitRunner.
func GetInitRunner(name string) *InitRunner {
r := &InitRunner{}
c := &cobra.Command{
Use: "init DIR...",
Args: cobra.RangeArgs(0, 1),
Short: commands.InitShort,
Long: commands.InitLong,
Example: commands.InitExamples,
RunE: r.runE,
}
fixDocs(name, c)
r.Command = c
return r
}
func InitCommand(name string) *cobra.Command {
return GetInitRunner(name).Command
}
// InitRunner contains the init function
type InitRunner struct {
Command *cobra.Command
}
func (r *InitRunner) runE(c *cobra.Command, args []string) error {
var dir string
if len(args) == 0 {
dir = "."
} else {
dir = args[0]
}
filename := filepath.Join(dir, krmfile.KrmfileName)
if _, err := os.Stat(filename); err == nil || !os.IsNotExist(err) {
return errors.Errorf("directory already initialized with a Krmfile")
}
return ioutil.WriteFile(filename, []byte(strings.TrimSpace(`
apiVersion: config.k8s.io/v1alpha1
kind: Krmfile
`)), 0600)
}

View File

@@ -32,8 +32,6 @@ func NewListSettersRunner(parent string) *ListSettersRunner {
}
c.Flags().BoolVar(&r.Markdown, "markdown", false,
"output as github markdown")
c.Flags().BoolVar(&r.IncludeSubst, "include-subst", false,
"include substitutions in the output")
fixDocs(parent, c)
r.Command = c
return r
@@ -44,11 +42,10 @@ func ListSettersCommand(parent string) *cobra.Command {
}
type ListSettersRunner struct {
Command *cobra.Command
Lookup setters.LookupSetters
List setters2.List
Markdown bool
IncludeSubst bool
Command *cobra.Command
Lookup setters.LookupSetters
List setters2.List
Markdown bool
}
func (r *ListSettersRunner) preRunE(c *cobra.Command, args []string) error {
@@ -66,10 +63,7 @@ func (r *ListSettersRunner) runE(c *cobra.Command, args []string) error {
if err := r.ListSetters(c, args); err != nil {
return err
}
if r.IncludeSubst {
return r.ListSubstitutions(c, args)
}
return nil
return r.ListSubstitutions(c, args)
}
return handleError(c, lookup(r.Lookup, c, args))
@@ -85,7 +79,7 @@ func (r *ListSettersRunner) ListSetters(c *cobra.Command, args []string) error {
return err
}
table := newTable(c.OutOrStdout(), r.Markdown)
table.SetHeader([]string{"NAME", "VALUE", "SET BY", "DESCRIPTION", "COUNT", "REQUIRED"})
table.SetHeader([]string{"NAME", "VALUE", "SET BY", "DESCRIPTION", "COUNT"})
for i := range r.List.Setters {
s := r.List.Setters[i]
v := s.Value
@@ -95,14 +89,8 @@ func (r *ListSettersRunner) ListSetters(c *cobra.Command, args []string) error {
v = strings.Join(s.ListValues, ",")
v = fmt.Sprintf("[%s]", v)
}
var required string
if s.Required {
required = "Yes"
} else {
required = "No"
}
table.Append([]string{
s.Name, v, s.SetBy, s.Description, fmt.Sprintf("%d", s.Count), required})
s.Name, v, s.SetBy, s.Description, fmt.Sprintf("%d", s.Count)})
}
table.Render()
@@ -125,28 +113,26 @@ func (r *ListSettersRunner) ListSubstitutions(c *cobra.Command, args []string) e
return err
}
table := newTable(c.OutOrStdout(), r.Markdown)
b := tablewriter.Border{Top: true}
table.SetBorders(b)
table.SetHeader([]string{"SUBSTITUTION", "PATTERN", "REFERENCES"})
table.SetHeader([]string{"SUBSTITUTION", "PATTERN", "SETTERS"})
for i := range r.List.Substitutions {
s := r.List.Substitutions[i]
refs := ""
setters := ""
for _, value := range s.Values {
// trim setter and substitution prefixes
ref := strings.TrimPrefix(
strings.TrimPrefix(value.Ref, fieldmeta.DefinitionsPrefix+fieldmeta.SetterDefinitionPrefix),
fieldmeta.DefinitionsPrefix+fieldmeta.SubstitutionDefinitionPrefix)
refs = refs + "," + ref
setter := strings.TrimPrefix(value.Ref, fieldmeta.DefinitionsPrefix+fieldmeta.SetterDefinitionPrefix)
setters = setters + "," + setter
}
refs = fmt.Sprintf("[%s]", strings.TrimPrefix(refs, ","))
setters = fmt.Sprintf("[%s]", strings.TrimPrefix(setters, ","))
table.Append([]string{
s.Name, s.Pattern, refs})
s.Name, s.Pattern, setters})
}
if len(r.List.Substitutions) == 0 {
return nil
// exit non-0 if no matching substitutions are found
if ExitOnError {
os.Exit(1)
}
} else {
table.Render()
}
table.Render()
return nil
}

View File

@@ -7,7 +7,6 @@ import (
"bytes"
"io/ioutil"
"os"
"strings"
"testing"
"github.com/stretchr/testify/assert"
@@ -35,7 +34,6 @@ openAPI:
name: replicas
value: "3"
setBy: me
required: true
description: "hello world"
`,
input: `
@@ -46,39 +44,12 @@ metadata:
spec:
replicas: 3 # {"$ref": "#/definitions/io.k8s.cli.setters.replicas"}
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
replicas 3 me hello world 1 Yes
`,
},
{
name: "list-replicas inconsistent with openapi",
openapi: `
openAPI:
definitions:
io.k8s.cli.setters.replicas:
x-k8s-cli:
setter:
name: replicas
value: "4"
setBy: me
description: "hello world"
`,
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3 # {"$ref": "#/definitions/io.k8s.cli.setters.replicas"}
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
replicas 4 me hello world 1 No
expected: ` NAME VALUE SET BY DESCRIPTION COUNT
replicas 3 me hello world 1
`,
},
{
name: "list-multiple",
args: []string{"--include-subst"},
openapi: `
openAPI:
definitions:
@@ -103,8 +74,6 @@ openAPI:
name: tag
value: "1.7.9"
setBy: me3
required: true
isSet: false
io.k8s.cli.substitutions.image:
x-k8s-cli:
substitution:
@@ -131,18 +100,16 @@ spec:
- name: nginx2
image: nginx # {"$ref": "#/definitions/io.k8s.cli.setters.image"}
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
image nginx me2 hello world 2 2 No
replicas 3 me1 hello world 1 1 No
tag 1.7.9 me3 hello world 3 1 Yes
--------------- ----------- --------------
SUBSTITUTION PATTERN REFERENCES
expected: ` NAME VALUE SET BY DESCRIPTION COUNT
image nginx me2 hello world 2 2
replicas 3 me1 hello world 1 1
tag 1.7.9 me3 hello world 3 1
SUBSTITUTION PATTERN SETTERS
image IMAGE:TAG [image,tag]
`,
},
{
name: "list-multiple-resources",
args: []string{"--include-subst"},
openapi: `
openAPI:
definitions:
@@ -207,12 +174,11 @@ spec:
- name: nginx2
image: nginx
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
image nginx me2 hello world 2 3 No
replicas 3 me1 hello world 1 2 No
tag 1.7.9 me3 hello world 3 2 No
--------------- ----------- --------------
SUBSTITUTION PATTERN REFERENCES
expected: ` NAME VALUE SET BY DESCRIPTION COUNT
image nginx me2 hello world 2 3
replicas 3 me1 hello world 1 2
tag 1.7.9 me3 hello world 3 2
SUBSTITUTION PATTERN SETTERS
image IMAGE:TAG [image,tag]
`,
},
@@ -236,7 +202,6 @@ openAPI:
name: image
value: "nginx"
setBy: me2
required: true
io.k8s.cli.setters.tag:
description: "hello world 3"
x-k8s-cli:
@@ -244,10 +209,10 @@ openAPI:
name: tag
value: "1.7.9"
setBy: me3
io.k8s.cli.substitutions.image-subst:
io.k8s.cli.substitutions.image:
x-k8s-cli:
substitution:
name: image-subst
name: image
pattern: IMAGE:TAG
values:
- marker: IMAGE
@@ -266,7 +231,7 @@ spec:
spec:
containers:
- name: nginx
image: nginx:1.7.9 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image-subst"}
image: nginx:1.7.9 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
- name: nginx2
image: nginx # {"$ref": "#/definitions/io.k8s.cli.setters.image"}
---
@@ -280,124 +245,14 @@ spec:
spec:
containers:
- name: nginx
image: nginx:1.7.9 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image-subst"}
image: nginx:1.7.9 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
- name: nginx2
image: nginx
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
image nginx me2 hello world 2 3 Yes
`,
},
{
name: "list array setter",
openapi: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.list:
items:
type: string
maxItems: 3
type: array
description: hello world
x-k8s-cli:
setter:
name: list
listValues:
- a
- b
- c
setBy: me
required: true
`,
input: `
apiVersion: example.com/v1beta1
kind: Example
metadata:
annotations:
foo: bar
spec:
list: # {"$openapi":"list"}
- "a"
- "b"
- "c"
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
list [a,b,c] me hello world 1 Yes
`,
},
{
name: "nested substitution",
args: []string{"--include-subst"},
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
spec:
containers:
- name: nginx
image: something/nginx::1.7.9/nginxotherthing # {"$openapi":"my-nested-subst"}
- name: sidecar
image: nginx::1.7.9 # {"$openapi":"my-image-subst"}
`,
openapi: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.my-image-setter:
x-k8s-cli:
setter:
name: my-image-setter
value: nginx
io.k8s.cli.setters.my-tag-setter:
x-k8s-cli:
setter:
name: my-tag-setter
value: 1.7.9
required: true
isSet: true
io.k8s.cli.substitutions.my-image-subst:
x-k8s-cli:
substitution:
name: my-image-subst
pattern: ${my-image-setter}::${my-tag-setter}
values:
- marker: ${my-image-setter}
ref: '#/definitions/io.k8s.cli.setters.my-image-setter'
- marker: ${my-tag-setter}
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
io.k8s.cli.substitutions.my-nested-subst:
x-k8s-cli:
substitution:
name: my-nested-subst
pattern: something/${my-image-subst}/${my-other-setter}
values:
- marker: ${my-image-subst}
ref: '#/definitions/io.k8s.cli.substitutions.my-image-subst'
- marker: ${my-other-setter}
ref: '#/definitions/io.k8s.cli.setters.my-other-setter'
io.k8s.cli.setters.my-other-setter:
x-k8s-cli:
setter:
name: my-other-setter
value: nginxotherthing
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
my-image-setter nginx 2 No
my-other-setter nginxotherthing 1 No
my-tag-setter 1.7.9 2 Yes
------------------ ------------------------------------------------ -----------------------------------
SUBSTITUTION PATTERN REFERENCES
my-image-subst ${my-image-setter}::${my-tag-setter} [my-image-setter,my-tag-setter]
my-nested-subst something/${my-image-subst}/${my-other-setter} [my-image-subst,my-other-setter]
expected: ` NAME VALUE SET BY DESCRIPTION COUNT
image nginx me2 hello world 2 3
SUBSTITUTION PATTERN SETTERS
image IMAGE:TAG [image,tag]
`,
},
}
@@ -445,27 +300,6 @@ openAPI:
if !assert.Equal(t, test.expected, actual.String()) {
t.FailNow()
}
// make sure that the resources are not altered
actualResources, err := ioutil.ReadFile(r.Name())
if !assert.NoError(t, err) {
t.FailNow()
}
if !assert.Equal(t,
strings.TrimSpace(test.input),
strings.TrimSpace(string(actualResources))) {
t.FailNow()
}
actualOpenAPI, err := ioutil.ReadFile(f.Name())
if !assert.NoError(t, err) {
t.FailNow()
}
if !assert.Equal(t,
strings.TrimSpace(test.openapi),
strings.TrimSpace(string(actualOpenAPI))) {
t.FailNow()
}
})
}
}

View File

@@ -64,7 +64,6 @@ openAPI:
name: replicas
value: "4"
setBy: pw
isSet: true
`,
expectedResources: `
apiVersion: apps/v1
@@ -159,7 +158,6 @@ openAPI:
setter:
name: replicas
value: "4"
isSet: true
`,
expectedResources: `
apiVersion: apps/v1
@@ -170,7 +168,6 @@ spec:
replicas: 4 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
`,
},
{
name: "set image with value",
args: []string{"tag", "1.8.1"},
@@ -231,7 +228,6 @@ openAPI:
setter:
name: tag
value: "1.8.1"
isSet: true
io.k8s.cli.substitutions.image:
x-k8s-cli:
substitution:
@@ -242,6 +238,7 @@ openAPI:
ref: '#/definitions/io.k8s.cli.setters.image-setter'
- marker: TAG
ref: '#/definitions/io.k8s.cli.setters.tag'
`,
expectedResources: `
apiVersion: apps/v1
@@ -435,6 +432,7 @@ openAPI:
ref: '#/definitions/io.k8s.cli.setters.image'
- marker: TAG
ref: '#/definitions/io.k8s.cli.setters.tag'
`,
expectedResources: `
apiVersion: apps/v1
@@ -542,7 +540,6 @@ openAPI:
setter:
name: replicas
value: "4"
isSet: true
`,
expectedResources: `
apiVersion: apps/v1
@@ -643,7 +640,6 @@ openAPI:
listValues:
- "10"
- "11"
isSet: true
`,
expectedResources: `
apiVersion: example.com/v1beta1
@@ -706,241 +702,6 @@ spec:
list in body must be of type integer: "boolean"
list in body should have at most 2 items`,
},
{
name: "nested substitution",
args: []string{"my-image-setter", "ubuntu"},
out: "set 2 fields\n",
inputOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.my-image-setter:
x-k8s-cli:
setter:
name: my-image-setter
value: nginx
io.k8s.cli.setters.my-tag-setter:
x-k8s-cli:
setter:
name: my-tag-setter
value: 1.7.9
io.k8s.cli.substitutions.my-image-subst:
x-k8s-cli:
substitution:
name: my-image-subst
pattern: ${my-image-setter}::${my-tag-setter}
values:
- marker: ${my-image-setter}
ref: '#/definitions/io.k8s.cli.setters.my-image-setter'
- marker: ${my-tag-setter}
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
io.k8s.cli.setters.my-other-setter:
x-k8s-cli:
setter:
name: my-other-setter
value: nginxotherthing
io.k8s.cli.substitutions.my-nested-subst:
x-k8s-cli:
substitution:
name: my-nested-subst
pattern: something/${my-image-subst}/${my-other-setter}
values:
- marker: ${my-image-subst}
ref: '#/definitions/io.k8s.cli.substitutions.my-image-subst'
- marker: ${my-other-setter}
ref: '#/definitions/io.k8s.cli.setters.my-other-setter'
`,
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
spec:
containers:
- name: nginx
image: something/nginx::1.7.9/nginxotherthing # {"$openapi":"my-nested-subst"}
- name: sidecar
image: nginx::1.7.9 # {"$openapi":"my-image-subst"}
`,
expectedOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.my-image-setter:
x-k8s-cli:
setter:
name: my-image-setter
value: ubuntu
isSet: true
io.k8s.cli.setters.my-tag-setter:
x-k8s-cli:
setter:
name: my-tag-setter
value: 1.7.9
io.k8s.cli.substitutions.my-image-subst:
x-k8s-cli:
substitution:
name: my-image-subst
pattern: ${my-image-setter}::${my-tag-setter}
values:
- marker: ${my-image-setter}
ref: '#/definitions/io.k8s.cli.setters.my-image-setter'
- marker: ${my-tag-setter}
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
io.k8s.cli.setters.my-other-setter:
x-k8s-cli:
setter:
name: my-other-setter
value: nginxotherthing
io.k8s.cli.substitutions.my-nested-subst:
x-k8s-cli:
substitution:
name: my-nested-subst
pattern: something/${my-image-subst}/${my-other-setter}
values:
- marker: ${my-image-subst}
ref: '#/definitions/io.k8s.cli.substitutions.my-image-subst'
- marker: ${my-other-setter}
ref: '#/definitions/io.k8s.cli.setters.my-other-setter'
`,
expectedResources: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
spec:
containers:
- name: nginx
image: something/ubuntu::1.7.9/nginxotherthing # {"$openapi":"my-nested-subst"}
- name: sidecar
image: ubuntu::1.7.9 # {"$openapi":"my-image-subst"}
`,
},
{
name: "nested cyclic substitution",
args: []string{"my-image-setter", "ubuntu"},
inputOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.my-image-setter:
x-k8s-cli:
setter:
name: my-image-setter
value: nginx
io.k8s.cli.setters.my-tag-setter:
x-k8s-cli:
setter:
name: my-tag-setter
value: 1.7.9
io.k8s.cli.substitutions.my-image-subst:
x-k8s-cli:
substitution:
name: my-image-subst
pattern: ${my-nested-subst}::${my-tag-setter}
values:
- marker: ${my-nested-subst}
ref: '#/definitions/io.k8s.cli.substitutions.my-nested-subst'
- marker: ${my-tag-setter}
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
io.k8s.cli.setters.my-other-setter:
x-k8s-cli:
setter:
name: my-other-setter
value: nginxotherthing
io.k8s.cli.substitutions.my-nested-subst:
x-k8s-cli:
substitution:
name: my-nested-subst
pattern: something/${my-image-subst}/${my-other-setter}
values:
- marker: ${my-image-subst}
ref: '#/definitions/io.k8s.cli.substitutions.my-image-subst'
- marker: ${my-other-setter}
ref: '#/definitions/io.k8s.cli.setters.my-other-setter'
`,
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
spec:
containers:
- name: nginx
image: something/nginx::1.7.9/nginxotherthing # {"$openapi":"my-nested-subst"}
- name: sidecar
image: nginx::1.7.9 # {"$openapi":"my-image-subst"}
`,
expectedOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.my-image-setter:
x-k8s-cli:
setter:
name: my-image-setter
value: nginx
io.k8s.cli.setters.my-tag-setter:
x-k8s-cli:
setter:
name: my-tag-setter
value: 1.7.9
io.k8s.cli.substitutions.my-image-subst:
x-k8s-cli:
substitution:
name: my-image-subst
pattern: ${my-nested-subst}::${my-tag-setter}
values:
- marker: ${my-nested-subst}
ref: '#/definitions/io.k8s.cli.substitutions.my-nested-subst'
- marker: ${my-tag-setter}
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
io.k8s.cli.setters.my-other-setter:
x-k8s-cli:
setter:
name: my-other-setter
value: nginxotherthing
io.k8s.cli.substitutions.my-nested-subst:
x-k8s-cli:
substitution:
name: my-nested-subst
pattern: something/${my-image-subst}/${my-other-setter}
values:
- marker: ${my-image-subst}
ref: '#/definitions/io.k8s.cli.substitutions.my-image-subst'
- marker: ${my-other-setter}
ref: '#/definitions/io.k8s.cli.setters.my-other-setter'
`,
expectedResources: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
spec:
containers:
- name: nginx
image: something/nginx::1.7.9/nginxotherthing # {"$openapi":"my-nested-subst"}
- name: sidecar
image: nginx::1.7.9 # {"$openapi":"my-image-subst"}
`,
errMsg: "cyclic substitution detected with name my-nested-subst",
},
}
for i := range tests {
test := tests[i]

View File

@@ -1,57 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package e2e
import (
"testing"
)
func TestCreateSetter(t *testing.T) {
tests := []test{
{
name: "create_setter",
args: []string{"cfg", "create-setter", ".", "replicas", "3"},
files: map[string]string{
"deployment.yaml": `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
`,
"Krmfile": `
apiVersion: config.k8s.io/v1alpha1
kind: Krmfile
`,
},
expectedFiles: map[string]string{
"deployment.yaml": `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3 # {"$openapi":"replicas"}
`,
"Krmfile": `
apiVersion: config.k8s.io/v1alpha1
kind: Krmfile
openAPI:
definitions:
io.k8s.cli.setters.replicas:
x-k8s-cli:
setter:
name: replicas
value: "3"
`,
},
},
}
runTests(t, tests)
}

View File

@@ -12,7 +12,6 @@ import (
"path/filepath"
"runtime"
"strings"
"sync"
"testing"
"github.com/stretchr/testify/assert"
@@ -20,7 +19,12 @@ import (
)
func TestRunE2e(t *testing.T) {
binDir := build()
binDir, err := ioutil.TempDir("", "kustomize-test-")
if !assert.NoError(t, err) {
t.FailNow()
}
defer os.RemoveAll(binDir)
build(t, binDir)
tests := []struct {
name string
@@ -30,7 +34,6 @@ func TestRunE2e(t *testing.T) {
expectedErr string
skipIfFalseEnv string
}{
{
name: "exec_function_no_args",
args: func(d string) []string {
@@ -64,36 +67,6 @@ metadata:
},
},
{
name: "exec_function_no_args_json",
args: func(d string) []string {
return []string{
"--enable-exec", "--exec-path", filepath.Join(d, "e2econtainerconfig"),
}
},
files: func(d string) map[string]string {
return map[string]string{
"deployment.json": `
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "foo"
}
}
`,
}
},
expectedFiles: func(d string) map[string]string {
return map[string]string{
"deployment.json": `
{"apiVersion": "apps/v1", "kind": "Deployment", "metadata": {"name": "foo", annotations: {
a-string-value: '', a-int-value: '0', a-bool-value: 'false'}}}
`,
}
},
},
{
name: "exec_function_args",
args: func(d string) []string {
@@ -499,6 +472,7 @@ def run(r, fc):
resource["metadata"]["annotations"]["a-string-value"] = fc["data"]["stringValue"]
resource["metadata"]["annotations"]["a-int-value"] = fc["data"]["intValue"]
resource["metadata"]["annotations"]["a-bool-value"] = fc["data"]["boolValue"]
run(ctx.resource_list["items"], ctx.resource_list["functionConfig"])
`,
"config.yaml": `
@@ -575,6 +549,7 @@ def run(r, fc):
resource["metadata"]["annotations"]["a-string-value"] = fc["data"]["stringValue"]
resource["metadata"]["annotations"]["a-int-value"] = fc["data"]["intValue"]
resource["metadata"]["annotations"]["a-bool-value"] = fc["data"]["boolValue"]
run(ctx.resource_list["items"], ctx.resource_list["functionConfig"])
`,
"deployment.yaml": `
@@ -686,7 +661,6 @@ metadata:
},
}
// TODO: dedup this with the shared version
for i := range tests {
tt := tests[i]
t.Run(tt.name, func(t *testing.T) {
@@ -707,7 +681,7 @@ metadata:
testutil.AssertNoError(t, err)
}
args := append([]string{"fn", "run", "."}, tt.args(binDir)...)
args := append([]string{"run", "."}, tt.args(binDir)...)
cmd := exec.Command(filepath.Join(binDir, kyamlBin), args...)
cmd.Dir = dir
var stdErr, stdOut bytes.Buffer
@@ -736,54 +710,36 @@ metadata:
}
}
var buildOnce sync.Once
var binDir string
func build(t *testing.T, binDir string) {
build := exec.Command("go", "build", "-o",
filepath.Join(binDir, e2econtainerconfigBin))
build.Dir = "e2econtainerconfig"
build.Stdout = os.Stdout
build.Stderr = os.Stderr
build.Env = os.Environ()
if !assert.NoError(t, build.Run()) {
t.FailNow()
}
func build() string {
// only build the binaries once
buildOnce.Do(func() {
var err error
binDir, err = ioutil.TempDir("", "kustomize-test-")
if err != nil {
panic(err)
}
build = exec.Command("go", "build", "-o", filepath.Join(binDir, kyamlBin))
build.Dir = filepath.Join("..", "..", "..")
build.Stdout = os.Stdout
build.Stderr = os.Stderr
if !assert.NoError(t, build.Run()) {
t.FailNow()
}
build := exec.Command("go", "build", "-o",
filepath.Join(binDir, e2econtainerconfigBin))
build.Dir = "e2econtainerconfig"
build.Stdout = os.Stdout
build.Stderr = os.Stderr
build.Env = os.Environ()
err = build.Run()
if err != nil {
panic(err)
}
build = exec.Command("go", "build", "-o", filepath.Join(binDir, kyamlBin))
build.Dir = filepath.Join("..", "..", "..", "kubectl-krm")
build.Stdout = os.Stdout
build.Stderr = os.Stderr
err = build.Run()
if err != nil {
panic(err)
}
if os.Getenv("KUSTOMIZE_DOCKER_E2E") == "false" {
return
}
build = exec.Command(
"docker", "build", ".", "-t", "gcr.io/kustomize-functions/e2econtainerconfig")
build.Dir = "e2econtainerconfig"
build.Stdout = os.Stdout
build.Stderr = os.Stderr
err = build.Run()
if err != nil {
panic(err)
}
})
return binDir
if os.Getenv("KUSTOMIZE_DOCKER_E2E") == "false" {
return
}
build = exec.Command(
"docker", "build", ".", "-t", "gcr.io/kustomize-functions/e2econtainerconfig")
build.Dir = "e2econtainerconfig"
build.Stdout = os.Stdout
build.Stderr = os.Stderr
if !assert.NoError(t, build.Run()) {
t.FailNow()
}
}
var (
@@ -792,11 +748,11 @@ var (
)
func init() {
kyamlBin = "kubectl-krm"
kyamlBin = "kyaml"
e2econtainerconfigBin = "e2econtainerconfig"
if runtime.GOOS == "windows" {
kyamlBin = "kubectl-krm.exe"
kyamlBin = "kyaml.exe"
e2econtainerconfigBin = "e2econtainerconfig.exe"
}
}

View File

@@ -1,33 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package e2e
import "testing"
func TestInit(t *testing.T) {
tests := []test{
{
name: "init",
args: []string{"cfg", "init"},
expectedFiles: map[string]string{
"Krmfile": `
apiVersion: config.k8s.io/v1alpha1
kind: Krmfile
`,
},
},
{
name: "init",
args: []string{"cfg", "init", "."},
expectedFiles: map[string]string{
"Krmfile": `
apiVersion: config.k8s.io/v1alpha1
kind: Krmfile
`,
},
},
}
runTests(t, tests)
}

View File

@@ -1,43 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package e2e
import "testing"
func TestListSetters(t *testing.T) {
tests := []test{
{
name: "set",
args: []string{"cfg", "list-setters", "."},
files: map[string]string{
"deployment.yaml": `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3 # {"$openapi":"replicas"}
`,
"Krmfile": `
apiVersion: config.k8s.io/v1alpha1
kind: Krmfile
openAPI:
definitions:
io.k8s.cli.setters.replicas:
x-k8s-cli:
setter:
name: replicas
value: "3"
`,
},
expectedStdOut: `
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
replicas 3 1 No
`,
},
}
runTests(t, tests)
}

View File

@@ -1,63 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package e2e
import "testing"
func TestSet(t *testing.T) {
tests := []test{
{
name: "set",
args: []string{"cfg", "set", ".", "replicas", "4"},
files: map[string]string{
"deployment.yaml": `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3 # {"$openapi":"replicas"}
`,
"Krmfile": `
apiVersion: config.k8s.io/v1alpha1
kind: Krmfile
openAPI:
definitions:
io.k8s.cli.setters.replicas:
x-k8s-cli:
setter:
name: replicas
value: "3"
`,
},
expectedFiles: map[string]string{
"deployment.yaml": `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 4 # {"$openapi":"replicas"}
`,
"Krmfile": `
apiVersion: config.k8s.io/v1alpha1
kind: Krmfile
openAPI:
definitions:
io.k8s.cli.setters.replicas:
x-k8s-cli:
setter:
name: replicas
value: "4"
isSet: true
`,
},
},
}
runTests(t, tests)
}

View File

@@ -1,86 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package e2e
import (
"bytes"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/kyaml/testutil"
)
func TestMain(m *testing.M) {
d := build()
defer os.RemoveAll(d)
os.Exit(m.Run())
}
type test struct {
name string
args []string
files map[string]string
expectedFiles map[string]string
expectedErr string
expectedStdOut string
}
func runTests(t *testing.T, tests []test) {
dir := build()
bin := filepath.Join(dir, kyamlBin)
for i := range tests {
tt := tests[i]
t.Run(tt.name, func(t *testing.T) {
dataDir, err := ioutil.TempDir("", "kustomize-test-data-")
if !assert.NoError(t, err) {
t.FailNow()
}
defer os.RemoveAll(dataDir)
os.Chdir(dataDir)
// write the input
for path, data := range tt.files {
err := ioutil.WriteFile(path, []byte(data), 0600)
testutil.AssertNoError(t, err)
}
cmd := exec.Command(bin, tt.args...)
cmd.Dir = dataDir
var stdErr, stdOut bytes.Buffer
cmd.Stdout = &stdOut
cmd.Stderr = &stdErr
cmd.Env = os.Environ()
err = cmd.Run()
if tt.expectedErr != "" {
if !assert.Contains(t, stdErr.String(), tt.expectedErr, stdErr.String()) {
t.FailNow()
}
return
}
testutil.AssertNoError(t, err, stdErr.String(), stdOut.String())
if tt.expectedStdOut != "" {
if !assert.Equal(t, strings.TrimSpace(stdOut.String()), strings.TrimSpace(tt.expectedStdOut)) {
t.FailNow()
}
}
for path, data := range tt.expectedFiles {
b, err := ioutil.ReadFile(path)
testutil.AssertNoError(t, err, stdErr.String())
if !assert.Equal(t, strings.TrimSpace(data), strings.TrimSpace(string(b)), stdErr.String()) {
t.FailNow()
}
}
})
}
}

Some files were not shown because too many files have changed in this diff Show More