Compare commits

..

1 Commits

Author SHA1 Message Date
Jeff Regan
f59f12947b Update release instructions. 2020-08-28 11:39:17 -07:00
370 changed files with 7224 additions and 75523 deletions

View File

@@ -1,68 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ""
labels:
- kind/bug
assignees: ""
---
<!--
Please read this page: https://kubernetes-sigs.github.io/kustomize/contributing/bugs/ before
filing a bug
-->
<!-- Feel free to skip the sections if they are not applicable. -->
**Describe the bug**
<!-- A clear and concise description of what the bug is. -->
**Files that can reproduce the issue**
<!--
We cannot figure out or fix the issue if we don't know how to reproduce. Please
provide a minimum set of files that can reproduce the issue. You can paste the
file contents here or provide a link to a tarball or git repo.
Example:
kustomization.yaml
```
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
...
```
resources.yaml
```
apiVersion: v1
kind: Deployment
...
```
...
-->
**Expected output**
<!-- What's the expected output? -->
**Actual output**
<!-- What's the actual output? -->
**Kustomize version**
<!-- Please use the latest version when it's possible. -->
**Platform**
<!-- Linux/macOS/Windows? -->
**Additional context**
<!-- Add any other context about the problem here. -->

View File

@@ -1 +0,0 @@
blank_issues_enabled: true

View File

@@ -1,26 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ""
labels:
- kind/feature
assignees: ""
---
<!-- Feel free to skip the sections if they are not applicable. -->
**Is your feature request related to a problem? Please describe.**
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
**Describe the solution you'd like**
<!-- A clear and concise description of what you want to happen. -->
**Describe alternatives you've considered**
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->

View File

@@ -1,9 +0,0 @@
---
name: Question
about: Ask a question about the kustomize
title: "[Question]"
labels: ""
assignees: ""
---
<!-- Please describe your question here -->

View File

@@ -15,8 +15,7 @@ verify-kustomize: \
lint-kustomize \ lint-kustomize \
test-unit-kustomize-all \ test-unit-kustomize-all \
test-examples-kustomize-against-HEAD \ test-examples-kustomize-against-HEAD \
test-examples-kustomize-against-3.8.0 \ test-examples-kustomize-against-3.8.0
test-examples-kustomize-against-3.8.2
# The following target referenced by a file in # The following target referenced by a file in
# https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/kustomize # https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/kustomize
@@ -27,8 +26,7 @@ prow-presubmit-check: \
test-unit-cmd-all \ test-unit-cmd-all \
test-go-mod \ test-go-mod \
test-examples-kustomize-against-HEAD \ test-examples-kustomize-against-HEAD \
test-examples-kustomize-against-3.8.0 \ test-examples-kustomize-against-3.8.0
test-examples-kustomize-against-3.8.2
.PHONY: verify-kustomize-e2e .PHONY: verify-kustomize-e2e
verify-kustomize-e2e: test-examples-e2e-kustomize verify-kustomize-e2e: test-examples-e2e-kustomize
@@ -47,18 +45,17 @@ $(MYGOBIN)/golangci-lint-kustomize:
GO111MODULE=on go build -tags=tools -o $(MYGOBIN)/golangci-lint-kustomize github.com/golangci/golangci-lint/cmd/golangci-lint; \ GO111MODULE=on go build -tags=tools -o $(MYGOBIN)/golangci-lint-kustomize github.com/golangci/golangci-lint/cmd/golangci-lint; \
) )
$(MYGOBIN)/gorepomod: # Version pinned by api/go.mod
cd api; \
go install github.com/monopole/gorepomod
$(MYGOBIN)/mdrip: $(MYGOBIN)/mdrip:
cd api; \ cd api; \
go install github.com/monopole/mdrip go install github.com/monopole/mdrip
# Version pinned by api/go.mod
$(MYGOBIN)/stringer: $(MYGOBIN)/stringer:
cd api; \ cd api; \
go install golang.org/x/tools/cmd/stringer go install golang.org/x/tools/cmd/stringer
# Version pinned by api/go.mod
$(MYGOBIN)/goimports: $(MYGOBIN)/goimports:
cd api; \ cd api; \
go install golang.org/x/tools/cmd/goimports go install golang.org/x/tools/cmd/goimports
@@ -84,8 +81,6 @@ $(MYGOBIN)/kustomize:
install-tools: \ install-tools: \
$(MYGOBIN)/goimports \ $(MYGOBIN)/goimports \
$(MYGOBIN)/golangci-lint-kustomize \ $(MYGOBIN)/golangci-lint-kustomize \
$(MYGOBIN)/gh \
$(MYGOBIN)/gorepomod \
$(MYGOBIN)/mdrip \ $(MYGOBIN)/mdrip \
$(MYGOBIN)/pluginator \ $(MYGOBIN)/pluginator \
$(MYGOBIN)/stringer $(MYGOBIN)/stringer
@@ -250,19 +245,6 @@ test-examples-kustomize-against-3.8.0: $(MYGOBIN)/mdrip
cd kustomize; go install .; \ cd kustomize; go install .; \
) )
.PHONY:
test-examples-kustomize-against-3.8.2: $(MYGOBIN)/mdrip
( \
set -e; \
tag=v3.8.2; \
/bin/rm -f $(MYGOBIN)/kustomize; \
echo "Installing kustomize $$tag."; \
GO111MODULE=on go get sigs.k8s.io/kustomize/kustomize/v3@$${tag}; \
./hack/testExamplesAgainstKustomize.sh $$tag; \
echo "Reinstalling kustomize from HEAD."; \
cd kustomize; go install .; \
)
# linux only. # linux only.
# This is for testing an example plugin that # This is for testing an example plugin that
# uses kubeval for validation. # uses kubeval for validation.
@@ -322,18 +304,6 @@ $(MYGOBIN)/kind:
rm -rf $$d; \ rm -rf $$d; \
) )
# linux only.
$(MYGOBIN)/gh:
( \
set -e; \
d=$(shell mktemp -d); cd $$d; \
tgzFile=gh_1.0.0_linux_amd64.tar.gz; \
wget https://github.com/cli/cli/releases/download/v1.0.0/$$tgzFile; \
tar -xvzf $$tgzFile; \
mv gh_1.0.0_linux_amd64/bin/gh $(MYGOBIN)/gh; \
rm -rf $$d \
)
.PHONY: clean .PHONY: clean
clean: kustomize-external-go-plugin-clean clean: kustomize-external-go-plugin-clean
go clean --cache go clean --cache

View File

@@ -11,4 +11,3 @@ aliases:
- pwittrock - pwittrock
- mortent - mortent
- phanimarupaka - phanimarupaka
- Shell32-Natsu

View File

@@ -31,15 +31,14 @@ func (p *ImageTagTransformerPlugin) Config(
func (p *ImageTagTransformerPlugin) Transform(m resmap.ResMap) error { func (p *ImageTagTransformerPlugin) Transform(m resmap.ResMap) error {
for _, r := range m.Resources() { for _, r := range m.Resources() {
// traverse all fields at first // If you're here because someone expected any field containing
err := filtersutil.ApplyToJSON(imagetag.LegacyFilter{ // the string "containers" or "initContainers" to get an image
ImageTag: p.ImageTag, // update (not just spec/template/spec/containers[], etc.) then
}, r) // a code change is needed. See api/filters/imagetag/legacy
if err != nil { // for the start of an implementation that won't use an
return err // allowlist like FsSlice, and instead walks the object looking
} // for fields named containers or initContainers.
// then use user specified field specs err := filtersutil.ApplyToJSON(imagetag.Filter{
err = filtersutil.ApplyToJSON(imagetag.Filter{
ImageTag: p.ImageTag, ImageTag: p.ImageTag,
FsSlice: p.FieldSpecs, FsSlice: p.FieldSpecs,
}, r) }, r)

View File

@@ -33,7 +33,7 @@ func (p *NamespaceTransformerPlugin) Transform(m resmap.ResMap) error {
return nil return nil
} }
for _, r := range m.Resources() { for _, r := range m.Resources() {
if r.IsEmpty() { if len(r.Map()) == 0 {
// Don't mutate empty objects? // Don't mutate empty objects?
continue continue
} }

View File

@@ -94,14 +94,14 @@ func (p *PatchStrategicMergeTransformerPlugin) Transform(m resmap.ResMap) error
// Some unknown error, let it through. // Some unknown error, let it through.
return err return err
} }
if !target.IsEmpty() { if len(target.Map()) != 0 {
return errors.Wrapf( return errors.Wrapf(
err, "with unexpectedly non-empty object map of size %d", err, "with unexpectedly non-empty object map of size %d",
len(target.Map())) len(target.Map()))
} }
// Fall through to handle deleted object. // Fall through to handle deleted object.
} }
if target.IsEmpty() { if len(target.Map()) == 0 {
// This means all fields have been removed from the object. // This means all fields have been removed from the object.
// This can happen if a patch required deletion of the // This can happen if a patch required deletion of the
// entire resource (not just a part of it). This means // entire resource (not just a part of it). This means

View File

@@ -8,7 +8,6 @@ import (
"strings" "strings"
jsonpatch "github.com/evanphx/json-patch" jsonpatch "github.com/evanphx/json-patch"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/filters/patchjson6902" "sigs.k8s.io/kustomize/api/filters/patchjson6902"
"sigs.k8s.io/kustomize/api/filters/patchstrategicmerge" "sigs.k8s.io/kustomize/api/filters/patchstrategicmerge"
"sigs.k8s.io/kustomize/api/resmap" "sigs.k8s.io/kustomize/api/resmap"
@@ -102,31 +101,7 @@ func (p *PatchTransformerPlugin) transformStrategicMerge(m resmap.ResMap, patch
patchCopy.SetGvk(res.GetGvk()) patchCopy.SetGvk(res.GetGvk())
err := p.applySMPatch(res, patchCopy) err := p.applySMPatch(res, patchCopy)
if err != nil { if err != nil {
// Check for an error string from UnmarshalJSON that's indicative return err
// of an object that's missing basic KRM fields, and thus may have been
// entirely deleted (an acceptable outcome). This error handling should
// be deleted along with use of ResMap and apimachinery functions like
// UnmarshalJSON.
if !strings.Contains(err.Error(), "Object 'Kind' is missing") {
// Some unknown error, let it through.
return err
}
if !res.IsEmpty() {
return errors.Wrapf(
err, "with unexpectedly non-empty object map of size %d",
len(res.Map()))
}
// Fall through to handle deleted object.
}
if res.IsEmpty() {
// This means all fields have been removed from the object.
// This can happen if a patch required deletion of the
// entire resource (not just a part of it). This means
// the overall resmap must shrink by one.
err = m.Remove(res.CurId())
if err != nil {
return err
}
} }
} }
return nil return nil
@@ -139,15 +114,9 @@ func (p *PatchTransformerPlugin) applySMPatch(resource, patch *resource.Resource
if err != nil { if err != nil {
return err return err
} }
n, ns := resource.GetName(), resource.GetNamespace() return filtersutil.ApplyToJSON(patchstrategicmerge.Filter{
err = filtersutil.ApplyToJSON(patchstrategicmerge.Filter{
Patch: node, Patch: node,
}, resource) }, resource)
if !resource.IsEmpty() {
resource.SetName(n)
resource.SetNamespace(ns)
}
return err
} }
// transformJson6902 applies the provided json6902 patch // transformJson6902 applies the provided json6902 patch

View File

@@ -51,9 +51,6 @@ func (fltr Filter) filter(obj *yaml.RNode) error {
// found the field -- set its value // found the field -- set its value
return fltr.SetValue(obj) return fltr.SetValue(obj)
} }
if obj.IsTaggedNull() {
return nil
}
switch obj.YNode().Kind { switch obj.YNode().Kind {
case yaml.SequenceNode: case yaml.SequenceNode:
return fltr.seq(obj) return fltr.seq(obj)
@@ -70,7 +67,7 @@ func (fltr Filter) field(obj *yaml.RNode) error {
// lookup the field matching the next path element // lookup the field matching the next path element
var lookupField yaml.Filter var lookupField yaml.Filter
var kind yaml.Kind var kind yaml.Kind
tag := yaml.NodeTagEmpty tag := "" // TODO: change to yaml.NodeTagEmpty
switch { switch {
case !fltr.FieldSpec.CreateIfNotPresent || fltr.CreateKind == 0 || isSeq: case !fltr.FieldSpec.CreateIfNotPresent || fltr.CreateKind == 0 || isSeq:
// dont' create the field if we don't find it // dont' create the field if we don't find it
@@ -98,10 +95,9 @@ func (fltr Filter) field(obj *yaml.RNode) error {
return errors.WrapPrefixf(err, "fieldName: %s", fieldName) return errors.WrapPrefixf(err, "fieldName: %s", fieldName)
} }
// if the value exists, but is null and kind is set, // if the value exists, but is null, then change it to the creation type
// then change it to the creation type
// TODO: update yaml.LookupCreate to support this // TODO: update yaml.LookupCreate to support this
if field.YNode().Tag == yaml.NodeTagNull && yaml.IsCreate(kind) { if field.YNode().Tag == yaml.NodeTagNull {
field.YNode().Kind = kind field.YNode().Kind = kind
field.YNode().Tag = tag field.YNode().Tag = tag
} }

View File

@@ -433,6 +433,7 @@ spec:
SetValue: filtersutil.SetScalar("bar"), SetValue: filtersutil.SetScalar("bar"),
CreateKind: yaml.ScalarNode, CreateKind: yaml.ScalarNode,
}, },
error: "obj '' at path 'spec/containers/image': expected sequence or mapping node",
}, },
{ {
name: "filedname with slash '/'", name: "filedname with slash '/'",

View File

@@ -88,20 +88,12 @@ func (f Filter) setScalar(node *yaml.RNode) error {
func filterReferralCandidates( func filterReferralCandidates(
referrer *resource.Resource, referrer *resource.Resource,
matches []*resource.Resource, matches []*resource.Resource) []*resource.Resource {
target resid.Gvk,
) []*resource.Resource {
var ret []*resource.Resource var ret []*resource.Resource
for _, m := range matches { for _, m := range matches {
// If target kind is not ServiceAccount, we shouldn't consider condidates which if referrer.PrefixesSuffixesEquals(m) {
// doesn't have same namespace. ret = append(ret, m)
if target.Kind != "ServiceAccount" && m.GetNamespace() != referrer.GetNamespace() {
continue
} }
if !referrer.PrefixesSuffixesEquals(m) {
continue
}
ret = append(ret, m)
} }
return ret return ret
} }
@@ -126,7 +118,7 @@ func selectReferral(
// If there's more than one match, // If there's more than one match,
// filter the matches by prefix and suffix // filter the matches by prefix and suffix
if len(matches) > 1 { if len(matches) > 1 {
filteredMatches := filterReferralCandidates(referrer, matches, target) filteredMatches := filterReferralCandidates(referrer, matches)
if len(filteredMatches) > 1 { if len(filteredMatches) > 1 {
return "", "", fmt.Errorf( return "", "", fmt.Errorf(
"multiple matches for %s:\n %v", "multiple matches for %s:\n %v",

View File

@@ -168,44 +168,6 @@ metadata:
map: map:
name: newName name: newName
namespace: oldNs namespace: oldNs
`,
filter: Filter{
FieldSpec: types.FieldSpec{Path: "map"},
Target: resid.Gvk{
Group: "apps",
Version: "v1",
Kind: "Secret",
},
},
},
"null value": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep
map:
name: null
`,
candidates: `
apiVersion: apps/v1
kind: Secret
metadata:
name: newName
---
apiVersion: apps/v1
kind: NotSecret
metadata:
name: newName2
`,
originalNames: []string{"oldName", ""},
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep
map:
name: null
`, `,
filter: Filter{ filter: Filter{
FieldSpec: types.FieldSpec{Path: "map"}, FieldSpec: types.FieldSpec{Path: "map"},
@@ -255,6 +217,27 @@ func TestNamerefFilterUnhappy(t *testing.T) {
filter Filter filter Filter
originalNames []string originalNames []string
}{ }{
"invalid node type": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep
ref:
name: null
`,
candidates: "",
originalNames: []string{},
expected: "obj '' at path 'ref/name': node is expected to be either a string or a slice of string or a map of string",
filter: Filter{
FieldSpec: types.FieldSpec{Path: "ref/name"},
Target: resid.Gvk{
Group: "apps",
Version: "v1",
Kind: "Secret",
},
},
},
"multiple match": { "multiple match": {
input: ` input: `
apiVersion: apps/v1 apiVersion: apps/v1

View File

@@ -69,7 +69,7 @@ func (ns Filter) hacks(obj *yaml.RNode) error {
// metaNamespaceHack is a hack for implementing the namespace transform // metaNamespaceHack is a hack for implementing the namespace transform
// for the metadata.namespace field on namespace scoped resources. // for the metadata.namespace field on namespace scoped resources.
// namespace scoped resources are determined by NOT being present // namespace scoped resources are determined by NOT being present
// in a hard-coded list of cluster-scoped resource types (by apiVersion and kind). // in a blacklist of cluster-scoped resource types (by apiVersion and kind).
// //
// This hack should be updated to allow individual resources to specify // This hack should be updated to allow individual resources to specify
// if they are cluster scoped through either an annotation on the resources, // if they are cluster scoped through either an annotation on the resources,

View File

@@ -18,12 +18,7 @@ var _ kio.Filter = Filter{}
func (pf Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { func (pf Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
var result []*yaml.RNode var result []*yaml.RNode
for i := range nodes { for i := range nodes {
r, err := merge2.Merge( r, err := merge2.Merge(pf.Patch, nodes[i])
pf.Patch, nodes[i],
yaml.MergeOptions{
ListIncreaseDirection: yaml.MergeOptionsListPrepend,
},
)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -67,10 +67,10 @@ spec:
template: template:
spec: spec:
containers: containers:
- name: foo0
- name: foo1 - name: foo1
- name: foo2 - name: foo2
- name: foo3 - name: foo3
- name: foo0
`, `,
}, },
"volumes patch": { "volumes patch": {
@@ -107,10 +107,10 @@ spec:
template: template:
spec: spec:
volumes: volumes:
- name: foo0
- name: foo1 - name: foo1
- name: foo2 - name: foo2
- name: foo3 - name: foo3
- name: foo0
`, `,
}, },
"nested patch": { "nested patch": {
@@ -142,234 +142,6 @@ spec:
- name: nginx - name: nginx
args: args:
- def - def
`,
},
"remove mapping - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
$patch: delete
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers: []
`,
},
"replace mapping - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
$patch: replace
containers:
- name: new
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: new
`,
},
"merge mapping - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test1
$patch: merge
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test1
`,
},
"remove list - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- whatever
- $patch: delete
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec: {}
`,
},
"replace list - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: replace
image: replace
- $patch: replace
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: replace
image: replace
`,
},
"merge list - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test2
image: test2
- $patch: merge
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test2
image: test2
- name: test
image: test
`, `,
}, },
} }

View File

@@ -188,26 +188,6 @@ data:
FieldSpec: types.FieldSpec{Path: "data/slice2"}, FieldSpec: types.FieldSpec{Path: "data/slice2"},
}, },
}, },
"null value": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep
data:
FOO: null`,
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep
data:
FOO: null`,
filter: Filter{
MappingFunc: expansion2.MappingFuncFor(replacementCounts, map[string]interface{}{}),
FieldSpec: types.FieldSpec{Path: "data/FOO"},
},
},
} }
for tn, tc := range testCases { for tn, tc := range testCases {
@@ -280,6 +260,20 @@ data:
FieldSpec: types.FieldSpec{Path: "data"}, FieldSpec: types.FieldSpec{Path: "data"},
}, },
}, },
"null input": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep
data:
FOO: null`,
expectedError: "obj '' at path 'data/FOO': invalid type encountered 0",
filter: Filter{
MappingFunc: expansion2.MappingFuncFor(replacementCounts, map[string]interface{}{}),
FieldSpec: types.FieldSpec{Path: "data/FOO"},
},
},
} }
for tn, tc := range testCases { for tn, tc := range testCases {

View File

@@ -10,13 +10,15 @@ require (
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
github.com/stretchr/testify v1.4.0 github.com/stretchr/testify v1.4.0
github.com/yujunz/go-getter v1.4.1-lite github.com/yujunz/go-getter v1.4.1-lite
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e golang.org/x/tools v0.0.0-20191010075000-0337d82405ff
gopkg.in/yaml.v2 v2.3.0 gopkg.in/yaml.v2 v2.3.0
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71
k8s.io/api v0.17.0 k8s.io/api v0.17.0
k8s.io/apimachinery v0.17.0 k8s.io/apimachinery v0.17.0
k8s.io/client-go v0.17.0 k8s.io/client-go v0.17.0
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a
sigs.k8s.io/kustomize/kyaml v0.9.1 sigs.k8s.io/kustomize/kyaml v0.6.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/kyaml v0.6.1 => ../kyaml

View File

@@ -307,8 +307,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@@ -528,8 +526,6 @@ golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff h1:XdBG6es/oFDr1HwaxkxgVve7NB281QhxgK/i4voubFs= golang.org/x/tools v0.0.0-20191010075000-0337d82405ff h1:XdBG6es/oFDr1HwaxkxgVve7NB281QhxgK/i4voubFs=
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e h1:aZzprAO9/8oim3qStq3wc1Xuxx4QmAGriC4VU4ojemQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
@@ -588,8 +584,6 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphD
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4= mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw= mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/kustomize/kyaml v0.9.1 h1:T7aNUraSioQp0NHJZtYjIhL/q8mqRzCiHcAKdvo09go=
sigs.k8s.io/kustomize/kyaml v0.9.1/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@@ -132,7 +132,7 @@ func TestRefVarTransformer(t *testing.T) {
' at path 'data/slice': invalid value type expect a string`, ' at path 'data/slice': invalid value type expect a string`,
}, },
{ {
description: "var replacement in nil", description: "var replacement panic in nil",
given: given{ given: given{
varMap: map[string]interface{}{}, varMap: map[string]interface{}{},
fs: []types.FieldSpec{ fs: []types.FieldSpec{
@@ -150,19 +150,7 @@ func TestRefVarTransformer(t *testing.T) {
"nil": nil, // noticeably *not* a []string "nil": nil, // noticeably *not* a []string
}}).ResMap(), }}).ResMap(),
}, },
expected: expected{ errMessage: `obj '' at path 'data/nil': invalid type encountered 0`,
res: resmaptest_test.NewRmBuilder(
t, resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "cm1",
},
"data": map[string]interface{}{
"nil": nil, // noticeably *not* a []string
}}).ResMap(),
},
}, },
} }

View File

@@ -217,7 +217,7 @@ overview of each component with the following sections going into more details.
The overall structure is outlined in the following figure: The overall structure is outlined in the following figure:
![overview]( ![overview](
https://github.com/kubernetes-sigs/kustomize/blob/master/api/internal/crawl/pictures/token_config.png) https://sigs.k8s.io/kustomize/internal/tools/pictures/sys_arch.png)
#### Crawler #### Crawler
The leftmost component consists of a crawler with an http cache of GitHub The leftmost component consists of a crawler with an http cache of GitHub

View File

@@ -271,8 +271,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@@ -472,7 +470,6 @@ golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDq
golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
@@ -527,8 +524,8 @@ k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw= mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/kustomize/kyaml v0.9.1 h1:T7aNUraSioQp0NHJZtYjIhL/q8mqRzCiHcAKdvo09go= sigs.k8s.io/kustomize/kyaml v0.6.1 h1:mwffj5vt3MPdbWV3fZnnwol8SO7sUoGdgejBlvseyak=
sigs.k8s.io/kustomize/kyaml v0.9.1/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw= sigs.k8s.io/kustomize/kyaml v0.6.1/go.mod h1:bEzbO5pN9OvlEeCLvFHo8Pu7SA26Herc2m60UeWZBdI=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=

View File

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

View File

@@ -9,7 +9,6 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"os/exec" "os/exec"
"runtime"
"strings" "strings"
"github.com/google/shlex" "github.com/google/shlex"
@@ -51,14 +50,7 @@ func (p *ExecPlugin) ErrIfNotExecutable() error {
if err != nil { if err != nil {
return err return err
} }
// In Windows, it is not possible to determine whether a if f.Mode()&0111 == 0000 {
// file is executable through file mode.
// TODO: provide for setting the executable FileMode bit on Windows
// The (fs *fileStat) Mode() (m FileMode) {} function in
// https://golang.org/src/os/types_windows.go
// lacks the ability to set the FileMode executable bit in response
// to file data on Windows.
if f.Mode()&0111 == 0000 && runtime.GOOS != "windows" {
return fmt.Errorf("unexecutable plugin at: %s", p.path) return fmt.Errorf("unexecutable plugin at: %s", p.path)
} }
return nil return nil

View File

@@ -4,15 +4,12 @@
package execplugin_test package execplugin_test
import ( import (
"path/filepath"
"runtime"
"strings" "strings"
"testing" "testing"
"sigs.k8s.io/kustomize/api/filesys" "sigs.k8s.io/kustomize/api/filesys"
. "sigs.k8s.io/kustomize/api/internal/plugins/execplugin" . "sigs.k8s.io/kustomize/api/internal/plugins/execplugin"
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader" pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct" "sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/konfig" "sigs.k8s.io/kustomize/api/konfig"
fLdr "sigs.k8s.io/kustomize/api/loader" fLdr "sigs.k8s.io/kustomize/api/loader"
@@ -92,32 +89,3 @@ metadata:
t.Fatalf("unexpected arg array: %#v", p.Args()) t.Fatalf("unexpected arg array: %#v", p.Args())
} }
} }
func TestExecPlugin_ErrIfNotExecutable(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skipf("always returns nil on Windows")
}
srcRoot, err := utils.DeterminePluginSrcRoot(filesys.MakeFsOnDisk())
if err != nil {
t.Error(err)
}
// Test unexecutable plugin
unexecutablePlugin := filepath.Join(
srcRoot, "builtin", "", "secretgenerator", "SecretGenerator.so")
p := NewExecPlugin(unexecutablePlugin)
err = p.ErrIfNotExecutable()
if err == nil {
t.Fatalf("unexpected err: %v", err)
}
// Test executable plugin
executablePlugin := filepath.Join(
srcRoot, "someteam.example.com", "v1", "bashedconfigmap", "BashedConfigMap")
p = NewExecPlugin(executablePlugin)
err = p.ErrIfNotExecutable()
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
}

View File

@@ -74,10 +74,10 @@ func NewFnPlugin(o *types.FnPluginLoadingOptions) *FnPlugin {
runFns: runfn.RunFns{ runFns: runfn.RunFns{
Functions: []*yaml.RNode{}, Functions: []*yaml.RNode{},
Network: o.Network, Network: o.Network,
NetworkName: o.NetworkName,
EnableStarlark: o.EnableStar, EnableStarlark: o.EnableStar,
EnableExec: o.EnableExec, EnableExec: o.EnableExec,
StorageMounts: toStorageMounts(o.Mounts), StorageMounts: toStorageMounts(o.Mounts),
Env: o.Env,
}, },
} }
} }

View File

@@ -65,8 +65,8 @@ func TestLoader(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
for _, behavior := range []types.BuiltinPluginLoadingOptions{ for _, behavior := range []types.BuiltinPluginLoadingOptions{
/* types.BploUseStaticallyLinked, types.BploUseStaticallyLinked,
types.BploLoadFromFileSys */} { types.BploLoadFromFileSys} {
c, err := konfig.EnabledPluginConfig(behavior) c, err := konfig.EnabledPluginConfig(behavior)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@@ -8,9 +8,6 @@ const (
namespace: namespace:
- path: metadata/namespace - path: metadata/namespace
create: true create: true
- path: metadata/name
kind: Namespace
create: true
- path: subjects - path: subjects
kind: RoleBinding kind: RoleBinding
- path: subjects - path: subjects

View File

@@ -87,9 +87,6 @@ varReference:
- path: spec/template/spec/volumes/nfs/server - path: spec/template/spec/volumes/nfs/server
kind: Deployment kind: Deployment
- path: spec/template/metadata/annotations
kind: Deployment
- path: spec/rules/host - path: spec/rules/host
kind: Ingress kind: Ingress

View File

@@ -225,13 +225,13 @@ spec:
spec: spec:
containers: containers:
- env: - env:
- name: foo
value: bar
- name: FOO - name: FOO
valueFrom: valueFrom:
configMapKeyRef: configMapKeyRef:
key: somekey key: somekey
name: test-infra-app-env-8h5mh7f7ch name: test-infra-app-env-8h5mh7f7ch
- name: foo
value: bar
image: nginx:1.8.0 image: nginx:1.8.0
name: nginx name: nginx
ports: ports:

View File

@@ -464,50 +464,3 @@ metadata:
name: another-namespace name: another-namespace
`) `)
} }
func TestFnContainerEnvVars(t *testing.T) {
skipIfNoDocker(t)
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("/app", `
generators:
- gener.yaml
`)
// TODO: cheange image to gcr.io/kpt-functions/templater:stable
// when https://github.com/GoogleContainerTools/kpt-functions-catalog/pull/103
// is merged
th.WriteF("/app/gener.yaml", `
apiVersion: v1
kind: ConfigMap
metadata:
name: demo
annotations:
config.kubernetes.io/function: |
container:
image: quay.io/aodinokov/kpt-templater:0.0.1
envs:
- TESTTEMPLATE=value
data:
template: |
apiVersion: v1
kind: ConfigMap
metadata:
name: env
data:
value: '{{ env "TESTTEMPLATE" }}'
`)
m := th.Run("/app", th.MakeOptionsPluginsEnabled())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
data:
value: value
kind: ConfigMap
metadata:
annotations:
config.kubernetes.io/path: configmap_env.yaml
name: env
`)
}

View File

@@ -385,12 +385,12 @@ spec:
- gcePersistentDisk: - gcePersistentDisk:
pdName: nginx-persistent-storage pdName: nginx-persistent-storage
name: nginx-persistent-storage name: nginx-persistent-storage
- configMap:
name: staging-configmap-in-overlay-dc6fm46dhm
name: configmap-in-overlay
- configMap: - configMap:
name: staging-team-foo-configmap-in-base-hc6g9dk6g9 name: staging-team-foo-configmap-in-base-hc6g9dk6g9
name: configmap-in-base name: configmap-in-base
- configMap:
name: staging-configmap-in-overlay-dc6fm46dhm
name: configmap-in-overlay
--- ---
apiVersion: v1 apiVersion: v1
kind: Service kind: Service

View File

@@ -1,106 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package krusty_test
import (
"testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
func writeIssueBase(th kusttest_test.Harness) {
th.WriteK("base", `
nameSuffix: -test-api
resources:
- deploy.yaml
`)
th.WriteF("base/deploy.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: example
spec:
template:
spec:
containers:
- name: example
image: example:1.0
volumeMounts:
- name: conf
mountPath: /etc/config
volumes:
- name: conf
configMap:
name: conf
`)
}
func TestIssue2896Base(t *testing.T) {
th := kusttest_test.MakeHarness(t)
writeIssueBase(th)
m := th.Run("base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-test-api
spec:
template:
spec:
containers:
- image: example:1.0
name: example
volumeMounts:
- mountPath: /etc/config
name: conf
volumes:
- configMap:
name: conf
name: conf
`)
}
func TestIssue2896Overlay(t *testing.T) {
th := kusttest_test.MakeHarness(t)
writeIssueBase(th)
th.WriteK("overlay", `
resources:
- ../base
patches:
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: example
spec:
template:
spec:
containers:
- name: example
image: example:2.0
`)
m := th.Run("overlay", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-test-api
spec:
template:
spec:
containers:
- image: example:2.0
name: example
volumeMounts:
- mountPath: /etc/config
name: conf
volumes:
- configMap:
name: conf
name: conf
`)
}

View File

@@ -1,57 +0,0 @@
package krusty_test
import (
"testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
func TestKustomizationMetadata(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("/app/resources.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: testing123
spec:
replicas: 1
selector: null
template:
spec:
containers:
- name: event
image: testing123
imagePullPolicy: IfNotPresent
imagePullSecrets: []`)
th.WriteK("/app", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
metadata:
annotations:
config.kubernetes.io/local-config: "true"
labels:
foo: bar
name: test_kustomization
resources:
- resources.yaml
`)
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: testing123
spec:
replicas: 1
selector: null
template:
spec:
containers:
- image: testing123
imagePullPolicy: IfNotPresent
name: event
imagePullSecrets: []
`)
}

View File

@@ -146,12 +146,12 @@ spec:
- gcePersistentDisk: - gcePersistentDisk:
pdName: nginx-persistent-storage pdName: nginx-persistent-storage
name: nginx-persistent-storage name: nginx-persistent-storage
- configMap:
name: a-configmap-in-overlay-dc6fm46dhm
name: configmap-in-overlay
- configMap: - configMap:
name: a-b-configmap-in-base-798k5k7g9f name: a-b-configmap-in-base-798k5k7g9f
name: configmap-in-base name: configmap-in-base
- configMap:
name: a-configmap-in-overlay-dc6fm46dhm
name: configmap-in-overlay
--- ---
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
@@ -351,12 +351,12 @@ spec:
- gcePersistentDisk: - gcePersistentDisk:
pdName: nginx-persistent-storage pdName: nginx-persistent-storage
name: nginx-persistent-storage name: nginx-persistent-storage
- configMap:
name: staging-configmap-in-overlay-dc6fm46dhm
name: configmap-in-overlay
- configMap: - configMap:
name: staging-team-foo-configmap-in-base-798k5k7g9f name: staging-team-foo-configmap-in-base-798k5k7g9f
name: configmap-in-base name: configmap-in-base
- configMap:
name: staging-configmap-in-overlay-dc6fm46dhm
name: configmap-in-overlay
--- ---
apiVersion: v1 apiVersion: v1
kind: Service kind: Service

View File

@@ -9,7 +9,7 @@ import (
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest" kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
) )
func TestNullValues1(t *testing.T) { func TestNullValues(t *testing.T) {
th := kusttest_test.MakeHarness(t) th := kusttest_test.MakeHarness(t)
th.WriteF("/app/deployment.yaml", ` th.WriteF("/app/deployment.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1
@@ -62,36 +62,3 @@ spec:
name: example name: example
`) `)
} }
func TestNullValues2(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("deploy.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: test
spec:
template:
spec:
containers:
- name: test
volumes: null
`)
th.WriteK(".", `
resources:
- deploy.yaml
`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: test
spec:
template:
spec:
containers:
- name: test
volumes: null
`)
}

View File

@@ -213,132 +213,3 @@ roleRef:
name: my-role-ns2 name: my-role-ns2
`) `)
} }
// The ServiceAccount in subjects in role binding can be across namespace
// but the roleRef is not. This test is used to cover such case.
func TestRoleBindingWhenSubjectsAcrossNamespace(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("/app", `
resources:
- ./ns1
- ./ns2
`)
th.WriteK("/app/ns1", `
namespace: namespace-1
resources:
- role-ns1.yaml
- rolebinding-ns1.yaml
`)
th.WriteF("/app/ns1/role-ns1.yaml", `
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: testRole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get"]
`)
th.WriteF("/app/ns1/rolebinding-ns1.yaml", `
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: testRoleBinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: testRole
subjects:
- kind: ServiceAccount
name: testAccount
namespace: namespace-2
`)
th.WriteK("/app/ns2", `
namespace: namespace-2
resources:
- role-ns2.yaml
- rolebinding-ns2.yaml
`)
th.WriteF("/app/ns2/role-ns2.yaml", `
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: testRole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get"]
`)
th.WriteF("/app/ns2/rolebinding-ns2.yaml", `
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: testRoleBinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: testRole
subjects:
- kind: ServiceAccount
name: testAccount
namespace: namespace-1
`)
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: testRole
namespace: namespace-1
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: testRoleBinding
namespace: namespace-1
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: testRole
subjects:
- kind: ServiceAccount
name: testAccount
namespace: namespace-2
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: testRole
namespace: namespace-2
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: testRoleBinding
namespace: namespace-2
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: testRole
subjects:
- kind: ServiceAccount
name: testAccount
namespace: namespace-1
`)
}

View File

@@ -215,25 +215,25 @@ spec2:
template: template:
spec: spec:
containers: containers:
- image: nginx:v2 - image: nginx:v1
name: nginx3 name: nginx3
- image: my-nginx:previous - image: my-nginx:latest
name: nginx4 name: nginx4
spec3: spec3:
template: template:
spec: spec:
initContainers: initContainers:
- image: my-postgres:v3 - image: postgres:alpine-9
name: postgresdb name: postgresdb
- image: my-docker@sha256:25a0d4b4 - image: docker:17-git
name: init-docker name: init-docker
- image: myprivaterepohostname:1234/my/image:v1.0.1 - image: myprivaterepohostname:1234/my/image:latest
name: myImage name: myImage
- image: myprivaterepohostname:1234/my/image:v1.0.1 - image: myprivaterepohostname:1234/my/image
name: myImage2 name: myImage2
- image: my-app-image:v1 - image: my-app-image:v1
name: my-app name: my-app
- image: my-cool-app:latest - image: gcr.io:8080/my-project/my-cool-app:latest
name: my-cool-app name: my-cool-app
`) `)
} }

View File

@@ -1969,70 +1969,3 @@ spec:
server: kustomized-nfs-server-service.default.srv.cluster.local server: kustomized-nfs-server-service.default.srv.cluster.local
`) `)
} }
func TestDeploymentAnnotations(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("/app", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: testConfigMap
envs:
- test.properties
vars:
- name: FOO
objref:
kind: ConfigMap
name: testConfigMap
apiVersion: v1
fieldref:
fieldpath: data.foo
commonAnnotations:
foo: $(FOO)
resources:
- deployment.yaml
`)
th.WriteF("/app/deployment.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: test
spec:
template:
spec:
containers:
- name: test
`)
th.WriteF("/app/test.properties", `foo=bar`)
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
foo: bar
name: test
spec:
template:
metadata:
annotations:
foo: bar
spec:
containers:
- name: test
---
apiVersion: v1
data:
foo: bar
kind: ConfigMap
metadata:
annotations:
foo: bar
name: testConfigMap-798k5k7g9f
`)
}

View File

@@ -20,9 +20,6 @@ type remoteTargetSpec struct {
// Dir is where the resource is saved // Dir is where the resource is saved
Dir filesys.ConfirmedDir Dir filesys.ConfirmedDir
// TempDir is the directory created to hold all resources, including Dir
TempDir filesys.ConfirmedDir
} }
// Getter is a function that can gets resource // Getter is a function that can gets resource
@@ -34,7 +31,7 @@ func newLoaderAtGetter(raw string, fSys filesys.FileSystem, referrer *fileLoader
} }
cleaner := func() error { cleaner := func() error {
return fSys.RemoveAll(rs.TempDir.String()) return fSys.RemoveAll(rs.Dir.String())
} }
if err := getter(rs); err != nil { if err := getter(rs); err != nil {
@@ -58,12 +55,12 @@ func newLoaderAtGetter(raw string, fSys filesys.FileSystem, referrer *fileLoader
func getRemoteTarget(rs *remoteTargetSpec) error { func getRemoteTarget(rs *remoteTargetSpec) error {
var err error var err error
rs.TempDir, err = filesys.NewTmpConfirmedDir() rs.Dir, err = filesys.NewTmpConfirmedDir()
if err != nil { if err != nil {
return err return err
} }
rs.Dir = filesys.ConfirmedDir(rs.TempDir.Join("repo")) rs.Dir = filesys.ConfirmedDir(rs.Dir.Join("repo"))
// Get the pwd // Get the pwd
pwd, err := os.Getwd() pwd, err := os.Getwd()

View File

@@ -5,8 +5,6 @@ package resid
import ( import (
"strings" "strings"
"sigs.k8s.io/kustomize/kyaml/yaml"
) )
// Gvk identifies a Kubernetes API type. // Gvk identifies a Kubernetes API type.
@@ -79,22 +77,6 @@ func (x Gvk) String() string {
return strings.Join([]string{g, v, k}, fieldSep) return strings.Join([]string{g, v, k}, fieldSep)
} }
// StringWoEmptyField returns a string representation of the GVK. Non-exist
// fields will be omitted.
func (x Gvk) StringWoEmptyField() string {
var s []string
if x.Group != "" {
s = append(s, x.Group)
}
if x.Version != "" {
s = append(s, x.Version)
}
if x.Kind != "" {
s = append(s, x.Kind)
}
return strings.Join(s, fieldSep)
}
// Equals returns true if the Gvk's have equal fields. // Equals returns true if the Gvk's have equal fields.
func (x Gvk) Equals(o Gvk) bool { func (x Gvk) Equals(o Gvk) bool {
return x.Group == o.Group && x.Version == o.Version && x.Kind == o.Kind return x.Group == o.Group && x.Version == o.Version && x.Kind == o.Kind
@@ -117,7 +99,6 @@ var orderFirst = []string{
"ClusterRoleBinding", "ClusterRoleBinding",
"ConfigMap", "ConfigMap",
"Secret", "Secret",
"Endpoints",
"Service", "Service",
"LimitRange", "LimitRange",
"PriorityClass", "PriorityClass",
@@ -190,22 +171,39 @@ func (x Gvk) IsSelected(selector *Gvk) bool {
return true return true
} }
// toKyamlTypeMeta returns a yaml.TypeMeta from x's information. var notNamespaceableKinds = []string{
func (x Gvk) toKyamlTypeMeta() yaml.TypeMeta { "APIService",
var apiVersion strings.Builder "CSIDriver",
if x.Group != "" { "CSINode",
apiVersion.WriteString(x.Group) "CertificateSigningRequest",
apiVersion.WriteString("/") "Cluster",
} "ClusterRole",
apiVersion.WriteString(x.Version) "ClusterRoleBinding",
return yaml.TypeMeta{ "ComponentStatus",
APIVersion: apiVersion.String(), "CustomResourceDefinition",
Kind: x.Kind, "MutatingWebhookConfiguration",
} "Namespace",
"Node",
"PersistentVolume",
"PodSecurityPolicy",
"PriorityClass",
"RuntimeClass",
"SelfSubjectAccessReview",
"SelfSubjectRulesReview",
"StorageClass",
"SubjectAccessReview",
"TokenReview",
"ValidatingWebhookConfiguration",
"VolumeAttachment",
} }
// IsNamespaceableKind returns true if x is a namespaceable Gvk // IsNamespaceableKind returns true if x is a namespaceable Gvk
// Implements https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/#not-all-objects-are-in-a-namespace // Implements https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/#not-all-objects-are-in-a-namespace
func (x Gvk) IsNamespaceableKind() bool { func (x Gvk) IsNamespaceableKind() bool {
return x.toKyamlTypeMeta().IsNamespaceable() for _, k := range notNamespaceableKinds {
if k == x.Kind {
return false
}
}
return true
} }

View File

@@ -78,8 +78,6 @@ var lessThanTests = []struct {
Gvk{Group: "a", Version: "b", Kind: "ValidatingWebhookConfiguration"}}, Gvk{Group: "a", Version: "b", Kind: "ValidatingWebhookConfiguration"}},
{Gvk{Group: "a", Version: "b", Kind: "Service"}, {Gvk{Group: "a", Version: "b", Kind: "Service"},
Gvk{Group: "a", Version: "b", Kind: "APIService"}}, Gvk{Group: "a", Version: "b", Kind: "APIService"}},
{Gvk{Group: "a", Version: "b", Kind: "Endpoints"},
Gvk{Group: "a", Version: "b", Kind: "Service"}},
} }
func TestIsLessThan1(t *testing.T) { func TestIsLessThan1(t *testing.T) {
@@ -96,16 +94,15 @@ func TestIsLessThan1(t *testing.T) {
var stringTests = []struct { var stringTests = []struct {
x Gvk x Gvk
s string s string
r string
}{ }{
{Gvk{}, "~G_~V_~K", ""}, {Gvk{}, "~G_~V_~K"},
{Gvk{Kind: "k"}, "~G_~V_k", "k"}, {Gvk{Kind: "k"}, "~G_~V_k"},
{Gvk{Version: "v"}, "~G_v_~K", "v"}, {Gvk{Version: "v"}, "~G_v_~K"},
{Gvk{Version: "v", Kind: "k"}, "~G_v_k", "v_k"}, {Gvk{Version: "v", Kind: "k"}, "~G_v_k"},
{Gvk{Group: "g"}, "g_~V_~K", "g"}, {Gvk{Group: "g"}, "g_~V_~K"},
{Gvk{Group: "g", Kind: "k"}, "g_~V_k", "g_k"}, {Gvk{Group: "g", Kind: "k"}, "g_~V_k"},
{Gvk{Group: "g", Version: "v"}, "g_v_~K", "g_v"}, {Gvk{Group: "g", Version: "v"}, "g_v_~K"},
{Gvk{Group: "g", Version: "v", Kind: "k"}, "g_v_k", "g_v_k"}, {Gvk{Group: "g", Version: "v", Kind: "k"}, "g_v_k"},
} }
func TestString(t *testing.T) { func TestString(t *testing.T) {
@@ -116,14 +113,6 @@ func TestString(t *testing.T) {
} }
} }
func TestStringWoEmptyField(t *testing.T) {
for _, hey := range stringTests {
if hey.x.StringWoEmptyField() != hey.r {
t.Fatalf("bad string %s for %v '%s'", hey.x.StringWoEmptyField(), hey.x, hey.r)
}
}
}
func TestParseGroupVersion(t *testing.T) { func TestParseGroupVersion(t *testing.T) {
tests := []struct { tests := []struct {
input string input string

View File

@@ -530,7 +530,7 @@ func (m *resWrangler) Select(s types.Selector) ([]*resource.Resource, error) {
// matches the namespace when namespace is not empty in the selector // matches the namespace when namespace is not empty in the selector
// It first tries to match with the original namespace // It first tries to match with the original namespace
// then matches with the current namespace // then matches with the current namespace
if s.Namespace != "" { if r.GetNamespace() != "" {
matched := ns.MatchString(orgId.EffectiveNamespace()) matched := ns.MatchString(orgId.EffectiveNamespace())
if !matched { if !matched {
matched = ns.MatchString(curId.EffectiveNamespace()) matched = ns.MatchString(curId.EffectiveNamespace())
@@ -543,7 +543,7 @@ func (m *resWrangler) Select(s types.Selector) ([]*resource.Resource, error) {
// matches the name when name is not empty in the selector // matches the name when name is not empty in the selector
// It first tries to match with the original name // It first tries to match with the original name
// then matches with the current name // then matches with the current name
if s.Name != "" { if r.GetName() != "" {
matched := nm.MatchString(orgId.Name) matched := nm.MatchString(orgId.Name)
if !matched { if !matched {
matched = nm.MatchString(curId.Name) matched = nm.MatchString(curId.Name)

View File

@@ -164,18 +164,6 @@ func TestFindPatchTargets(t *testing.T) {
}, },
count: 2, count: 2,
}, },
{
target: types.Selector{
Namespace: "NotMatched",
},
count: 0,
},
{
target: types.Selector{
Namespace: "ns1",
},
count: 1,
},
} }
for _, testcase := range testcases { for _, testcase := range testcases {
actual, err := rm.Select(testcase.target) actual, err := rm.Select(testcase.target)

View File

@@ -68,10 +68,6 @@ func (r *Resource) GetString(p string) (string, error) {
return r.kunStr.GetString(p) return r.kunStr.GetString(p)
} }
func (r *Resource) IsEmpty() bool {
return len(r.kunStr.Map()) == 0
}
func (r *Resource) Map() map[string]interface{} { func (r *Resource) Map() map[string]interface{} {
return r.kunStr.Map() return r.kunStr.Map()
} }

View File

@@ -22,9 +22,6 @@ const (
type Kustomization struct { type Kustomization struct {
TypeMeta `json:",inline" yaml:",inline"` TypeMeta `json:",inline" yaml:",inline"`
// MetaData is a pointer to avoid marshalling empty struct
MetaData *ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
// //
// Operators - what kustomize can do. // Operators - what kustomize can do.
// //

View File

@@ -141,13 +141,6 @@ func TestUnmarshal(t *testing.T) {
y := []byte(` y := []byte(`
apiVersion: kustomize.config.k8s.io/v1beta1 apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization kind: Kustomization
metadata:
name: kust
namespace: default
labels:
foo: bar
annotations:
foo: bar
resources: resources:
- foo - foo
- bar - bar
@@ -158,20 +151,8 @@ namePrefix: cat`)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
meta := ObjectMeta{
Name: "kust",
Namespace: "default",
Labels: map[string]string{
"foo": "bar",
},
Annotations: map[string]string{
"foo": "bar",
},
}
if k.Kind != KustomizationKind || k.APIVersion != KustomizationVersion || if k.Kind != KustomizationKind || k.APIVersion != KustomizationVersion ||
len(k.Resources) != 2 || k.NamePrefix != "cat" || k.NameSuffix != "dog" || len(k.Resources) != 2 || k.NamePrefix != "cat" || k.NameSuffix != "dog" {
k.MetaData.Name != meta.Name || k.MetaData.Namespace != meta.Namespace ||
k.MetaData.Labels["foo"] != meta.Labels["foo"] || k.MetaData.Annotations["foo"] != meta.Annotations["foo"] {
t.Fatalf("wrong unmarshal result: %v", k) t.Fatalf("wrong unmarshal result: %v", k)
} }
} }

View File

@@ -6,8 +6,6 @@ package types
// ObjectMeta partially copies apimachinery/pkg/apis/meta/v1.ObjectMeta // ObjectMeta partially copies apimachinery/pkg/apis/meta/v1.ObjectMeta
// No need for a direct dependence; the fields are stable. // No need for a direct dependence; the fields are stable.
type ObjectMeta struct { type ObjectMeta struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"` Name string `json:"name,omitempty" yaml:"name,omitempty"`
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
} }

View File

@@ -53,6 +53,4 @@ type FnPluginLoadingOptions struct {
NetworkName string NetworkName string
// list of mounts // list of mounts
Mounts []string Mounts []string
// list of env variables to pass to fn
Env []string
} }

View File

@@ -39,7 +39,7 @@ var (
ExitOnError = &commands.ExitOnError ExitOnError = &commands.ExitOnError
) )
// AddCommands adds the cfg and fn commands to kustomize. // AddCommands adds the cfg, fn and live commands to kustomize.
func AddCommands(root *cobra.Command, name string) *cobra.Command { func AddCommands(root *cobra.Command, name string) *cobra.Command {
commands.ExitOnError = true commands.ExitOnError = true
@@ -48,6 +48,7 @@ func AddCommands(root *cobra.Command, name string) *cobra.Command {
root.AddCommand(GetCfg(name)) root.AddCommand(GetCfg(name))
root.AddCommand(GetFn(name)) root.AddCommand(GetFn(name))
root.AddCommand(GetLive(name))
root.AddCommand(&cobra.Command{ root.AddCommand(&cobra.Command{
Use: "docs-merge", Use: "docs-merge",

View File

@@ -0,0 +1,89 @@
// 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.GetPreviewRunner(f, ioStreams).Command,
diff.NewCmdDiff(f, ioStreams),
destroy.GetDestroyRunner(f, ioStreams).Command)
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

@@ -3,8 +3,22 @@
package ext package ext
// KRMFileName returns the name of the KRM file. KRM file determines package import (
// boundaries and contains the openapi information for a package. "path/filepath"
var KRMFileName = func() string { )
return "Krmfile"
// 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
}
// OpenAPIFileName returns the name of the file with openAPI definitions
// uses OpenAPIFile function to derive it
func OpenAPIFileName() (string, error) {
openAPIFileName, err := GetOpenAPIFile([]string{"."})
if err != nil {
return "", err
}
return openAPIFileName, nil
} }

View File

@@ -5,17 +5,17 @@ go 1.14
require ( require (
github.com/go-errors/errors v1.0.1 github.com/go-errors/errors v1.0.1
github.com/go-openapi/spec v0.19.5 github.com/go-openapi/spec v0.19.5
github.com/google/go-cmp v0.5.2 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/olekukonko/tablewriter v0.0.4 github.com/olekukonko/tablewriter v0.0.4
github.com/posener/complete/v2 v2.0.1-alpha.12 github.com/posener/complete/v2 v2.0.1-alpha.12
github.com/spf13/cobra v1.0.0 github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.6.1 github.com/stretchr/testify v1.4.0
golang.org/x/net v0.0.0-20200625001655-4c5254603344 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
k8s.io/apimachinery v0.17.3 k8s.io/apimachinery v0.17.3
sigs.k8s.io/kustomize/kyaml v0.9.1 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.19.0
sigs.k8s.io/kustomize/kyaml v0.6.1
) )
replace sigs.k8s.io/kustomize/kyaml => ../../kyaml

View File

@@ -1,6 +1,20 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 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/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/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/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/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg= github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
@@ -22,33 +36,62 @@ 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/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 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/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/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/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/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/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/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/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.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.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/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/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/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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 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.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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/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/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.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/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 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= 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/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 h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M=
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= 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 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.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 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 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 v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -63,6 +106,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= 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 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= 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.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.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
@@ -116,6 +161,7 @@ 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/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.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.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 h1:YFzsdWIDfVuLvIOF+ZmKjVg1MbPJ1QgY9PihMwei1ys=
github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
@@ -126,48 +172,74 @@ 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/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/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-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 h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 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.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 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.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.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= 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/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 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 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.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= 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 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 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.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 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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.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/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.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/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.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 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 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 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= 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 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 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/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 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 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 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 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 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= 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 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 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 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/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.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
@@ -181,8 +253,9 @@ 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/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 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 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/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-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -191,10 +264,15 @@ 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.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 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= 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 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= 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/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-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 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -205,28 +283,35 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/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 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= 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 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.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 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 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 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 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= 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/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/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/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.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/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 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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -234,35 +319,53 @@ 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/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 h1:nSuXW5ZdmFnQIueLB2s0qvs4oNsUloM1Zydzh75v42w=
github.com/posener/script v1.0.4/go.mod h1:Rg3ijooqulo05aGLyGsHoLmIOUzHUVK19WVgrYBPU/E= 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.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 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-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 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-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.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-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.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/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 h1:K6eOUihrFLdZjZnA4XlRp864fmWXv9YTIk7VPLhRacA=
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d/go.mod h1:7DPO4domFU579Ga6E61sB9VFNaniPVwJP5C4bBCu3wA= 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/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/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.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 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 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/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.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/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/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.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/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 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= 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/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 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.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 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 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/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.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -274,79 +377,120 @@ github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb/go.mod h1:a8OnR
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= 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/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 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/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/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 h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI=
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= 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= 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.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.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.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 h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA=
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= 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-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 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= 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 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= 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 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= 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 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= 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-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-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-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-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-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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-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/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-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-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-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-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-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-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-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-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-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-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-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-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-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 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-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/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-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/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-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-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-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-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-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-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-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-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-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-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-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-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 h1:Vco5b+cuG5NNfORVxZy6bYZQ7rsigisU1WQFkvQ0L5E=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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.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 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 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 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -355,31 +499,54 @@ 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-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-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-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-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-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-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/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.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-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.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 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/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 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-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 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 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 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= 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/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 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 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-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.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.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.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -389,19 +556,79 @@ 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.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo= gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo=
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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-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 h1:f+uZV6rm4/tHE7xXgLyToprg6xWairaClGVkm2t8omg=
k8s.io/apimachinery v0.17.3/go.mod h1:gxLnyZcGNdZTCLnq3fgzyg2A5BVCHTNDFrw8AmuJ+0g= 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/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= 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.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 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= 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 h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
sigs.k8s.io/kustomize/kyaml v0.9.1 h1:T7aNUraSioQp0NHJZtYjIhL/q8mqRzCiHcAKdvo09go= k8s.io/kubectl v0.0.0-20191219154910-1528d4eea6dd h1:nZX5+wEqTu/EBIYjrZlFOA63z4+Zcy96lDkCZPU9a9c=
sigs.k8s.io/kustomize/kyaml v0.9.1/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw= 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.19.0 h1:lAoR5okhSV/dIusodaQp5VbDpHMcKnvjqKYHU+AB3a4=
sigs.k8s.io/cli-utils v0.19.0/go.mod h1:B7KdqkSkHNIUn3cFbaR4aKUZMKtr+Benboi1w/HW/Fg=
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/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
sigs.k8s.io/structured-merge-diff 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 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI=

View File

@@ -4,12 +4,9 @@
package commands package commands
import ( import (
"fmt"
"io"
"strings" "strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands" "sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio"
@@ -34,8 +31,6 @@ func NewAnnotateRunner(parent string) *AnnotateRunner {
c.Flags().StringVar(&r.Name, "name", "", "Resource name to annotate") c.Flags().StringVar(&r.Name, "name", "", "Resource name to annotate")
c.Flags().StringVar(&r.Namespace, "namespace", "", "Resource namespace to annotate") c.Flags().StringVar(&r.Namespace, "namespace", "", "Resource namespace to annotate")
c.Flags().StringSliceVar(&r.Values, "kv", []string{}, "annotation as KEY=VALUE") c.Flags().StringSliceVar(&r.Values, "kv", []string{}, "annotation as KEY=VALUE")
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
"add annotations recursively in all the nested subpackages")
return r return r
} }
@@ -44,14 +39,13 @@ func AnnotateCommand(parent string) *cobra.Command {
} }
type AnnotateRunner struct { type AnnotateRunner struct {
Command *cobra.Command Command *cobra.Command
Values []string Values []string
Kind string Kind string
Name string Name string
ApiVersion string ApiVersion string
Namespace string Namespace string
Path string Path string
RecurseSubPackages bool
} }
func (r *AnnotateRunner) runE(c *cobra.Command, args []string) error { func (r *AnnotateRunner) runE(c *cobra.Command, args []string) error {
@@ -61,54 +55,16 @@ func (r *AnnotateRunner) runE(c *cobra.Command, args []string) error {
rw := &kio.ByteReadWriter{Reader: c.InOrStdin(), Writer: c.OutOrStdout()} rw := &kio.ByteReadWriter{Reader: c.InOrStdin(), Writer: c.OutOrStdout()}
input = []kio.Reader{rw} input = []kio.Reader{rw}
output = []kio.Writer{rw} output = []kio.Writer{rw}
} else {
return handleError(c, kio.Pipeline{ rw := &kio.LocalPackageReadWriter{PackagePath: args[0], NoDeleteFiles: true}
Inputs: input, input = []kio.Reader{rw}
Filters: []kio.Filter{r}, output = []kio.Writer{rw}
Outputs: output,
}.Execute())
} }
return handleError(c, kio.Pipeline{
e := executeCmdOnPkgs{
writer: c.OutOrStdout(),
needOpenAPI: false,
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
rootPkgPath: args[0],
}
err := e.execute()
if err != nil {
return err
}
return nil
}
func (r *AnnotateRunner) executeCmd(w io.Writer, pkgPath string) error {
rw := &kio.LocalPackageReadWriter{
PackagePath: pkgPath,
NoDeleteFiles: true,
PackageFileName: ext.KRMFileName(),
}
input := []kio.Reader{rw}
output := []kio.Writer{rw}
err := kio.Pipeline{
Inputs: input, Inputs: input,
Filters: []kio.Filter{r}, Filters: []kio.Filter{r},
Outputs: output, Outputs: output,
}.Execute() }.Execute())
if err != nil {
// return err if there is only package
if !r.RecurseSubPackages {
return err
} else {
// print error message and continue if there are multiple packages to annotate
fmt.Fprintf(w, "%s\n", err.Error())
}
} else {
fmt.Fprint(w, "added annotations in the package\n")
}
return nil
} }
func (r *AnnotateRunner) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { func (r *AnnotateRunner) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {

View File

@@ -12,9 +12,7 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/kyaml/copyutil"
"sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/openapi"
) )
func TestAnnotateCommand(t *testing.T) { func TestAnnotateCommand(t *testing.T) {
@@ -488,80 +486,3 @@ spec:
replicas: 3 replicas: 3
` `
) )
func TestAnnotateSubPackages(t *testing.T) {
var tests = []struct {
name string
dataset string
packagePath string
args []string
expected string
}{
{
name: "annotate-recurse-subpackages",
dataset: "dataset-without-setters",
args: []string{"--kv", "foo=bar", "-R"},
expected: `${baseDir}/
added annotations in the package
${baseDir}/mysql/
added annotations in the package
${baseDir}/mysql/storage/
added annotations in the package
`,
},
{
name: "annotate-top-level-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
packagePath: "mysql",
args: []string{"--kv", "foo=bar"},
expected: `${baseDir}/mysql/
added annotations in the package
`,
},
{
name: "annotate-nested-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
packagePath: "mysql/storage",
args: []string{"--kv", "foo=bar"},
expected: `${baseDir}/mysql/storage/
added annotations in the package
`,
},
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
// reset the openAPI afterward
openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI()
sourceDir := filepath.Join("test", "testdata", test.dataset)
baseDir, err := ioutil.TempDir("", "")
if !assert.NoError(t, err) {
t.FailNow()
}
copyutil.CopyDir(sourceDir, baseDir)
defer os.RemoveAll(baseDir)
runner := NewAnnotateRunner("")
actual := &bytes.Buffer{}
runner.Command.SetOut(actual)
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
err = runner.Command.Execute()
if !assert.NoError(t, err) {
t.FailNow()
}
// normalize path format for windows
actualNormalized := strings.Replace(
strings.Replace(actual.String(), "\\", "/", -1),
"//", "/", -1)
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
if !assert.Equal(t, expectedNormalized, actualNormalized) {
t.FailNow()
}
})
}
}

View File

@@ -4,14 +4,10 @@
package commands package commands
import ( import (
"bytes"
"fmt" "fmt"
"io"
"os" "os"
"strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands" "sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio"
@@ -23,14 +19,15 @@ import (
func GetCatRunner(name string) *CatRunner { func GetCatRunner(name string) *CatRunner {
r := &CatRunner{} r := &CatRunner{}
c := &cobra.Command{ c := &cobra.Command{
Use: "cat DIR", Use: "cat DIR...",
Short: commands.CatShort, Short: commands.CatShort,
Long: commands.CatLong, Long: commands.CatLong,
Example: commands.CatExamples, Example: commands.CatExamples,
RunE: r.runE, RunE: r.runE,
Args: cobra.MaximumNArgs(1),
} }
fixDocs(name, c) fixDocs(name, c)
c.Flags().BoolVar(&r.IncludeSubpackages, "include-subpackages", true,
"also print resources from subpackages.")
c.Flags().BoolVar(&r.Format, "format", true, c.Flags().BoolVar(&r.Format, "format", true,
"format resource config yaml before printing.") "format resource config yaml before printing.")
c.Flags().BoolVar(&r.KeepAnnotations, "annotate", false, c.Flags().BoolVar(&r.KeepAnnotations, "annotate", false,
@@ -52,8 +49,6 @@ func GetCatRunner(name string) *CatRunner {
"if true, exclude non-local-config in the output.") "if true, exclude non-local-config in the output.")
c.Flags().StringVar(&r.OutputDest, "dest", "", c.Flags().StringVar(&r.OutputDest, "dest", "",
"if specified, write output to a file rather than stdout") "if specified, write output to a file rather than stdout")
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", true,
"print resources recursively in all the nested subpackages")
r.Command = c r.Command = c
return r return r
} }
@@ -64,6 +59,7 @@ func CatCommand(name string) *cobra.Command {
// CatRunner contains the run function // CatRunner contains the run function
type CatRunner struct { type CatRunner struct {
IncludeSubpackages bool
Format bool Format bool
KeepAnnotations bool KeepAnnotations bool
WrapKind string WrapKind string
@@ -75,111 +71,56 @@ type CatRunner struct {
IncludeLocal bool IncludeLocal bool
ExcludeNonLocal bool ExcludeNonLocal bool
Command *cobra.Command Command *cobra.Command
RecurseSubPackages bool
} }
func (r *CatRunner) runE(c *cobra.Command, args []string) error { func (r *CatRunner) runE(c *cobra.Command, args []string) error {
var writer = c.OutOrStdout() // if there is a function-config specified, emit it
if r.OutputDest != "" {
o, err := os.Create(r.OutputDest)
if err != nil {
return errors.Wrap(err)
}
defer o.Close()
writer = o
}
if len(args) == 0 {
input := &kio.ByteReader{Reader: c.InOrStdin()}
// if there is a function-config specified, emit it
outputs, err := r.out(writer)
if err != nil {
return err
}
return handleError(c, kio.Pipeline{Inputs: []kio.Reader{input}, Filters: r.catFilters(), Outputs: outputs}.Execute())
}
out := &bytes.Buffer{}
e := executeCmdOnPkgs{
writer: out,
needOpenAPI: false,
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
rootPkgPath: args[0],
skipPkgPathPrint: true,
}
err := e.execute()
if err != nil {
return err
}
res := strings.TrimSuffix(out.String(), "---")
fmt.Fprintf(writer, "%s", res)
return nil
}
func (r *CatRunner) executeCmd(w io.Writer, pkgPath string) error {
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: ext.KRMFileName()}
out := &bytes.Buffer{}
outputs, err := r.out(out)
if err != nil {
return err
}
err = kio.Pipeline{
Inputs: []kio.Reader{input},
Filters: r.catFilters(),
Outputs: outputs,
}.Execute()
if err != nil {
// return err if there is only package
if !r.RecurseSubPackages {
return err
} else {
// print error message and continue if there are multiple packages to annotate
fmt.Fprintf(w, "%s in package %q\n", err.Error(), pkgPath)
}
}
fmt.Fprint(w, out.String())
if out.String() != "" {
fmt.Fprint(w, "---")
}
return nil
}
func (r *CatRunner) catFilters() []kio.Filter {
var fltrs []kio.Filter
// don't include reconcilers
fltrs = append(fltrs, &filters.IsLocalConfig{
IncludeLocalConfig: r.IncludeLocal,
ExcludeNonLocalConfig: r.ExcludeNonLocal,
})
if r.Format {
fltrs = append(fltrs, filters.FormatFilter{})
}
if r.StripComments {
fltrs = append(fltrs, filters.StripCommentsFilter{})
}
return fltrs
}
func (r *CatRunner) out(w io.Writer) ([]kio.Writer, error) {
var outputs []kio.Writer
var functionConfig *yaml.RNode var functionConfig *yaml.RNode
if r.FunctionConfig != "" { if r.FunctionConfig != "" {
configs, err := kio.LocalPackageReader{PackagePath: r.FunctionConfig, configs, err := kio.LocalPackageReader{PackagePath: r.FunctionConfig,
OmitReaderAnnotations: !r.KeepAnnotations}.Read() OmitReaderAnnotations: !r.KeepAnnotations}.Read()
if err != nil { if err != nil {
return outputs, err return err
} }
if len(configs) != 1 { if len(configs) != 1 {
return outputs, fmt.Errorf("expected exactly 1 functionConfig, found %d", len(configs)) return fmt.Errorf("expected exactly 1 functionConfig, found %d", len(configs))
} }
functionConfig = configs[0] functionConfig = configs[0]
} }
var inputs []kio.Reader
for _, a := range args {
inputs = append(inputs, kio.LocalPackageReader{
PackagePath: a,
IncludeSubpackages: r.IncludeSubpackages,
})
}
if len(inputs) == 0 {
inputs = append(inputs, &kio.ByteReader{Reader: c.InOrStdin()})
}
var fltr []kio.Filter
// don't include reconcilers
fltr = append(fltr, &filters.IsLocalConfig{
IncludeLocalConfig: r.IncludeLocal,
ExcludeNonLocalConfig: r.ExcludeNonLocal,
})
if r.Format {
fltr = append(fltr, filters.FormatFilter{})
}
if r.StripComments {
fltr = append(fltr, filters.StripCommentsFilter{})
}
var out = c.OutOrStdout()
if r.OutputDest != "" {
o, err := os.Create(r.OutputDest)
if err != nil {
return handleError(c, errors.Wrap(err))
}
defer o.Close()
out = o
}
// remove this annotation explicitly, the ByteWriter won't clear it by // remove this annotation explicitly, the ByteWriter won't clear it by
// default because it doesn't set it // default because it doesn't set it
clear := []string{"config.kubernetes.io/path"} clear := []string{"config.kubernetes.io/path"}
@@ -187,8 +128,9 @@ func (r *CatRunner) out(w io.Writer) ([]kio.Writer, error) {
clear = nil clear = nil
} }
var outputs []kio.Writer
outputs = append(outputs, kio.ByteWriter{ outputs = append(outputs, kio.ByteWriter{
Writer: w, Writer: out,
KeepReaderAnnotations: r.KeepAnnotations, KeepReaderAnnotations: r.KeepAnnotations,
WrappingKind: r.WrapKind, WrappingKind: r.WrapKind,
WrappingAPIVersion: r.WrapApiVersion, WrappingAPIVersion: r.WrapApiVersion,
@@ -197,5 +139,5 @@ func (r *CatRunner) out(w io.Writer) ([]kio.Writer, error) {
ClearAnnotations: clear, ClearAnnotations: clear,
}) })
return outputs, nil return handleError(c, kio.Pipeline{Inputs: inputs, Filters: fltr, Outputs: outputs}.Execute())
} }

View File

@@ -8,13 +8,10 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/config/internal/commands" "sigs.k8s.io/kustomize/cmd/config/internal/commands"
"sigs.k8s.io/kustomize/kyaml/copyutil"
"sigs.k8s.io/kustomize/kyaml/openapi"
) )
// TODO(pwittrock): write tests for reading / writing ResourceLists // TODO(pwittrock): write tests for reading / writing ResourceLists
@@ -171,7 +168,8 @@ metadata:
annotations: annotations:
app: nginx app: nginx
spec: spec:
replicas: 3`), 0600) replicas: 3
`), 0600)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
return return
} }
@@ -364,7 +362,8 @@ metadata:
annotations: annotations:
app: nginx app: nginx
spec: spec:
replicas: 3`), 0600) replicas: 3
`), 0600)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
return return
} }
@@ -478,7 +477,8 @@ metadata:
annotations: annotations:
app: nginx app: nginx
spec: spec:
replicas: 3`), 0600) replicas: 3
`), 0600)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
return return
} }
@@ -540,129 +540,3 @@ spec:
return return
} }
} }
func TestCatSubPackages(t *testing.T) {
var tests = []struct {
name string
dataset string
packagePath string
args []string
expected string
}{
{
name: "cat-recurse-subpackages",
dataset: "dataset-without-setters",
expected: `
# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deployment
namespace: myspace
spec:
replicas: 3
template:
spec:
containers:
- name: mysql
image: mysql:1.7.9
---
# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apps/v1
kind: Deployment
metadata:
name: storage-deployment
namespace: myspace
spec:
replicas: 4
template:
spec:
containers:
- name: storage
image: storage:1.7.7
`,
},
{
name: "cat-top-level-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
args: []string{"-R=false"},
packagePath: "mysql",
expected: `# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deployment
namespace: myspace
spec:
replicas: 3
template:
spec:
containers:
- name: mysql
image: mysql:1.7.9
`,
},
{
name: "cat-nested-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
packagePath: "mysql/storage",
args: []string{"-R=false"},
expected: `# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apps/v1
kind: Deployment
metadata:
name: storage-deployment
namespace: myspace
spec:
replicas: 4
template:
spec:
containers:
- name: storage
image: storage:1.7.7
`,
},
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
// reset the openAPI afterward
openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI()
sourceDir := filepath.Join("test", "testdata", test.dataset)
baseDir, err := ioutil.TempDir("", "")
if !assert.NoError(t, err) {
t.FailNow()
}
copyutil.CopyDir(sourceDir, baseDir)
defer os.RemoveAll(baseDir)
runner := commands.GetCatRunner("")
actual := &bytes.Buffer{}
runner.Command.SetOut(actual)
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
err = runner.Command.Execute()
if !assert.NoError(t, err) {
t.FailNow()
}
// normalize path format for windows
actualNormalized := strings.Replace(
strings.Replace(actual.String(), "\\", "/", -1),
"//", "/", -1)
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
if !assert.Equal(t, expectedNormalized, actualNormalized) {
t.FailNow()
}
})
}
}

View File

@@ -5,10 +5,7 @@ package commands
import ( import (
"encoding/json" "encoding/json"
"fmt"
"io"
"io/ioutil" "io/ioutil"
"path/filepath"
"strings" "strings"
"github.com/go-openapi/spec" "github.com/go-openapi/spec"
@@ -16,7 +13,9 @@ import (
"sigs.k8s.io/kustomize/cmd/config/ext" "sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands" "sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
"sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/setters" "sigs.k8s.io/kustomize/kyaml/setters"
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil" "sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
) )
@@ -60,8 +59,6 @@ func NewCreateSetterRunner(parent string) *CreateSetterRunner {
set.Flags().StringVar(&r.SchemaPath, "schema-path", "", set.Flags().StringVar(&r.SchemaPath, "schema-path", "",
`openAPI schema file path for setter constraints -- file content `+ `openAPI schema file path for setter constraints -- file content `+
`e.g. {"type": "string", "maxLength": 15, "enum": ["allowedValue1", "allowedValue2"]}`) `e.g. {"type": "string", "maxLength": 15, "enum": ["allowedValue1", "allowedValue2"]}`)
set.Flags().BoolVarP(&r.CreateSetter.RecurseSubPackages, "recurse-subpackages", "R", false,
"creates setter recursively in all the nested subpackages")
set.Flags().MarkHidden("version") set.Flags().MarkHidden("version")
fixDocs(parent, set) fixDocs(parent, set)
r.Command = set r.Command = set
@@ -81,7 +78,7 @@ type CreateSetterRunner struct {
} }
func (r *CreateSetterRunner) runE(c *cobra.Command, args []string) error { func (r *CreateSetterRunner) runE(c *cobra.Command, args []string) error {
return handleError(c, r.createSetter(c, args)) return handleError(c, r.set(c, args))
} }
func (r *CreateSetterRunner) preRunE(c *cobra.Command, args []string) error { func (r *CreateSetterRunner) preRunE(c *cobra.Command, args []string) error {
@@ -114,6 +111,42 @@ func (r *CreateSetterRunner) preRunE(c *cobra.Command, args []string) error {
} }
if setterVersion == "v2" { if setterVersion == "v2" {
var err error
r.OpenAPIFile, err = ext.GetOpenAPIFile(args)
if err != nil {
return err
}
if err := openapi.AddSchemaFromFile(r.OpenAPIFile); err != nil {
return err
}
// check if substitution with same name exists and throw error
ref, err := spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SubstitutionDefinitionPrefix + r.CreateSetter.Name)
if err != nil {
return err
}
subst, _ := openapi.Resolve(&ref)
// if substitution already exists with the input setter name, throw error
if subst != nil {
return errors.Errorf("substitution with name %s already exists, "+
"substitution and setter can't have same name", r.CreateSetter.Name)
}
// check if setter with same name exists and throw error
ref, err = spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SetterDefinitionPrefix + r.CreateSetter.Name)
if err != nil {
return err
}
setter, _ := openapi.Resolve(&ref)
// if setter already exists with the input setter name, throw error
if setter != nil {
return errors.Errorf("setter with name %s already exists, "+
"if you want to modify it, please delete the existing setter and recreate it", r.CreateSetter.Name)
}
r.CreateSetter.Description = r.Set.SetPartialField.Description r.CreateSetter.Description = r.Set.SetPartialField.Description
r.CreateSetter.SetBy = r.Set.SetPartialField.SetBy r.CreateSetter.SetBy = r.Set.SetPartialField.SetBy
r.CreateSetter.Type = r.Set.SetPartialField.Type r.CreateSetter.Type = r.Set.SetPartialField.Type
@@ -177,20 +210,9 @@ func (r *CreateSetterRunner) processSchema() error {
return nil return nil
} }
func (r *CreateSetterRunner) createSetter(c *cobra.Command, args []string) error { func (r *CreateSetterRunner) set(c *cobra.Command, args []string) error {
if setterVersion == "v2" { if setterVersion == "v2" {
e := executeCmdOnPkgs{ return r.CreateSetter.Create(r.OpenAPIFile, args[0])
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.CreateSetter.RecurseSubPackages,
cmdRunner: r,
}
err := e.execute()
if err != nil {
return handleError(c, err)
}
return nil
} }
rw := &kio.LocalPackageReadWriter{PackagePath: args[0]} rw := &kio.LocalPackageReadWriter{PackagePath: args[0]}
@@ -204,37 +226,6 @@ func (r *CreateSetterRunner) createSetter(c *cobra.Command, args []string) error
return nil return nil
} }
func (r *CreateSetterRunner) executeCmd(w io.Writer, pkgPath string) error {
r.CreateSetter = settersutil.SetterCreator{
Name: r.CreateSetter.Name,
SetBy: r.CreateSetter.SetBy,
Description: r.CreateSetter.Description,
Type: r.CreateSetter.Type,
Schema: r.CreateSetter.Schema,
FieldName: r.CreateSetter.FieldName,
FieldValue: r.CreateSetter.FieldValue,
Required: r.CreateSetter.Required,
RecurseSubPackages: r.CreateSetter.RecurseSubPackages,
OpenAPIFileName: ext.KRMFileName(),
OpenAPIPath: filepath.Join(pkgPath, ext.KRMFileName()),
ResourcesPath: pkgPath,
}
err := r.CreateSetter.Create()
if err != nil {
// return err if RecurseSubPackages is false
if !r.CreateSetter.RecurseSubPackages {
return err
} else {
// print error message and continue if RecurseSubPackages is true
fmt.Fprintf(w, "%s\n", err.Error())
}
} else {
fmt.Fprintf(w, "created setter %q\n", r.CreateSetter.Name)
}
return nil
}
// schemaFromFile reads the contents from schemaPath and returns schema // schemaFromFile reads the contents from schemaPath and returns schema
func schemaFromFile(schemaPath string) (*spec.Schema, error) { func schemaFromFile(schemaPath string) (*spec.Schema, error) {
sc := &spec.Schema{} sc := &spec.Schema{}

View File

@@ -7,13 +7,12 @@ import (
"bytes" "bytes"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath"
"strings" "strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/commands" "sigs.k8s.io/kustomize/cmd/config/internal/commands"
"sigs.k8s.io/kustomize/kyaml/copyutil"
"sigs.k8s.io/kustomize/kyaml/openapi" "sigs.k8s.io/kustomize/kyaml/openapi"
) )
@@ -44,7 +43,6 @@ spec:
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
`, `,
out: `created setter "replicas"`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -83,7 +81,6 @@ spec:
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
`, `,
out: `created setter "replicas"`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -125,7 +122,7 @@ openAPI:
- marker: ${my-tag-setter} - marker: ${my-tag-setter}
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter' ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
`, `,
err: `substitution with name "my-image" already exists, substitution and setter can't have same name`, err: "substitution with name my-image already exists, substitution and setter can't have same name",
}, },
{ {
@@ -143,7 +140,7 @@ openAPI:
name: my-image name: my-image
value: "nginx" value: "nginx"
`, `,
err: `setter with name "my-image" already exists, if you want to modify it, please delete the existing setter and recreate it`, err: "setter with name my-image already exists, if you want to modify it, please delete the existing setter and recreate it",
}, },
{ {
@@ -162,7 +159,6 @@ spec:
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
`, `,
out: `created setter "replicas"`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -204,7 +200,6 @@ spec:
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
`, `,
out: `created setter replicas`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -259,7 +254,6 @@ spec:
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
`, `,
out: `created setter "list"`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -360,7 +354,6 @@ spec:
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
`, `,
out: `created setter replicas`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -407,7 +400,6 @@ spec:
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
`, `,
out: `created setter "replicas"`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -445,7 +437,6 @@ spec:
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
`, `,
out: `created setter "foo.bar"`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -596,7 +587,6 @@ spec:
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
`, `,
out: `created setter "replicas"`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -722,7 +712,6 @@ spec:
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
`, `,
out: `created setter "replicas"`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -753,14 +742,13 @@ spec:
openapi.ResetOpenAPI() openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI() defer openapi.ResetOpenAPI()
baseDir, err := ioutil.TempDir("", "") f, err := ioutil.TempFile("", "k8s-cli-")
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
defer os.RemoveAll(baseDir) defer os.Remove(f.Name())
f := filepath.Join(baseDir, "Krmfile") err = ioutil.WriteFile(f.Name(), []byte(test.inputOpenAPI), 0600)
err = ioutil.WriteFile(f, []byte(test.inputOpenAPI), 0600)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
@@ -780,7 +768,13 @@ spec:
test.args = append(test.args, "--schema-path", sch.Name()) test.args = append(test.args, "--schema-path", sch.Name())
} }
r, err := ioutil.TempFile(baseDir, "k8s-cli-*.yaml") 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) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
@@ -793,7 +787,7 @@ spec:
runner := commands.NewCreateSetterRunner("") runner := commands.NewCreateSetterRunner("")
out := &bytes.Buffer{} out := &bytes.Buffer{}
runner.Command.SetOut(out) runner.Command.SetOut(out)
runner.Command.SetArgs(append([]string{baseDir}, test.args...)) runner.Command.SetArgs(append([]string{r.Name()}, test.args...))
err = runner.Command.Execute() err = runner.Command.Execute()
if test.err != "" { if test.err != "" {
if !assert.NotNil(t, err) { if !assert.NotNil(t, err) {
@@ -807,14 +801,7 @@ spec:
t.FailNow() t.FailNow()
} }
expectedOut := strings.Replace(test.out, "${baseDir}", baseDir, -1) if !assert.Equal(t, test.out, out.String()) {
expectedNormalized := strings.Replace(expectedOut, "\\", "/", -1)
// normalize path format for windows
actualNormalized := strings.Replace(
strings.Replace(out.String(), "\\", "/", -1),
"//", "/", -1)
if !assert.Contains(t, actualNormalized, expectedNormalized) {
t.FailNow() t.FailNow()
} }
@@ -828,7 +815,7 @@ spec:
t.FailNow() t.FailNow()
} }
actualOpenAPI, err := ioutil.ReadFile(f) actualOpenAPI, err := ioutil.ReadFile(f.Name())
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
@@ -840,92 +827,3 @@ spec:
}) })
} }
} }
func TestCreateSetterSubPackages(t *testing.T) {
var tests = []struct {
name string
dataset string
packagePath string
args []string
expected string
}{
{
name: "create-setter-recurse-subpackages",
dataset: "dataset-without-setters",
args: []string{"namespace", "myspace", "-R"},
expected: `${baseDir}/mysql/
created setter "namespace"
${baseDir}/mysql/storage/
created setter "namespace"
`,
},
{
name: "create-setter-top-level-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
packagePath: "mysql",
args: []string{"namespace", "myspace"},
expected: `${baseDir}/mysql/
created setter "namespace"
`,
},
{
name: "create-setter-nested-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
packagePath: "mysql/storage",
args: []string{"namespace", "myspace"},
expected: `${baseDir}/mysql/storage/
created setter "namespace"
`,
},
{
name: "create-setter-already-exists",
dataset: "dataset-with-setters",
packagePath: "mysql",
args: []string{"namespace", "myspace", "-R"},
expected: `${baseDir}/mysql/
setter with name "namespace" already exists, if you want to modify it, please delete the existing setter and recreate it
${baseDir}/mysql/nosetters/
created setter "namespace"
${baseDir}/mysql/storage/
setter with name "namespace" already exists, if you want to modify it, please delete the existing setter and recreate it
`,
},
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
// reset the openAPI afterward
openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI()
sourceDir := filepath.Join("test", "testdata", test.dataset)
baseDir, err := ioutil.TempDir("", "")
if !assert.NoError(t, err) {
t.FailNow()
}
copyutil.CopyDir(sourceDir, baseDir)
defer os.RemoveAll(baseDir)
runner := commands.NewCreateSetterRunner("")
actual := &bytes.Buffer{}
runner.Command.SetOut(actual)
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
err = runner.Command.Execute()
if !assert.NoError(t, err) {
t.FailNow()
}
// normalize path format for windows
actualNormalized := strings.Replace(
strings.Replace(actual.String(), "\\", "/", -1),
"//", "/", -1)
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
if !assert.Equal(t, expectedNormalized, actualNormalized) {
t.FailNow()
}
})
}
}

View File

@@ -5,11 +5,13 @@ package commands
import ( import (
"fmt" "fmt"
"io"
"path/filepath"
"github.com/go-openapi/spec"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext" "sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil" "sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
) )
@@ -17,10 +19,10 @@ import (
func NewCreateSubstitutionRunner(parent string) *CreateSubstitutionRunner { func NewCreateSubstitutionRunner(parent string) *CreateSubstitutionRunner {
r := &CreateSubstitutionRunner{} r := &CreateSubstitutionRunner{}
cs := &cobra.Command{ cs := &cobra.Command{
Use: "create-subst DIR NAME", Use: "create-subst DIR NAME",
Args: cobra.ExactArgs(2), Args: cobra.ExactArgs(2),
PreRun: r.preRun, PreRunE: r.preRunE,
RunE: r.runE, RunE: r.runE,
} }
cs.Flags().StringVar(&r.CreateSubstitution.FieldName, "field", "", cs.Flags().StringVar(&r.CreateSubstitution.FieldName, "field", "",
"name of the field to set -- e.g. --field image") "name of the field to set -- e.g. --field image")
@@ -28,8 +30,6 @@ func NewCreateSubstitutionRunner(parent string) *CreateSubstitutionRunner {
"value of the field to create substitution for -- e.g. --field-value nginx:0.1.0") "value of the field to create substitution for -- e.g. --field-value nginx:0.1.0")
cs.Flags().StringVar(&r.CreateSubstitution.Pattern, "pattern", "", cs.Flags().StringVar(&r.CreateSubstitution.Pattern, "pattern", "",
`substitution pattern -- e.g. --pattern \${my-image-setter}:\${my-tag-setter}`) `substitution pattern -- e.g. --pattern \${my-image-setter}:\${my-tag-setter}`)
cs.Flags().BoolVarP(&r.CreateSubstitution.RecurseSubPackages, "recurse-subpackages", "R", false,
"creates substitution recursively in all the nested subpackages")
_ = cs.MarkFlagRequired("pattern") _ = cs.MarkFlagRequired("pattern")
_ = cs.MarkFlagRequired("field-value") _ = cs.MarkFlagRequired("field-value")
fixDocs(parent, cs) fixDocs(parent, cs)
@@ -49,48 +49,49 @@ type CreateSubstitutionRunner struct {
} }
func (r *CreateSubstitutionRunner) runE(c *cobra.Command, args []string) error { func (r *CreateSubstitutionRunner) runE(c *cobra.Command, args []string) error {
e := executeCmdOnPkgs{ return handleError(c, r.CreateSubstitution.Create(r.OpenAPIFile, args[0]))
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.CreateSubstitution.RecurseSubPackages,
cmdRunner: r,
}
err := e.execute()
if err != nil {
return handleError(c, err)
}
return nil
} }
func (r *CreateSubstitutionRunner) executeCmd(w io.Writer, pkgPath string) error { func (r *CreateSubstitutionRunner) preRunE(c *cobra.Command, args []string) error {
r.CreateSubstitution = settersutil.SubstitutionCreator{ var err error
Name: r.CreateSubstitution.Name,
FieldName: r.CreateSubstitution.FieldName,
FieldValue: r.CreateSubstitution.FieldValue,
RecurseSubPackages: r.CreateSubstitution.RecurseSubPackages,
Pattern: r.CreateSubstitution.Pattern,
OpenAPIFileName: ext.KRMFileName(),
OpenAPIPath: filepath.Join(pkgPath, ext.KRMFileName()),
ResourcesPath: pkgPath,
}
err := r.CreateSubstitution.Create()
if err != nil {
// return err if RecurseSubPackages is false
if !r.CreateSubstitution.RecurseSubPackages {
return err
} else {
// print error message and continue if RecurseSubPackages is true
fmt.Fprintf(w, "%s\n", err.Error())
}
} else {
fmt.Fprintf(w, "created substitution %q\n", r.CreateSubstitution.Name)
}
return nil
}
func (r *CreateSubstitutionRunner) preRun(c *cobra.Command, args []string) {
r.CreateSubstitution.Name = args[1] r.CreateSubstitution.Name = args[1]
if err != nil {
return err
}
r.OpenAPIFile, err = ext.GetOpenAPIFile(args)
if err != nil {
return err
}
if err := openapi.AddSchemaFromFile(r.OpenAPIFile); err != nil {
return err
}
// check if substitution with same name exists and throw error
ref, err := spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SubstitutionDefinitionPrefix + r.CreateSubstitution.Name)
if err != nil {
return err
}
subst, _ := openapi.Resolve(&ref)
// if substitution already exists with the input substitution name, throw error
if subst != nil {
return errors.Errorf("substitution with name %s already exists", r.CreateSubstitution.Name)
}
// check if setter with same name exists and throw error
ref, err = spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SetterDefinitionPrefix + r.CreateSubstitution.Name)
if err != nil {
return err
}
setter, _ := openapi.Resolve(&ref)
// if setter already exists with input substitution name, throw error
if setter != nil {
return errors.Errorf(fmt.Sprintf("setter with name %s already exists, "+
"substitution and setter can't have same name", r.CreateSubstitution.Name))
}
return nil
} }

View File

@@ -7,13 +7,12 @@ import (
"bytes" "bytes"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath"
"strings" "strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/commands" "sigs.k8s.io/kustomize/cmd/config/internal/commands"
"sigs.k8s.io/kustomize/kyaml/copyutil"
"sigs.k8s.io/kustomize/kyaml/openapi" "sigs.k8s.io/kustomize/kyaml/openapi"
) )
@@ -63,7 +62,6 @@ openAPI:
name: my-tag-setter name: my-tag-setter
value: "1.7.9" value: "1.7.9"
`, `,
out: `created substitution "my-image-subst"`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -125,7 +123,7 @@ openAPI:
- marker: ${my-tag-setter} - marker: ${my-tag-setter}
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter' ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
`, `,
err: `substitution with name "my-image" already exists`, err: "substitution with name my-image already exists",
}, },
{ {
name: "error if setter with same name exists", name: "error if setter with same name exists",
@@ -142,7 +140,7 @@ openAPI:
name: my-image name: my-image
value: "nginx" value: "nginx"
`, `,
err: `setter with name "my-image" already exists, substitution and setter can't have same name`, err: "setter with name my-image already exists, substitution and setter can't have same name",
}, },
{ {
name: "substitution and create setters 1", name: "substitution and create setters 1",
@@ -167,7 +165,6 @@ spec:
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
`, `,
out: `created substitution "my-image-subst"`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -256,7 +253,6 @@ openAPI:
- marker: ${my-tag-setter} - marker: ${my-tag-setter}
ref: '#/definitions/io.k8s.cli.setters.my-tag-setter' ref: '#/definitions/io.k8s.cli.setters.my-tag-setter'
`, `,
out: `created substitution "my-nested-subst"`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -345,7 +341,7 @@ spec:
substVal: prefix-1234 substVal: prefix-1234
`, `,
err: `setters must have different name than the substitution: foo`, err: "setters must have different name than the substitution: foo",
}, },
} }
for i := range tests { for i := range tests {
@@ -355,18 +351,22 @@ spec:
openapi.ResetOpenAPI() openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI() defer openapi.ResetOpenAPI()
baseDir, err := ioutil.TempDir("", "") f, err := ioutil.TempFile("", "k8s-cli-")
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
defer os.RemoveAll(baseDir) defer os.Remove(f.Name())
f := filepath.Join(baseDir, "Krmfile") err = ioutil.WriteFile(f.Name(), []byte(test.inputOpenAPI), 0600)
err = ioutil.WriteFile(f, []byte(test.inputOpenAPI), 0600)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
old := ext.GetOpenAPIFile
defer func() { ext.GetOpenAPIFile = old }()
ext.GetOpenAPIFile = func(args []string) (s string, err error) {
return f.Name(), nil
}
r, err := ioutil.TempFile(baseDir, "k8s-cli-*.yaml") r, err := ioutil.TempFile("", "k8s-cli-*.yaml")
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
@@ -379,7 +379,7 @@ spec:
runner := commands.NewCreateSubstitutionRunner("") runner := commands.NewCreateSubstitutionRunner("")
out := &bytes.Buffer{} out := &bytes.Buffer{}
runner.Command.SetOut(out) runner.Command.SetOut(out)
runner.Command.SetArgs(append([]string{baseDir}, test.args...)) runner.Command.SetArgs(append([]string{r.Name()}, test.args...))
err = runner.Command.Execute() err = runner.Command.Execute()
if test.err != "" { if test.err != "" {
@@ -393,14 +393,7 @@ spec:
t.FailNow() t.FailNow()
} }
expectedOut := strings.Replace(test.out, "${baseDir}", baseDir, -1) if !assert.Equal(t, test.out, out.String()) {
expectedNormalized := strings.Replace(expectedOut, "\\", "/", -1)
// normalize path format for windows
actualNormalized := strings.Replace(
strings.Replace(out.String(), "\\", "/", -1),
"//", "/", -1)
if !assert.Contains(t, actualNormalized, expectedNormalized) {
t.FailNow() t.FailNow()
} }
@@ -414,7 +407,7 @@ spec:
t.FailNow() t.FailNow()
} }
actualOpenAPI, err := ioutil.ReadFile(f) actualOpenAPI, err := ioutil.ReadFile(f.Name())
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
@@ -426,89 +419,3 @@ spec:
}) })
} }
} }
func TestCreateSubstSubPackages(t *testing.T) {
var tests = []struct {
name string
dataset string
packagePath string
args []string
expected string
}{
{
name: "create-subst-recurse-subpackages",
dataset: "dataset-without-setters",
args: []string{"image-tag", "--field-value", "mysql:1.7.9", "--pattern", "${image}:${tag}", "-R"},
expected: `${baseDir}/mysql/
created substitution "image-tag"
${baseDir}/mysql/storage/
created substitution "image-tag"
`,
},
{
name: "create-subst-top-level-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
packagePath: "mysql",
args: []string{"image-tag", "--field-value", "mysql:1.7.9", "--pattern", "${image}:${tag}"},
expected: `${baseDir}/mysql/
created substitution "image-tag"`,
},
{
name: "create-subst-nested-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
packagePath: "mysql/storage",
args: []string{"image-tag", "--field-value", "storage:1.7.9", "--pattern", "${image}:${tag}"},
expected: `${baseDir}/mysql/storage/
created substitution "image-tag"`,
},
{
name: "create-subst-already-exists",
dataset: "dataset-with-setters",
packagePath: "mysql",
args: []string{"image-tag", "--field-value", "mysql:1.7.9", "--pattern", "${image}:${tag}", "-R"},
expected: `${baseDir}/mysql/
substitution with name "image-tag" already exists
${baseDir}/mysql/nosetters/
created substitution "image-tag"
${baseDir}/mysql/storage/
created substitution "image-tag"`,
},
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
// reset the openAPI afterward
openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI()
sourceDir := filepath.Join("test", "testdata", test.dataset)
baseDir, err := ioutil.TempDir("", "")
if !assert.NoError(t, err) {
t.FailNow()
}
copyutil.CopyDir(sourceDir, baseDir)
defer os.RemoveAll(baseDir)
runner := commands.NewCreateSubstitutionRunner("")
actual := &bytes.Buffer{}
runner.Command.SetOut(actual)
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
err = runner.Command.Execute()
if !assert.NoError(t, err) {
t.FailNow()
}
// normalize path format for windows
actualNormalized := strings.Replace(
strings.Replace(actual.String(), "\\", "/", -1),
"//", "/", -1)
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
if !assert.Equal(t, strings.TrimSpace(expectedNormalized), strings.TrimSpace(actualNormalized)) {
t.FailNow()
}
})
}
}

View File

@@ -4,14 +4,11 @@
package commands package commands
import ( import (
"fmt"
"io"
"path/filepath"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext" "sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands" "sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/fieldmeta" "sigs.k8s.io/kustomize/kyaml/fieldmeta"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil" "sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
) )
@@ -27,8 +24,6 @@ func NewDeleteSetterRunner(parent string) *DeleteSetterRunner {
PreRunE: r.preRunE, PreRunE: r.preRunE,
RunE: r.runE, RunE: r.runE,
} }
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
"deletes setter recursively in all the nested subpackages")
fixDocs(parent, c) fixDocs(parent, c)
r.Command = c r.Command = c
@@ -40,58 +35,32 @@ func DeleteSetterCommand(parent string) *cobra.Command {
} }
type DeleteSetterRunner struct { type DeleteSetterRunner struct {
Command *cobra.Command Command *cobra.Command
DeleteSetter settersutil.DeleterCreator DeleteSetter settersutil.DeleterCreator
OpenAPIFile string OpenAPIFile string
RecurseSubPackages bool
} }
func (r *DeleteSetterRunner) preRunE(c *cobra.Command, args []string) error { func (r *DeleteSetterRunner) preRunE(c *cobra.Command, args []string) error {
var err error
r.DeleteSetter.Name = args[1] r.DeleteSetter.Name = args[1]
r.DeleteSetter.DefinitionPrefix = fieldmeta.SetterDefinitionPrefix r.DeleteSetter.DefinitionPrefix = fieldmeta.SetterDefinitionPrefix
r.OpenAPIFile = filepath.Join(args[0], ext.KRMFileName()) r.OpenAPIFile, err = ext.GetOpenAPIFile(args)
if err != nil {
return err
}
if err := openapi.AddSchemaFromFile(r.OpenAPIFile); err != nil {
return err
}
return nil return nil
} }
func (r *DeleteSetterRunner) runE(c *cobra.Command, args []string) error { func (r *DeleteSetterRunner) runE(c *cobra.Command, args []string) error {
e := executeCmdOnPkgs{ return handleError(c, r.delete(c, args))
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
}
err := e.execute()
if err != nil {
return handleError(c, err)
}
return nil
} }
func (r *DeleteSetterRunner) executeCmd(w io.Writer, pkgPath string) error { func (r *DeleteSetterRunner) delete(c *cobra.Command, args []string) error {
return r.DeleteSetter.Delete(r.OpenAPIFile, args[0])
r.DeleteSetter = settersutil.DeleterCreator{
Name: r.DeleteSetter.Name,
DefinitionPrefix: fieldmeta.SetterDefinitionPrefix,
RecurseSubPackages: r.RecurseSubPackages,
OpenAPIFileName: ext.KRMFileName(),
OpenAPIPath: filepath.Join(pkgPath, ext.KRMFileName()),
ResourcesPath: pkgPath,
}
err := r.DeleteSetter.Delete()
if err != nil {
// return err if RecurseSubPackages is false
if !r.DeleteSetter.RecurseSubPackages {
return err
} else {
// print error message and continue if RecurseSubPackages is true
fmt.Fprintf(w, "%s\n", err.Error())
}
} else {
fmt.Fprintf(w, "deleted setter %q\n", r.DeleteSetter.Name)
}
return nil
} }

View File

@@ -7,13 +7,12 @@ import (
"bytes" "bytes"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath"
"strings" "strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/commands" "sigs.k8s.io/kustomize/cmd/config/internal/commands"
"sigs.k8s.io/kustomize/kyaml/copyutil"
"sigs.k8s.io/kustomize/kyaml/openapi" "sigs.k8s.io/kustomize/kyaml/openapi"
) )
@@ -53,7 +52,6 @@ openAPI:
value: "3" value: "3"
setBy: me setBy: me
`, `,
out: `deleted setter "replicas-setter"`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -97,7 +95,6 @@ openAPI:
name: image name: image
value: nginx value: nginx
`, `,
out: `deleted setter "replicas-setter"`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -161,7 +158,6 @@ spec:
- "b" - "b"
- "c" - "c"
`, `,
out: `deleted setter "list"`,
expectedResources: ` expectedResources: `
apiVersion: example.com/v1beta1 apiVersion: example.com/v1beta1
kind: Example1 kind: Example1
@@ -230,7 +226,7 @@ metadata:
spec: spec:
replicas: 3 # {"$openapi" : "replicas-setter"} replicas: 3 # {"$openapi" : "replicas-setter"}
`, `,
err: `setter "image" does not exist`, err: `setter with name image does not exist`,
}, },
{ {
name: "delete setter used in substitution error", name: "delete setter used in substitution error",
@@ -291,7 +287,7 @@ openAPI:
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
`, `,
err: `setter "image-name" is used in substitution "image", please delete the parent substitution first`, err: `setter is used in substitution image, please delete the parent substitution first`,
}, },
} }
for i := range tests { for i := range tests {
@@ -301,18 +297,24 @@ kind: Deployment
openapi.ResetOpenAPI() openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI() defer openapi.ResetOpenAPI()
baseDir, err := ioutil.TempDir("", "") f, err := ioutil.TempFile("", "k8s-cli-")
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
defer os.RemoveAll(baseDir) defer os.Remove(f.Name())
f := filepath.Join(baseDir, "Krmfile")
err = ioutil.WriteFile(f, []byte(test.inputOpenAPI), 0600) err = ioutil.WriteFile(f.Name(), []byte(test.inputOpenAPI), 0600)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
r, err := ioutil.TempFile(baseDir, "k8s-cli-*.yaml") 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) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
@@ -325,29 +327,21 @@ kind: Deployment
runner := commands.NewDeleteSetterRunner("") runner := commands.NewDeleteSetterRunner("")
out := &bytes.Buffer{} out := &bytes.Buffer{}
runner.Command.SetOut(out) runner.Command.SetOut(out)
runner.Command.SetArgs(append([]string{baseDir}, test.args...)) runner.Command.SetArgs(append([]string{r.Name()}, test.args...))
err = runner.Command.Execute() err = runner.Command.Execute()
if test.err != "" { if test.err != "" {
if !assert.NotNil(t, err) { if !assert.NotNil(t, err) {
t.FailNow() t.FailNow()
} else {
assert.Equal(t, err.Error(), test.err)
return
} }
assert.Equal(t, test.err, err.Error())
return
} }
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
// normalize path format for windows if !assert.Equal(t, test.out, out.String()) {
actualNorm := strings.Replace(
strings.Replace(out.String(), "\\", "/", -1),
"//", "/", -1)
expectedOut := strings.Replace(test.out, "${baseDir}", baseDir, -1)
expectedNormalized := strings.Replace(expectedOut, "\\", "/", -1)
if !assert.Contains(t, strings.TrimSpace(actualNorm), expectedNormalized) {
t.FailNow() t.FailNow()
} }
@@ -361,7 +355,7 @@ kind: Deployment
t.FailNow() t.FailNow()
} }
actualOpenAPI, err := ioutil.ReadFile(f) actualOpenAPI, err := ioutil.ReadFile(f.Name())
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
@@ -373,80 +367,3 @@ kind: Deployment
}) })
} }
} }
func TestDeleteSetterSubPackages(t *testing.T) {
var tests = []struct {
name string
dataset string
packagePath string
args []string
expected string
}{
{
name: "delete-setter-recurse-subpackages",
dataset: "dataset-with-setters",
args: []string{"namespace", "-R"},
expected: `${baseDir}/mysql/
deleted setter "namespace"
${baseDir}/mysql/nosetters/
setter "namespace" does not exist
${baseDir}/mysql/storage/
deleted setter "namespace"
`,
},
{
name: "delete-setter-top-level-pkg-no-recurse-subpackages",
dataset: "dataset-with-setters",
packagePath: "mysql",
args: []string{"namespace"},
expected: `${baseDir}/mysql/
deleted setter "namespace"
`,
},
{
name: "delete-setter-nested-pkg-no-recurse-subpackages",
dataset: "dataset-with-setters",
packagePath: "mysql/storage",
args: []string{"namespace"},
expected: `${baseDir}/mysql/storage/
deleted setter "namespace"
`,
},
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
// reset the openAPI afterward
openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI()
sourceDir := filepath.Join("test", "testdata", test.dataset)
baseDir, err := ioutil.TempDir("", "")
if !assert.NoError(t, err) {
t.FailNow()
}
copyutil.CopyDir(sourceDir, baseDir)
//defer os.RemoveAll(baseDir)
runner := commands.NewDeleteSetterRunner("")
actual := &bytes.Buffer{}
runner.Command.SetOut(actual)
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
err = runner.Command.Execute()
if !assert.NoError(t, err) {
t.FailNow()
}
// normalize path format for windows
actualNormalized := strings.Replace(
strings.Replace(actual.String(), "\\", "/", -1),
"//", "/", -1)
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
if !assert.Equal(t, expectedNormalized, actualNormalized) {
t.FailNow()
}
})
}
}

View File

@@ -4,13 +4,10 @@
package commands package commands
import ( import (
"fmt"
"io"
"path/filepath"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext" "sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/kyaml/fieldmeta" "sigs.k8s.io/kustomize/kyaml/fieldmeta"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil" "sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
) )
@@ -23,8 +20,6 @@ func NewDeleteSubstitutionRunner(parent string) *DeleteSubstitutionRunner {
PreRunE: r.preRunE, PreRunE: r.preRunE,
RunE: r.runE, RunE: r.runE,
} }
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
"deletes substitution recursively in all the nested subpackages")
fixDocs(parent, c) fixDocs(parent, c)
r.Command = c r.Command = c
@@ -39,54 +34,29 @@ type DeleteSubstitutionRunner struct {
Command *cobra.Command Command *cobra.Command
DeleteSubstitution settersutil.DeleterCreator DeleteSubstitution settersutil.DeleterCreator
OpenAPIFile string OpenAPIFile string
RecurseSubPackages bool
} }
func (r *DeleteSubstitutionRunner) preRunE(c *cobra.Command, args []string) error { func (r *DeleteSubstitutionRunner) preRunE(c *cobra.Command, args []string) error {
var err error
r.DeleteSubstitution.Name = args[1] r.DeleteSubstitution.Name = args[1]
r.DeleteSubstitution.DefinitionPrefix = fieldmeta.SubstitutionDefinitionPrefix r.DeleteSubstitution.DefinitionPrefix = fieldmeta.SubstitutionDefinitionPrefix
r.OpenAPIFile = filepath.Join(args[0], ext.KRMFileName()) r.OpenAPIFile, err = ext.GetOpenAPIFile(args)
if err != nil {
return err
}
if err := openapi.AddSchemaFromFile(r.OpenAPIFile); err != nil {
return err
}
return nil return nil
} }
func (r *DeleteSubstitutionRunner) runE(c *cobra.Command, args []string) error { func (r *DeleteSubstitutionRunner) runE(c *cobra.Command, args []string) error {
e := executeCmdOnPkgs{ return handleError(c, r.delete(c, args))
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
}
err := e.execute()
if err != nil {
return handleError(c, err)
}
return nil
} }
func (r *DeleteSubstitutionRunner) executeCmd(w io.Writer, pkgPath string) error { func (r *DeleteSubstitutionRunner) delete(c *cobra.Command, args []string) error {
r.DeleteSubstitution = settersutil.DeleterCreator{ return r.DeleteSubstitution.Delete(r.OpenAPIFile, args[0])
Name: r.DeleteSubstitution.Name,
DefinitionPrefix: fieldmeta.SubstitutionDefinitionPrefix,
RecurseSubPackages: r.RecurseSubPackages,
OpenAPIFileName: ext.KRMFileName(),
OpenAPIPath: filepath.Join(pkgPath, ext.KRMFileName()),
ResourcesPath: pkgPath,
}
err := r.DeleteSubstitution.Delete()
if err != nil {
// return err if RecurseSubPackages is false
if !r.DeleteSubstitution.RecurseSubPackages {
return err
} else {
// print error message and continue if RecurseSubPackages is true
fmt.Fprintf(w, "%s\n", err.Error())
}
} else {
fmt.Fprintf(w, "deleted substitution %q\n", r.DeleteSubstitution.Name)
}
return nil
} }

View File

@@ -7,13 +7,12 @@ import (
"bytes" "bytes"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath"
"strings" "strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/commands" "sigs.k8s.io/kustomize/cmd/config/internal/commands"
"sigs.k8s.io/kustomize/kyaml/copyutil"
"sigs.k8s.io/kustomize/kyaml/openapi" "sigs.k8s.io/kustomize/kyaml/openapi"
) )
@@ -80,7 +79,6 @@ spec:
- name: sidecar - name: sidecar
image: nginx:1.7.9 # {"$ref":"#/definitions/io.k8s.cli.substitutions.my.image"} image: nginx:1.7.9 # {"$ref":"#/definitions/io.k8s.cli.substitutions.my.image"}
`, `,
out: `deleted substitution "my.image"`,
expectedResources: ` expectedResources: `
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
@@ -171,7 +169,6 @@ spec:
- name: sidecar - name: sidecar
image: nginx:1.7.9 # {"$openapi":"my-image-sub"} image: nginx:1.7.9 # {"$openapi":"my-image-sub"}
`, `,
out: `deleted substitution "my-image-sub"`,
expectedResources: ` expectedResources: `
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
@@ -300,7 +297,7 @@ openAPI:
value: "3" value: "3"
setBy: me setBy: me
`, `,
err: `substitution "my-image-sub-not-present" does not exist`, err: "substitution with name my-image-sub-not-present does not exist",
}, },
{ {
@@ -418,7 +415,7 @@ spec:
- name: sidecar - name: sidecar
image: nginx::1.7.9 # {"$openapi":"my-image-subst"} image: nginx::1.7.9 # {"$openapi":"my-image-subst"}
`, `,
err: `substitution "my-image-subst" is used in substitution "my-nested-subst", please delete the parent substitution first`, err: "substitution is used in substitution my-nested-subst, please delete the parent substitution first",
}, },
} }
for i := range tests { for i := range tests {
@@ -428,18 +425,24 @@ spec:
openapi.ResetOpenAPI() openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI() defer openapi.ResetOpenAPI()
baseDir, err := ioutil.TempDir("", "") f, err := ioutil.TempFile("", "k8s-cli-")
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
defer os.RemoveAll(baseDir) defer os.Remove(f.Name())
f := filepath.Join(baseDir, "Krmfile")
err = ioutil.WriteFile(f, []byte(test.inputOpenAPI), 0600) err = ioutil.WriteFile(f.Name(), []byte(test.inputOpenAPI), 0600)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
r, err := ioutil.TempFile(baseDir, "k8s-cli-*.yaml") 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) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
@@ -452,38 +455,21 @@ spec:
runner := commands.NewDeleteSubstitutionRunner("") runner := commands.NewDeleteSubstitutionRunner("")
out := &bytes.Buffer{} out := &bytes.Buffer{}
runner.Command.SetOut(out) runner.Command.SetOut(out)
runner.Command.SetArgs(append([]string{baseDir}, test.args...)) runner.Command.SetArgs(append([]string{r.Name()}, test.args...))
err = runner.Command.Execute() err = runner.Command.Execute()
if test.err != "" { if test.err != "" {
if !assert.NotNil(t, err) { if !assert.NotNil(t, err) {
t.FailNow() t.FailNow()
} else {
assert.Equal(t, err.Error(), test.err)
return
} }
assert.Equal(t, test.err, err.Error())
return
} }
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
// normalize path format for windows if !assert.Equal(t, test.out, out.String()) {
actualNorm := strings.Replace(
strings.Replace(out.String(), "\\", "/", -1),
"//", "/", -1)
expectedOut := strings.Replace(test.out, "${baseDir}", baseDir, -1)
expectedNorm := strings.Replace(expectedOut, "\\", "/", -1)
if !assert.Contains(t, strings.TrimSpace(actualNorm), expectedNorm) {
t.FailNow()
}
actualOpenAPI, err := ioutil.ReadFile(f)
if !assert.NoError(t, err) {
t.FailNow()
}
if !assert.Equal(t,
strings.TrimSpace(test.expectedOpenAPI),
strings.TrimSpace(string(actualOpenAPI))) {
t.FailNow() t.FailNow()
} }
@@ -494,74 +480,16 @@ spec:
if !assert.Equal(t, if !assert.Equal(t,
strings.TrimSpace(test.expectedResources), strings.TrimSpace(test.expectedResources),
strings.TrimSpace(string(actualResources))) { strings.TrimSpace(string(actualResources))) {
t.FailNow() return
} }
})
} actualOpenAPI, err := ioutil.ReadFile(f.Name())
} if !assert.NoError(t, err) {
t.FailNow()
func TestDeleteSubstitutionSubPackages(t *testing.T) { }
var tests = []struct { if !assert.Equal(t,
name string strings.TrimSpace(test.expectedOpenAPI),
dataset string strings.TrimSpace(string(actualOpenAPI))) {
packagePath string
args []string
expected string
}{
{
name: "delete-substitution-recurse-subpackages",
dataset: "dataset-with-setters",
args: []string{"image-tag", "-R"},
expected: `${baseDir}/mysql/
deleted substitution "image-tag"
${baseDir}/mysql/nosetters/
substitution "image-tag" does not exist
${baseDir}/mysql/storage/
substitution "image-tag" does not exist
`,
},
{
name: "delete-setter-top-level-pkg-no-recurse-subpackages",
dataset: "dataset-with-setters",
packagePath: "mysql",
args: []string{"image-tag"},
expected: `${baseDir}/mysql/
deleted substitution "image-tag"
`,
},
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
// reset the openAPI afterward
openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI()
sourceDir := filepath.Join("test", "testdata", test.dataset)
baseDir, err := ioutil.TempDir("", "")
if !assert.NoError(t, err) {
t.FailNow()
}
copyutil.CopyDir(sourceDir, baseDir)
//defer os.RemoveAll(baseDir)
runner := commands.NewDeleteSubstitutionRunner("")
actual := &bytes.Buffer{}
runner.Command.SetOut(actual)
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
err = runner.Command.Execute()
if !assert.NoError(t, err) {
t.FailNow()
}
// normalize path format for windows
actualNormalized := strings.Replace(
strings.Replace(actual.String(), "\\", "/", -1),
"//", "/", -1)
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
if !assert.Equal(t, expectedNormalized, actualNormalized) {
t.FailNow() t.FailNow()
} }
}) })

View File

@@ -7,14 +7,15 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"path/filepath"
"strings" "strings"
"github.com/olekukonko/tablewriter" "github.com/olekukonko/tablewriter"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext" "sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands" "sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/fieldmeta" "sigs.k8s.io/kustomize/kyaml/fieldmeta"
"sigs.k8s.io/kustomize/kyaml/pathutil"
"sigs.k8s.io/kustomize/kyaml/setters" "sigs.k8s.io/kustomize/kyaml/setters"
"sigs.k8s.io/kustomize/kyaml/setters2" "sigs.k8s.io/kustomize/kyaml/setters2"
) )
@@ -35,8 +36,6 @@ func NewListSettersRunner(parent string) *ListSettersRunner {
"output as github markdown") "output as github markdown")
c.Flags().BoolVar(&r.IncludeSubst, "include-subst", false, c.Flags().BoolVar(&r.IncludeSubst, "include-subst", false,
"include substitutions in the output") "include substitutions in the output")
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", true,
"list setters recursively in all the nested subpackages")
fixDocs(parent, c) fixDocs(parent, c)
r.Command = c r.Command = c
return r return r
@@ -47,12 +46,11 @@ func ListSettersCommand(parent string) *cobra.Command {
} }
type ListSettersRunner struct { type ListSettersRunner struct {
Command *cobra.Command Command *cobra.Command
Lookup setters.LookupSetters Lookup setters.LookupSetters
List setters2.List List setters2.List
Markdown bool Markdown bool
IncludeSubst bool IncludeSubst bool
RecurseSubPackages bool
} }
func (r *ListSettersRunner) preRunE(c *cobra.Command, args []string) error { func (r *ListSettersRunner) preRunE(c *cobra.Command, args []string) error {
@@ -67,46 +65,48 @@ func (r *ListSettersRunner) preRunE(c *cobra.Command, args []string) error {
func (r *ListSettersRunner) runE(c *cobra.Command, args []string) error { func (r *ListSettersRunner) runE(c *cobra.Command, args []string) error {
if setterVersion == "v2" { if setterVersion == "v2" {
e := executeCmdOnPkgs{ openAPIFileName, err := ext.OpenAPIFileName()
needOpenAPI: true, if err != nil {
writer: c.OutOrStdout(), return err
rootPkgPath: args[0],
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
} }
err := e.execute() openAPIPaths, err := pathutil.SubDirsWithFile(args[0], openAPIFileName)
if err != nil { if err != nil {
return handleError(c, err) return err
}
if len(openAPIPaths) == 0 {
return errors.Errorf("unable to find %s in %s", openAPIFileName, args[0])
}
// list setters for all the subpackages with openAPI file paths
for _, openAPIPath := range openAPIPaths {
r.List = setters2.List{
Name: r.List.Name,
OpenAPIFileName: openAPIFileName,
}
resourcePath := strings.TrimSuffix(openAPIPath, openAPIFileName)
fmt.Fprintf(c.OutOrStdout(), "%s\n", resourcePath)
if err := r.ListSetters(c, openAPIPath, resourcePath); err != nil {
return err
}
if r.IncludeSubst {
if err := r.ListSubstitutions(c, openAPIPath); err != nil {
return err
}
}
} }
return nil return nil
} }
return handleError(c, lookup(r.Lookup, c, args)) return handleError(c, lookup(r.Lookup, c, args))
} }
func (r *ListSettersRunner) executeCmd(w io.Writer, pkgPath string) error { func (r *ListSettersRunner) ListSetters(c *cobra.Command, openAPIPath, resourcePath string) error {
r.List = setters2.List{
Name: r.List.Name,
OpenAPIFileName: ext.KRMFileName(),
}
openAPIPath := filepath.Join(pkgPath, ext.KRMFileName())
if err := r.ListSetters(w, openAPIPath, pkgPath); err != nil {
return err
}
if r.IncludeSubst {
if err := r.ListSubstitutions(w, openAPIPath); err != nil {
return err
}
}
return nil
}
func (r *ListSettersRunner) ListSetters(w io.Writer, openAPIPath, resourcePath string) error {
// use setters v2 // use setters v2
if err := r.List.ListSetters(openAPIPath, resourcePath); err != nil { if err := r.List.ListSetters(openAPIPath, resourcePath); err != nil {
return err return err
} }
table := newTable(w, r.Markdown) 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", "REQUIRED"})
for i := range r.List.Setters { for i := range r.List.Setters {
s := r.List.Setters[i] s := r.List.Setters[i]
@@ -137,12 +137,12 @@ func (r *ListSettersRunner) ListSetters(w io.Writer, openAPIPath, resourcePath s
return nil return nil
} }
func (r *ListSettersRunner) ListSubstitutions(w io.Writer, openAPIPath string) error { func (r *ListSettersRunner) ListSubstitutions(c *cobra.Command, openAPIPath string) error {
// use setters v2 // use setters v2
if err := r.List.ListSubst(openAPIPath); err != nil { if err := r.List.ListSubst(openAPIPath); err != nil {
return err return err
} }
table := newTable(w, r.Markdown) table := newTable(c.OutOrStdout(), r.Markdown)
b := tablewriter.Border{Top: true} b := tablewriter.Border{Top: true}
table.SetBorders(b) table.SetBorders(b)

View File

@@ -471,11 +471,9 @@ func TestListSettersSubPackages(t *testing.T) {
}{ }{
{ {
name: "list-replicas", name: "list-replicas",
dataset: "dataset-with-setters", dataset: "dataset1",
args: []string{"--include-subst"}, args: []string{"--include-subst"},
expected: ` expected: `test/testdata/dataset1/mysql/
test/testdata/dataset-with-setters/mysql/
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
image mysql 1 No image mysql 1 No
namespace myspace 1 No namespace myspace 1 No
@@ -483,26 +481,11 @@ test/testdata/dataset-with-setters/mysql/
--------------- ----------------- -------------- --------------- ----------------- --------------
SUBSTITUTION PATTERN REFERENCES SUBSTITUTION PATTERN REFERENCES
image-tag ${image}:${tag} [image,tag] image-tag ${image}:${tag} [image,tag]
test/testdata/dataset1/mysql/nosetters/
test/testdata/dataset-with-setters/mysql/nosetters/
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
test/testdata/dataset1/mysql/storage/
test/testdata/dataset-with-setters/mysql/storage/
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
namespace myspace 1 No namespace myspace 1 No
`,
},
{
name: "list-replicas",
dataset: "dataset-with-setters/mysql",
args: []string{"--recurse-subpackages=false"},
expected: `
test/testdata/dataset-with-setters/mysql/
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
image mysql 1 No
namespace myspace 1 No
tag 1.7.9 1 No
`, `,
}, },
} }
@@ -526,7 +509,7 @@ test/testdata/dataset-with-setters/mysql/
// normalize path format for windows // normalize path format for windows
actualNormalized := strings.Replace(actual.String(), "\\", "/", -1) actualNormalized := strings.Replace(actual.String(), "\\", "/", -1)
if !assert.Equal(t, strings.TrimSpace(test.expected), strings.TrimSpace(actualNormalized)) { if !assert.Equal(t, test.expected, actualNormalized) {
t.FailNow() t.FailNow()
} }
}) })

View File

@@ -5,9 +5,7 @@ package commands
import ( import (
"fmt" "fmt"
"io"
"os" "os"
"path/filepath"
"github.com/olekukonko/tablewriter" "github.com/olekukonko/tablewriter"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@@ -41,8 +39,6 @@ func NewSetRunner(parent string) *SetRunner {
"annotate the field with a description of its value") "annotate the field with a description of its value")
c.Flags().StringVar(&setterVersion, "version", "", c.Flags().StringVar(&setterVersion, "version", "",
"use this version of the setter format") "use this version of the setter format")
c.Flags().BoolVarP(&r.Set.RecurseSubPackages, "recurse-subpackages", "R", false,
"sets recursively in all the nested subpackages")
c.Flags().MarkHidden("version") c.Flags().MarkHidden("version")
return r return r
@@ -108,6 +104,7 @@ func (r *SetRunner) preRunE(c *cobra.Command, args []string) error {
} }
} }
if setterVersion == "v2" { if setterVersion == "v2" {
var err error
r.Set.Name = args[1] r.Set.Name = args[1]
if valueFlagSet { if valueFlagSet {
r.Set.Value = r.Values[0] r.Set.Value = r.Values[0]
@@ -124,25 +121,20 @@ func (r *SetRunner) preRunE(c *cobra.Command, args []string) error {
r.Set.Description = r.Perform.Description r.Set.Description = r.Perform.Description
r.Set.SetBy = r.Perform.SetBy r.Set.SetBy = r.Perform.SetBy
r.OpenAPIFile = filepath.Join(args[0], ext.KRMFileName()) r.OpenAPIFile, err = ext.GetOpenAPIFile(args)
if err != nil {
return err
}
} }
return nil return nil
} }
func (r *SetRunner) runE(c *cobra.Command, args []string) error { func (r *SetRunner) runE(c *cobra.Command, args []string) error {
if setterVersion == "v2" { if setterVersion == "v2" {
e := executeCmdOnPkgs{ count, err := r.Set.Set(r.OpenAPIFile, args[0])
needOpenAPI: true, fmt.Fprintf(c.OutOrStdout(), "set %d fields\n", count)
writer: c.OutOrStdout(), return handleError(c, err)
rootPkgPath: args[0],
recurseSubPackages: r.Set.RecurseSubPackages,
cmdRunner: r,
}
err := e.execute()
if err != nil {
return handleError(c, err)
}
return nil
} }
if len(args) > 2 || c.Flag("values").Changed { if len(args) > 2 || c.Flag("values").Changed {
return handleError(c, r.perform(c, args)) return handleError(c, r.perform(c, args))
@@ -150,34 +142,6 @@ func (r *SetRunner) runE(c *cobra.Command, args []string) error {
return handleError(c, lookup(r.Lookup, c, args)) return handleError(c, lookup(r.Lookup, c, args))
} }
func (r *SetRunner) executeCmd(w io.Writer, pkgPath string) error {
r.Set = settersutil.FieldSetter{
Name: r.Set.Name,
Value: r.Set.Value,
ListValues: r.Set.ListValues,
Description: r.Set.Description,
SetBy: r.Set.SetBy,
Count: 0,
OpenAPIPath: filepath.Join(pkgPath, ext.KRMFileName()),
OpenAPIFileName: ext.KRMFileName(),
ResourcesPath: pkgPath,
RecurseSubPackages: r.Set.RecurseSubPackages,
}
count, err := r.Set.Set()
if err != nil {
// return err if RecurseSubPackages is false
if !r.Set.RecurseSubPackages {
return err
} else {
// print error message and continue if RecurseSubPackages is true
fmt.Fprintf(w, "%s\n", err.Error())
}
} else {
fmt.Fprintf(w, "set %d field(s) of setter %q to value %q\n", count, r.Set.Name, r.Set.Value)
}
return nil
}
func lookup(l setters.LookupSetters, c *cobra.Command, args []string) error { func lookup(l setters.LookupSetters, c *cobra.Command, args []string) error {
// lookup the setters // lookup the setters
err := kio.Pipeline{ err := kio.Pipeline{

View File

@@ -7,13 +7,12 @@ import (
"bytes" "bytes"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath"
"strings" "strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/commands" "sigs.k8s.io/kustomize/cmd/config/internal/commands"
"sigs.k8s.io/kustomize/kyaml/copyutil"
"sigs.k8s.io/kustomize/kyaml/openapi" "sigs.k8s.io/kustomize/kyaml/openapi"
) )
@@ -31,7 +30,7 @@ func TestSetCommand(t *testing.T) {
{ {
name: "set replicas", name: "set replicas",
args: []string{"replicas", "4", "--description", "hi there", "--set-by", "pw"}, args: []string{"replicas", "4", "--description", "hi there", "--set-by", "pw"},
out: "set 1 field(s)\n", out: "set 1 fields\n",
inputOpenAPI: ` inputOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -127,7 +126,7 @@ spec:
{ {
name: "set replicas no description", name: "set replicas no description",
args: []string{"replicas", "4"}, args: []string{"replicas", "4"},
out: "set 1 field(s)\n", out: "set 1 fields\n",
inputOpenAPI: ` inputOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -175,7 +174,7 @@ spec:
{ {
name: "set image with value", name: "set image with value",
args: []string{"tag", "1.8.1"}, args: []string{"tag", "1.8.1"},
out: "set 1 field(s)\n", out: "set 1 fields\n",
inputOpenAPI: ` inputOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -510,7 +509,7 @@ list in body should have at most 2 items`,
{ {
name: "set replicas with value set by flag", name: "set replicas with value set by flag",
args: []string{"replicas", "--values", "4", "--description", "hi there"}, args: []string{"replicas", "--values", "4", "--description", "hi there"},
out: "set 1 field(s)\n", out: "set 1 fields\n",
inputOpenAPI: ` inputOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -606,7 +605,7 @@ spec:
{ {
name: "openAPI list values set by flag success", name: "openAPI list values set by flag success",
args: []string{"list", "--values", "10", "--values", "11"}, args: []string{"list", "--values", "10", "--values", "11"},
out: "set 1 field(s)\n", out: "set 1 fields\n",
inputOpenAPI: ` inputOpenAPI: `
kind: Kptfile kind: Kptfile
openAPI: openAPI:
@@ -710,7 +709,7 @@ list in body should have at most 2 items`,
{ {
name: "nested substitution", name: "nested substitution",
args: []string{"my-image-setter", "ubuntu"}, args: []string{"my-image-setter", "ubuntu"},
out: "set 2 field(s)\n", out: "set 2 fields\n",
inputOpenAPI: ` inputOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -1014,19 +1013,22 @@ spec:
openapi.ResetOpenAPI() openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI() defer openapi.ResetOpenAPI()
baseDir, err := ioutil.TempDir("", "") f, err := ioutil.TempFile("", "k8s-cli-")
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
defer os.RemoveAll(baseDir) defer os.Remove(f.Name())
err = ioutil.WriteFile(f.Name(), []byte(test.inputOpenAPI), 0600)
f := filepath.Join(baseDir, "Krmfile")
err = ioutil.WriteFile(f, []byte(test.inputOpenAPI), 0600)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
old := ext.GetOpenAPIFile
defer func() { ext.GetOpenAPIFile = old }()
ext.GetOpenAPIFile = func(args []string) (s string, err error) {
return f.Name(), nil
}
r, err := ioutil.TempFile(baseDir, "k8s-cli-*.yaml") r, err := ioutil.TempFile("", "k8s-cli-*.yaml")
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
@@ -1039,7 +1041,7 @@ spec:
runner := commands.NewSetRunner("") runner := commands.NewSetRunner("")
out := &bytes.Buffer{} out := &bytes.Buffer{}
runner.Command.SetOut(out) runner.Command.SetOut(out)
runner.Command.SetArgs(append([]string{baseDir}, test.args...)) runner.Command.SetArgs(append([]string{r.Name()}, test.args...))
err = runner.Command.Execute() err = runner.Command.Execute()
if test.errMsg != "" { if test.errMsg != "" {
if !assert.NotNil(t, err) { if !assert.NotNil(t, err) {
@@ -1054,7 +1056,7 @@ spec:
t.FailNow() t.FailNow()
} }
if test.errMsg == "" && !assert.Contains(t, out.String(), strings.TrimSpace(test.out)) { if test.errMsg == "" && !assert.Equal(t, test.out, out.String()) {
t.FailNow() t.FailNow()
} }
@@ -1068,7 +1070,7 @@ spec:
t.FailNow() t.FailNow()
} }
actualOpenAPI, err := ioutil.ReadFile(f) actualOpenAPI, err := ioutil.ReadFile(f.Name())
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
@@ -1080,82 +1082,3 @@ spec:
}) })
} }
} }
func TestSetSubPackages(t *testing.T) {
var tests = []struct {
name string
dataset string
packagePath string
args []string
expected string
}{
{
name: "set-recurse-subpackages",
dataset: "dataset-with-setters",
args: []string{"namespace", "otherspace", "-R"},
expected: `${baseDir}/mysql/
set 1 field(s) of setter "namespace" to value "otherspace"
${baseDir}/mysql/nosetters/
setter "namespace" is not found
${baseDir}/mysql/storage/
set 1 field(s) of setter "namespace" to value "otherspace"
`,
},
{
name: "set-top-level-pkg-no-recurse-subpackages",
dataset: "dataset-with-setters",
packagePath: "mysql",
args: []string{"namespace", "otherspace"},
expected: `${baseDir}/mysql/
set 1 field(s) of setter "namespace" to value "otherspace"
`,
},
{
name: "set-nested-pkg-no-recurse-subpackages",
dataset: "dataset-with-setters",
packagePath: "mysql/storage",
args: []string{"namespace", "otherspace"},
expected: `${baseDir}/mysql/storage/
set 1 field(s) of setter "namespace" to value "otherspace"
`,
},
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
// reset the openAPI afterward
openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI()
sourceDir := filepath.Join("test", "testdata", test.dataset)
baseDir, err := ioutil.TempDir("", "")
if !assert.NoError(t, err) {
t.FailNow()
}
copyutil.CopyDir(sourceDir, baseDir)
defer os.RemoveAll(baseDir)
runner := commands.NewSetRunner("")
actual := &bytes.Buffer{}
runner.Command.SetOut(actual)
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
err = runner.Command.Execute()
if !assert.NoError(t, err) {
t.FailNow()
}
// normalize path format for windows
actualNormalized := strings.Replace(
strings.Replace(actual.String(), "\\", "/", -1),
"//", "/", -1)
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
expectedNormalized := strings.Replace(
strings.Replace(expected, "\\", "/", -1),
"//", "/", -1)
if !assert.Equal(t, strings.TrimSpace(expectedNormalized), strings.TrimSpace(actualNormalized)) {
t.FailNow()
}
})
}
}

View File

@@ -182,7 +182,7 @@ items:
kind: Deployment kind: Deployment
metadata: metadata:
name: mysql-deployment name: mysql-deployment
namespace: myspace namespace: myspace # {"$openapi":"namespace"}
annotations: annotations:
config.kubernetes.io/index: '0' config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'config/mysql-deployment_deployment.yaml' config.kubernetes.io/path: 'config/mysql-deployment_deployment.yaml'
@@ -192,7 +192,7 @@ items:
spec: spec:
containers: containers:
- name: mysql - name: mysql
image: mysql:1.7.9 image: mysql:1.7.9 # {"$openapi":"image-tag"}
- apiVersion: apps/v1 - apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
@@ -212,7 +212,7 @@ items:
kind: Deployment kind: Deployment
metadata: metadata:
name: storage-deployment name: storage-deployment
namespace: myspace namespace: myspace # {"$openapi":"namespace"}
annotations: annotations:
config.kubernetes.io/index: '0' config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'config/storage-deployment_deployment.yaml' config.kubernetes.io/path: 'config/storage-deployment_deployment.yaml'

View File

@@ -5,11 +5,9 @@ package commands
import ( import (
"fmt" "fmt"
"io"
"sort" "sort"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands" "sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/sets" "sigs.k8s.io/kustomize/kyaml/sets"
@@ -19,18 +17,18 @@ import (
func GetCountRunner(name string) *CountRunner { func GetCountRunner(name string) *CountRunner {
r := &CountRunner{} r := &CountRunner{}
c := &cobra.Command{ c := &cobra.Command{
Use: "count [DIR]", Use: "count DIR...",
Args: cobra.MaximumNArgs(1),
Short: commands.CountShort, Short: commands.CountShort,
Long: commands.CountLong, Long: commands.CountLong,
Example: commands.CountExamples, Example: commands.CountExamples,
RunE: r.runE, RunE: r.runE,
} }
fixDocs(name, c) fixDocs(name, c)
c.Flags().BoolVar(&r.IncludeSubpackages, "include-subpackages", true,
"also print resources from subpackages.")
c.Flags().BoolVar(&r.Kind, "kind", true, c.Flags().BoolVar(&r.Kind, "kind", true,
"count resources by kind.") "count resources by kind.")
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", true,
"prints count of resources recursively in all the nested subpackages")
r.Command = c r.Command = c
return r return r
} }
@@ -44,51 +42,20 @@ type CountRunner struct {
IncludeSubpackages bool IncludeSubpackages bool
Kind bool Kind bool
Command *cobra.Command Command *cobra.Command
RecurseSubPackages bool
} }
func (r *CountRunner) runE(c *cobra.Command, args []string) error { func (r *CountRunner) runE(c *cobra.Command, args []string) error {
if len(args) == 0 { var inputs []kio.Reader
input := &kio.ByteReader{Reader: c.InOrStdin()} for _, a := range args {
inputs = append(inputs, kio.LocalPackageReader{
return handleError(c, kio.Pipeline{ PackagePath: a,
Inputs: []kio.Reader{input}, IncludeSubpackages: r.IncludeSubpackages,
Outputs: r.out(c.OutOrStdout()), })
}.Execute()) }
if len(inputs) == 0 {
inputs = append(inputs, &kio.ByteReader{Reader: c.InOrStdin()})
} }
e := executeCmdOnPkgs{
writer: c.OutOrStdout(),
needOpenAPI: false,
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
rootPkgPath: args[0],
}
return e.execute()
}
func (r *CountRunner) executeCmd(w io.Writer, pkgPath string) error {
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: ext.KRMFileName()}
err := kio.Pipeline{
Inputs: []kio.Reader{input},
Outputs: r.out(w),
}.Execute()
if err != nil {
// return err if there is only package
if !r.RecurseSubPackages {
return err
} else {
// print error message and continue if there are multiple packages to annotate
fmt.Fprintf(w, "%s\n", err.Error())
}
}
return nil
}
func (r *CountRunner) out(w io.Writer) []kio.Writer {
var out []kio.Writer var out []kio.Writer
if r.Kind { if r.Kind {
out = append(out, kio.WriterFunc(func(nodes []*yaml.RNode) error { out = append(out, kio.WriterFunc(func(nodes []*yaml.RNode) error {
@@ -102,15 +69,20 @@ func (r *CountRunner) out(w io.Writer) []kio.Writer {
order := k.List() order := k.List()
sort.Strings(order) sort.Strings(order)
for _, k := range order { for _, k := range order {
fmt.Fprintf(w, "%s: %d\n", k, count[k]) fmt.Fprintf(c.OutOrStdout(), "%s: %d\n", k, count[k])
} }
return nil return nil
})) }))
} else { } else {
out = append(out, kio.WriterFunc(func(nodes []*yaml.RNode) error { out = append(out, kio.WriterFunc(func(nodes []*yaml.RNode) error {
fmt.Fprintf(w, "%d\n", len(nodes)) fmt.Fprintf(c.OutOrStdout(), "%d\n", len(nodes))
return nil return nil
})) }))
} }
return out return handleError(c, kio.Pipeline{
Inputs: inputs,
Outputs: out,
}.Execute())
} }

View File

@@ -8,13 +8,10 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/config/internal/commands" "sigs.k8s.io/kustomize/cmd/config/internal/commands"
"sigs.k8s.io/kustomize/kyaml/copyutil"
"sigs.k8s.io/kustomize/kyaml/openapi"
) )
func TestCountCommand_files(t *testing.T) { func TestCountCommand_files(t *testing.T) {
@@ -70,82 +67,7 @@ spec:
return return
} }
if !assert.Contains(t, b.String(), "Deployment: 2\nService: 1\n") { if !assert.Equal(t, "Deployment: 2\nService: 1\n", b.String()) {
return return
} }
} }
func TestCountSubPackages(t *testing.T) {
var tests = []struct {
name string
dataset string
packagePath string
args []string
expected string
}{
{
name: "count-recurse-subpackages",
dataset: "dataset-without-setters",
expected: `${baseDir}/
${baseDir}/mysql/
Deployment: 1
${baseDir}/mysql/storage/
Deployment: 1
`,
},
{
name: "count-top-level-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
args: []string{"-R=false"},
packagePath: "mysql",
expected: `${baseDir}/mysql/
Deployment: 1
`,
},
{
name: "count-nested-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
packagePath: "mysql/storage",
args: []string{"-R=false"},
expected: `${baseDir}/mysql/storage/
Deployment: 1
`,
},
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
// reset the openAPI afterward
openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI()
sourceDir := filepath.Join("test", "testdata", test.dataset)
baseDir, err := ioutil.TempDir("", "")
if !assert.NoError(t, err) {
t.FailNow()
}
copyutil.CopyDir(sourceDir, baseDir)
defer os.RemoveAll(baseDir)
runner := commands.GetCountRunner("")
actual := &bytes.Buffer{}
runner.Command.SetOut(actual)
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
err = runner.Command.Execute()
if !assert.NoError(t, err) {
t.FailNow()
}
// normalize path format for windows
actualNormalized := strings.Replace(
strings.Replace(actual.String(), "\\", "/", -1),
"//", "/", -1)
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
if !assert.Equal(t, expectedNormalized, actualNormalized) {
t.FailNow()
}
})
}
}

View File

@@ -4,11 +4,7 @@
package commands package commands
import ( import (
"fmt"
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands" "sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/filters" "sigs.k8s.io/kustomize/kyaml/kio/filters"
@@ -37,8 +33,6 @@ formatting substitution verbs {'%n': 'metadata.name', '%s': 'metadata.namespace'
`if true, override existing filepath annotations.`) `if true, override existing filepath annotations.`)
c.Flags().BoolVar(&r.UseSchema, "use-schema", false, c.Flags().BoolVar(&r.UseSchema, "use-schema", false,
`if true, uses openapi resource schema to format resources.`) `if true, uses openapi resource schema to format resources.`)
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
"formats resource files recursively in all the nested subpackages")
r.Command = c r.Command = c
return r return r
} }
@@ -49,13 +43,12 @@ func FmtCommand(name string) *cobra.Command {
// FmtRunner contains the run function // FmtRunner contains the run function
type FmtRunner struct { type FmtRunner struct {
Command *cobra.Command Command *cobra.Command
FilenamePattern string FilenamePattern string
SetFilenames bool SetFilenames bool
KeepAnnotations bool KeepAnnotations bool
Override bool Override bool
UseSchema bool UseSchema bool
RecurseSubPackages bool
} }
func (r *FmtRunner) preRunE(c *cobra.Command, args []string) error { func (r *FmtRunner) preRunE(c *cobra.Command, args []string) error {
@@ -66,6 +59,17 @@ func (r *FmtRunner) preRunE(c *cobra.Command, args []string) error {
} }
func (r *FmtRunner) runE(c *cobra.Command, args []string) error { func (r *FmtRunner) runE(c *cobra.Command, args []string) error {
f := []kio.Filter{filters.FormatFilter{
UseSchema: r.UseSchema,
}}
// format with file names
if r.SetFilenames {
f = append(f, &filters.FileSetter{
FilenamePattern: r.FilenamePattern,
Override: r.Override,
})
}
// format stdin if there are no args // format stdin if there are no args
if len(args) == 0 { if len(args) == 0 {
@@ -75,59 +79,20 @@ func (r *FmtRunner) runE(c *cobra.Command, args []string) error {
KeepReaderAnnotations: r.KeepAnnotations, KeepReaderAnnotations: r.KeepAnnotations,
} }
return handleError(c, kio.Pipeline{ return handleError(c, kio.Pipeline{
Inputs: []kio.Reader{rw}, Filters: r.fmtFilters(), Outputs: []kio.Writer{rw}}.Execute()) Inputs: []kio.Reader{rw}, Filters: f, Outputs: []kio.Writer{rw}}.Execute())
} }
for _, rootPkgPath := range args { for i := range args {
e := executeCmdOnPkgs{ path := args[i]
writer: c.OutOrStdout(), rw := &kio.LocalPackageReadWriter{
needOpenAPI: false, NoDeleteFiles: true,
recurseSubPackages: r.RecurseSubPackages, PackagePath: path,
cmdRunner: r, KeepReaderAnnotations: r.KeepAnnotations}
rootPkgPath: rootPkgPath, err := kio.Pipeline{
} Inputs: []kio.Reader{rw}, Filters: f, Outputs: []kio.Writer{rw}}.Execute()
err := e.execute()
if err != nil { if err != nil {
return err return handleError(c, err)
} }
} }
return nil return nil
} }
func (r *FmtRunner) executeCmd(w io.Writer, pkgPath string) error {
rw := &kio.LocalPackageReadWriter{
NoDeleteFiles: true,
PackagePath: pkgPath,
KeepReaderAnnotations: r.KeepAnnotations, PackageFileName: ext.KRMFileName()}
err := kio.Pipeline{
Inputs: []kio.Reader{rw}, Filters: r.fmtFilters(), Outputs: []kio.Writer{rw}}.Execute()
if err != nil {
// return err if RecurseSubPackages is false
if !r.RecurseSubPackages {
return err
} else {
// print error message and continue if RecurseSubPackages is true
fmt.Fprintf(w, "%s\n", err.Error())
}
} else {
fmt.Fprint(w, "formatted resource files in the package\n")
}
return nil
}
func (r *FmtRunner) fmtFilters() []kio.Filter {
fmtFilters := []kio.Filter{filters.FormatFilter{
UseSchema: r.UseSchema,
}}
// format with file names
if r.SetFilenames {
fmtFilters = append(fmtFilters, &filters.FileSetter{
FilenamePattern: r.FilenamePattern,
Override: r.Override,
})
}
return fmtFilters
}

View File

@@ -7,15 +7,12 @@ import (
"bytes" "bytes"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath"
"strings" "strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/config/internal/commands" "sigs.k8s.io/kustomize/cmd/config/internal/commands"
"sigs.k8s.io/kustomize/kyaml/copyutil"
"sigs.k8s.io/kustomize/kyaml/kio/filters/testyaml" "sigs.k8s.io/kustomize/kyaml/kio/filters/testyaml"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/testutil" "sigs.k8s.io/kustomize/kyaml/testutil"
) )
@@ -166,81 +163,3 @@ func TestCmd_failFileContents(t *testing.T) {
// expect an error // expect an error
assert.EqualError(t, err, "yaml: line 1: did not find expected node content") assert.EqualError(t, err, "yaml: line 1: did not find expected node content")
} }
func TestFmtSubPackages(t *testing.T) {
var tests = []struct {
name string
dataset string
packagePath string
args []string
expected string
}{
{
name: "fmt-recurse-subpackages",
dataset: "dataset-with-setters",
args: []string{"-R"},
expected: `${baseDir}/
formatted resource files in the package
${baseDir}/mysql/
formatted resource files in the package
${baseDir}/mysql/nosetters/
formatted resource files in the package
${baseDir}/mysql/storage/
formatted resource files in the package
`,
},
{
name: "fmt-top-level-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
packagePath: "mysql",
expected: `${baseDir}/mysql/
formatted resource files in the package
`,
},
{
name: "fmt-nested-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
packagePath: "mysql/storage",
expected: `${baseDir}/mysql/storage/
formatted resource files in the package
`,
},
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
// reset the openAPI afterward
openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI()
sourceDir := filepath.Join("test", "testdata", test.dataset)
baseDir, err := ioutil.TempDir("", "")
if !assert.NoError(t, err) {
t.FailNow()
}
copyutil.CopyDir(sourceDir, baseDir)
defer os.RemoveAll(baseDir)
runner := commands.GetFmtRunner("")
actual := &bytes.Buffer{}
runner.Command.SetOut(actual)
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
err = runner.Command.Execute()
if !assert.NoError(t, err) {
t.FailNow()
}
// normalize path format for windows
actualNormalized := strings.Replace(
strings.Replace(actual.String(), "\\", "/", -1),
"//", "/", -1)
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
if !assert.Equal(t, strings.TrimSpace(expectedNormalized), strings.TrimSpace(actualNormalized)) {
t.FailNow()
}
})
}
}

View File

@@ -4,14 +4,11 @@
package commands package commands
import ( import (
"bytes"
"fmt" "fmt"
"io"
"strings" "strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands" "sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/filters" "sigs.k8s.io/kustomize/kyaml/kio/filters"
@@ -21,21 +18,22 @@ import (
func GetGrepRunner(name string) *GrepRunner { func GetGrepRunner(name string) *GrepRunner {
r := &GrepRunner{} r := &GrepRunner{}
c := &cobra.Command{ c := &cobra.Command{
Use: "grep QUERY [DIR]", Use: "grep QUERY [DIR]...",
Short: commands.GrepShort, Short: commands.GrepShort,
Long: commands.GrepLong, Long: commands.GrepLong,
Example: commands.GrepExamples, Example: commands.GrepExamples,
PreRunE: r.preRunE, PreRunE: r.preRunE,
RunE: r.runE, RunE: r.runE,
Args: cobra.MaximumNArgs(2), Args: cobra.MinimumNArgs(1),
} }
fixDocs(name, c) fixDocs(name, c)
c.Flags().BoolVar(&r.IncludeSubpackages, "include-subpackages", true,
"also print resources from subpackages.")
c.Flags().BoolVar(&r.KeepAnnotations, "annotate", true, c.Flags().BoolVar(&r.KeepAnnotations, "annotate", true,
"annotate resources with their file origins.") "annotate resources with their file origins.")
c.Flags().BoolVarP(&r.InvertMatch, "invert-match", "", false, c.Flags().BoolVarP(&r.InvertMatch, "invert-match", "", false,
"Selected Resources are those not matching any of the specified patterns..") "Selected Resources are those not matching any of the specified patterns..")
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", true,
"also print resources recursively in all the nested subpackages")
r.Command = c r.Command = c
return r return r
} }
@@ -46,11 +44,11 @@ func GrepCommand(name string) *cobra.Command {
// GrepRunner contains the run function // GrepRunner contains the run function
type GrepRunner struct { type GrepRunner struct {
KeepAnnotations bool IncludeSubpackages bool
Command *cobra.Command KeepAnnotations bool
Command *cobra.Command
filters.GrepFilter filters.GrepFilter
Format bool Format bool
RecurseSubPackages bool
} }
func (r *GrepRunner) preRunE(c *cobra.Command, args []string) error { func (r *GrepRunner) preRunE(c *cobra.Command, args []string) error {
@@ -103,65 +101,25 @@ func (r *GrepRunner) preRunE(c *cobra.Command, args []string) error {
} }
func (r *GrepRunner) runE(c *cobra.Command, args []string) error { func (r *GrepRunner) runE(c *cobra.Command, args []string) error {
if len(args) == 1 { var filters = []kio.Filter{r.GrepFilter}
input := &kio.ByteReader{Reader: c.InOrStdin()}
return handleError(c, kio.Pipeline{ var inputs []kio.Reader
Inputs: []kio.Reader{input}, for _, a := range args[1:] {
Filters: []kio.Filter{r.GrepFilter}, inputs = append(inputs, kio.LocalPackageReader{
Outputs: []kio.Writer{kio.ByteWriter{ PackagePath: a,
Writer: c.OutOrStdout(), IncludeSubpackages: r.IncludeSubpackages,
KeepReaderAnnotations: r.KeepAnnotations, })
}}, }
}.Execute()) if len(inputs) == 0 {
inputs = append(inputs, &kio.ByteReader{Reader: c.InOrStdin()})
} }
out := bytes.Buffer{} return handleError(c, kio.Pipeline{
Inputs: inputs,
e := executeCmdOnPkgs{ Filters: filters,
writer: &out,
needOpenAPI: false,
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
rootPkgPath: args[1],
skipPkgPathPrint: true,
}
err := e.execute()
if err != nil {
return err
}
res := strings.TrimSuffix(out.String(), "---")
fmt.Fprintf(c.OutOrStdout(), "%s", res)
return nil
}
func (r *GrepRunner) executeCmd(w io.Writer, pkgPath string) error {
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: ext.KRMFileName()}
out := &bytes.Buffer{}
err := kio.Pipeline{
Inputs: []kio.Reader{input},
Filters: []kio.Filter{r.GrepFilter},
Outputs: []kio.Writer{kio.ByteWriter{ Outputs: []kio.Writer{kio.ByteWriter{
Writer: out, Writer: c.OutOrStdout(),
KeepReaderAnnotations: r.KeepAnnotations, KeepReaderAnnotations: r.KeepAnnotations,
}}, }},
}.Execute() }.Execute())
if err != nil {
// return err if there is only package
if !r.RecurseSubPackages {
return err
} else {
// print error message and continue if there are multiple packages to annotate
fmt.Fprintf(w, "%s\n", err.Error())
}
}
fmt.Fprint(w, out.String())
if out.String() != "" {
fmt.Fprint(w, "---")
}
return nil
} }

View File

@@ -8,12 +8,10 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/config/internal/commands" "sigs.k8s.io/kustomize/cmd/config/internal/commands"
"sigs.k8s.io/kustomize/kyaml/copyutil"
) )
// TestGrepCommand_files verifies grep reads the files and filters them // TestGrepCommand_files verifies grep reads the files and filters them
@@ -70,7 +68,7 @@ spec:
return return
} }
if !assert.Contains(t, b.String(), `kind: Deployment if !assert.Equal(t, `kind: Deployment
metadata: metadata:
labels: labels:
app: nginx2 app: nginx2
@@ -92,7 +90,7 @@ metadata:
spec: spec:
selector: selector:
app: nginx app: nginx
`) { `, b.String()) {
return return
} }
} }
@@ -138,7 +136,7 @@ spec:
return return
} }
if !assert.Contains(t, b.String(), `kind: Deployment if !assert.Equal(t, `kind: Deployment
metadata: metadata:
labels: labels:
app: nginx2 app: nginx2
@@ -158,7 +156,7 @@ metadata:
spec: spec:
selector: selector:
app: nginx app: nginx
`) { `, b.String()) {
return return
} }
} }
@@ -252,7 +250,7 @@ spec:
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
return return
} }
if !assert.Contains(t, b.String(), `kind: Deployment if !assert.Equal(t, `kind: Deployment
metadata: metadata:
labels: labels:
app: nginx1.7 app: nginx1.7
@@ -266,151 +264,7 @@ spec:
containers: containers:
- name: nginx - name: nginx
image: nginx:1.7.9 image: nginx:1.7.9
`) { `, b.String()) {
return return
} }
} }
func TestGrepSubPackages(t *testing.T) {
var tests = []struct {
name string
dataset string
packagePath string
args []string
expected string
}{
{
name: "grep-recurse-subpackages",
dataset: "dataset-without-setters",
args: []string{"kind=Deployment"},
expected: `
# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: myspace
name: mysql-deployment
annotations:
config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'deployment.yaml'
spec:
replicas: 3
template:
spec:
containers:
- name: mysql
image: mysql:1.7.9
---
# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: myspace
name: storage-deployment
annotations:
config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'deployment.yaml'
spec:
replicas: 4
template:
spec:
containers:
- name: storage
image: storage:1.7.7
`,
},
{
name: "grep-top-level-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
args: []string{"kind=Deployment", "-R=false"},
packagePath: "mysql",
expected: `# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: myspace
name: mysql-deployment
annotations:
config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'deployment.yaml'
spec:
replicas: 3
template:
spec:
containers:
- name: mysql
image: mysql:1.7.9
`,
},
{
name: "grep-nested-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
packagePath: "mysql/storage",
args: []string{"kind=Deployment", "-R=false"},
expected: `# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: myspace
name: storage-deployment
annotations:
config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'deployment.yaml'
spec:
replicas: 4
template:
spec:
containers:
- name: storage
image: storage:1.7.7
`,
},
{
name: "grep-recurse-subpackages-no-result",
dataset: "dataset-without-setters",
args: []string{"kind=ConfigMap"},
expected: `
`,
},
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
sourceDir := filepath.Join("test", "testdata", test.dataset)
baseDir, err := ioutil.TempDir("", "")
if !assert.NoError(t, err) {
t.FailNow()
}
copyutil.CopyDir(sourceDir, baseDir)
defer os.RemoveAll(baseDir)
runner := commands.GetGrepRunner("")
actual := &bytes.Buffer{}
runner.Command.SetOut(actual)
runner.Command.SetArgs(append(test.args, filepath.Join(baseDir, test.packagePath)))
err = runner.Command.Execute()
if !assert.NoError(t, err) {
t.FailNow()
}
// normalize path format for windows
actualNormalized := strings.Replace(
strings.Replace(actual.String(), "\\", "/", -1),
"//", "/", -1)
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
if !assert.Equal(t, expectedNormalized, actualNormalized) {
t.FailNow()
}
})
}
}

View File

@@ -9,13 +9,11 @@ import (
"strings" "strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil" "sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil"
"sigs.k8s.io/kustomize/kyaml/runfn" "sigs.k8s.io/kustomize/kyaml/runfn"
"sigs.k8s.io/kustomize/kyaml/yaml" "sigs.k8s.io/kustomize/kyaml/yaml"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
) )
// GetCatRunner returns a RunFnRunner. // GetCatRunner returns a RunFnRunner.
@@ -62,14 +60,11 @@ func GetRunFnRunner(name string) *RunFnRunner {
r.Command.Flags().BoolVar( r.Command.Flags().BoolVar(
&r.Network, "network", false, "enable network access for functions that declare it") &r.Network, "network", false, "enable network access for functions that declare it")
r.Command.Flags().StringVar(
&r.NetworkName, "network-name", "bridge", "the docker network to run the container in")
r.Command.Flags().StringArrayVar( r.Command.Flags().StringArrayVar(
&r.Mounts, "mount", []string{}, &r.Mounts, "mount", []string{},
"a list of storage options read from the filesystem") "a list of storage options read from the filesystem")
r.Command.Flags().BoolVar(
&r.LogSteps, "log-steps", false, "log steps to stderr")
r.Command.Flags().StringArrayVarP(
&r.Env, "env", "e", []string{},
"a list of environment variables to be used by functions")
return r return r
} }
@@ -94,9 +89,8 @@ type RunFnRunner struct {
RunFns runfn.RunFns RunFns runfn.RunFns
ResultsDir string ResultsDir string
Network bool Network bool
NetworkName string
Mounts []string Mounts []string
LogSteps bool
Env []string
} }
func (r *RunFnRunner) runE(c *cobra.Command, args []string) error { func (r *RunFnRunner) runE(c *cobra.Command, args []string) error {
@@ -105,7 +99,7 @@ func (r *RunFnRunner) runE(c *cobra.Command, args []string) error {
// getContainerFunctions parses the commandline flags and arguments into explicit // getContainerFunctions parses the commandline flags and arguments into explicit
// Functions to run. // Functions to run.
func (r *RunFnRunner) getContainerFunctions(c *cobra.Command, dataItems []string) ( func (r *RunFnRunner) getContainerFunctions(c *cobra.Command, args, dataItems []string) (
[]*yaml.RNode, error) { []*yaml.RNode, error) {
if r.Image == "" && r.StarPath == "" && r.ExecPath == "" && r.StarURL == "" { if r.Image == "" && r.StarPath == "" && r.ExecPath == "" && r.StarURL == "" {
@@ -130,8 +124,8 @@ func (r *RunFnRunner) getContainerFunctions(c *cobra.Command, dataItems []string
} }
if r.Network { if r.Network {
err = fn.PipeE( err = fn.PipeE(
yaml.Lookup("container"), yaml.LookupCreate(yaml.MappingNode, "container", "network"),
yaml.SetField("network", yaml.NewScalarRNode("true"))) yaml.SetField("required", yaml.NewScalarRNode("true")))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -199,7 +193,7 @@ data: {}
} }
err = rc.PipeE( err = rc.PipeE(
yaml.LookupCreate(yaml.MappingNode, "metadata", "annotations"), yaml.LookupCreate(yaml.MappingNode, "metadata", "annotations"),
yaml.SetField(runtimeutil.FunctionAnnotationKey, yaml.NewScalarRNode(value))) yaml.SetField("config.kubernetes.io/function", yaml.NewScalarRNode(value)))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -273,7 +267,7 @@ func (r *RunFnRunner) preRunE(c *cobra.Command, args []string) error {
return errors.Errorf("0 or 1 arguments supported, function arguments go after '--'") return errors.Errorf("0 or 1 arguments supported, function arguments go after '--'")
} }
fns, err := r.getContainerFunctions(c, dataItems) fns, err := r.getContainerFunctions(c, args, dataItems)
if err != nil { if err != nil {
return err return err
} }
@@ -306,12 +300,11 @@ func (r *RunFnRunner) preRunE(c *cobra.Command, args []string) error {
Input: input, Input: input,
Path: path, Path: path,
Network: r.Network, Network: r.Network,
NetworkName: r.NetworkName,
EnableStarlark: r.EnableStar, EnableStarlark: r.EnableStar,
EnableExec: r.EnableExec, EnableExec: r.EnableExec,
StorageMounts: storageMounts, StorageMounts: storageMounts,
ResultsDir: r.ResultsDir, ResultsDir: r.ResultsDir,
LogSteps: r.LogSteps,
Env: r.Env,
} }
// don't consider args for the function // don't consider args for the function

View File

@@ -11,7 +11,6 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/kyaml/runfn" "sigs.k8s.io/kustomize/kyaml/runfn"
) )
@@ -29,6 +28,7 @@ func TestRunFnCommand_preRunE(t *testing.T) {
output io.Writer output io.Writer
functionPaths []string functionPaths []string
network bool network bool
networkName string
mount []string mount []string
}{ }{
{ {
@@ -94,32 +94,34 @@ apiVersion: v1
`, `,
}, },
{ {
name: "network enabled", name: "network enabled",
args: []string{"run", "dir", "--image", "foo:bar", "--network"}, args: []string{"run", "dir", "--image", "foo:bar", "--network"},
path: "dir", path: "dir",
network: true, network: true,
networkName: "bridge",
expected: ` expected: `
metadata: metadata:
name: function-input name: function-input
annotations: annotations:
config.kubernetes.io/function: | config.kubernetes.io/function: |
container: {image: 'foo:bar', network: true} container: {image: 'foo:bar', network: {required: true}}
data: {} data: {}
kind: ConfigMap kind: ConfigMap
apiVersion: v1 apiVersion: v1
`, `,
}, },
{ {
name: "with network name", name: "with network name",
args: []string{"run", "dir", "--image", "foo:bar", "--network"}, args: []string{"run", "dir", "--image", "foo:bar", "--network", "--network-name", "foo"},
path: "dir", path: "dir",
network: true, network: true,
networkName: "foo",
expected: ` expected: `
metadata: metadata:
name: function-input name: function-input
annotations: annotations:
config.kubernetes.io/function: | config.kubernetes.io/function: |
container: {image: 'foo:bar', network: true} container: {image: 'foo:bar', network: {required: true}}
data: {} data: {}
kind: ConfigMap kind: ConfigMap
apiVersion: v1 apiVersion: v1
@@ -199,8 +201,8 @@ apiVersion: v1
path: "dir", path: "dir",
expectedStruct: &runfn.RunFns{ expectedStruct: &runfn.RunFns{
Path: "dir", Path: "dir",
NetworkName: "bridge",
EnableStarlark: true, EnableStarlark: true,
Env: []string{},
}, },
}, },
{ {
@@ -251,9 +253,9 @@ apiVersion: v1
args: []string{"run", "dir", "--results-dir", "foo/", "--image", "foo:bar", "--", "a=b", "c=d", "e=f"}, args: []string{"run", "dir", "--results-dir", "foo/", "--image", "foo:bar", "--", "a=b", "c=d", "e=f"},
path: "dir", path: "dir",
expectedStruct: &runfn.RunFns{ expectedStruct: &runfn.RunFns{
Path: "dir", Path: "dir",
ResultsDir: "foo/", NetworkName: "bridge",
Env: []string{}, ResultsDir: "foo/",
}, },
expected: ` expected: `
metadata: metadata:
@@ -281,25 +283,6 @@ apiVersion: v1
args: []string{"run", "dir", "--image", "foo:bar", "--", "a=b", "c", "e=f"}, args: []string{"run", "dir", "--image", "foo:bar", "--", "a=b", "c", "e=f"},
err: "must have keys and values separated by", err: "must have keys and values separated by",
}, },
{
name: "log steps",
args: []string{"run", "dir", "--log-steps"},
path: "dir",
expectedStruct: &runfn.RunFns{
Path: "dir",
LogSteps: true,
Env: []string{},
},
},
{
name: "envs",
args: []string{"run", "dir", "--env", "FOO=BAR", "-e", "BAR"},
path: "dir",
expectedStruct: &runfn.RunFns{
Path: "dir",
Env: []string{"FOO=BAR", "BAR"},
},
},
} }
for i := range tests { for i := range tests {
@@ -355,6 +338,9 @@ apiVersion: v1
if !assert.Equal(t, tt.network, r.RunFns.Network) { if !assert.Equal(t, tt.network, r.RunFns.Network) {
t.FailNow() t.FailNow()
} }
if !assert.Equal(t, tt.networkName, r.RunFns.NetworkName) {
t.FailNow()
}
} else { } else {
if !assert.Equal(t, false, r.RunFns.Network) { if !assert.Equal(t, false, r.RunFns.Network) {
t.FailNow() t.FailNow()
@@ -399,4 +385,5 @@ apiVersion: v1
}) })
} }
} }

View File

@@ -1,6 +0,0 @@
apiVersion: krm.dev/v1alpha1
kind: Krmfile
metadata:
name: mysql
packageMetadata:
shortDescription: sample description

View File

@@ -1,15 +0,0 @@
# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: myspace
name: mysql-deployment
spec:
replicas: 3
template:
spec:
containers:
- name: mysql
image: mysql:1.7.9

View File

@@ -1,6 +0,0 @@
apiVersion: krm.dev/v1alpha1
kind: Krmfile
metadata:
name: storage
packageMetadata:
shortDescription: sample description

View File

@@ -1,15 +0,0 @@
# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: myspace
name: storage-deployment
spec:
replicas: 4
template:
spec:
containers:
- name: storage
image: storage:1.7.7

View File

@@ -7,7 +7,6 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands" "sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/kio/filters" "sigs.k8s.io/kustomize/kyaml/kio/filters"
@@ -27,6 +26,8 @@ func GetTreeRunner(name string) *TreeRunner {
Args: cobra.MaximumNArgs(1), Args: cobra.MaximumNArgs(1),
} }
fixDocs(name, c) fixDocs(name, c)
c.Flags().BoolVar(&r.IncludeSubpackages, "include-subpackages", true,
"also print resources from subpackages.")
// TODO(pwittrock): Figure out if these are the right things to expose, and consider making it // TODO(pwittrock): Figure out if these are the right things to expose, and consider making it
// a list of options instead of individual flags // a list of options instead of individual flags
@@ -58,25 +59,21 @@ func TreeCommand(name string) *cobra.Command {
// TreeRunner contains the run function // TreeRunner contains the run function
type TreeRunner struct { type TreeRunner struct {
Command *cobra.Command IncludeSubpackages bool
name bool Command *cobra.Command
resources bool name bool
ports bool resources bool
images bool ports bool
replicas bool images bool
all bool replicas bool
env bool all bool
args bool env bool
cmd bool args bool
fields []string cmd bool
includeLocal bool fields []string
excludeNonLocal bool includeLocal bool
structure string excludeNonLocal bool
} structure string
func (r *TreeRunner) getMatchFilesGlob() []string {
matchFilesGlob := append([]string{ext.KRMFileName()}, kio.DefaultMatch...)
return append(matchFilesGlob, "Kustomization")
} }
func (r *TreeRunner) runE(c *cobra.Command, args []string) error { func (r *TreeRunner) runE(c *cobra.Command, args []string) error {
@@ -84,7 +81,7 @@ func (r *TreeRunner) runE(c *cobra.Command, args []string) error {
var root = "." var root = "."
if len(args) == 1 { if len(args) == 1 {
root = filepath.Clean(args[0]) root = filepath.Clean(args[0])
input = kio.LocalPackageReader{PackagePath: args[0], MatchFilesGlob: r.getMatchFilesGlob()} input = kio.LocalPackageReader{PackagePath: args[0]}
} else { } else {
input = &kio.ByteReader{Reader: c.InOrStdin()} input = &kio.ByteReader{Reader: c.InOrStdin()}
} }
@@ -159,12 +156,10 @@ func (r *TreeRunner) runE(c *cobra.Command, args []string) error {
Inputs: []kio.Reader{input}, Inputs: []kio.Reader{input},
Filters: fltrs, Filters: fltrs,
Outputs: []kio.Writer{kio.TreeWriter{ Outputs: []kio.Writer{kio.TreeWriter{
Root: root, Root: root,
Writer: c.OutOrStdout(), Writer: c.OutOrStdout(),
Fields: fields, Fields: fields,
Structure: kio.TreeStructure(r.structure), Structure: kio.TreeStructure(r.structure)}},
OpenAPIFileName: ext.KRMFileName(),
}},
}.Execute()) }.Execute())
} }

View File

@@ -90,156 +90,6 @@ spec:
} }
} }
func TestTreeCommand_Kustomization(t *testing.T) {
d, err := ioutil.TempDir("", "kustomize-tree-test")
defer os.RemoveAll(d)
if !assert.NoError(t, err) {
return
}
err = ioutil.WriteFile(filepath.Join(d, "f2.yaml"), []byte(`kind: Deployment
metadata:
labels:
app: nginx
name: bar
annotations:
app: nginx
spec:
replicas: 3
`), 0600)
if !assert.NoError(t, err) {
return
}
err = ioutil.WriteFile(filepath.Join(d, "Kustomization"), []byte(`apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- f2.yaml
`), 0600)
if !assert.NoError(t, err) {
return
}
// fmt the files
b := &bytes.Buffer{}
r := commands.GetTreeRunner("")
r.Command.SetArgs([]string{d})
r.Command.SetOut(b)
if !assert.NoError(t, r.Command.Execute()) {
return
}
if !assert.Equal(t, fmt.Sprintf(`%s
├── [Kustomization] Kustomization
└── [f2.yaml] Deployment bar
`, d), b.String()) {
return
}
}
func TestTreeCommand_subpkgs(t *testing.T) {
d, err := ioutil.TempDir("", "kustomize-tree-test")
defer os.RemoveAll(d)
if !assert.NoError(t, err) {
t.FailNow()
}
err = os.MkdirAll(filepath.Join(d, "subpkg"), 0700)
if !assert.NoError(t, err) {
t.FailNow()
}
err = ioutil.WriteFile(filepath.Join(d, "f1.yaml"), []byte(`
apiVersion: v1
kind: Abstraction
metadata:
name: foo
configFn:
container:
image: gcr.io/example/reconciler:v1
annotations:
config.kubernetes.io/local-config: "true"
spec:
replicas: 1
---
kind: Deployment
metadata:
labels:
app: nginx2
name: foo
annotations:
app: nginx2
spec:
replicas: 1
---
kind: Service
metadata:
name: foo
annotations:
app: nginx
spec:
selector:
app: nginx
`), 0600)
if !assert.NoError(t, err) {
return
}
err = ioutil.WriteFile(filepath.Join(d, "subpkg", "f2.yaml"), []byte(`kind: Deployment
metadata:
labels:
app: nginx
name: bar
annotations:
app: nginx
spec:
replicas: 3
`), 0600)
if !assert.NoError(t, err) {
return
}
err = ioutil.WriteFile(filepath.Join(d, "Krmfile"), []byte(`apiVersion: kpt.dev/v1alpha1
kind: Krmfile
metadata:
name: mainpkg
openAPI:
definitions:
`), 0600)
if !assert.NoError(t, err) {
return
}
err = ioutil.WriteFile(filepath.Join(d, "subpkg", "Krmfile"), []byte(`apiVersion: kpt.dev/v1alpha1
kind: Krmfile
metadata:
name: subpkg
openAPI:
definitions:
`), 0600)
if !assert.NoError(t, err) {
return
}
// fmt the files
b := &bytes.Buffer{}
r := commands.GetTreeRunner("")
r.Command.SetArgs([]string{d})
r.Command.SetOut(b)
if !assert.NoError(t, r.Command.Execute()) {
return
}
if !assert.Equal(t, fmt.Sprintf(`%s
├── [Krmfile] Krmfile mainpkg
├── [f1.yaml] Deployment foo
├── [f1.yaml] Service foo
└── Pkg: subpkg
├── [Krmfile] Krmfile subpkg
└── [f2.yaml] Deployment bar
`, d), b.String()) {
return
}
}
func TestTreeCommand_stdin(t *testing.T) { func TestTreeCommand_stdin(t *testing.T) {
// fmt the files // fmt the files
b := &bytes.Buffer{} b := &bytes.Buffer{}

View File

@@ -5,92 +5,13 @@ package commands
import ( import (
"fmt" "fmt"
"io"
"os" "os"
"path/filepath"
"strings" "strings"
"github.com/go-errors/errors" "github.com/go-errors/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/pathutil"
) )
// cmdRunner interface holds executeCmd definition which executes respective command's
// implementation on single package
type cmdRunner interface {
executeCmd(w io.Writer, pkgPath string) error
}
// executeCmdOnPkgs struct holds the parameters necessary to
// execute the filter command on packages in rootPkgPath
type executeCmdOnPkgs struct {
rootPkgPath string
recurseSubPackages bool
needOpenAPI bool
cmdRunner cmdRunner
writer io.Writer
skipPkgPathPrint bool
}
// executeCmdOnPkgs takes the function definition for a command to be executed on single package, applies that definition
// recursively on all the subpackages present in rootPkgPath if recurseSubPackages is true, else applies the command on rootPkgPath only
func (e executeCmdOnPkgs) execute() error {
pkgsPaths, err := pathutil.DirsWithFile(e.rootPkgPath, ext.KRMFileName(), e.recurseSubPackages)
if err != nil {
return err
}
if len(pkgsPaths) == 0 {
// at this point, there are no openAPI files in the rootPkgPath
if e.needOpenAPI {
// few executions need openAPI file to be present(ex: setters commands), if true throw an error
return errors.Errorf("unable to find %q in package %q", ext.KRMFileName(), e.rootPkgPath)
}
// add root path for commands which doesn't need openAPI(ex: annotate, fmt)
pkgsPaths = []string{e.rootPkgPath}
}
// for commands which doesn't need openAPI file, make sure that the root package is
// included all the times
if !e.needOpenAPI && !containsString(pkgsPaths, e.rootPkgPath) {
pkgsPaths = append([]string{e.rootPkgPath}, pkgsPaths...)
}
for i := range pkgsPaths {
pkgPath := pkgsPaths[i]
// Add schema present in openAPI file for current package
if e.needOpenAPI {
if err := openapi.AddSchemaFromFile(filepath.Join(pkgPath, ext.KRMFileName())); err != nil {
return err
}
}
if !e.skipPkgPathPrint {
fmt.Fprintf(e.writer, "%s/\n", pkgPath)
}
err := e.cmdRunner.executeCmd(e.writer, pkgPath)
if err != nil {
return err
}
if i != len(pkgsPaths)-1 {
fmt.Fprint(e.writer, "\n")
}
// Delete schema present in openAPI file for current package
if e.needOpenAPI {
if err := openapi.DeleteSchemaInFile(filepath.Join(pkgPath, ext.KRMFileName())); err != nil {
return err
}
}
}
return nil
}
// parseFieldPath parse a flag value into a field path // parseFieldPath parse a flag value into a field path
func parseFieldPath(path string) ([]string, error) { func parseFieldPath(path string) ([]string, error) {
// fixup '\.' so we don't split on it // fixup '\.' so we don't split on it
@@ -151,13 +72,3 @@ func fixDocs(new string, c *cobra.Command) {
c.Long = strings.ReplaceAll(c.Long, cmdName, new) c.Long = strings.ReplaceAll(c.Long, cmdName, new)
c.Example = strings.ReplaceAll(c.Example, cmdName, new) c.Example = strings.ReplaceAll(c.Example, cmdName, new)
} }
// containsString returns true if slice contains s
func containsString(slice []string, s string) bool {
for _, item := range slice {
if item == s {
return true
}
}
return false
}

View File

@@ -1,184 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package commands
import (
"bytes"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/kyaml/errors"
)
func TestExecuteCmdOnPkgs(t *testing.T) {
var tests = []struct {
name string
recurse bool
pkgPath string
needOpenAPI bool
errMsg string
expectedOut string
}{
{
name: "need_Krmfile_error",
recurse: true,
needOpenAPI: true,
pkgPath: "subpkg1/subdir1",
errMsg: `unable to find "Krmfile" in package`,
},
{
name: "Krmfile_not_needed_no_err",
recurse: true,
needOpenAPI: false,
pkgPath: "subpkg1/subdir1",
expectedOut: `${baseDir}/subpkg1/subdir1/
`,
},
{
name: "executeCmd_returns_error",
recurse: true,
needOpenAPI: false,
pkgPath: "subpkg4",
expectedOut: `${baseDir}/subpkg4/
`,
errMsg: `this command returns an error if package has error.txt file`,
},
{
name: "executeCmd_prints_pkgpaths",
recurse: true,
needOpenAPI: false,
pkgPath: "subpkg2",
expectedOut: `${baseDir}/subpkg2/
${baseDir}/subpkg2/subpkg3/
`,
},
}
dir, err := ioutil.TempDir("", "")
if !assert.NoError(t, err) {
t.FailNow()
}
defer os.RemoveAll(dir)
err = createTestDirStructure(dir)
if !assert.NoError(t, err) {
t.FailNow()
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
actual := &bytes.Buffer{}
r := &TestRunner{}
e := executeCmdOnPkgs{
needOpenAPI: test.needOpenAPI,
writer: actual,
rootPkgPath: filepath.Join(dir, test.pkgPath),
recurseSubPackages: test.recurse,
cmdRunner: r,
}
err := e.execute()
if test.errMsg == "" {
if !assert.NoError(t, err) {
t.FailNow()
}
} else {
if !assert.Error(t, err) {
t.FailNow()
}
if !assert.Contains(t, err.Error(), test.errMsg) {
t.FailNow()
}
}
// normalize path format for windows
actualNormalized := strings.Replace(
strings.Replace(actual.String(), "\\", "/", -1),
"//", "/", -1)
expected := strings.Replace(test.expectedOut, "${baseDir}", dir+"/", -1)
expectedNormalized := strings.Replace(
strings.Replace(expected, "\\", "/", -1),
"//", "/", -1)
if !assert.Equal(t, expectedNormalized, actualNormalized) {
t.FailNow()
}
})
}
}
func createTestDirStructure(dir string) error {
/*
Adds the folders to the input dir with following structure
dir
├── subpkg1
│   ├── Krmfile
│   └── subdir1
├── subpkg4
│   ├── Krmfile
│   └── error.txt
└── subpkg2
├── subpkg3
│ ├── Krmfile
│ └── subdir2
└── Krmfile
*/
err := os.MkdirAll(filepath.Join(dir, "subpkg1/subdir1"), 0777|os.ModeDir)
if err != nil {
return err
}
err = os.MkdirAll(filepath.Join(dir, "subpkg2/subpkg3/subdir2"), 0777|os.ModeDir)
if err != nil {
return err
}
err = os.MkdirAll(filepath.Join(dir, "subpkg4"), 0777|os.ModeDir)
if err != nil {
return err
}
err = ioutil.WriteFile(filepath.Join(dir, "subpkg1", "Krmfile"), []byte(""), 0777)
if err != nil {
return err
}
err = ioutil.WriteFile(filepath.Join(dir, "subpkg2", "Krmfile"), []byte(""), 0777)
if err != nil {
return err
}
err = ioutil.WriteFile(filepath.Join(dir, "subpkg2/subpkg3", "Krmfile"), []byte(""), 0777)
if err != nil {
return err
}
err = ioutil.WriteFile(filepath.Join(dir, "subpkg4", "error.txt"), []byte(""), 0777)
if err != nil {
return err
}
err = ioutil.WriteFile(filepath.Join(dir, "subpkg4", "Krmfile"), []byte(""), 0777)
if err != nil {
return err
}
err = ioutil.WriteFile(filepath.Join(dir, "Krmfile"), []byte(""), 0777)
if err != nil {
return err
}
return nil
}
type TestRunner struct{}
func (r *TestRunner) executeCmd(w io.Writer, pkgPath string) error {
children, err := ioutil.ReadDir(pkgPath)
if err != nil {
return err
}
for _, child := range children {
if child.Name() == "error.txt" {
return errors.Errorf("this command returns an error if package has error.txt file")
}
}
return nil
}

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.68.3" /> <meta name="generator" content="Hugo 0.74.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"> <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
@@ -29,7 +29,8 @@
<meta property="og:site_name" content="Kustomize" /> <meta property="og:site_name" content="Kustomize" />
<meta itemprop="name" content="Glossary"> <meta itemprop="name" content="Glossary">
<meta itemprop="description" content="Glossary of terms <meta itemprop="description" content="Glossary of terms
"><meta name="twitter:card" content="summary"/> ">
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="Glossary"/> <meta name="twitter:title" content="Glossary"/>
<meta name="twitter:description" content="Glossary of terms <meta name="twitter:description" content="Glossary of terms
"/> "/>
@@ -911,8 +912,8 @@ absolute path, or by relative path.</p>
<li><strong>B</strong> may not <em>depend on</em> <strong>A</strong>, even transitively.</li> <li><strong>B</strong> may not <em>depend on</em> <strong>A</strong>, even transitively.</li>
</ul> </ul>
<p><strong>A</strong> may contain <strong>B</strong>, but in this case it might be <p><strong>A</strong> may contain <strong>B</strong>, but in this case it might be
simplest to have <strong>A</strong> directly depend on <strong>B</strong>&lsquo;s simplest to have <strong>A</strong> directly depend on <strong>B</strong>&rsquo;s
resources and eliminate <strong>B</strong>&lsquo;s kustomization.yaml file resources and eliminate <strong>B</strong>&rsquo;s kustomization.yaml file
(i.e. absorb <strong>B</strong> into <strong>A</strong>).</p> (i.e. absorb <strong>B</strong> into <strong>A</strong>).</p>
<p>Conventionally, <strong>B</strong> is in a directory that&rsquo;s sibling <p>Conventionally, <strong>B</strong> is in a directory that&rsquo;s sibling
to <strong>A</strong>, or <strong>B</strong> is off in a completely independent to <strong>A</strong>, or <strong>B</strong> is off in a completely independent

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.68.3" /> <meta name="generator" content="Hugo 0.74.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"> <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
@@ -29,7 +29,8 @@
<meta property="og:site_name" content="Kustomize" /> <meta property="og:site_name" content="Kustomize" />
<meta itemprop="name" content="API Reference"> <meta itemprop="name" content="API Reference">
<meta itemprop="description" content="Reference for Kustomize client-side APIs <meta itemprop="description" content="Reference for Kustomize client-side APIs
"><meta name="twitter:card" content="summary"/> ">
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="API Reference"/> <meta name="twitter:title" content="API Reference"/>
<meta name="twitter:description" content="Reference for Kustomize client-side APIs <meta name="twitter:description" content="Reference for Kustomize client-side APIs
"/> "/>

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.68.3" /> <meta name="generator" content="Hugo 0.74.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"> <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
@@ -29,7 +29,8 @@
<meta property="og:site_name" content="Kustomize" /> <meta property="og:site_name" content="Kustomize" />
<meta itemprop="name" content="bases"> <meta itemprop="name" content="bases">
<meta itemprop="description" content="Add resources from a kustomization dir. <meta itemprop="description" content="Add resources from a kustomization dir.
"><meta name="twitter:card" content="summary"/> ">
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="bases"/> <meta name="twitter:title" content="bases"/>
<meta name="twitter:description" content="Add resources from a kustomization dir. <meta name="twitter:description" content="Add resources from a kustomization dir.
"/> "/>

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.68.3" /> <meta name="generator" content="Hugo 0.74.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"> <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
@@ -29,7 +29,8 @@
<meta property="og:site_name" content="Kustomize" /> <meta property="og:site_name" content="Kustomize" />
<meta itemprop="name" content="commonAnnotations"> <meta itemprop="name" content="commonAnnotations">
<meta itemprop="description" content="Add annotations to add all resources. <meta itemprop="description" content="Add annotations to add all resources.
"><meta name="twitter:card" content="summary"/> ">
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="commonAnnotations"/> <meta name="twitter:title" content="commonAnnotations"/>
<meta name="twitter:description" content="Add annotations to add all resources. <meta name="twitter:description" content="Add annotations to add all resources.
"/> "/>

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.68.3" /> <meta name="generator" content="Hugo 0.74.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"> <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
@@ -29,7 +29,8 @@
<meta property="og:site_name" content="Kustomize" /> <meta property="og:site_name" content="Kustomize" />
<meta itemprop="name" content="commonLabels"> <meta itemprop="name" content="commonLabels">
<meta itemprop="description" content="Add labels and selectors to add all resources. <meta itemprop="description" content="Add labels and selectors to add all resources.
"><meta name="twitter:card" content="summary"/> ">
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="commonLabels"/> <meta name="twitter:title" content="commonLabels"/>
<meta name="twitter:description" content="Add labels and selectors to add all resources. <meta name="twitter:description" content="Add labels and selectors to add all resources.
"/> "/>

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.68.3" /> <meta name="generator" content="Hugo 0.74.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"> <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
@@ -29,7 +29,8 @@
<meta property="og:site_name" content="Kustomize" /> <meta property="og:site_name" content="Kustomize" />
<meta itemprop="name" content="components"> <meta itemprop="name" content="components">
<meta itemprop="description" content="Compose kustomizations. <meta itemprop="description" content="Compose kustomizations.
"><meta name="twitter:card" content="summary"/> ">
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="components"/> <meta name="twitter:title" content="components"/>
<meta name="twitter:description" content="Compose kustomizations. <meta name="twitter:description" content="Compose kustomizations.
"/> "/>

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