Compare commits

..

110 Commits

Author SHA1 Message Date
Kubernetes Prow Robot
b736b81167 Merge pull request #3151 from Shell32-Natsu/master
Pin to cmd/config 0.8.4
2020-10-29 15:24:06 -07:00
Donny Xia
0a04b1bb78 Pin to cmd/config 0.8.4 2020-10-29 15:11:09 -07:00
Kubernetes Prow Robot
f7ebaae39e Merge pull request #3150 from Shell32-Natsu/master
Pin to kyaml v0.9.3
2020-10-29 15:04:06 -07:00
Donny Xia
08099f0cea Pin to kyaml v0.9.3 2020-10-29 14:47:52 -07:00
Kubernetes Prow Robot
6fd04dd253 Merge pull request #3146 from ilyakaznacheev/fix-configmap-doc
Add better configMap cleanup description.
2020-10-28 17:38:59 -07:00
Ilya Kaznacheev
9ac97ef91f Add better configMap cleanup descripion 2020-10-29 01:50:45 +03:00
Jeff Regan
cfbf426174 Merge pull request #3129 from Shell32-Natsu/patches-command
Update edit patch command
2020-10-28 12:47:13 -07:00
Donny Xia
9aafc61c5b disable edit add patch command tests temporarily 2020-10-28 12:24:51 -07:00
Donny Xia
cd2ebd3046 code review 2020-10-27 15:10:29 -07:00
Jeff Regan
b20e5d7f84 Merge pull request #3135 from Shell32-Natsu/cleanup-namespace-transformer
cleanup namespace transformer
2020-10-27 09:54:28 -07:00
Jeff Regan
13c9a2873e Update comments in multi-transformer 2020-10-27 07:17:14 -07:00
Kubernetes Prow Robot
fc06283905 Merge pull request #3140 from teruyam/patch-1
Fix broken link to release page
2020-10-26 12:37:02 -07:00
Jeff Regan
119d7cadf5 Merge pull request #3136 from natasha41575/NamespaceabilityFromOpenAPI
removed hardcoded list of namespaceable resources
2020-10-26 12:22:36 -07:00
Masashi Teruya
cdc6d1fc28 Fix broken link to release page 2020-10-24 11:18:33 +09:00
Natasha Sarkar
49dced2e01 removed hardcoded list of namespaceable resources 2020-10-23 11:47:29 -07:00
Donny Xia
76a8f034cb Merge pull request #3133 from robinbraemer/patch-2
Add Ingress tls secretName to Secret builtin nameref
2020-10-23 11:20:11 -07:00
Donny Xia
52060ac480 Merge pull request #3132 from robinbraemer/patch-1
Add Ingress v1 support to builtin name references
2020-10-23 11:19:51 -07:00
Donny Xia
719532e4df Merge pull request #3123 from AlphaWong/patch-1
doc: add varReference example
2020-10-22 14:42:05 -07:00
Donny Xia
70dcc79bf4 cleanup namespace transformer 2020-10-22 13:18:20 -07:00
Kubernetes Prow Robot
55b4448862 Merge pull request #3134 from phanimarupaka/OptionallySuppressIsSet
Make isSet a parameter
2020-10-22 11:43:37 -07:00
Phani Teja Marupaka
bcaac6f8c1 Make isSet a parameter 2020-10-22 11:31:30 -07:00
Jeff Regan
ba4b44db6b Merge pull request #3126 from monopole/mechanical
Generated go.sum/mod and docs.go changes.
2020-10-22 10:30:52 -07:00
Robin Brämer
fd280d0c0b Add Ingress tls secretName to Secret builtin nameref 2020-10-22 17:00:10 +02:00
Robin Brämer
1dbf490146 Add IngressClass kind
Adds IngressClass kind and Ingress fieldSpecs path spec/ingressClassName
2020-10-22 16:11:44 +02:00
Robin Brämer
62e4df72d3 Add Service name references for Ingress v1
Since Kubernetes v1.19, Ingress networking.k8s.io/v1 has two more Server name references.
- https://kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource
- https://kubernetes.io/docs/setup/release/notes/
2020-10-22 15:59:22 +02:00
Donny Xia
bb77a7c86d refactor edit remove patch 2020-10-21 18:48:53 -07:00
Donny Xia
41abeb85be refactor edit add patch command 2020-10-21 14:56:20 -07:00
Jeff Regan
3c86d37148 Merge pull request #3122 from Shell32-Natsu/ref-target
check Gvk in roleRef when update name reference
2020-10-21 11:19:20 -07:00
Kubernetes Prow Robot
287b38cc87 Merge pull request #3106 from Shell32-Natsu/array-index
support array index in PathGetter
2020-10-21 11:16:20 -07:00
jregan
d8d727b1ca Generated go.sum/mod and docs.go changes. 2020-10-20 17:22:48 -07:00
Jeff Regan
a81a3d40ce Merge pull request #3087 from etefera/add-isSet-to-list-setters
Add isSet to ListSetters cmd.
2020-10-20 16:52:13 -07:00
Eyob Tefera
52e682489c Merge branch 'add-isSet-to-list-setters' of https://github.com/etefera/kustomize into add-isSet-to-list-setters 2020-10-20 23:24:11 +00:00
Eyob Tefera
8714ca5a58 Move "Is Set" column to after "Required" 2020-10-20 23:17:54 +00:00
Eyob Tefera
0490ca163f Fix list_setters test. 2020-10-20 23:17:54 +00:00
Eyob Tefera
b4947fe8a0 Add isSet to ListSetters cmd. 2020-10-20 23:17:54 +00:00
Donny Xia
9c7b4fddf9 code review 2020-10-20 12:39:50 -07:00
Alpha
5d5b1c2c38 doc: simplify the language for understanding 2020-10-20 13:13:13 +08:00
Alpha
cf1aafb121 doc: add description for new user about vars 2020-10-20 13:06:31 +08:00
Alpha
2d4e406a86 doc: add varReference example 2020-10-20 12:56:43 +08:00
Jeff Regan
2a8edd2859 Merge pull request #3110 from aude/completion
Use Cobra for shell completion
2020-10-19 18:03:06 -07:00
Kubernetes Prow Robot
a3bc13847c Merge pull request #3119 from phanimarupaka/MakeRecurseLogicPublic
Make recurse logic public
2020-10-19 17:28:07 -07:00
Kubernetes Prow Robot
944b19ff7c Merge pull request #3114 from monopole/hideOpenapi
Hide openapi top-level command
2020-10-19 17:14:07 -07:00
Jeff Regan
f75274bae7 Merge pull request #3085 from mikeyrcamp/feat/add-edit-transformer
Add kustomize edit add/remove transformer command #3053
2020-10-19 15:04:12 -07:00
Donny Xia
62a8a8c57d check Gvk in roleRef when update name reference 2020-10-19 14:01:13 -07:00
Kubernetes Prow Robot
9514f9cd3a Merge pull request #3121 from natasha41575/regenerateSwagger
regenerated swagger.go files and updated asset name
2020-10-19 13:39:18 -07:00
Natasha Sarkar
c1c2725360 regenerated swagger.go files and updated asset name 2020-10-19 13:04:56 -07:00
Phani Teja Marupaka
e9ff26bb1b Make recurse logic public 2020-10-19 12:26:15 -07:00
Kubernetes Prow Robot
14dc3dfb81 Merge pull request #3112 from KnVerey/pipeline_continue
[kyaml] Option to continue pipeline processing when filter returns empty result
2020-10-19 10:46:14 -07:00
Katrina Verey
44619d5ca2 Option to continue pipeline processing when filter returns empty result 2020-10-19 10:34:28 -07:00
Kubernetes Prow Robot
a458ed84f9 Merge pull request #3113 from etefera/add-isSet-to-setter-struct
Add IsSet to SetterDefinition for kyaml release.
2020-10-18 11:26:13 -07:00
Kubernetes Prow Robot
108f44377d Merge pull request #3115 from monopole/refactorOpenapiMakefile
Refactor making of openapi generated files.
2020-10-16 19:24:12 -07:00
jregan
dc8439fbfa Refactor making of openapi generated files. 2020-10-16 19:03:33 -07:00
Jeff Regan
f5353fafa1 Update info.go 2020-10-16 18:00:18 -07:00
jregan
3d1376bbbc oopsHideProperCommand 2020-10-16 17:57:25 -07:00
Eyob Tefera
b1ea25e86a Add IsSet to SetterDefinition for kyaml release. 2020-10-17 00:46:30 +00:00
Jeff Regan
495f6df973 Merge pull request #3107 from natasha41575/reportOpenAPIinfo
Created a "kustomize openapi info" command
2020-10-16 14:33:21 -07:00
Natasha Sarkar
a4f1f0841e added a hidden openapi info command 2020-10-16 13:55:37 -07:00
Asbjørn Apeland
9d0fba81f0 Use Cobra for shell completion 2020-10-16 18:55:54 +02:00
Donny Xia
92826c6a1e support array index in PathGetter 2020-10-15 16:28:09 -07:00
Kubernetes Prow Robot
7e04be9ec6 Merge pull request #3105 from Shell32-Natsu/unpinKyaml
Unpin kyaml
2020-10-15 14:23:25 -07:00
Donny Xia
d954c39ef7 Unpin kyaml 2020-10-15 14:05:31 -07:00
Jeff Regan
176ac5b4fa Merge pull request #3104 from Shell32-Natsu/pinToKyaml0.9.2
Pin to kyaml v0.9.2
2020-10-15 14:02:47 -07:00
Donny Xia
dd696b5cb4 Pin to kyaml v0.9.2 2020-10-15 13:55:30 -07:00
Jeff Regan
501404e403 Merge pull request #3103 from monopole/prchecker
Move multi-module-span.go to cmd/prchecker
2020-10-15 13:39:48 -07:00
Jeff Regan
ddf94175ee Merge pull request #3102 from natasha41575/rollbackPortMergeKey
changed port merge key back to containerPort
2020-10-15 12:06:51 -07:00
Jeff Regan
232da9e12b Update Makefile 2020-10-15 11:58:50 -07:00
jregan
8b9ce8eacb Move multi-module-span.go to cmd/prchecker 2020-10-15 11:46:27 -07:00
Natasha Sarkar
ee9a4f2526 changed port merge key back to containerport 2020-10-15 11:43:14 -07:00
Kubernetes Prow Robot
006ce72b2d Merge pull request #3099 from umangachapagain/patch-1
Updated description for commonannotations
2020-10-15 11:35:25 -07:00
Jeff Regan
a80bd15bda Merge pull request #3096 from runewake2/multi-module-golang
Add Support for Paginated Pull Request Responses to Multi-Module Check
2020-10-15 11:23:30 -07:00
Sam Wronski
6c63bb2727 Revert Makefile changes 2020-10-15 10:29:38 -07:00
Jeff Regan
a7ba93b1d8 Merge pull request #3101 from monopole/cleanUpMakeTargets
Cleanup Makefile.
2020-10-15 10:03:37 -07:00
jregan
4a78cd6579 Cleanup Makefile. 2020-10-15 10:02:15 -07:00
Jeff Regan
b2b8c12203 Update README.md 2020-10-15 09:46:35 -07:00
Jeff Regan
8cc281fad6 Merge pull request #3100 from monopole/movePluginatorToCmd
Move pluginator to cmd dir.
2020-10-15 09:43:46 -07:00
jregan
7346813b8d Move pluginator to cmd dir. 2020-10-15 09:22:29 -07:00
Umanga Chapagain
52f3aca22d Updated description for commonannotations 2020-10-15 09:13:39 +05:30
Mike Camp
a6a061215f Add kustomize edit add/remove transformer command #3053
Similar to edit add/remove patch these commands
add the ability to add or remove a transformer file path
from the kustomization.yaml.

Refactored the "remove resource" and new "remove transformer"
tests into a common testRemoveCommand function to prevent
code duplication.
2020-10-14 22:24:08 -04:00
Kubernetes Prow Robot
7464d8ac8f Merge pull request #3097 from Shell32-Natsu/as-current-user
add --as-current-user flag to fn run
2020-10-14 18:09:51 -07:00
Donny Xia
64fda38e2d add --as-current-user flag to fn run 2020-10-14 17:07:03 -07:00
Sam Wronski
4cefb62d41 Add multi-module check to prow-presubmit-check 2020-10-14 15:34:52 -07:00
Eyob Tefera
ccca424234 Move "Is Set" column to after "Required" 2020-10-14 19:38:47 +00:00
Jeff Regan
ca45907af0 Merge pull request #3083 from stuartpb/patch-1
Group regex within anchoring
2020-10-14 08:34:28 -07:00
Jeff Regan
dcf43c7f2b Merge pull request #3076 from natasha41575/fetchOpenAPIdata
Fetch openAPI data
2020-10-14 08:20:27 -07:00
Natasha Sarkar
1386ec3850 edited kpt target 2020-10-13 17:19:03 -07:00
Natasha Sarkar
de8e16df15 added script for installing kpt 2020-10-13 17:11:00 -07:00
Natasha Sarkar
222b2d4485 added MYGOBIN variable for kind 2020-10-13 16:25:29 -07:00
Natasha Sarkar
e107020bd2 edited make schema for kyaml 2020-10-13 13:53:25 -07:00
Natasha Sarkar
430665e984 version -> api_version 2020-10-13 13:21:19 -07:00
Kubernetes Prow Robot
017d5673ba Merge pull request #3088 from Shell32-Natsu/arm-build
add arm build
2020-10-12 15:33:22 -07:00
Donny Xia
f346b9803e add arm build 2020-10-12 13:41:24 -07:00
Eyob Tefera
58092bf66d Fix list_setters test. 2020-10-12 20:23:53 +00:00
Eyob Tefera
747323efce Add isSet to ListSetters cmd. 2020-10-12 20:14:25 +00:00
Jeff Regan
7428e08f93 Merge pull request #3081 from Shell32-Natsu/release-container
files for building image when release kustomize
2020-10-12 11:18:09 -07:00
Stuart P. Bentley
3c8e6d7151 Group regex within anchoring
This ensures that anchoring will apply to the entire anchored expression, eg. a pattern like `foo|bar` will only match the strings "foo" and "bar" (`^(?:foo|bar)$`), instead of matching any string that begins with "foo" or ends with "bar" (`^foo|bar$`).
2020-10-10 15:47:38 -07:00
Donny Xia
43bd2f4cdb files for building image when release kustomize 2020-10-09 14:35:17 -07:00
Natasha Sarkar
1dfc9a88a8 moved openapi instructions to top of readme 2020-10-09 12:31:14 -07:00
Natasha Sarkar
01beba8697 formatting documentation: 2020-10-09 12:29:06 -07:00
Natasha Sarkar
b1e01b238b updated documentation 2020-10-09 12:29:06 -07:00
Natasha Sarkar
1f595da9ad updated way to fetch go-bindata 2020-10-09 12:29:06 -07:00
Natasha Sarkar
1cf876927d minor makefile fix 2020-10-09 12:29:06 -07:00
Natasha Sarkar
a422c935d8 added make target to fetch new openapi schema 2020-10-09 12:29:06 -07:00
Jeff Regan
1971816663 Update README.md 2020-10-09 09:45:19 -07:00
Kubernetes Prow Robot
3d1eab872b Merge pull request #3071 from monopole/unpinAll
Unpin api,cmd/config,kyaml
2020-10-08 13:03:06 -07:00
Jeff Regan
10c1b0c5fa Update README.md 2020-10-08 11:34:07 -07:00
Jeff Regan
4d95cd3630 Merge pull request #3072 from monopole/gorepomod
Replace bash release helper scripts with Go progam
2020-10-08 11:10:57 -07:00
jregan
0c169e96e5 Replace bash release helper scripts with Go progam 2020-10-08 10:54:14 -07:00
jregan
5baea8400f Unpin api,cmd/config,kyaml 2020-10-08 09:39:49 -07:00
Jeff Regan
4052cd4fd8 Merge pull request #3069 from monopole/pinToCmdConfigV0.8.2
Pin to cmd/config/v0.8.2,  api/v0.6.3
2020-10-07 19:40:12 -07:00
jregan
21ac400d49 Pin to cmd/config/v0.8.2 2020-10-07 19:21:23 -07:00
206 changed files with 4770 additions and 1650 deletions

8
.dockerignore Normal file
View File

@@ -0,0 +1,8 @@
.github
docs
examples
functions
hack
site
travis
*.md

View File

@@ -47,35 +47,37 @@ $(MYGOBIN)/golangci-lint-kustomize:
GO111MODULE=on go build -tags=tools -o $(MYGOBIN)/golangci-lint-kustomize github.com/golangci/golangci-lint/cmd/golangci-lint; \
)
$(MYGOBIN)/gorepomod:
cd api; \
go install github.com/monopole/gorepomod
# Install from version specified in api/go.mod.
$(MYGOBIN)/mdrip:
cd api; \
go install github.com/monopole/mdrip
# Install from version specified in api/go.mod.
$(MYGOBIN)/stringer:
cd api; \
go install golang.org/x/tools/cmd/stringer
# Install from version specified in api/go.mod.
$(MYGOBIN)/goimports:
cd api; \
go install golang.org/x/tools/cmd/goimports
# Install resource from whatever is checked out.
$(MYGOBIN)/resource:
cd cmd/resource; \
# Build from local source.
$(MYGOBIN)/gorepomod:
cd cmd/gorepomod; \
go install .
# To pin pluginator, use this recipe instead:
# cd api;
# go install sigs.k8s.io/kustomize/pluginator/v2
# Build from local source.
$(MYGOBIN)/pluginator:
cd pluginator; \
cd cmd/pluginator; \
go install .
# Install kustomize from whatever is checked out.
# Build from local source.
$(MYGOBIN)/prchecker:
cd cmd/prchecker; \
go install .
# Build from local source.
$(MYGOBIN)/kustomize:
cd kustomize; \
go install .
@@ -88,6 +90,7 @@ install-tools: \
$(MYGOBIN)/gorepomod \
$(MYGOBIN)/mdrip \
$(MYGOBIN)/pluginator \
$(MYGOBIN)/prchecker \
$(MYGOBIN)/stringer
### Begin kustomize plugin rules.
@@ -190,8 +193,8 @@ lint-kustomize: install-tools $(builtinplugins)
$(MYGOBIN)/golangci-lint-kustomize -c ../.golangci-kustomize.yml run ./...
cd kustomize; \
$(MYGOBIN)/golangci-lint-kustomize -c ../.golangci-kustomize.yml run ./...
cd pluginator; \
$(MYGOBIN)/golangci-lint-kustomize -c ../.golangci-kustomize.yml run ./...
cd cmd/pluginator; \
$(MYGOBIN)/golangci-lint-kustomize -c ../../.golangci-kustomize.yml run ./...
# Used to add non-default compilation flags when experimenting with
# plugin-to-api compatibility checks.

View File

@@ -7,9 +7,7 @@ import (
"fmt"
"sigs.k8s.io/kustomize/api/filters/namespace"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filtersutil"
"sigs.k8s.io/yaml"
@@ -53,74 +51,6 @@ func (p *NamespaceTransformerPlugin) Transform(m resmap.ResMap) error {
return nil
}
// Special casing metadata.namespace since
// all objects have it, even "ClusterKind" objects
// that don't exist in a namespace (the Namespace
// object itself doesn't live in a namespace).
func (p *NamespaceTransformerPlugin) applicableFieldSpecs(id resid.ResId) []types.FieldSpec {
var res []types.FieldSpec
for _, fs := range p.FieldSpecs {
if id.IsSelected(&fs.Gvk) &&
(fs.Path != types.MetadataNamespacePath ||
(fs.Path == types.MetadataNamespacePath && id.IsNamespaceableKind())) {
res = append(res, fs)
}
}
return res
}
func (p *NamespaceTransformerPlugin) changeNamespace(
_ *resource.Resource) func(in interface{}) (interface{}, error) {
return func(in interface{}) (interface{}, error) {
switch in.(type) {
case string:
// will happen when the metadata/namespace
// value is replaced
return p.Namespace, nil
case []interface{}:
l, _ := in.([]interface{})
for idx, item := range l {
switch item.(type) {
case map[string]interface{}:
// Will happen when mutating the subjects
// field of ClusterRoleBinding and RoleBinding
inMap, _ := item.(map[string]interface{})
if _, ok := inMap["name"]; !ok {
continue
}
name, ok := inMap["name"].(string)
if !ok {
continue
}
// The only case we need to force the namespace
// if for the "service account". "default" is
// kind of hardcoded here for right now.
if name != "default" {
continue
}
inMap["namespace"] = p.Namespace
l[idx] = inMap
default:
// nothing to do for right now
}
}
return in, nil
case map[string]interface{}:
// Will happen if the createField=true
// when the namespace is added to the
// object
inMap := in.(map[string]interface{})
if len(inMap) == 0 {
return p.Namespace, nil
} else {
return in, nil
}
default:
return in, nil
}
}
}
func NewNamespaceTransformerPlugin() resmap.TransformerPlugin {
return &NamespaceTransformerPlugin{}
}

View File

@@ -1,7 +1,9 @@
package nameref
import (
"encoding/json"
"fmt"
"strings"
"sigs.k8s.io/kustomize/api/filters/fieldspec"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
@@ -9,6 +11,7 @@ import (
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
kyaml_filtersutil "sigs.k8s.io/kustomize/kyaml/filtersutil"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
@@ -19,6 +22,7 @@ type Filter struct {
Referrer *resource.Resource
Target resid.Gvk
ReferralCandidates resmap.ResMap
isRoleRef bool
}
func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
@@ -37,6 +41,9 @@ func (f Filter) set(node *yaml.RNode) error {
if yaml.IsMissingOrNull(node) {
return nil
}
if strings.HasSuffix(f.FieldSpec.Path, "roleRef/name") {
f.isRoleRef = true
}
switch node.YNode().Kind {
case yaml.ScalarNode:
return f.setScalar(node)
@@ -65,6 +72,7 @@ func (f Filter) setMapping(node *yaml.RNode) error {
f.Referrer,
f.Target,
f.ReferralCandidates,
f.isRoleRef,
)
}
@@ -75,6 +83,7 @@ func (f Filter) setScalar(node *yaml.RNode) error {
f.Target,
f.ReferralCandidates,
f.ReferralCandidates.Resources(),
f.isRoleRef,
)
if err != nil {
return err
@@ -86,6 +95,40 @@ func (f Filter) setScalar(node *yaml.RNode) error {
return nil
}
// getRoleRefGvk returns a Gvk in the roleRef field. Return error
// if the roleRef, roleRef/apiGroup or roleRef/kind is missing.
func getRoleRefGvk(res json.Marshaler) (*resid.Gvk, error) {
n, err := kyaml_filtersutil.GetRNode(res)
if err != nil {
return nil, err
}
roleRef, err := n.Pipe(yaml.Lookup("roleRef"))
if err != nil {
return nil, err
}
if roleRef.IsNil() {
return nil, fmt.Errorf("roleRef cannot be found in %s", n.MustString())
}
apiGroup, err := roleRef.Pipe(yaml.Lookup("apiGroup"))
if err != nil {
return nil, err
}
if apiGroup.IsNil() {
return nil, fmt.Errorf("apiGroup cannot be found in roleRef %s", roleRef.MustString())
}
kind, err := roleRef.Pipe(yaml.Lookup("kind"))
if err != nil {
return nil, err
}
if kind.IsNil() {
return nil, fmt.Errorf("kind cannot be found in roleRef %s", roleRef.MustString())
}
return &resid.Gvk{
Group: apiGroup.YNode().Value,
Kind: kind.YNode().Value,
}, nil
}
func filterReferralCandidates(
referrer *resource.Resource,
matches []*resource.Resource,
@@ -117,11 +160,22 @@ func selectReferral(
referrer *resource.Resource,
target resid.Gvk,
referralCandidates resmap.ResMap,
referralCandidateSubset []*resource.Resource) (string, string, error) {
referralCandidateSubset []*resource.Resource,
isRoleRef bool) (string, string, error) {
var roleRefGvk *resid.Gvk
if isRoleRef {
var err error
roleRefGvk, err = getRoleRefGvk(referrer)
if err != nil {
return "", "", err
}
}
for _, res := range referralCandidateSubset {
id := res.OrgId()
if id.IsSelected(&target) && res.GetOriginalName() == oldName {
// If the we are processing a roleRef, the apiGroup and Kind in the
// roleRef are needed to be considered.
if (!isRoleRef || id.IsSelected(roleRefGvk)) &&
id.IsSelected(&target) && res.GetOriginalName() == oldName {
matches := referralCandidates.GetMatchingResourcesByOriginalId(id.Equals)
// If there's more than one match,
// filter the matches by prefix and suffix
@@ -155,10 +209,11 @@ func getSimpleNameField(
referrer *resource.Resource,
target resid.Gvk,
referralCandidates resmap.ResMap,
referralCandidateSubset []*resource.Resource) (string, error) {
referralCandidateSubset []*resource.Resource,
isRoleRef bool) (string, error) {
newName, _, err := selectReferral(oldName, referrer, target,
referralCandidates, referralCandidateSubset)
referralCandidates, referralCandidateSubset, isRoleRef)
return newName, err
}
@@ -177,7 +232,8 @@ func setNameAndNs(
in *yaml.RNode,
referrer *resource.Resource,
target resid.Gvk,
referralCandidates resmap.ResMap) error {
referralCandidates resmap.ResMap,
isRoleRef bool) error {
if in.YNode().Kind != yaml.MappingNode {
return fmt.Errorf("expect a mapping node")
@@ -213,7 +269,7 @@ func setNameAndNs(
oldName := nameNode.YNode().Value
newname, newnamespace, err := selectReferral(oldName, referrer, target,
referralCandidates, subset)
referralCandidates, subset, isRoleRef)
if err != nil {
return err
}

View File

@@ -194,47 +194,47 @@ metadata:
{
name: "update-clusterrolebinding",
input: `
apiVersion: example.com/v1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
subjects:
- name: default
---
apiVersion: example.com/v1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
subjects:
- name: default
namespace: foo
---
apiVersion: example.com/v1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
subjects:
- name: something
---
apiVersion: example.com/v1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
subjects:
- name: something
namespace: foo
`,
expected: `
apiVersion: example.com/v1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
subjects:
- name: default
namespace: bar
---
apiVersion: example.com/v1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
subjects:
- name: default
namespace: bar
---
apiVersion: example.com/v1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
subjects:
- name: something
---
apiVersion: example.com/v1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
subjects:
- name: something

View File

@@ -17,6 +17,6 @@ require (
k8s.io/apimachinery v0.17.0
k8s.io/client-go v0.17.0
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a
sigs.k8s.io/kustomize/kyaml v0.9.1
sigs.k8s.io/kustomize/kyaml v0.9.3
sigs.k8s.io/yaml v1.2.0
)

View File

@@ -588,8 +588,8 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphD
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/kustomize/kyaml v0.9.1 h1:T7aNUraSioQp0NHJZtYjIhL/q8mqRzCiHcAKdvo09go=
sigs.k8s.io/kustomize/kyaml v0.9.1/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/kustomize/kyaml v0.9.3 h1:kZ5HnNmmnbndSXFivrAVM6u3Ik1dwu4kbpaV8KNwy8I=
sigs.k8s.io/kustomize/kyaml v0.9.3/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
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.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@@ -789,9 +789,9 @@ func TestNameReferenceClusterWide(t *testing.T) {
"name": modifiedname,
},
"roleRef": map[string]interface{}{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"name": orgname,
"apiGroup": "rbac.authorization.k8s.io",
"kind": "ClusterRole",
"name": orgname,
},
"subjects": []interface{}{
map[string]interface{}{
@@ -845,9 +845,9 @@ func TestNameReferenceClusterWide(t *testing.T) {
"name": modifiedname,
},
"roleRef": map[string]interface{}{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"name": modifiedname,
"apiGroup": "rbac.authorization.k8s.io",
"kind": "ClusterRole",
"name": modifiedname,
},
// The following tests required a change in
// getNameFunc implementation in order to leverage
@@ -937,9 +937,9 @@ func TestNameReferenceNamespaceTransformation(t *testing.T) {
"name": modifiedname,
},
"roleRef": map[string]interface{}{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"name": orgname,
"apiGroup": "rbac.authorization.k8s.io",
"kind": "ClusterRole",
"name": orgname,
},
"subjects": []interface{}{
map[string]interface{}{
@@ -973,9 +973,9 @@ func TestNameReferenceNamespaceTransformation(t *testing.T) {
"name": modifiedname,
},
"roleRef": map[string]interface{}{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"name": modifiedname,
"apiGroup": "rbac.authorization.k8s.io",
"kind": "ClusterRole",
"name": modifiedname,
},
// The following tests required a change in
// getNameFunc implementation in order to leverage

View File

@@ -527,8 +527,8 @@ k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/kustomize/kyaml v0.9.1 h1:T7aNUraSioQp0NHJZtYjIhL/q8mqRzCiHcAKdvo09go=
sigs.k8s.io/kustomize/kyaml v0.9.1/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/kustomize/kyaml v0.9.3 h1:kZ5HnNmmnbndSXFivrAVM6u3Ik1dwu4kbpaV8KNwy8I=
sigs.k8s.io/kustomize/kyaml v0.9.3/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=

View File

@@ -26,13 +26,15 @@ func newMultiTransformer(t []resmap.Transformer) resmap.Transformer {
return r
}
// Transform prepends the name prefix.
// Transform applies the member transformers in order to the resources,
// optionally detecting and erroring on commutation conflict.
func (o *multiTransformer) Transform(m resmap.ResMap) error {
if o.checkConflictEnabled {
return o.transformWithCheckConflict(m)
}
return o.transform(m)
}
func (o *multiTransformer) transform(m resmap.ResMap) error {
for _, t := range o.transformers {
err := t.Transform(m)

View File

@@ -21,5 +21,5 @@ import (
// major version increments in pluginator with each
// api release to allow this trick to work and not
// introduce cycles.
// _ "sigs.k8s.io/kustomize/pluginator/v2"
// _ "sigs.k8s.io/kustomize/cmd/pluginator/v2"
)

View File

@@ -238,6 +238,8 @@ nameReference:
kind: Ingress
- path: metadata/annotations/nginx.ingress.kubernetes.io\/auth-tls-secret
kind: Ingress
- path: spec/tls/secretName
kind: Ingress
- path: imagePullSecrets/name
kind: ServiceAccount
- path: parameters/secretName
@@ -267,6 +269,10 @@ nameReference:
kind: Ingress
- path: spec/backend/serviceName
kind: Ingress
- path: spec/rules/http/paths/backend/service/name
kind: Ingress
- path: spec/defaultBackend/service/name
kind: Ingress
- path: spec/service/name
kind: APIService
group: apiregistration.k8s.io
@@ -373,5 +379,12 @@ nameReference:
kind: Job
- path: spec/template/spec/priorityClassName
kind: DaemonSet
- kind: IngressClass
version: v1
group: networking.k8s.io/v1
fieldSpecs:
- path: spec/ingressClassName
kind: Ingress
`
)

View File

@@ -159,7 +159,7 @@ subjects:
name: default
namespace: irrelevant
---
apiVersion: admissionregistration.k8s.io/v1beta1
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: example
@@ -180,15 +180,17 @@ webhooks:
name: svc3
namespace: random
---
apiVersion: apiextensions.k8s.io/v1beta1
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: crds.my.org
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cr1
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: crb1
@@ -197,6 +199,7 @@ subjects:
name: default
namespace: irrelevant
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
@@ -257,7 +260,7 @@ subjects:
name: default
namespace: newnamespace
---
apiVersion: admissionregistration.k8s.io/v1beta1
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: p1-example-s1
@@ -278,15 +281,17 @@ webhooks:
namespace: random
name: example3
---
apiVersion: apiextensions.k8s.io/v1beta1
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: crds.my.org
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: p1-cr1-s1
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: p1-crb1-s1
@@ -295,6 +300,7 @@ subjects:
name: default
namespace: newnamespace
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: p1-pv1-s1

View File

@@ -0,0 +1,287 @@
package krusty_test
import (
"testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
// https://github.com/kubernetes-sigs/kustomize/issues/2640
func TestNameUpdateInRoleRef(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("/app/rbac.yaml", `
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: my-role
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: my-role
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: my-role
subjects:
- kind: ServiceAccount
name: default
namespace: foo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: my-role
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-role
roleRef:
apiGroup: rbac.authorization.k8s.io
version: v1
kind: Role
name: my-role
subjects:
- kind: ServiceAccount
name: default
`)
th.WriteK("/app", `
namespace: foo
resources:
- rbac.yaml
patches:
- patch: |-
- op: add
path: /metadata/name
value: prefix_my-role
target:
group: rbac.authorization.k8s.io
version: v1
kind: ClusterRole
name: my-role
`)
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prefix_my-role
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: my-role
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prefix_my-role
subjects:
- kind: ServiceAccount
name: default
namespace: foo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: my-role
namespace: foo
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-role
namespace: foo
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: my-role
version: v1
subjects:
- kind: ServiceAccount
name: default
namespace: foo
`)
}
// https://github.com/kubernetes-sigs/kustomize/issues/3073
func TestNameUpdateInRoleRef2(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("/app/workloads.yaml", `
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: myapp
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: myapp
rules:
- apiGroups:
- ""
resources:
- nodes/metrics
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: myapp
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: myapp
subjects:
- kind: ServiceAccount
name: myapp
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: myapp
rules:
- apiGroups:
- ""
resources:
- services
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: myapp
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: myapp
subjects:
- kind: ServiceAccount
name: myapp
`)
th.WriteF("/app/suffixTransformer.yaml", `
apiVersion: builtin
kind: PrefixSuffixTransformer
metadata:
name: notImportantHere
suffix: -suffix
fieldSpecs:
- path: metadata/name
kind: ClusterRole
name: myapp
- path: metadata/name
kind: ClusterRoleBinding
name: myapp
`)
th.WriteK("/app", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- workloads.yaml
transformers:
- suffixTransformer.yaml
namespace: test
`)
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: ServiceAccount
metadata:
name: myapp
namespace: test
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: myapp-suffix
rules:
- apiGroups:
- ""
resources:
- nodes/metrics
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: myapp-suffix
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: myapp-suffix
subjects:
- kind: ServiceAccount
name: myapp
namespace: test
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: myapp
namespace: test
rules:
- apiGroups:
- ""
resources:
- services
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: myapp
namespace: test
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: myapp
subjects:
- kind: ServiceAccount
name: myapp
namespace: test
`)
}

View File

@@ -6,6 +6,7 @@ package resid
import (
"strings"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
@@ -207,5 +208,6 @@ func (x Gvk) toKyamlTypeMeta() yaml.TypeMeta {
// 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
func (x Gvk) IsNamespaceableKind() bool {
return x.toKyamlTypeMeta().IsNamespaceable()
isNamespaceScoped, found := openapi.IsNamespaceScoped(x.toKyamlTypeMeta())
return !found || isNamespaceScoped
}

View File

@@ -18,6 +18,8 @@ package resid
import (
"testing"
"github.com/stretchr/testify/assert"
)
var equalsTests = []struct {
@@ -255,3 +257,40 @@ func TestSelectByGVK(t *testing.T) {
}
}
}
func TestIsNamespaceableKind(t *testing.T) {
testCases := []struct {
name string
gvk Gvk
expected bool
}{
{
"namespaceable resource",
Gvk{Group: "apps", Version: "v1", Kind: "Deployment"},
true,
},
{
"clusterscoped resource",
Gvk{Group: "", Version: "v1", Kind: "Namespace"},
false,
},
{
"unknown resource (should default to namespaceable)",
Gvk{Group: "example1.com", Version: "v1", Kind: "Bar"},
true,
},
{
"unknown resource (should default to namespaceable)",
Gvk{Group: "apps", Version: "v1", Kind: "ClusterRoleBinding"},
true,
},
}
for i := range testCases {
test := testCases[i]
t.Run(test.name, func(t *testing.T) {
isNamespaceable := test.gvk.IsNamespaceableKind()
assert.Equal(t, test.expected, isNamespaceable)
})
}
}

View File

@@ -265,7 +265,7 @@ func TestResIdEquals(t *testing.T) {
Name: "nm",
},
gVknResult: false,
nsEquals: false,
nsEquals: true,
equals: false,
},
{
@@ -376,7 +376,7 @@ func TestEffectiveNamespace(t *testing.T) {
}{
{
id: ResId{
Gvk: Gvk{Group: "g", Version: "v", Kind: "Node"},
Gvk: Gvk{Group: "", Version: "v1", Kind: "Node"},
Name: "nm",
},
expected: TotallyNotANamespace,
@@ -384,7 +384,7 @@ func TestEffectiveNamespace(t *testing.T) {
{
id: ResId{
Namespace: "foo",
Gvk: Gvk{Group: "g", Version: "v", Kind: "Node"},
Gvk: Gvk{Group: "", Version: "v1", Kind: "Node"},
Name: "nm",
},
expected: TotallyNotANamespace,

View File

@@ -514,7 +514,7 @@ func anchorRegex(pattern string) string {
if pattern == "" {
return pattern
}
return "^" + pattern + "$"
return "^(?:" + pattern + ")$"
}
// Select returns a list of resources that

View File

@@ -355,7 +355,7 @@ func TestSubsetThatCouldBeReferencedByResource(t *testing.T) {
})
r4 := rf.FromMap(
map[string]interface{}{
"apiVersion": "v1",
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "charlie",
@@ -374,7 +374,7 @@ func TestSubsetThatCouldBeReferencedByResource(t *testing.T) {
r5.AddNamePrefix("little-")
r6 := rf.FromMap(
map[string]interface{}{
"apiVersion": "v1",
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "domino",
@@ -384,7 +384,7 @@ func TestSubsetThatCouldBeReferencedByResource(t *testing.T) {
r6.AddNamePrefix("little-")
r7 := rf.FromMap(
map[string]interface{}{
"apiVersion": "v1",
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRoleBinding",
"metadata": map[string]interface{}{
"name": "meh",

View File

@@ -17,3 +17,12 @@ type Patch struct {
// Target points to the resources that the patch is applied to
Target *Selector `json:"target,omitempty" yaml:"target,omitempty"`
}
// Equals return true if p equals o.
func (p *Patch) Equals(o Patch) bool {
targetEqual := (p.Target == o.Target) ||
(p.Target != nil && o.Target != nil && *p.Target == *o.Target)
return p.Path == o.Path &&
p.Patch == o.Patch &&
targetEqual
}

125
api/types/patch_test.go Normal file
View File

@@ -0,0 +1,125 @@
package types_test
import (
"testing"
"sigs.k8s.io/kustomize/api/resid"
. "sigs.k8s.io/kustomize/api/types"
)
func TestPatchEquals(t *testing.T) {
selector := Selector{
Gvk: resid.Gvk{
Group: "group",
Version: "version",
Kind: "kind",
},
Name: "name",
Namespace: "namespace",
LabelSelector: "selector",
AnnotationSelector: "selector",
}
type testcase struct {
patch1 Patch
patch2 Patch
expect bool
name string
}
testcases := []testcase{
{
name: "empty patches",
patch1: Patch{},
patch2: Patch{},
expect: true,
},
{
name: "full patches",
patch1: Patch{
Path: "foo",
Patch: "bar",
Target: &Selector{
Gvk: resid.Gvk{
Group: "group",
Version: "version",
Kind: "kind",
},
Name: "name",
Namespace: "namespace",
LabelSelector: "selector",
AnnotationSelector: "selector",
},
},
patch2: Patch{
Path: "foo",
Patch: "bar",
Target: &Selector{
Gvk: resid.Gvk{
Group: "group",
Version: "version",
Kind: "kind",
},
Name: "name",
Namespace: "namespace",
LabelSelector: "selector",
AnnotationSelector: "selector",
},
},
expect: true,
},
{
name: "same target",
patch1: Patch{
Path: "foo",
Patch: "bar",
Target: &selector,
},
patch2: Patch{
Path: "foo",
Patch: "bar",
Target: &selector,
},
expect: true,
},
{
name: "omit target",
patch1: Patch{
Path: "foo",
Patch: "bar",
},
patch2: Patch{
Path: "foo",
Patch: "bar",
},
expect: true,
},
{
name: "one nil target",
patch1: Patch{
Path: "foo",
Patch: "bar",
Target: &selector,
},
patch2: Patch{
Path: "foo",
Patch: "bar",
},
expect: false,
},
{
name: "different path",
patch1: Patch{
Path: "foo",
},
patch2: Patch{
Path: "bar",
},
expect: false,
},
}
for _, tc := range testcases {
if tc.expect != tc.patch1.Equals(tc.patch2) {
t.Fatalf("%s: unexpected result %v", tc.name, !tc.expect)
}
}
}

View File

@@ -1,72 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package complete
import (
"os"
"strings"
"github.com/posener/complete/v2"
"github.com/posener/complete/v2/predict"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/errors"
)
// NewCommand returns a new install-completion command
func NewCommand() *cobra.Command {
return &cobra.Command{
Use: "install-completion",
Short: commands.CompletionShort,
Long: commands.CompletionLong,
PreRunE: preRunE,
Run: run,
}
}
func preRunE(cmd *cobra.Command, args []string) error {
// install by default
if os.Getenv("COMP_INSTALL") == "" {
if err := errors.Wrap(os.Setenv("COMP_INSTALL", "1")); err != nil {
return err
}
}
return nil
}
func run(cmd *cobra.Command, args []string) {
// find the root command
for cmd.Parent() != nil {
cmd = cmd.Parent()
}
// do completion
Complete(cmd).Complete("kustomize")
}
// Complete returns a completion command for a cobra command
func Complete(cmd *cobra.Command) *complete.Command {
cc := &complete.Command{
Flags: map[string]complete.Predictor{},
Sub: map[string]*complete.Command{},
}
if strings.Contains(cmd.Use, "DIR") {
// if usage contains directory, then use a file predictor
cc.Args = predict.Dirs("*")
}
// add completion for each subcommand
for i := range cmd.Commands() {
c := cmd.Commands()[i]
name := strings.Split(c.Use, " ")[0]
cc.Sub[name] = Complete(c)
}
// add completion for each flag
cmd.Flags().VisitAll(func(flag *pflag.Flag) {
cc.Flags[flag.Name] = predict.Nothing
})
return cc
}

View File

@@ -0,0 +1,33 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package completion
import (
"os"
"github.com/spf13/cobra"
)
func NewCommand() *cobra.Command {
return &cobra.Command{
Use: "completion [bash|zsh|fish|powershell]",
Short: "Generate shell completion script",
Long: "Generate shell completion.",
DisableFlagsInUseLine: true,
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
Args: cobra.ExactValidArgs(1),
Run: func(cmd *cobra.Command, args []string) {
switch args[0] {
case "bash":
cmd.Root().GenBashCompletion(os.Stdout)
case "zsh":
cmd.Root().GenZshCompletion(os.Stdout)
case "fish":
cmd.Root().GenFishCompletion(os.Stdout, true)
case "powershell":
cmd.Root().GenPowerShellCompletion(os.Stdout)
}
},
}
}

View File

@@ -10,6 +10,7 @@ import (
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/api"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/tutorials"
"sigs.k8s.io/kustomize/cmd/config/runner"
)
// Export commands publicly for composition
@@ -35,13 +36,13 @@ var (
Wrap = commands.WrapCommand
XArgs = commands.XArgsCommand
StackOnError = &commands.StackOnError
ExitOnError = &commands.ExitOnError
StackOnError = &runner.StackOnError
ExitOnError = &runner.ExitOnError
)
// AddCommands adds the cfg and fn commands to kustomize.
func AddCommands(root *cobra.Command, name string) *cobra.Command {
commands.ExitOnError = true
runner.ExitOnError = true
root.PersistentFlags().BoolVar(StackOnError, "stack-trace", false,
"print a stack-trace on error")

View File

@@ -1,20 +1,25 @@
## install-completion
## completion
Install shell completion.
Generate shell completion.
### Synopsis
Install shell completion for kustomize commands and flags -- supports bash, fish and zsh.
Generate shell completion for `kustomize` -- supports bash, zsh, fish and powershell.
kustomize install-completion
### Examples
Registers the completion command with known shells (e.g. .bashrc, .bash_profile, etc):
# load completion for Bash
source <(kustomize completion bash)
complete -C /Users/USER/go/bin/kustomize kustomize
# install for Bash in Linux
kustomize completion bash > /etc/bash_completion.d/kustomize
Because the completion command is embedded in kustomize directly, there is no need to update
it separately from the kustomize binary.
# install for Bash in MacOS
kustomize completion bash > /usr/local/etc/bash_completion.d/kustomize
To uninstall shell completion run:
# package for Bash
kustomize completion bash > /usr/share/bash-completion/completions/kustomize
# package for zsh
kustomize completion zsh > /usr/share/zsh/site-functions/_kustomize
COMP_UNINSTALL=1 kustomize install-completion

View File

@@ -9,13 +9,11 @@ require (
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/posener/complete/v2 v2.0.1-alpha.12
github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.6.1
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
sigs.k8s.io/kustomize/kyaml v0.9.1
sigs.k8s.io/kustomize/kyaml v0.9.3
)

View File

@@ -152,10 +152,6 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
@@ -226,14 +222,9 @@ github.com/paulmach/orb v0.1.3/go.mod h1:VFlX/8C+IQ1p6FTRRKzKoOPJnvEtA5G0Veuqwbu
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/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete/v2 v2.0.1-alpha.12 h1:0wvkuDfHb5vSZlNBYgpEH4XQHpF46MjLPHav8XC77Nc=
github.com/posener/complete/v2 v2.0.1-alpha.12/go.mod h1://JlL91cS2JV7rOl6LVHrRqBXoBUecJu3ILQPgbJiMQ=
github.com/posener/script v1.0.4 h1:nSuXW5ZdmFnQIueLB2s0qvs4oNsUloM1Zydzh75v42w=
github.com/posener/script v1.0.4/go.mod h1:Rg3ijooqulo05aGLyGsHoLmIOUzHUVK19WVgrYBPU/E=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@@ -400,8 +391,8 @@ k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU=
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=
sigs.k8s.io/kustomize/kyaml v0.9.1/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/kustomize/kyaml v0.9.3 h1:kZ5HnNmmnbndSXFivrAVM6u3Ik1dwu4kbpaV8KNwy8I=
sigs.k8s.io/kustomize/kyaml v0.9.3/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=

View File

@@ -11,6 +11,7 @@ import (
"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/runner"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
@@ -27,7 +28,7 @@ func NewAnnotateRunner(parent string) *AnnotateRunner {
Example: commands.AnnotateExamples,
RunE: r.runE,
}
fixDocs(parent, c)
runner.FixDocs(parent, c)
r.Command = c
c.Flags().StringVar(&r.Kind, "kind", "", "Resource kind to annotate")
c.Flags().StringVar(&r.ApiVersion, "apiVersion", "", "Resource apiVersion to annotate")
@@ -62,29 +63,29 @@ func (r *AnnotateRunner) runE(c *cobra.Command, args []string) error {
input = []kio.Reader{rw}
output = []kio.Writer{rw}
return handleError(c, kio.Pipeline{
return runner.HandleError(c, kio.Pipeline{
Inputs: input,
Filters: []kio.Filter{r},
Outputs: output,
}.Execute())
}
e := executeCmdOnPkgs{
writer: c.OutOrStdout(),
needOpenAPI: false,
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
rootPkgPath: args[0],
e := runner.ExecuteCmdOnPkgs{
Writer: c.OutOrStdout(),
NeedOpenAPI: false,
RecurseSubPackages: r.RecurseSubPackages,
CmdRunner: r,
RootPkgPath: args[0],
}
err := e.execute()
err := e.Execute()
if err != nil {
return err
}
return nil
}
func (r *AnnotateRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *AnnotateRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
rw := &kio.LocalPackageReadWriter{
PackagePath: pkgPath,
NoDeleteFiles: true,

View File

@@ -13,6 +13,7 @@ import (
"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/runner"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/filters"
@@ -30,7 +31,7 @@ func GetCatRunner(name string) *CatRunner {
RunE: r.runE,
Args: cobra.MaximumNArgs(1),
}
fixDocs(name, c)
runner.FixDocs(name, c)
c.Flags().BoolVar(&r.Format, "format", true,
"format resource config yaml before printing.")
c.Flags().BoolVar(&r.KeepAnnotations, "annotate", false,
@@ -95,21 +96,21 @@ func (r *CatRunner) runE(c *cobra.Command, args []string) error {
if err != nil {
return err
}
return handleError(c, kio.Pipeline{Inputs: []kio.Reader{input}, Filters: r.catFilters(), Outputs: outputs}.Execute())
return runner.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,
e := runner.ExecuteCmdOnPkgs{
Writer: out,
NeedOpenAPI: false,
RecurseSubPackages: r.RecurseSubPackages,
CmdRunner: r,
RootPkgPath: args[0],
SkipPkgPathPrint: true,
}
err := e.execute()
err := e.Execute()
if err != nil {
return err
}
@@ -120,7 +121,7 @@ func (r *CatRunner) runE(c *cobra.Command, args []string) error {
return nil
}
func (r *CatRunner) executeCmd(w io.Writer, pkgPath string) error {
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)

View File

@@ -15,6 +15,7 @@ import (
"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/runner"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/setters"
@@ -63,7 +64,7 @@ func NewCreateSetterRunner(parent string) *CreateSetterRunner {
set.Flags().BoolVarP(&r.CreateSetter.RecurseSubPackages, "recurse-subpackages", "R", false,
"creates setter recursively in all the nested subpackages")
set.Flags().MarkHidden("version")
fixDocs(parent, set)
runner.FixDocs(parent, set)
r.Command = set
return r
}
@@ -81,7 +82,7 @@ type CreateSetterRunner struct {
}
func (r *CreateSetterRunner) runE(c *cobra.Command, args []string) error {
return handleError(c, r.createSetter(c, args))
return runner.HandleError(c, r.createSetter(c, args))
}
func (r *CreateSetterRunner) preRunE(c *cobra.Command, args []string) error {
@@ -179,16 +180,16 @@ func (r *CreateSetterRunner) processSchema() error {
func (r *CreateSetterRunner) createSetter(c *cobra.Command, args []string) error {
if setterVersion == "v2" {
e := executeCmdOnPkgs{
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.CreateSetter.RecurseSubPackages,
cmdRunner: r,
e := runner.ExecuteCmdOnPkgs{
NeedOpenAPI: true,
Writer: c.OutOrStdout(),
RootPkgPath: args[0],
RecurseSubPackages: r.CreateSetter.RecurseSubPackages,
CmdRunner: r,
}
err := e.execute()
err := e.Execute()
if err != nil {
return handleError(c, err)
return runner.HandleError(c, err)
}
return nil
}
@@ -204,7 +205,7 @@ func (r *CreateSetterRunner) createSetter(c *cobra.Command, args []string) error
return nil
}
func (r *CreateSetterRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *CreateSetterRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
r.CreateSetter = settersutil.SetterCreator{
Name: r.CreateSetter.Name,
SetBy: r.CreateSetter.SetBy,

View File

@@ -10,6 +10,7 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
)
@@ -32,7 +33,7 @@ func NewCreateSubstitutionRunner(parent string) *CreateSubstitutionRunner {
"creates substitution recursively in all the nested subpackages")
_ = cs.MarkFlagRequired("pattern")
_ = cs.MarkFlagRequired("field-value")
fixDocs(parent, cs)
runner.FixDocs(parent, cs)
r.Command = cs
return r
}
@@ -49,22 +50,22 @@ type CreateSubstitutionRunner struct {
}
func (r *CreateSubstitutionRunner) runE(c *cobra.Command, args []string) error {
e := executeCmdOnPkgs{
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.CreateSubstitution.RecurseSubPackages,
cmdRunner: r,
e := runner.ExecuteCmdOnPkgs{
NeedOpenAPI: true,
Writer: c.OutOrStdout(),
RootPkgPath: args[0],
RecurseSubPackages: r.CreateSubstitution.RecurseSubPackages,
CmdRunner: r,
}
err := e.execute()
err := e.Execute()
if err != nil {
return handleError(c, err)
return runner.HandleError(c, err)
}
return nil
}
func (r *CreateSubstitutionRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *CreateSubstitutionRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
r.CreateSubstitution = settersutil.SubstitutionCreator{
Name: r.CreateSubstitution.Name,
FieldName: r.CreateSubstitution.FieldName,

View File

@@ -11,6 +11,7 @@ import (
"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/runner"
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
)
@@ -29,7 +30,7 @@ func NewDeleteSetterRunner(parent string) *DeleteSetterRunner {
}
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
"deletes setter recursively in all the nested subpackages")
fixDocs(parent, c)
runner.FixDocs(parent, c)
r.Command = c
return r
@@ -56,22 +57,21 @@ func (r *DeleteSetterRunner) preRunE(c *cobra.Command, args []string) error {
}
func (r *DeleteSetterRunner) runE(c *cobra.Command, args []string) error {
e := executeCmdOnPkgs{
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
e := runner.ExecuteCmdOnPkgs{
NeedOpenAPI: true,
Writer: c.OutOrStdout(),
RootPkgPath: args[0],
RecurseSubPackages: r.RecurseSubPackages,
CmdRunner: r,
}
err := e.execute()
err := e.Execute()
if err != nil {
return handleError(c, err)
return runner.HandleError(c, err)
}
return nil
}
func (r *DeleteSetterRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *DeleteSetterRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
r.DeleteSetter = settersutil.DeleterCreator{
Name: r.DeleteSetter.Name,
DefinitionPrefix: fieldmeta.SetterDefinitionPrefix,

View File

@@ -10,6 +10,7 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
)
@@ -25,7 +26,7 @@ func NewDeleteSubstitutionRunner(parent string) *DeleteSubstitutionRunner {
}
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
"deletes substitution recursively in all the nested subpackages")
fixDocs(parent, c)
runner.FixDocs(parent, c)
r.Command = c
return r
@@ -52,21 +53,21 @@ func (r *DeleteSubstitutionRunner) preRunE(c *cobra.Command, args []string) erro
}
func (r *DeleteSubstitutionRunner) runE(c *cobra.Command, args []string) error {
e := executeCmdOnPkgs{
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
e := runner.ExecuteCmdOnPkgs{
NeedOpenAPI: true,
Writer: c.OutOrStdout(),
RootPkgPath: args[0],
RecurseSubPackages: r.RecurseSubPackages,
CmdRunner: r,
}
err := e.execute()
err := e.Execute()
if err != nil {
return handleError(c, err)
return runner.HandleError(c, err)
}
return nil
}
func (r *DeleteSubstitutionRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *DeleteSubstitutionRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
r.DeleteSubstitution = settersutil.DeleterCreator{
Name: r.DeleteSubstitution.Name,
DefinitionPrefix: fieldmeta.SubstitutionDefinitionPrefix,

View File

@@ -11,6 +11,7 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/krmfile"
)
@@ -26,7 +27,7 @@ func GetInitRunner(name string) *InitRunner {
Example: commands.InitExamples,
RunE: r.runE,
}
fixDocs(name, c)
runner.FixDocs(name, c)
r.Command = c
return r
}

View File

@@ -14,6 +14,7 @@ import (
"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/runner"
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
"sigs.k8s.io/kustomize/kyaml/setters"
"sigs.k8s.io/kustomize/kyaml/setters2"
@@ -37,7 +38,7 @@ func NewListSettersRunner(parent string) *ListSettersRunner {
"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)
runner.FixDocs(parent, c)
r.Command = c
return r
}
@@ -67,24 +68,24 @@ func (r *ListSettersRunner) preRunE(c *cobra.Command, args []string) error {
func (r *ListSettersRunner) runE(c *cobra.Command, args []string) error {
if setterVersion == "v2" {
e := executeCmdOnPkgs{
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
e := runner.ExecuteCmdOnPkgs{
NeedOpenAPI: true,
Writer: c.OutOrStdout(),
RootPkgPath: args[0],
RecurseSubPackages: r.RecurseSubPackages,
CmdRunner: r,
}
err := e.execute()
err := e.Execute()
if err != nil {
return handleError(c, err)
return runner.HandleError(c, err)
}
return nil
}
return handleError(c, lookup(r.Lookup, c, args))
return runner.HandleError(c, lookup(r.Lookup, c, args))
}
func (r *ListSettersRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *ListSettersRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
r.List = setters2.List{
Name: r.List.Name,
OpenAPIFileName: ext.KRMFileName(),
@@ -107,7 +108,7 @@ func (r *ListSettersRunner) ListSetters(w io.Writer, openAPIPath, resourcePath s
return err
}
table := newTable(w, r.Markdown)
table.SetHeader([]string{"NAME", "VALUE", "SET BY", "DESCRIPTION", "COUNT", "REQUIRED"})
table.SetHeader([]string{"NAME", "VALUE", "SET BY", "DESCRIPTION", "COUNT", "REQUIRED", "IS SET"})
for i := range r.List.Setters {
s := r.List.Setters[i]
v := s.Value
@@ -117,20 +118,23 @@ func (r *ListSettersRunner) ListSetters(w io.Writer, openAPIPath, resourcePath s
v = strings.Join(s.ListValues, ",")
v = fmt.Sprintf("[%s]", v)
}
var required string
required := "No"
if s.Required {
required = "Yes"
} else {
required = "No"
}
isSet := "No"
if s.IsSet {
isSet = "Yes"
}
table.Append([]string{
s.Name, v, s.SetBy, s.Description, fmt.Sprintf("%d", s.Count), required})
s.Name, v, s.SetBy, s.Description, fmt.Sprintf("%d", s.Count), required, isSet})
}
table.Render()
if len(r.List.Setters) == 0 {
// exit non-0 if no matching setters are found
if ExitOnError {
if runner.ExitOnError {
os.Exit(1)
}
}

View File

@@ -46,8 +46,8 @@ metadata:
spec:
replicas: 3 # {"$ref": "#/definitions/io.k8s.cli.setters.replicas"}
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
replicas 3 me hello world 1 Yes
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
replicas 3 me hello world 1 Yes No
`,
},
@@ -72,8 +72,8 @@ metadata:
spec:
replicas: 3 # {"$ref": "#/definitions/io.k8s.cli.setters.replicas"}
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
replicas 4 me hello world 1 No
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
replicas 4 me hello world 1 No No
`,
},
{
@@ -131,10 +131,10 @@ spec:
- name: nginx2
image: nginx # {"$ref": "#/definitions/io.k8s.cli.setters.image"}
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
image nginx me2 hello world 2 2 No
replicas 3 me1 hello world 1 1 No
tag 1.7.9 me3 hello world 3 1 Yes
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
image nginx me2 hello world 2 2 No No
replicas 3 me1 hello world 1 1 No No
tag 1.7.9 me3 hello world 3 1 Yes No
--------------- ----------- --------------
SUBSTITUTION PATTERN REFERENCES
image IMAGE:TAG [image,tag]
@@ -207,10 +207,10 @@ spec:
- name: nginx2
image: nginx
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
image nginx me2 hello world 2 3 No
replicas 3 me1 hello world 1 2 No
tag 1.7.9 me3 hello world 3 2 No
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
image nginx me2 hello world 2 3 No No
replicas 3 me1 hello world 1 2 No No
tag 1.7.9 me3 hello world 3 2 No No
--------------- ----------- --------------
SUBSTITUTION PATTERN REFERENCES
image IMAGE:TAG [image,tag]
@@ -284,8 +284,8 @@ spec:
- name: nginx2
image: nginx
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
image nginx me2 hello world 2 3 Yes
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
image nginx me2 hello world 2 3 Yes No
`,
},
@@ -324,8 +324,8 @@ spec:
- "b"
- "c"
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
list [a,b,c] me hello world 1 Yes
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
list [a,b,c] me hello world 1 Yes No
`,
},
@@ -390,10 +390,10 @@ openAPI:
name: my-other-setter
value: nginxotherthing
`,
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
my-image-setter nginx 2 No
my-other-setter nginxotherthing 1 No
my-tag-setter 1.7.9 2 Yes
expected: ` NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
my-image-setter nginx 2 No No
my-other-setter nginxotherthing 1 No No
my-tag-setter 1.7.9 2 Yes Yes
------------------ ------------------------------------------------ -----------------------------------
SUBSTITUTION PATTERN REFERENCES
my-image-subst ${my-image-setter}::${my-tag-setter} [my-image-setter,my-tag-setter]
@@ -476,20 +476,20 @@ func TestListSettersSubPackages(t *testing.T) {
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
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
image mysql 1 No No
namespace myspace 1 No No
tag 1.7.9 1 No No
--------------- ----------------- --------------
SUBSTITUTION PATTERN REFERENCES
image-tag ${image}:${tag} [image,tag]
test/testdata/dataset-with-setters/mysql/nosetters/
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
test/testdata/dataset-with-setters/mysql/storage/
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
namespace myspace 1 No
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
namespace myspace 1 No No
`,
},
{
@@ -499,10 +499,10 @@ test/testdata/dataset-with-setters/mysql/storage/
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
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
image mysql 1 No No
namespace myspace 1 No No
tag 1.7.9 1 No No
`,
},
}

View File

@@ -13,6 +13,7 @@ import (
"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/runner"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/setters"
@@ -31,7 +32,7 @@ func NewSetRunner(parent string) *SetRunner {
PreRunE: r.preRunE,
RunE: r.runE,
}
fixDocs(parent, c)
runner.FixDocs(parent, c)
r.Command = c
c.Flags().StringArrayVar(&r.Values, "values", []string{},
"optional flag, the values of the setter to be set to")
@@ -131,26 +132,26 @@ func (r *SetRunner) preRunE(c *cobra.Command, args []string) error {
func (r *SetRunner) runE(c *cobra.Command, args []string) error {
if setterVersion == "v2" {
e := executeCmdOnPkgs{
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.Set.RecurseSubPackages,
cmdRunner: r,
e := runner.ExecuteCmdOnPkgs{
NeedOpenAPI: true,
Writer: c.OutOrStdout(),
RootPkgPath: args[0],
RecurseSubPackages: r.Set.RecurseSubPackages,
CmdRunner: r,
}
err := e.execute()
err := e.Execute()
if err != nil {
return handleError(c, err)
return runner.HandleError(c, err)
}
return nil
}
if len(args) > 2 || c.Flag("values").Changed {
return handleError(c, r.perform(c, args))
return runner.HandleError(c, r.perform(c, args))
}
return handleError(c, lookup(r.Lookup, c, args))
return runner.HandleError(c, lookup(r.Lookup, c, args))
}
func (r *SetRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *SetRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
r.Set = settersutil.FieldSetter{
Name: r.Set.Name,
Value: r.Set.Value,
@@ -162,6 +163,7 @@ func (r *SetRunner) executeCmd(w io.Writer, pkgPath string) error {
OpenAPIFileName: ext.KRMFileName(),
ResourcesPath: pkgPath,
RecurseSubPackages: r.Set.RecurseSubPackages,
IsSet: true,
}
count, err := r.Set.Set()
if err != nil {

View File

@@ -10,6 +10,7 @@ import (
"path/filepath"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/filters"
)
@@ -135,5 +136,5 @@ func (r *WrapRunner) runE(c *cobra.Command, args []string) error {
Writer: c.OutOrStdout(),
WrappingKind: kio.ResourceListKind,
WrappingAPIVersion: kio.ResourceListAPIVersion}}}.Execute()
return handleError(c, err)
return runner.HandleError(c, err)
}

View File

@@ -11,6 +11,7 @@ import (
"unicode"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
@@ -211,7 +212,7 @@ func (r *XArgsRunner) runE(c *cobra.Command, _ []string) error {
return err
}
return handleError(c, run.Run())
return runner.HandleError(c, run.Run())
}
func parseYNode(node *yaml.Node) string {

View File

@@ -11,6 +11,7 @@ import (
"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/runner"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/sets"
"sigs.k8s.io/kustomize/kyaml/yaml"
@@ -26,7 +27,7 @@ func GetCountRunner(name string) *CountRunner {
Example: commands.CountExamples,
RunE: r.runE,
}
fixDocs(name, c)
runner.FixDocs(name, c)
c.Flags().BoolVar(&r.Kind, "kind", true,
"count resources by kind.")
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", true,
@@ -51,24 +52,24 @@ func (r *CountRunner) runE(c *cobra.Command, args []string) error {
if len(args) == 0 {
input := &kio.ByteReader{Reader: c.InOrStdin()}
return handleError(c, kio.Pipeline{
return runner.HandleError(c, kio.Pipeline{
Inputs: []kio.Reader{input},
Outputs: r.out(c.OutOrStdout()),
}.Execute())
}
e := executeCmdOnPkgs{
writer: c.OutOrStdout(),
needOpenAPI: false,
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
rootPkgPath: args[0],
e := runner.ExecuteCmdOnPkgs{
Writer: c.OutOrStdout(),
NeedOpenAPI: false,
RecurseSubPackages: r.RecurseSubPackages,
CmdRunner: r,
RootPkgPath: args[0],
}
return e.execute()
return e.Execute()
}
func (r *CountRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *CountRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: ext.KRMFileName()}
err := kio.Pipeline{

View File

@@ -35,8 +35,8 @@ openAPI:
},
expectedStdOut: `
./
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED
replicas 3 1 No
NAME VALUE SET BY DESCRIPTION COUNT REQUIRED IS SET
replicas 3 1 No No
`,
},
}

View File

@@ -10,6 +10,7 @@ import (
"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/runner"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/filters"
)
@@ -25,7 +26,7 @@ func GetFmtRunner(name string) *FmtRunner {
RunE: r.runE,
PreRunE: r.preRunE,
}
fixDocs(name, c)
runner.FixDocs(name, c)
c.Flags().StringVar(&r.FilenamePattern, "pattern", filters.DefaultFilenamePattern,
`pattern to use for generating filenames for resources -- may contain the following
formatting substitution verbs {'%n': 'metadata.name', '%s': 'metadata.namespace', '%k': 'kind'}`)
@@ -74,20 +75,20 @@ func (r *FmtRunner) runE(c *cobra.Command, args []string) error {
Writer: c.OutOrStdout(),
KeepReaderAnnotations: r.KeepAnnotations,
}
return handleError(c, kio.Pipeline{
return runner.HandleError(c, kio.Pipeline{
Inputs: []kio.Reader{rw}, Filters: r.fmtFilters(), Outputs: []kio.Writer{rw}}.Execute())
}
for _, rootPkgPath := range args {
e := executeCmdOnPkgs{
writer: c.OutOrStdout(),
needOpenAPI: false,
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
rootPkgPath: rootPkgPath,
e := runner.ExecuteCmdOnPkgs{
Writer: c.OutOrStdout(),
NeedOpenAPI: false,
RecurseSubPackages: r.RecurseSubPackages,
CmdRunner: r,
RootPkgPath: rootPkgPath,
}
err := e.execute()
err := e.Execute()
if err != nil {
return err
}
@@ -95,7 +96,7 @@ func (r *FmtRunner) runE(c *cobra.Command, args []string) error {
return nil
}
func (r *FmtRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *FmtRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
rw := &kio.LocalPackageReadWriter{
NoDeleteFiles: true,
PackagePath: pkgPath,

View File

@@ -13,6 +13,7 @@ import (
"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/runner"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/filters"
)
@@ -29,7 +30,7 @@ func GetGrepRunner(name string) *GrepRunner {
RunE: r.runE,
Args: cobra.MaximumNArgs(2),
}
fixDocs(name, c)
runner.FixDocs(name, c)
c.Flags().BoolVar(&r.KeepAnnotations, "annotate", true,
"annotate resources with their file origins.")
c.Flags().BoolVarP(&r.InvertMatch, "invert-match", "", false,
@@ -66,7 +67,7 @@ func (r *GrepRunner) preRunE(c *cobra.Command, args []string) error {
return qa.Cmp(qb), err
}
parts, err := parseFieldPath(args[0])
parts, err := runner.ParseFieldPath(args[0])
if err != nil {
return err
}
@@ -105,7 +106,7 @@ func (r *GrepRunner) preRunE(c *cobra.Command, args []string) error {
func (r *GrepRunner) runE(c *cobra.Command, args []string) error {
if len(args) == 1 {
input := &kio.ByteReader{Reader: c.InOrStdin()}
return handleError(c, kio.Pipeline{
return runner.HandleError(c, kio.Pipeline{
Inputs: []kio.Reader{input},
Filters: []kio.Filter{r.GrepFilter},
Outputs: []kio.Writer{kio.ByteWriter{
@@ -117,16 +118,16 @@ func (r *GrepRunner) runE(c *cobra.Command, args []string) error {
out := bytes.Buffer{}
e := executeCmdOnPkgs{
writer: &out,
needOpenAPI: false,
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
rootPkgPath: args[1],
skipPkgPathPrint: true,
e := runner.ExecuteCmdOnPkgs{
Writer: &out,
NeedOpenAPI: false,
RecurseSubPackages: r.RecurseSubPackages,
CmdRunner: r,
RootPkgPath: args[1],
SkipPkgPathPrint: true,
}
err := e.execute()
err := e.Execute()
if err != nil {
return err
}
@@ -138,7 +139,7 @@ func (r *GrepRunner) runE(c *cobra.Command, args []string) error {
}
func (r *GrepRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *GrepRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: ext.KRMFileName()}
out := &bytes.Buffer{}
err := kio.Pipeline{

View File

@@ -6,6 +6,7 @@ package commands
import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/filters"
)
@@ -19,7 +20,7 @@ func GetMergeRunner(name string) *MergeRunner {
Example: commands.MergeExamples,
RunE: r.runE,
}
fixDocs(name, c)
runner.FixDocs(name, c)
r.Command = c
r.Command.Flags().BoolVar(&r.InvertOrder, "invert-order", false,
"if true, merge Resources in the reverse order")
@@ -64,5 +65,5 @@ func (r *MergeRunner) runE(c *cobra.Command, args []string) error {
}
filters := []kio.Filter{filters.MergeFilter{}, filters.FormatFilter{}}
return handleError(c, kio.Pipeline{Inputs: inputs, Filters: filters, Outputs: outputs}.Execute())
return runner.HandleError(c, kio.Pipeline{Inputs: inputs, Filters: filters, Outputs: outputs}.Execute())
}

View File

@@ -6,6 +6,7 @@ package commands
import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/kio/filters"
)
@@ -18,7 +19,7 @@ func GetMerge3Runner(name string) *Merge3Runner {
Example: commands.Merge3Examples,
RunE: r.runE,
}
fixDocs(name, c)
runner.FixDocs(name, c)
c.Flags().StringVar(&r.ancestor, "ancestor", "",
"Path to original package")
c.Flags().StringVar(&r.fromDir, "from", "",

View File

@@ -9,6 +9,7 @@ import (
"strings"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil"
@@ -29,7 +30,7 @@ func GetRunFnRunner(name string) *RunFnRunner {
RunE: r.runE,
PreRunE: r.preRunE,
}
fixDocs(name, c)
runner.FixDocs(name, c)
c.Flags().BoolVar(&r.IncludeSubpackages, "include-subpackages", true,
"also print resources from subpackages.")
r.Command = c
@@ -70,6 +71,8 @@ func GetRunFnRunner(name string) *RunFnRunner {
r.Command.Flags().StringArrayVarP(
&r.Env, "env", "e", []string{},
"a list of environment variables to be used by functions")
r.Command.Flags().BoolVar(
&r.AsCurrentUser, "as-current-user", false, "use the uid and gid that kpt is running with to run the function in the container")
return r
}
@@ -97,10 +100,11 @@ type RunFnRunner struct {
Mounts []string
LogSteps bool
Env []string
AsCurrentUser bool
}
func (r *RunFnRunner) runE(c *cobra.Command, args []string) error {
return handleError(c, r.RunFns.Execute())
return runner.HandleError(c, r.RunFns.Execute())
}
// getContainerFunctions parses the commandline flags and arguments into explicit
@@ -312,6 +316,7 @@ func (r *RunFnRunner) preRunE(c *cobra.Command, args []string) error {
ResultsDir: r.ResultsDir,
LogSteps: r.LogSteps,
Env: r.Env,
AsCurrentUser: r.AsCurrentUser,
}
// don't consider args for the function

View File

@@ -300,6 +300,16 @@ apiVersion: v1
Env: []string{"FOO=BAR", "BAR"},
},
},
{
name: "as current user",
args: []string{"run", "dir", "--as-current-user"},
path: "dir",
expectedStruct: &runfn.RunFns{
Path: "dir",
AsCurrentUser: true,
Env: []string{},
},
},
}
for i := range tests {

View File

@@ -6,6 +6,7 @@ package commands
import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/kioutil"
)
@@ -21,7 +22,7 @@ func GetSinkRunner(name string) *SinkRunner {
RunE: r.runE,
Args: cobra.MaximumNArgs(1),
}
fixDocs(name, c)
runner.FixDocs(name, c)
r.Command = c
return r
}
@@ -49,5 +50,5 @@ func (r *SinkRunner) runE(c *cobra.Command, args []string) error {
err := kio.Pipeline{
Inputs: []kio.Reader{&kio.ByteReader{Reader: c.InOrStdin()}},
Outputs: outputs}.Execute()
return handleError(c, err)
return runner.HandleError(c, err)
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
@@ -22,7 +23,7 @@ func GetSourceRunner(name string) *SourceRunner {
Example: commands.SourceExamples,
RunE: r.runE,
}
fixDocs(name, c)
runner.FixDocs(name, c)
c.Flags().StringVar(&r.WrapKind, "wrap-kind", kio.ResourceListKind,
"output using this format.")
c.Flags().StringVar(&r.WrapApiVersion, "wrap-version", kio.ResourceListAPIVersion,
@@ -78,5 +79,5 @@ func (r *SourceRunner) runE(c *cobra.Command, args []string) error {
}
err := kio.Pipeline{Inputs: inputs, Outputs: outputs}.Execute()
return handleError(c, err)
return runner.HandleError(c, err)
}

View File

@@ -9,6 +9,7 @@ import (
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/cmd/config/runner"
"sigs.k8s.io/kustomize/kyaml/kio/filters"
"github.com/spf13/cobra"
@@ -26,7 +27,7 @@ func GetTreeRunner(name string) *TreeRunner {
RunE: r.runE,
Args: cobra.MaximumNArgs(1),
}
fixDocs(name, c)
runner.FixDocs(name, c)
// TODO(pwittrock): Figure out if these are the right things to expose, and consider making it
// a list of options instead of individual flags
@@ -91,7 +92,7 @@ func (r *TreeRunner) runE(c *cobra.Command, args []string) error {
var fields []kio.TreeWriterField
for _, field := range r.fields {
path, err := parseFieldPath(field)
path, err := runner.ParseFieldPath(field)
if err != nil {
return err
}
@@ -155,7 +156,7 @@ func (r *TreeRunner) runE(c *cobra.Command, args []string) error {
ExcludeNonLocalConfig: r.excludeNonLocal,
}}
return handleError(c, kio.Pipeline{
return runner.HandleError(c, kio.Pipeline{
Inputs: []kio.Reader{input},
Filters: fltrs,
Outputs: []kio.Writer{kio.TreeWriter{

View File

@@ -35,22 +35,26 @@ var CatExamples = `
# unwrap Resource config from a directory in an ResourceList
... | kustomize cfg cat`
var CompletionShort = `Install shell completion.`
var CompletionShort = `Generate shell completion.`
var CompletionLong = `
Install shell completion for kustomize commands and flags -- supports bash, fish and zsh.
Generate shell completion for ` + "`" + `kustomize` + "`" + ` -- supports bash, zsh, fish and powershell.
`
var CompletionExamples = `
# load completion for Bash
source <(kustomize completion bash)
kustomize install-completion
# install for Bash in Linux
kustomize completion bash > /etc/bash_completion.d/kustomize
Registers the completion command with known shells (e.g. .bashrc, .bash_profile, etc):
# install for Bash in MacOS
kustomize completion bash > /usr/local/etc/bash_completion.d/kustomize
complete -C /Users/USER/go/bin/kustomize kustomize
# package for Bash
kustomize completion bash > /usr/share/bash-completion/completions/kustomize
Because the completion command is embedded in kustomize directly, there is no need to update
it separately from the kustomize binary.
To uninstall shell completion run:
COMP_UNINSTALL=1 kustomize install-completion`
# package for zsh
kustomize completion zsh > /usr/share/zsh/site-functions/_kustomize
`
var CountShort = `[Alpha] Count Resources Config from a local directory.`
var CountLong = `

View File

@@ -1,7 +1,7 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
//
package commands
package runner
import (
"fmt"
@@ -17,72 +17,72 @@ import (
"sigs.k8s.io/kustomize/kyaml/pathutil"
)
// cmdRunner interface holds executeCmd definition which executes respective command's
// CmdRunner interface holds ExecuteCmd definition which executes respective command's
// implementation on single package
type cmdRunner interface {
executeCmd(w io.Writer, pkgPath string) error
type CmdRunner interface {
ExecuteCmd(w io.Writer, pkgPath string) error
}
// executeCmdOnPkgs struct holds the parameters necessary to
// 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
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
// 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)
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 {
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)
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}
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...)
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 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)
if !e.SkipPkgPathPrint {
fmt.Fprintf(e.Writer, "%s/\n", pkgPath)
}
err := e.cmdRunner.executeCmd(e.writer, pkgPath)
err := e.CmdRunner.ExecuteCmd(e.Writer, pkgPath)
if err != nil {
return err
}
if i != len(pkgsPaths)-1 {
fmt.Fprint(e.writer, "\n")
fmt.Fprint(e.Writer, "\n")
}
// Delete schema present in openAPI file for current package
if e.needOpenAPI {
if e.NeedOpenAPI {
if err := openapi.DeleteSchemaInFile(filepath.Join(pkgPath, ext.KRMFileName())); err != nil {
return err
}
@@ -91,8 +91,8 @@ func (e executeCmdOnPkgs) execute() error {
return nil
}
// parseFieldPath parse a flag value into a field path
func parseFieldPath(path string) ([]string, error) {
// ParseFieldPath parse a flag value into a field path
func ParseFieldPath(path string) ([]string, error) {
// fixup '\.' so we don't split on it
match := strings.ReplaceAll(path, "\\.", "$$$$")
parts := strings.Split(match, ".")
@@ -118,7 +118,7 @@ func parseFieldPath(path string) ([]string, error) {
return newParts, nil
}
func handleError(c *cobra.Command, err error) error {
func HandleError(c *cobra.Command, err error) error {
if err == nil {
return nil
}
@@ -145,7 +145,7 @@ var StackOnError bool
const cmdName = "kustomize config"
// FixDocs replaces instances of old with new in the docs for c
func fixDocs(new string, c *cobra.Command) {
func FixDocs(new string, c *cobra.Command) {
c.Use = strings.ReplaceAll(c.Use, cmdName, new)
c.Short = strings.ReplaceAll(c.Short, cmdName, new)
c.Long = strings.ReplaceAll(c.Long, cmdName, new)

View File

@@ -1,7 +1,7 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package commands
package runner
import (
"bytes"
@@ -76,14 +76,14 @@ ${baseDir}/subpkg2/subpkg3/
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,
e := ExecuteCmdOnPkgs{
NeedOpenAPI: test.needOpenAPI,
Writer: actual,
RootPkgPath: filepath.Join(dir, test.pkgPath),
RecurseSubPackages: test.recurse,
CmdRunner: r,
}
err := e.execute()
err := e.Execute()
if test.errMsg == "" {
if !assert.NoError(t, err) {
t.FailNow()
@@ -170,7 +170,7 @@ func createTestDirStructure(dir string) error {
type TestRunner struct{}
func (r *TestRunner) executeCmd(w io.Writer, pkgPath string) error {
func (r *TestRunner) ExecuteCmd(w io.Writer, pkgPath string) error {
children, err := ioutil.ReadDir(pkgPath)
if err != nil {
return err

15
cmd/gorepomod/Makefile Normal file
View File

@@ -0,0 +1,15 @@
MYGOBIN := $(shell go env GOPATH)/bin
$(MYGOBIN)/gorepomod: usage.go
go install .
.PHONY: test
test: $(MYGOBIN)/gorepomod
go test ./...
usage.go: README.md $(MYGOBIN)/goimports
go generate . \
$(MYGOBIN)/goimports -w usage.go
$(MYGOBIN)/goimports:
go install golang.org/x/tools/cmd/goimports

103
cmd/gorepomod/README.md Normal file
View File

@@ -0,0 +1,103 @@
# gorepomod
Helps when you have a git repository with multiple Go modules.
It handles tasks one might otherwise attempt with
```
find ./ -name "go.mod" | xargs {some hack}
```
Run it from a git repository root.
It walks the repository, reads `go.mod` files, builds
a model of Go modules and intra-repo module
dependencies, then performs some operation.
Install:
```
go get sigs.k8s.io/kustomize/cmd/gorepomod
```
## Usage
_Commands that change things (everything but `list`)
do nothing but log commands
unless you add the `--doIt` flag,
allowing the change._
#### `gorepomod list`
Lists modules and intra-repo dependencies.
Use this to get module names for use in other commands.
#### `gorepomod tidy`
Creates a change with mechanical updates
to `go.mod` and `go.sum` files.
#### `gorepomod unpin {module}`
Creates a change to `go.mod` files.
For each module _m_ in the repository,
if _m_ depends on a _{module}_,
then _m_'s dependency on it will be replaced by
a relative path to the in-repo module.
#### `gorepomod pin {module} [{version}]`
Creates a change to `go.mod` files.
The opposite of `unpin`.
The change removes replacements and pins _m_ to a
specific, previously tagged and released version of _{module}_.
The argument _{version}_ defaults to recent version of _{module}_.
_{version}_ should be in semver form, e.g. `v1.2.3`.
#### `gorepomod release {module} [patch|minor|major]`
Computes a new version for the module, tags the repo
with that version, and pushes the tag to the remote.
The value of the 2nd argument, either `patch` (the default),
`minor` or `major`, determines the new version.
If the existing version is _v1.2.7_, then the new version will be:
- `patch` -> _v1.2.8_
- `minor` -> _v1.3.0_
- `major` -> _v2.0.0_
After establishing the the version, the command looks for a branch named
> _release-{module}/-v{major}.{minor}_
If the branch doesn't exist, the command creates it and pushes it to the remote.
The command then creates a new tag in the form
> _{module}/v{major}.{minor}.{patch}_
The command pushes this tag to the remote. This typically triggers
cloud activity to create release artifacts.
#### `gorepomod unrelease {module}`
This undoes the work of `release`, by deleting the
most recent tag both locally and at the remote.
You can then fix whatever, and re-release.
This, however, must be done almost immediately.
If there's a chance someone (or some cloud robot) already
imported the module at the given tag, then don't do this,
because it will confuse module caches.
Do a new patch release instead.

5
cmd/gorepomod/go.mod Normal file
View File

@@ -0,0 +1,5 @@
module sigs.k8s.io/kustomize/cmd/gorepomod
go 1.15
require golang.org/x/mod v0.3.0

14
cmd/gorepomod/go.sum Normal file
View File

@@ -0,0 +1,14 @@
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
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-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@@ -0,0 +1,195 @@
package arguments
import (
"fmt"
"os"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/semver"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/utils"
)
const (
doItFlag = "--doIt"
cmdPin = "pin"
cmdUnPin = "unpin"
cmdTidy = "tidy"
cmdList = "list"
cmdRelease = "release"
cmdUnRelease = "unrelease"
cmdDebug = "debug"
)
var (
commands = []string{
cmdPin, cmdUnPin, cmdTidy, cmdList, cmdRelease, cmdUnRelease, cmdDebug}
// TODO: make this a PATH-like flag
// e.g.: --excludes ".git:.idea:site:docs"
excSlice = []string{
".git",
".github",
".idea",
"docs",
"examples",
"hack",
"site",
"releasing",
}
)
type Command int
const (
Tidy Command = iota
UnPin
Pin
List
Release
UnRelease
Debug
)
type Args struct {
cmd Command
moduleName misc.ModuleShortName
version semver.SemVer
bump semver.SvBump
doIt bool
}
func (a *Args) GetCommand() Command {
return a.cmd
}
func (a *Args) Bump() semver.SvBump {
return a.bump
}
func (a *Args) Version() semver.SemVer {
return a.version
}
func (a *Args) ModuleName() misc.ModuleShortName {
return a.moduleName
}
func (a *Args) Exclusions() (result []string) {
// Make sure the list has no repeats.
for k := range utils.SliceToSet(excSlice) {
result = append(result, k)
}
return
}
func (a *Args) DoIt() bool {
return a.doIt
}
type myArgs struct {
args []string
doIt bool
}
func (a *myArgs) next() (result string) {
if !a.more() {
panic("no args left")
}
result = a.args[0]
a.args = a.args[1:]
return
}
func (a *myArgs) more() bool {
return len(a.args) > 0
}
func newArgs() *myArgs {
result := &myArgs{}
for _, a := range os.Args[1:] {
if a == doItFlag {
result.doIt = true
} else {
result.args = append(result.args, a)
}
}
return result
}
func Parse() (result *Args, err error) {
result = &Args{}
clArgs := newArgs()
result.doIt = clArgs.doIt
result.moduleName = misc.ModuleUnknown
if !clArgs.more() {
return nil, fmt.Errorf("command needs at least one arg")
}
command := clArgs.next()
switch command {
case cmdPin:
if !clArgs.more() {
return nil, fmt.Errorf("pin needs a moduleName to pin")
}
result.moduleName = misc.ModuleShortName(clArgs.next())
if clArgs.more() {
result.version, err = semver.Parse(clArgs.next())
if err != nil {
return nil, err
}
} else {
result.version = semver.Zero()
}
result.cmd = Pin
case cmdUnPin:
if !clArgs.more() {
return nil, fmt.Errorf("unpin needs a moduleName to unpin")
}
result.moduleName = misc.ModuleShortName(clArgs.next())
result.cmd = UnPin
case cmdTidy:
result.cmd = Tidy
case cmdList:
result.cmd = List
case cmdRelease:
if !clArgs.more() {
return nil, fmt.Errorf("specify {module} to release")
}
result.moduleName = misc.ModuleShortName(clArgs.next())
bump := "patch"
if clArgs.more() {
bump = clArgs.next()
}
switch bump {
case "major":
result.bump = semver.Major
case "minor":
result.bump = semver.Minor
case "patch":
result.bump = semver.Patch
default:
return nil, fmt.Errorf(
"unknown bump %s; specify one of 'major', 'minor' or 'patch'", bump)
}
result.cmd = Release
case cmdUnRelease:
if !clArgs.more() {
return nil, fmt.Errorf("specify {module} to unrelease")
}
result.moduleName = misc.ModuleShortName(clArgs.next())
result.cmd = UnRelease
case cmdDebug:
if !clArgs.more() {
return nil, fmt.Errorf("specify {module} to debug")
}
result.moduleName = misc.ModuleShortName(clArgs.next())
result.cmd = Debug
default:
return nil, fmt.Errorf(
"unknown command %q; must be one of %v", command, commands)
}
if clArgs.more() {
return nil, fmt.Errorf("unknown extra args: %v", clArgs.args)
}
return
}

View File

@@ -0,0 +1,82 @@
package edit
import (
"fmt"
"os/exec"
"strings"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/semver"
)
// Editor runs `go mod` commands on an instance of Module.
// If doIt is false, the command is printed, but not run.
type Editor struct {
module misc.LaModule
doIt bool
}
func New(m misc.LaModule, doIt bool) *Editor {
return &Editor{
doIt: doIt,
module: m,
}
}
func (e *Editor) run(args ...string) error {
c := exec.Command(
"go",
append([]string{"mod"}, args...)...)
c.Dir = string(e.module.ShortName())
if e.doIt {
out, err := c.CombinedOutput()
if err != nil {
return fmt.Errorf("%s out=%q", err.Error(), out)
}
} else {
fmt.Printf("in %-60s; %s\n", c.Dir, c.String())
}
return nil
}
func upstairs(depth int) string {
var b strings.Builder
for i := 0; i < depth; i++ {
b.WriteString("../")
}
return b.String()
}
func (e *Editor) Tidy() error {
return e.run("tidy")
}
func (e *Editor) Pin(target misc.LaModule, oldV, newV semver.SemVer) error {
err := e.run(
"edit",
"-dropreplace="+target.ImportPath()+"@"+oldV.String(),
"-require="+target.ImportPath()+"@"+newV.String(),
)
if err != nil {
return err
}
return e.run("tidy")
}
func (e *Editor) UnPin(target misc.LaModule, oldV semver.SemVer) error {
var r strings.Builder
r.WriteString(target.ImportPath())
r.WriteString("@")
r.WriteString(oldV.String())
r.WriteString("=")
r.WriteString(upstairs(e.module.ShortName().Depth()))
r.WriteString(string(target.ShortName()))
err := e.run(
"edit",
"-replace="+r.String(),
)
if err != nil {
return err
}
return e.run("tidy")
}

View File

@@ -0,0 +1,32 @@
package edit
import (
"testing"
)
func TestUpstairs(t *testing.T) {
var testCases = map[string]struct {
depth int
expected string
}{
"zero": {
depth: 0,
expected: "",
},
"one": {
depth: 1,
expected: "../",
},
"five": {
depth: 5,
expected: "../../../../../",
},
}
for n, tc := range testCases {
if tc.expected != upstairs(tc.depth) {
t.Fatalf(
"%s: for depth %d, expected %q, got %q",
n, tc.depth, tc.expected, upstairs(tc.depth))
}
}
}

View File

@@ -0,0 +1,75 @@
package main
import (
"bufio"
"log"
"os"
"strings"
)
const (
inputFile = "README.md"
outputFile = "usage.go"
)
// Convert README.md to a usage function.
func main() {
inFile, err := os.Open(inputFile)
if err != nil {
log.Fatal(err)
}
defer inFile.Close()
scanner := bufio.NewScanner(inFile)
w := NewWriter(outputFile)
w.prLn("// Code generated by internal/gen/main.go; DO NOT EDIT.")
w.prLn("package main")
w.prLn("")
w.prLn("")
w.prLn("const (")
w.prLn(" usageMsg = `")
// Skip the first two lines.
scanner.Scan()
scanner.Scan()
for scanner.Scan() {
line := scanner.Text()
line = strings.Replace(line, "`", "'", -1)
line = strings.Replace(line, "\\[", "[", -1)
line = strings.Replace(line, "\\]", "]", -1)
w.prLn(line)
}
w.prLn("`")
w.prLn(")")
w.close()
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
}
type writer struct {
f *os.File
}
func NewWriter(n string) *writer {
f, err := os.Create(n)
if err != nil {
log.Fatalf("unable to create `%s`; %v", n, err)
}
return &writer{f: f}
}
func (w *writer) prLn(line string) {
_, err := w.f.WriteString(line + "\n")
if err != nil {
log.Printf("Trouble writing: %s", line)
log.Fatal(err)
}
}
func (w *writer) close() {
if err := w.f.Close(); err != nil {
log.Fatal(err)
}
}

View File

@@ -0,0 +1,340 @@
package git
import (
"fmt"
"os/exec"
"sort"
"strings"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/semver"
)
const (
refsTags = "refs/tags/"
pathSep = "/"
remoteOrigin = misc.TrackedRepo("origin")
remoteUpstream = misc.TrackedRepo("upstream")
mainBranch = "master"
indent = " "
doing = " [x] "
faking = " [ ] "
)
type safetyLevel int
const (
// Commands that don't hurt, e.g. checking out an existing branch.
noHarmDone safetyLevel = iota
// Commands that write, and could be hard to undo.
undoPainful
)
type Verbosity int
const (
Low Verbosity = iota
High
)
var recognizedRemotes = []misc.TrackedRepo{remoteUpstream, remoteOrigin}
// Runner runs specific git tasks using the git CLI.
type Runner struct {
// From which directory do we run the commands.
workDir string
// Run commands, or merely print commands.
doIt bool
// Run commands, or merely print commands.
verbosity Verbosity
}
func NewLoud(wd string, doIt bool) *Runner {
return newRunner(wd, doIt, High)
}
func NewQuiet(wd string, doIt bool) *Runner {
return newRunner(wd, doIt, Low)
}
func newRunner(wd string, doIt bool, v Verbosity) *Runner {
return &Runner{workDir: wd, doIt: doIt, verbosity: v}
}
func (gr *Runner) comment(f string) {
if gr.verbosity == Low {
return
}
fmt.Print(indent)
fmt.Println(f)
}
func (gr *Runner) doing(s string) {
if gr.verbosity == Low {
return
}
fmt.Print(indent)
fmt.Print(doing)
fmt.Println(s)
}
func (gr *Runner) faking(s string) {
if gr.verbosity == Low {
return
}
fmt.Print(indent)
fmt.Print(faking)
fmt.Println(s)
}
func (gr *Runner) run(sl safetyLevel, args ...string) (string, error) {
c := exec.Command("git", args...)
c.Dir = gr.workDir
if gr.doIt || sl == noHarmDone {
gr.doing(c.String())
out, err := c.CombinedOutput()
if err != nil {
return "", fmt.Errorf(
"%s out=%q", err.Error(), strings.TrimSpace(string(out)))
}
return string(out), nil
}
gr.faking(c.String())
return "", nil
}
func (gr *Runner) runNoOut(s safetyLevel, args ...string) error {
_, err := gr.run(s, args...)
return err
}
// TODO: allow for other remote names.
func (gr *Runner) DetermineRemoteToUse() (misc.TrackedRepo, error) {
gr.comment("determining remote to use")
out, err := gr.run(noHarmDone, "remote")
if err != nil {
return "", err
}
remotes := strings.Split(out, "\n")
if len(remotes) < 1 {
return "", fmt.Errorf("need at least one remote")
}
for _, n := range recognizedRemotes {
if contains(remotes, n) {
return n, nil
}
}
return "", fmt.Errorf(
"unable to find recognized remote %v", recognizedRemotes)
}
func contains(list []string, item misc.TrackedRepo) bool {
for _, n := range list {
if n == string(item) {
return true
}
}
return false
}
func (gr *Runner) LoadLocalTags() (result misc.VersionMap, err error) {
gr.comment("loading local tags")
var out string
out, err = gr.run(noHarmDone, "tag", "-l")
if err != nil {
return nil, err
}
result = make(misc.VersionMap)
lines := strings.Split(out, "\n")
for _, l := range lines {
n, v, err := parseModuleSpec(l)
if err != nil {
// ignore it
continue
}
result[n] = append(result[n], v)
}
for _, versions := range result {
sort.Sort(versions)
}
return
}
func (gr *Runner) LoadRemoteTags(
remote misc.TrackedRepo) (result misc.VersionMap, err error) {
gr.comment("loading remote tags")
var out string
out, err = gr.run(noHarmDone, "ls-remote", "--ref", string(remote))
if err != nil {
return nil, err
}
result = make(misc.VersionMap)
lines := strings.Split(out, "\n")
for _, l := range lines {
fields := strings.Fields(l)
if len(fields) < 2 {
// ignore it
continue
}
if !strings.HasPrefix(fields[1], refsTags) {
// ignore it
continue
}
path := fields[1][len(refsTags):]
n, v, err := parseModuleSpec(path)
if err != nil {
// ignore it
continue
}
result[n] = append(result[n], v)
}
for _, versions := range result {
sort.Sort(versions)
}
return
}
func parseModuleSpec(
path string) (n misc.ModuleShortName, v semver.SemVer, err error) {
fields := strings.Split(path, pathSep)
v, err = semver.Parse(fields[len(fields)-1])
if err != nil {
// Silently ignore versions we don't understand.
return "", v, err
}
n = misc.ModuleAtTop
if len(fields) > 1 {
n = misc.ModuleShortName(
strings.Join(fields[:len(fields)-1], pathSep))
}
return
}
func (gr *Runner) Debug(remote misc.TrackedRepo) error {
return nil // gr.CheckoutMainBranch(remote)
}
func (gr *Runner) AssureCleanWorkspace() error {
gr.comment("assuring a clean workspace")
out, err := gr.run(noHarmDone, "status")
if err != nil {
return err
}
if !strings.Contains(out, "nothing to commit, working tree clean") {
return fmt.Errorf("the workspace isn't clean")
}
return nil
}
func (gr *Runner) AssureOnMainBranch() error {
gr.comment("assuring main branch checked out")
out, err := gr.run(noHarmDone, "status")
if err != nil {
return err
}
if !strings.Contains(out, "On branch "+mainBranch) {
return fmt.Errorf("expected to be on branch %q", mainBranch)
}
return nil
}
// CheckoutMainBranch does that.
func (gr *Runner) CheckoutMainBranch() error {
gr.comment("checking out main branch")
return gr.runNoOut(noHarmDone, "checkout", mainBranch)
}
// FetchRemote does that.
func (gr *Runner) FetchRemote(remote misc.TrackedRepo) error {
gr.comment("fetching remote")
return gr.runNoOut(noHarmDone, "fetch", string(remote))
}
// MergeFromRemoteMain does a fast forward only merge with main branch.
func (gr *Runner) MergeFromRemoteMain(remote misc.TrackedRepo) error {
remo := strings.Join(
[]string{string(remote), mainBranch}, pathSep)
gr.comment("merging from remote")
return gr.runNoOut(undoPainful, "merge", "--ff-only", remo)
}
// CheckoutReleaseBranch attempts to checkout or create a branch.
// If it's on the remote already, fail if we cannot check it out locally.
func (gr *Runner) CheckoutReleaseBranch(
remote misc.TrackedRepo, branch string) error {
yes, err := gr.doesRemoteBranchExist(remote, branch)
if err != nil {
return err
}
if yes {
gr.comment("checking out branch")
if out, err := gr.run(noHarmDone, "checkout", branch); err != nil {
fmt.Printf("error with checkout: %q", err.Error())
fmt.Printf("out: %q", out)
return fmt.Errorf(
"branch %q exists on remote %q, but isn't present locally",
branch, string(remote))
}
return nil
}
gr.comment("creating branch")
// The branch doesn't exist. Create it.
out, err := gr.run(noHarmDone, "checkout", "-b", branch)
if err != nil {
return err
}
if !strings.Contains(out, "Switched to a new branch ") {
return fmt.Errorf("unexpected branch creation output: %q", out)
}
return nil
}
func (gr *Runner) doesRemoteBranchExist(
remote misc.TrackedRepo, branch string) (bool, error) {
gr.comment("looking for branch on remote")
out, err := gr.run(noHarmDone, "branch", "-r")
if err != nil {
return false, err
}
lookFor := strings.Join([]string{string(remote), branch}, pathSep)
lines := strings.Split(out, "\n")
for _, l := range lines {
if strings.TrimSpace(l) == lookFor {
return true, nil
}
}
return false, nil
}
func (gr *Runner) PushBranchToRemote(
remote misc.TrackedRepo, branch string) error {
gr.comment("pushing branch to remote")
return gr.runNoOut(undoPainful, "push", "-f", string(remote), branch)
}
func (gr *Runner) CreateLocalReleaseTag(tag, branch string) error {
msg := fmt.Sprintf("\"Release %s on branch %s\"", tag, branch)
gr.comment("creating local release tag")
return gr.runNoOut(
undoPainful,
"tag", "-a",
"-m", msg,
tag)
}
func (gr *Runner) DeleteLocalTag(tag string) error {
gr.comment("deleting local tag")
return gr.runNoOut(undoPainful, "tag", "--delete", tag)
}
func (gr *Runner) PushTagToRemote(
remote misc.TrackedRepo, tag string) error {
gr.comment("pushing tag to remote")
return gr.runNoOut(undoPainful, "push", string(remote), tag)
}
func (gr *Runner) DeleteTagFromRemote(
remote misc.TrackedRepo, tag string) error {
gr.comment("deleting tags from remote")
return gr.runNoOut(undoPainful, "push", string(remote), ":"+refsTags+tag)
}

View File

@@ -0,0 +1,126 @@
package misc
import (
"fmt"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/semver"
)
// ModFunc is a function accepting a module, and returning an error.
type ModFunc func(LaModule) error
type LaRepository interface {
// RepoPath is the import of the of repository,
// e.g. github.com/kubernetes-sigs/kustomize
// The directory {srcRoot}/{importPath} should contain a
// dotGit directory.
// This directory might be a Go module, or contain directories
// that are Go modules, or both.
RepoPath() string
// AbsPath is the full local filesystem path.
AbsPath() string
// FindModule returns a module or nil.
FindModule(ModuleShortName) LaModule
}
type LaModule interface {
// ShortName is the module's name without the repo.
ShortName() ModuleShortName
// ImportPath is the relative path below the Go src root,
// which is the same path as would be used to
// import the module.
ImportPath() string
// AbsPath is the absolute path to the module's
// go.mod file on the local file system.
AbsPath() string
// Latest version tagged locally.
VersionLocal() semver.SemVer
// Latest version tagged remotely.
VersionRemote() semver.SemVer
// Does this module depend on the argument, and
// if so at what version?
DependsOn(LaModule) (bool, semver.SemVer)
// GetReplacements returns a list of replacements.
GetReplacements() []string
}
// VersionMap holds the versions associated with modules.
type VersionMap map[ModuleShortName]semver.Versions
func (m VersionMap) Report() {
for n, versions := range m {
fmt.Println(n)
for _, v := range versions {
fmt.Print(" ")
fmt.Println(v)
}
}
}
func (m VersionMap) Latest(
n ModuleShortName) semver.SemVer {
versions := m[n]
if versions == nil {
return semver.Zero()
}
return versions[0]
}
type LesModules []LaModule
func (s LesModules) LenLongestName() (ans int) {
for _, m := range s {
l := len(m.ShortName())
if l > ans {
ans = l
}
}
return
}
func (s LesModules) Apply(f ModFunc) error {
for _, m := range s {
err := f(m)
if err != nil {
return err
}
}
return nil
}
func (s LesModules) Find(target ModuleShortName) LaModule {
for _, m := range s {
if m.ShortName() == target {
return m
}
}
return nil
}
func (s LesModules) GetAllThatDependOn(
target LaModule) (result TaggedModules) {
for _, m := range s {
if yes, v := m.DependsOn(target); yes {
result = append(result, TaggedModule{M: m, V: v})
}
}
return
}
func (s LesModules) InternalDeps(
target LaModule) (result TaggedModules) {
for _, m := range s {
if yes, v := target.DependsOn(m); yes {
result = append(result, TaggedModule{M: m, V: v})
}
}
return
}

View File

@@ -0,0 +1,23 @@
package misc
import (
"path/filepath"
"strings"
)
// ModuleShortName is the in-repo path to the directory holding the module
// (holding the go.mod file). It's the unique in-repo name of the module.
// It's the name used to tag the repo at a particular module version.
// E.g. "" (empty), "kyaml", "cmd/config", "plugin/example/whatever".
type ModuleShortName string
// Never used in a tag.
const ModuleAtTop = ModuleShortName("{top}")
const ModuleUnknown = ModuleShortName("{unknown}")
func (m ModuleShortName) Depth() int {
if m == ModuleAtTop || m == ModuleUnknown {
return 0
}
return strings.Count(string(m), string(filepath.Separator)) + 1
}

View File

@@ -0,0 +1,36 @@
package misc_test
import (
"testing"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
)
func TestDepth(t *testing.T) {
var testCases = map[string]struct {
path string
expectedDepth int
}{
"zero": {
path: "{top}",
expectedDepth: 0,
},
"one": {
path: "one",
expectedDepth: 1,
},
"three": {
path: "one/two/three",
expectedDepth: 3,
},
}
for n, tc := range testCases {
m := misc.ModuleShortName(tc.path)
d := m.Depth()
if d != tc.expectedDepth {
t.Fatalf(
"%s: %s, expected %d, got %d",
n, tc.path, tc.expectedDepth, d)
}
}
}

View File

@@ -0,0 +1,42 @@
package misc
import (
"fmt"
"strings"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/semver"
)
// TaggedModule is a module known to be tagged with the given version.
type TaggedModule struct {
M LaModule
V semver.SemVer
}
func (p TaggedModule) String() string {
if p.V.IsZero() {
return string(p.M.ShortName())
}
return string(p.M.ShortName()) + "/" + p.V.String()
}
type TaggedModules []TaggedModule
func (s TaggedModules) String() string {
// format := "%-"+strconv.Itoa(s.LenLongestString()+2)+"s"
var b strings.Builder
for i := range s {
b.WriteString(fmt.Sprintf("%-15s", s[i]))
}
return b.String()
}
func (s TaggedModules) LenLongestString() (ans int) {
for _, m := range s {
l := len(m.String())
if l > ans {
ans = l
}
}
return
}

View File

@@ -0,0 +1,4 @@
package misc
// TrackedRepo identifies a git remote repository.
type TrackedRepo string

View File

@@ -0,0 +1,79 @@
package mod
import (
"fmt"
"path/filepath"
"golang.org/x/mod/modfile"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/semver"
)
// Module is an immutable representation of a Go module.
type Module struct {
repo misc.LaRepository
shortName misc.ModuleShortName
mf *modfile.File
vLocal semver.SemVer
vRemote semver.SemVer
}
func New(
repo misc.LaRepository,
shortName misc.ModuleShortName,
mf *modfile.File,
vl semver.SemVer,
vr semver.SemVer) *Module {
return &Module{
repo: repo,
shortName: shortName,
mf: mf,
vLocal: vl,
vRemote: vr,
}
}
func (m *Module) GitRepo() misc.LaRepository {
return m.repo
}
func (m *Module) VersionLocal() semver.SemVer {
return m.vLocal
}
func (m *Module) VersionRemote() semver.SemVer {
return m.vRemote
}
func (m *Module) ShortName() misc.ModuleShortName {
return m.shortName
}
func (m *Module) ImportPath() string {
return filepath.Join(m.repo.RepoPath(), string(m.ShortName()))
}
func (m *Module) AbsPath() string {
return filepath.Join(m.repo.AbsPath(), string(m.ShortName()))
}
func (m *Module) DependsOn(target misc.LaModule) (bool, semver.SemVer) {
for _, r := range m.mf.Require {
if r.Mod.Path == target.ImportPath() {
v, err := semver.Parse(r.Mod.Version)
if err != nil {
panic(err)
}
return true, v
}
}
return false, semver.Zero()
}
func (m *Module) GetReplacements() (result []string) {
for _, r := range m.mf.Replace {
result = append(
result, fmt.Sprintf("%s => %s", r.Old.String(), r.New.String()))
}
return
}

View File

@@ -0,0 +1 @@
package mod_test

View File

@@ -0,0 +1,134 @@
package repo
import (
"fmt"
"path/filepath"
"strings"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/git"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/utils"
)
const (
dotGitFileName = ".git"
srcHint = "/src/"
goModFile = "go.mod"
)
// DotGitData holds basic information about a local .git file
type DotGitData struct {
// srcPath is the absolute path to the local Go src directory.
// This used to be $GOPATH/src.
// It's the directory containing git repository clones.
srcPath string
// The path below srcPath to a particular repository
// directory, a directory containing a .git directory.
// Typically {repoOrg}/{repoUserName}, e.g. sigs.k8s.io/cli-utils
repoPath string
}
func (dg *DotGitData) SrcPath() string {
return dg.srcPath
}
func (dg *DotGitData) RepoPath() string {
return dg.repoPath
}
func (dg *DotGitData) AbsPath() string {
return filepath.Join(dg.srcPath, dg.repoPath)
}
// NewDotGitDataFromPath wants the incoming path to hold dotGit
// E.g.
// ~/gopath/src/sigs.k8s.io/kustomize
// ~/gopath/src/github.com/monopole/gorepomod
func NewDotGitDataFromPath(path string) (*DotGitData, error) {
if !utils.DirExists(filepath.Join(path, dotGitFileName)) {
return nil, fmt.Errorf(
"%q doesn't have a %q file", path, dotGitFileName)
}
// This is an attempt to figure out where the user has cloned
// their repos. In the old days, it was an import path under
// $GOPATH/src. If we cannot guess it, we may need to ask for it,
// or maybe proceed without knowing it.
index := strings.Index(path, srcHint)
if index < 0 {
return nil, fmt.Errorf(
"path %q doesn't contain %q", path, srcHint)
}
return &DotGitData{
srcPath: path[:index+len(srcHint)-1],
repoPath: path[index+len(srcHint):],
}, nil
}
// It's a factory factory.
func (dg *DotGitData) NewRepoFactory(
exclusions []string) (*ManagerFactory, error) {
modules, err := loadProtoModules(dg.AbsPath(), exclusions)
if err != nil {
return nil, err
}
err = dg.checkModules(modules)
if err != nil {
return nil, err
}
runner := git.NewQuiet(dg.AbsPath(), true)
remoteName, err := runner.DetermineRemoteToUse()
if err != nil {
return nil, err
}
// Some tags might exist for modules that
// have been renamed or deleted; ignore those.
// There might be newer tags locally than remote,
// so report both.
localTags, err := runner.LoadLocalTags()
if err != nil {
return nil, err
}
remoteTags, err := runner.LoadRemoteTags(remoteName)
if err != nil {
return nil, err
}
return &ManagerFactory{
dg: dg,
modules: modules,
remoteName: remoteName,
versionMapLocal: localTags,
versionMapRemote: remoteTags,
}, nil
}
func (dg *DotGitData) checkModules(modules []*protoModule) error {
for _, pm := range modules {
file := filepath.Join(pm.PathToGoMod(), goModFile)
// Do the paths make sense?
if !strings.HasPrefix(pm.FullPath(), dg.RepoPath()) {
return fmt.Errorf(
"module %q doesn't start with the repository name %q",
pm.FullPath(), dg.RepoPath())
}
shortName := pm.ShortName(dg.RepoPath())
if shortName == misc.ModuleAtTop {
if pm.PathToGoMod() != dg.AbsPath() {
return fmt.Errorf("in %q, problem with top module", file)
}
} else {
// Do the relative path and short name make sense?
if !strings.HasSuffix(pm.PathToGoMod(), string(shortName)) {
return fmt.Errorf(
"in %q, the module name %q doesn't match the file's pathToGoMod %q",
file, shortName, pm.PathToGoMod())
}
}
}
return nil
}

View File

@@ -0,0 +1,6 @@
package repo
import "testing"
func TestLoadTags(t *testing.T) {
}

View File

@@ -0,0 +1,194 @@
package repo
import (
"fmt"
"strconv"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/edit"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/git"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/semver"
)
// Manager manages a git repo.
// All data already loaded and validated, it's ready to go.
type Manager struct {
// Underlying file system facts.
dg *DotGitData
// The remote used for fetching tags, pushing tags,
// and pushing release branches.
remoteName misc.TrackedRepo
// The list of known Go modules in the repo.
modules misc.LesModules
}
func (mgr *Manager) AbsPath() string {
return mgr.dg.AbsPath()
}
func (mgr *Manager) RepoPath() string {
return mgr.dg.RepoPath()
}
func (mgr *Manager) FindModule(
target misc.ModuleShortName) misc.LaModule {
return mgr.modules.Find(target)
}
func (mgr *Manager) Tidy(doIt bool) error {
return mgr.modules.Apply(func(m misc.LaModule) error {
return edit.New(m, doIt).Tidy()
})
}
func (mgr *Manager) Pin(
doIt bool, target misc.LaModule, newV semver.SemVer) error {
return mgr.modules.Apply(func(m misc.LaModule) error {
if yes, oldVersion := m.DependsOn(target); yes {
return edit.New(m, doIt).Pin(target, oldVersion, newV)
}
return nil
})
}
func (mgr *Manager) UnPin(doIt bool, target misc.LaModule) error {
return mgr.modules.Apply(func(m misc.LaModule) error {
if yes, oldVersion := m.DependsOn(target); yes {
return edit.New(m, doIt).UnPin(target, oldVersion)
}
return nil
})
}
func hasUnPinnedDeps(m misc.LaModule) string {
if len(m.GetReplacements()) > 0 {
return "yes"
}
return ""
}
func (mgr *Manager) List() error {
fmt.Printf(" src path: %s\n", mgr.dg.SrcPath())
fmt.Printf(" repo path: %s\n", mgr.RepoPath())
fmt.Printf(" remote: %s\n", mgr.remoteName)
format := "%-" +
strconv.Itoa(mgr.modules.LenLongestName()+2) +
"s%-11s%-11s%17s %s\n"
fmt.Printf(
format, "NAME", "LOCAL", "REMOTE",
"HAS-UNPINNED-DEPS", "INTRA-REPO-DEPENDENCIES")
return mgr.modules.Apply(func(m misc.LaModule) error {
fmt.Printf(
format, m.ShortName(),
m.VersionLocal().Pretty(),
m.VersionRemote().Pretty(),
hasUnPinnedDeps(m),
mgr.modules.InternalDeps(m))
return nil
})
}
func determineBranchAndTag(
m misc.LaModule, v semver.SemVer) (string, string) {
if m.ShortName() == misc.ModuleAtTop {
return fmt.Sprintf("release-%s", v.BranchLabel()), v.String()
}
return fmt.Sprintf(
"release-%s-%s", m.ShortName(), v.BranchLabel()),
string(m.ShortName()) + "/" + v.String()
}
func (mgr *Manager) Debug(_ misc.LaModule, doIt bool) error {
gr := git.NewLoud(mgr.AbsPath(), doIt)
return gr.Debug(mgr.remoteName)
}
// Release supports a gitlab flow style release process.
//
// * All development happens in the branch named "master".
// * Each minor release gets its own branch.
// *
func (mgr *Manager) Release(
target misc.LaModule, bump semver.SvBump, doIt bool) error {
if reps := target.GetReplacements(); len(reps) > 0 {
return fmt.Errorf(
"to release %q, first pin these replacements: %v",
target.ShortName(), reps)
}
newVersion := target.VersionLocal().Bump(bump)
if newVersion.Equals(target.VersionRemote()) {
return fmt.Errorf(
"version %s already exists on remote - delete it first", newVersion)
}
if newVersion.LessThan(target.VersionRemote()) {
fmt.Printf(
"version %s is less than the most recent remote version (%s)",
newVersion, target.VersionRemote())
}
gr := git.NewLoud(mgr.AbsPath(), doIt)
relBranch, relTag := determineBranchAndTag(target, newVersion)
fmt.Printf(
"Releasing %s, stepping from %s to %s\n",
target.ShortName(), target.VersionLocal(), newVersion)
if err := gr.AssureCleanWorkspace(); err != nil {
return err
}
if err := gr.FetchRemote(mgr.remoteName); err != nil {
return err
}
if err := gr.CheckoutMainBranch(); err != nil {
return err
}
if err := gr.MergeFromRemoteMain(mgr.remoteName); err != nil {
return err
}
if err := gr.AssureCleanWorkspace(); err != nil {
return err
}
if err := gr.CheckoutReleaseBranch(mgr.remoteName, relBranch); err != nil {
return err
}
if err := gr.MergeFromRemoteMain(mgr.remoteName); err != nil {
return err
}
if err := gr.PushBranchToRemote(mgr.remoteName, relBranch); err != nil {
return err
}
if err := gr.CreateLocalReleaseTag(relTag, relBranch); err != nil {
return err
}
if err := gr.PushTagToRemote(mgr.remoteName, relTag); err != nil {
return err
}
if err := gr.CheckoutMainBranch(); err != nil {
return err
}
return nil
}
func (mgr *Manager) UnRelease(target misc.LaModule, doIt bool) error {
fmt.Printf(
"Unreleasing %s/%s\n",
target.ShortName(), target.VersionRemote())
_, tag := determineBranchAndTag(target, target.VersionRemote())
gr := git.NewLoud(mgr.AbsPath(), doIt)
if err := gr.DeleteTagFromRemote(mgr.remoteName, tag); err != nil {
return err
}
if err := gr.DeleteLocalTag(tag); err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,35 @@
package repo
import (
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/mod"
)
// ManagerFactory is a collection of clean data needed to build
// clean, fully wired up instances of Manager.
type ManagerFactory struct {
dg *DotGitData
modules []*protoModule
remoteName misc.TrackedRepo
versionMapLocal misc.VersionMap
versionMapRemote misc.VersionMap
}
func (mf *ManagerFactory) NewRepoManager() *Manager {
result := &Manager{
dg: mf.dg,
remoteName: mf.remoteName,
}
var modules misc.LesModules
for _, pm := range mf.modules {
shortName := pm.ShortName(mf.dg.RepoPath())
modules = append(
modules,
mod.New(
result, shortName, pm.mf,
mf.versionMapLocal.Latest(shortName),
mf.versionMapRemote.Latest(shortName)))
}
result.modules = modules
return result
}

View File

@@ -0,0 +1,101 @@
package repo
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"golang.org/x/mod/modfile"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/utils"
)
const (
dotDir = "."
)
// protoModule holds parts being collected to represent a module.
type protoModule struct {
pathToGoMod string
mf *modfile.File
}
func (pm *protoModule) FullPath() string {
return pm.mf.Module.Mod.Path
}
func (pm *protoModule) PathToGoMod() string {
return pm.pathToGoMod
}
// Represents the trailing version label in a module name.
// See https://blog.golang.org/v2-go-modules
var trailingVersionPattern = regexp.MustCompile("/v\\d+$")
func (pm *protoModule) ShortName(
repoImportPath string) misc.ModuleShortName {
fp := pm.FullPath()
if fp == repoImportPath {
return misc.ModuleAtTop
}
p := fp[len(repoImportPath)+1:]
stripped := trailingVersionPattern.ReplaceAllString(p, "")
return misc.ModuleShortName(stripped)
}
func loadProtoModules(
repoRoot string, exclusions []string) (result []*protoModule, err error) {
var paths []string
paths, err = getPathsToModules(repoRoot, exclusions)
if err != nil {
return
}
for _, p := range paths {
var pm *protoModule
pm, err = loadProtoModule(p)
if err != nil {
return
}
result = append(result, pm)
}
return
}
func loadProtoModule(path string) (*protoModule, error) {
mPath := filepath.Join(path, goModFile)
content, err := ioutil.ReadFile(mPath)
if err != nil {
return nil, fmt.Errorf("error reading %q: %v\n", mPath, err)
}
f, err := modfile.Parse(mPath, content, nil)
if err != nil {
return nil, err
}
return &protoModule{pathToGoMod: path, mf: f}, nil
}
func getPathsToModules(
repoRoot string, exclusions []string) (result []string, err error) {
exclusionMap := utils.SliceToSet(exclusions)
err = filepath.Walk(
repoRoot,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("trouble at pathToGoMod %q: %v\n", path, err)
}
if info.IsDir() {
if _, ok := exclusionMap[info.Name()]; ok {
return filepath.SkipDir
}
return nil
}
if info.Name() == goModFile {
result = append(result, path[:len(path)-len(goModFile)-1])
return filepath.SkipDir
}
return nil
})
return
}

View File

@@ -0,0 +1,47 @@
package repo
import (
"testing"
"golang.org/x/mod/modfile"
"golang.org/x/mod/module"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
)
func TestShortName(t *testing.T) {
var testCases = map[string]struct {
name misc.ModuleShortName
modFile *modfile.File
}{
"one": {
name: misc.ModuleShortName("garage"),
modFile: &modfile.File{
Module: &modfile.Module{
Mod: module.Version{
Path: "gh.com/micheal/garage",
Version: "v2.3.4",
},
},
},
},
"three": {
name: misc.ModuleShortName("fruit/yellow/banana"),
modFile: &modfile.File{
Module: &modfile.Module{
Mod: module.Version{
Path: "gh.com/micheal/fruit/yellow/banana",
Version: "v2.3.4",
},
},
},
},
}
for n, tc := range testCases {
m := protoModule{pathToGoMod: "irrelevant", mf: tc.modFile}
actual := m.ShortName("gh.com/micheal")
if actual != tc.name {
t.Errorf(
"%s: expected %s, got %s", n, tc.name, actual)
}
}
}

View File

@@ -0,0 +1,98 @@
package semver
import (
"fmt"
"strconv"
"strings"
)
// SemVer is the immutable semantic version per https://semver.org
type SemVer struct {
major int
minor int
patch int
}
func New(major, minor, patch int) SemVer {
return SemVer{
major: major,
minor: minor,
patch: patch,
}
}
var zero = New(0, 0, 0)
func Zero() SemVer {
return zero
}
// Versions implements sort.Interface to get decreasing order.
type Versions []SemVer
func (v Versions) Len() int { return len(v) }
func (v Versions) Less(i, j int) bool { return v[j].LessThan(v[i]) }
func (v Versions) Swap(i, j int) { v[i], v[j] = v[j], v[i] }
func Parse(raw string) (SemVer, error) {
if len(raw) < 6 {
// e.g. minimal length is 6, e.g. "v1.2.3"
return zero, fmt.Errorf("%q too short to be a version", raw)
}
if raw[0] != 'v' {
return zero, fmt.Errorf("%q must start with letter 'v'", raw)
}
fields := strings.Split(raw[1:], ".")
if len(fields) < 3 {
return zero, fmt.Errorf("%q doesn't have the form v1.2.3", raw)
}
n := make([]int, 3)
for i := 0; i < 3; i++ {
var err error
n[i], err = strconv.Atoi(fields[i])
if err != nil {
return zero, err
}
}
return New(n[0], n[1], n[2]), nil
}
func (v SemVer) Bump(b SvBump) SemVer {
switch b {
case Major:
return New(v.major+1, 0, 0)
case Minor:
return New(v.major, v.minor+1, 0)
default:
return New(v.major, v.minor, v.patch+1)
}
}
func (v SemVer) BranchLabel() string {
return fmt.Sprintf("v%d.%d", v.major, v.minor)
}
func (v SemVer) String() string {
return fmt.Sprintf("v%d.%d.%d", v.major, v.minor, v.patch)
}
func (v SemVer) Pretty() string {
if v.IsZero() {
return ""
}
return v.String()
}
func (v SemVer) Equals(o SemVer) bool {
return v.major == o.major && v.minor == o.minor && v.patch == o.patch
}
func (v SemVer) LessThan(o SemVer) bool {
return v.major < o.major ||
(v.major == o.major && v.minor < o.minor) ||
(v.major == o.major && v.minor == o.minor && v.patch < o.patch)
}
func (v SemVer) IsZero() bool {
return v.Equals(zero)
}

View File

@@ -0,0 +1,105 @@
package semver
import (
"testing"
)
func TestParse(t *testing.T) {
var testCases = map[string]struct {
raw string
v SemVer
errMsg string
}{
"one": {
raw: "v1.2.3",
v: SemVer{major: 1, minor: 2, patch: 3},
errMsg: "",
},
"two": {
raw: "v2.0.9999",
v: SemVer{major: 2, minor: 0, patch: 9999},
errMsg: "",
},
"three": {
raw: "pizza",
v: zero,
errMsg: "\"pizza\" too short to be a version",
},
"non-digit": {
raw: "v1.x.222",
v: zero,
errMsg: "strconv.Atoi: parsing \"x\": invalid syntax",
},
"bad fields": {
raw: "v1.222",
v: zero,
errMsg: "\"v1.222\" doesn't have the form v1.2.3",
},
}
for n, tc := range testCases {
v, err := Parse(tc.raw)
if err == nil {
if tc.errMsg != "" {
t.Errorf(
"%s: no error, but expected err %q", n, tc.errMsg)
}
if !v.Equals(tc.v) {
t.Errorf(
"%s: expected %v, got %v", n, tc.v, v)
}
} else {
if tc.errMsg == "" {
t.Errorf(
"%s: unexpected error %v", n, err)
} else {
if tc.errMsg != err.Error() {
t.Errorf(
"%s: expected err msg %q, but got %q",
n, tc.errMsg, err.Error())
}
}
}
}
}
func TestLessThan(t *testing.T) {
var testCases = map[string]struct {
v1 SemVer
v2 SemVer
expected bool
}{
"one": {
v1: SemVer{major: 2, minor: 2, patch: 3},
v2: SemVer{major: 1, minor: 2, patch: 3},
expected: false,
},
"two": {
v1: SemVer{major: 1, minor: 3, patch: 3},
v2: SemVer{major: 1, minor: 2, patch: 3},
expected: false,
},
"three": {
v1: SemVer{major: 1, minor: 2, patch: 4},
v2: SemVer{major: 1, minor: 2, patch: 3},
expected: false,
},
"eq": {
v1: SemVer{major: 2, minor: 2, patch: 3},
v2: SemVer{major: 2, minor: 2, patch: 3},
expected: false,
},
"four": {
v1: zero,
v2: SemVer{major: 0, minor: 0, patch: 1},
expected: true,
},
}
for n, tc := range testCases {
actual := tc.v1.LessThan(tc.v2)
if actual != tc.expected {
t.Errorf(
"%s: expected %v, got %v for %s LessThan %s",
n, tc.expected, actual, tc.v1.String(), tc.v2.String())
}
}
}

View File

@@ -0,0 +1,17 @@
package semver
type SvBump int
const (
Patch SvBump = iota
Minor
Major
)
func (b SvBump) String() string {
return map[SvBump]string{
Patch: "Patch",
Minor: "Minor",
Major: "Major",
}[b]
}

View File

@@ -0,0 +1,26 @@
package utils
import (
"log"
"os"
)
func DirExists(name string) bool {
info, err := os.Stat(name)
if os.IsNotExist(err) {
return false
}
return info.IsDir()
}
func SliceToSet(slice []string) map[string]bool {
result := make(map[string]bool)
for _, x := range slice {
if _, ok := result[x]; ok {
log.Fatalf("programmer error - repeated value: %s", x)
} else {
result[x] = true
}
}
return result
}

84
cmd/gorepomod/main.go Normal file
View File

@@ -0,0 +1,84 @@
package main
import (
"fmt"
"os"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/arguments"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/repo"
)
//go:generate go run internal/gen/main.go
func loadRepoManager(args *arguments.Args) (*repo.Manager, error) {
path, err := os.Getwd()
if err != nil {
return nil, err
}
dg, err := repo.NewDotGitDataFromPath(path)
if err != nil {
return nil, err
}
pr, err := dg.NewRepoFactory(args.Exclusions())
if err != nil {
return nil, err
}
return pr.NewRepoManager(), nil
}
func actualMain() error {
args, err := arguments.Parse()
if err != nil {
return err
}
mgr, err := loadRepoManager(args)
if err != nil {
return err
}
var targetModule misc.LaModule = nil
if args.ModuleName() != misc.ModuleUnknown {
targetModule = mgr.FindModule(args.ModuleName())
if targetModule == nil {
return fmt.Errorf(
"cannot find module %q in repo %s",
args.ModuleName(), mgr.RepoPath())
}
}
switch args.GetCommand() {
case arguments.List:
return mgr.List()
case arguments.Tidy:
return mgr.Tidy(args.DoIt())
case arguments.Pin:
v := args.Version()
if v.IsZero() {
v = targetModule.VersionLocal()
}
return mgr.Pin(args.DoIt(), targetModule, v)
case arguments.UnPin:
return mgr.UnPin(args.DoIt(), targetModule)
case arguments.Release:
return mgr.Release(targetModule, args.Bump(), args.DoIt())
case arguments.UnRelease:
return mgr.UnRelease(targetModule, args.DoIt())
case arguments.Debug:
return mgr.Debug(targetModule, args.DoIt())
default:
return fmt.Errorf("cannot handle cmd %v", args.GetCommand())
}
}
func main() {
if len(os.Args) < 2 {
fmt.Print(usageMsg)
return
}
if err := actualMain(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

109
cmd/gorepomod/usage.go Normal file
View File

@@ -0,0 +1,109 @@
// Code generated by internal/gen/main.go; DO NOT EDIT.
package main
const (
usageMsg = `
Helps when you have a git repository with multiple Go modules.
It handles tasks one might otherwise attempt with
'''
find ./ -name "go.mod" | xargs {some hack}
'''
Run it from a git repository root.
It walks the repository, reads 'go.mod' files, builds
a model of Go modules and intra-repo module
dependencies, then performs some operation.
Install:
'''
go get github.com/monopole/gorepomod
'''
## Usage
_Commands that change things (everything but 'list')
do nothing but log commands
unless you add the '--doIt' flag,
allowing the change._
#### 'gorepomod list'
Lists modules and intra-repo dependencies.
Use this to get module names for use in other commands.
#### 'gorepomod tidy'
Creates a change with mechanical updates
to 'go.mod' and 'go.sum' files.
#### 'gorepomod unpin {module}'
Creates a change to 'go.mod' files.
For each module _m_ in the repository,
if _m_ depends on a _{module}_,
then _m_'s dependency on it will be replaced by
a relative path to the in-repo module.
#### 'gorepomod pin {module} [{version}]'
Creates a change to 'go.mod' files.
The opposite of 'unpin'.
The change removes replacements and pins _m_ to a
specific, previously tagged and released version of _{module}_.
The argument _{version}_ defaults to recent version of _{module}_.
_{version}_ should be in semver form, e.g. 'v1.2.3'.
#### 'gorepomod release {module} [patch|minor|major]'
Computes a new version for the module, tags the repo
with that version, and pushes the tag to the remote.
The value of the 2nd argument, either 'patch' (the default),
'minor' or 'major', determines the new version.
If the existing version is _v1.2.7_, then the new version will be:
- 'patch' -> _v1.2.8_
- 'minor' -> _v1.3.0_
- 'major' -> _v2.0.0_
After establishing the the version, the command looks for a branch named
> _release-{module}/-v{major}.{minor}_
If the branch doesn't exist, the command creates it and pushes it to the remote.
The command then creates a new tag in the form
> _{module}/v{major}.{minor}.{patch}_
The command pushes this tag to the remote. This typically triggers
cloud activity to create release artifacts.
#### 'gorepomod unrelease {module}'
This undoes the work of 'release', by deleting the
most recent tag both locally and at the remote.
You can then fix whatever, and re-release.
This, however, must be done almost immediately.
If there's a chance someone (or some cloud robot) already
imported the module at the given tag, then don't do this,
because it will confuse module caches.
Do a new patch release instead.
`
)

7
cmd/pluginator/go.mod Normal file
View File

@@ -0,0 +1,7 @@
module sigs.k8s.io/kustomize/pluginator/v2
go 1.14
require sigs.k8s.io/kustomize/api v0.6.3
replace sigs.k8s.io/kustomize/api v0.6.3 => ../../api

View File

@@ -482,8 +482,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/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/kustomize/kyaml v0.9.1 h1:T7aNUraSioQp0NHJZtYjIhL/q8mqRzCiHcAKdvo09go=
sigs.k8s.io/kustomize/kyaml v0.9.1/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/kustomize/kyaml v0.9.3 h1:kZ5HnNmmnbndSXFivrAVM6u3Ik1dwu4kbpaV8KNwy8I=
sigs.k8s.io/kustomize/kyaml v0.9.3/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=

8
cmd/prchecker/go.mod Normal file
View File

@@ -0,0 +1,8 @@
module sigs.k8s.io/kustomize/cmd/prchecker
go 1.15
require (
github.com/google/go-github v17.0.0+incompatible
github.com/google/go-querystring v1.0.0 // indirect
)

4
cmd/prchecker/go.sum Normal file
View File

@@ -0,0 +1,4 @@
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=

View File

@@ -1,12 +1,16 @@
// multi-module-span script:
// A script which can detect when a pull request would make changes which
// span a series of restricted directories (ex: multiple go modules or projects)
// prchecker examines pull requests
//
// When a pull request includes files which span two modules the script will
// exit with a non-zero exit code.
// - When a PR includes files from multiple modules that we'd rather not
// modify at the same time (in an effort to have more self-contained
// release notes), the script will exit with a non-zero exit code.
//
// Running:
// go run multi-module-span.go -owner=kubernetes-sigs -repo=kustomize -pr=2997 cmd/config api/ kustomize/ kyaml/
// Usage:
//
// go run . \
// -owner=kubernetes-sigs \
// -repo=kustomize \
// -pr=2997 \
// cmd/config api kustomize kyaml
package main
@@ -57,15 +61,30 @@ func main() {
// ListAllPullRequestFiles retrieves as many files as possible for the
// target pull request.
//
// NOTE: GitHub API limits ListFiles to a maximum of 3000 files. Very large
// Note: GitHub API limits ListFiles to a maximum of 3000 files. Very large
// changes which exceed this limit may pass this check even if they
// do contain spanning changes.
// see: https://developer.github.com/v3/pulls/#list-pull-requests-files
func ListAllPullRequestFiles(client *github.Client, owner *string, pullrequest *int, repo *string) ([]*github.CommitFile, error) {
// foundFiles across all pages from github api
var foundFiles []*github.CommitFile
// GitHub returns the first 30 files by default, increase this value
options := &github.ListOptions{PerPage: 3000}
files, _, err := client.PullRequests.ListFiles(context.Background(), *owner, *repo, *pullrequest, options)
return files, err
// Note: Page 1 is the first page of results. Page 0 is an end of list mark.
// Github only returns (max) 100 results per page and PR's may exceed this
// so loop until all pages have been enumerated.
options := &github.ListOptions{PerPage: 100, Page: 1}
for options.Page != 0 {
files, response, err := client.PullRequests.ListFiles(context.Background(), *owner, *repo, *pullrequest, options)
// If an error has occurred while querying api exit early, report error
if err != nil {
return nil, err
}
foundFiles = append(foundFiles, files...)
// setup next page to continue loop
options = &github.ListOptions{PerPage: 100, Page: response.NextPage}
}
return foundFiles, nil
}
// CountModifiedRestrictedDirectories Accepts a map of paths and the number of

View File

@@ -251,8 +251,15 @@ specification of the cluster's desired state to
point deployments to _new_ configMaps with _new_ names.
`kustomize` makes this easy with its
`configMapGenerator` directive and associated naming
controls. A GC process in the k8s master eventually
deletes unused configMaps.
controls.
To remove outdated configMaps add a label
to your resource, for example, kustomize-cleanup="true",
and then you can use `kustomize` to prune old resources^
> ```
> kustomize build | kubectl apply --prune -f- -l kustomize-cleanup="true"
> ```
### Create and use the overlay for _production_

View File

@@ -4,13 +4,13 @@
## ConfigMap generation and rolling updates
Kustomize provides two ways of adding ConfigMap in one `kustomization`, either by declaring ConfigMap as a [resource] or declaring ConfigMap from a ConfigMapGenerator. The formats inside `kustomization.yaml` are
Kustomize provides two ways of adding ConfigMap in one `kustomization`, either by declaring ConfigMap as a [resource] or declaring ConfigMap from a ConfigMapGenerator. The formats inside `kustomization.yaml` are
> ```
> # declare ConfigMap as a resource
> resources:
> - configmap.yaml
>
>
> # declare ConfigMap from a ConfigMapGenerator
> configMapGenerator:
> - name: a-configmap
@@ -28,7 +28,9 @@ In this demo, the same [hello_world](helloWorld/README.md) is used while the Con
### Establish base and staging
Establish the base with a configMapGenerator
<!-- @establishBase @testAgainstLatestRelease -->
```
DEMO_HOME=$(mktemp -d)
@@ -46,16 +48,18 @@ commonLabels:
resources:
- deployment.yaml
- service.yaml
configMapGenerator:
- name: the-map
literals:
- altGreeting=Good Morning!
configMapGenerator:
- name: the-map
literals:
- altGreeting=Good Morning!
- enableRisky="false"
EOF
```
Establish the staging with a patch applied to the ConfigMap
<!-- @establishStaging @testAgainstLatestRelease -->
```
OVERLAYS=$DEMO_HOME/overlays
mkdir -p $OVERLAYS/staging
@@ -92,8 +96,8 @@ configured with data from a configMap.
The deployment refers to this map by name:
<!-- @showDeployment @testAgainstLatestRelease -->
```
grep -C 2 configMapKeyRef $BASE/deployment.yaml
```
@@ -106,12 +110,12 @@ changed, so such updates have no effect.
The recommended way to change a deployment's
configuration is to
1. create a new configMap with a new name,
1. patch the _deployment_, modifying the name value of
1. create a new configMap with a new name,
1. patch the _deployment_, modifying the name value of
the appropriate `configMapKeyRef` field.
This latter change initiates rolling update to the pods
in the deployment. The older configMap, when no longer
in the deployment. The older configMap, when no longer
referenced by any other resource, is eventually [garbage
collected](/../../issues/242).
@@ -120,6 +124,7 @@ collected](/../../issues/242).
The _staging_ [variant] here has a configMap [patch]:
<!-- @showMapPatch @testAgainstLatestRelease -->
```
cat $OVERLAYS/staging/map.yaml
```
@@ -131,6 +136,7 @@ resource spec.
The ConfigMap it modifies is declared from a configMapGenerator.
<!-- @showMapBase @testAgainstLatestRelease -->
```
grep -C 4 configMapGenerator $BASE/kustomization.yaml
```
@@ -139,11 +145,12 @@ For a patch to work, the names in the `metadata/name`
fields must match.
However, the name values specified in the file are
_not_ what gets used in the cluster. By design,
kustomize modifies names of ConfigMaps declared from ConfigMapGenerator. To see the names
_not_ what gets used in the cluster. By design,
kustomize modifies names of ConfigMaps declared from ConfigMapGenerator. To see the names
ultimately used in the cluster, just run kustomize:
<!-- @grepStagingName @testAgainstLatestRelease -->
```
kustomize build $OVERLAYS/staging |\
grep -B 8 -A 1 staging-the-map
@@ -161,7 +168,8 @@ The suffix to the configMap name is generated from a
hash of the maps content - in this case the name suffix
is _5276h4th55_:
<!-- @grepStagingHash -->
<!-- @grepStagingHash @testAgainstLatestRelease -->
```
kustomize build $OVERLAYS/staging | grep 5276h4th55
```
@@ -170,6 +178,7 @@ Now modify the map patch, to change the greeting
the server will use:
<!-- @changeMap @testAgainstLatestRelease -->
```
sed -i.bak 's/pineapple/kiwi/' $OVERLAYS/staging/map.yaml
```
@@ -184,6 +193,7 @@ kustomize build $OVERLAYS/staging |\
Run kustomize again to see the new configMap names:
<!-- @grepStagingName @testAgainstLatestRelease -->
```
kustomize build $OVERLAYS/staging |\
grep -B 8 -A 1 staging-the-map
@@ -194,7 +204,8 @@ in three new names ending in _c2g8fcbf88_ - one in the
configMap name itself, and two in the deployment that
uses the map:
<!-- @countHashes -->
<!-- @countHashes @testAgainstLatestRelease -->
```
test 3 == \
$(kustomize build $OVERLAYS/staging | grep c2g8fcbf88 | wc -l); \
@@ -204,7 +215,7 @@ test 3 == \
Applying these resources to the cluster will result in
a rolling update of the deployments pods, retargetting
them from the _5276h4th55_ maps to the _c2g8fcbf88_
maps. The system will later garbage collect the
maps. The system will later garbage collect the
unused maps.
## Rollback

View File

@@ -102,7 +102,7 @@ For Spring Boot application, we can set an active profile through the environmen
the application will pick up an extra `application-<profile>.properties` file. With this, we can customize the configMap in two
steps. Add an environment variable through the patch and add a file to the configMap.
<!-- @customizeConfigMap @testAgainstLatestRelease -->
<!-- @customizeConfigMap -->
```
cat <<EOF >$DEMO_HOME/patch.yaml
apiVersion: apps/v1
@@ -119,7 +119,7 @@ spec:
value: prod
EOF
kustomize edit add patch patch.yaml
kustomize edit add patch --path patch.yaml --name sbdemo --kind Deployment --group apps --version v1
cat <<EOF >$DEMO_HOME/application-prod.properties
spring.jpa.hibernate.ddl-auto=update
@@ -281,20 +281,35 @@ The output contains
Add these patches to the kustomization:
<!-- @addPatch @testAgainstLatestRelease -->
<!-- @addPatch -->
```
cd $DEMO_HOME
kustomize edit add patch memorylimit_patch.yaml
kustomize edit add patch healthcheck_patch.yaml
kustomize edit add patch --path memorylimit_patch.yaml --name sbdemo --kind Deployment --group apps --version v1
kustomize edit add patch --path healthcheck_patch.yaml --name sbdemo --kind Deployment --group apps --version v1
```
`kustomization.yaml` should have patches field:
> ```
> patchesStrategicMerge:
> - patch.yaml
> - memorylimit_patch.yaml
> - healthcheck_patch.yaml
> patches:
> - path: patch.yaml
> target:
> group: apps
> version: v1
> kind: Deployment
> name: sbdemo
> - path: memorylimit_patch.yaml
> target:
> group: apps
> version: v1
> kind: Deployment
> name: sbdemo
> - path: healthcheck_patch.yaml
> target:
> group: apps
> version: v1
> kind: Deployment
> name: sbdemo
> ```
The output of the following command can now be applied

View File

@@ -5,6 +5,7 @@
## ConfigMap 的生成和滚动更新
kustomize 提供了两种添加 ConfigMap 的方法:
- 将 ConfigMap 声明为 [resource]
- 通过 ConfigMapGenerator 声明 ConfigMap
@@ -14,7 +15,7 @@ kustomize 提供了两种添加 ConfigMap 的方法:
> # 将 ConfigMap 声明为 resource
> resources:
> - configmap.yaml
>
>
> # 在 ConfigMapGenerator 中声明 ConfigMap
> configMapGenerator:
> - name: a-configmap
@@ -30,7 +31,9 @@ kustomize 提供了两种添加 ConfigMap 的方法:
### 建立 base 和 staging
使用 configMapGenerator 建立 base
<!-- @establishBase @testAgainstLatestRelease -->
```
DEMO_HOME=$(mktemp -d)
@@ -48,16 +51,18 @@ commonLabels:
resources:
- deployment.yaml
- service.yaml
configMapGenerator:
- name: the-map
literals:
- altGreeting=Good Morning!
configMapGenerator:
- name: the-map
literals:
- altGreeting=Good Morning!
- enableRisky="false"
EOF
```
通过应用 ConfigMap patch 的方式建立 staging
<!-- @establishStaging @testAgainstLatestRelease -->
```
OVERLAYS=$DEMO_HOME/overlays
mkdir -p $OVERLAYS/staging
@@ -94,6 +99,7 @@ EOF
deployment 按照名称引用此 ConfigMap
<!-- @showDeployment @testAgainstLatestRelease -->
```
grep -C 2 configMapKeyRef $BASE/deployment.yaml
```
@@ -102,16 +108,17 @@ grep -C 2 configMapKeyRef $BASE/deployment.yaml
更改 Deployment 配置的推荐方法是:
1. 使用新名称创建一个新的 configMap
2. 为_deployment_ 添加 patch修改相应 `configMapKeyRef` 字段的名称值。
1. 使用新名称创建一个新的 configMap
2. 为*deployment* 添加 patch修改相应 `configMapKeyRef` 字段的名称值。
后一种更改会启动对 deployment 中的 pod 的滚动更新。旧的 configMap 在不再被任何其他资源引用时最终会被[垃圾回收](/../../issues/242)。
### 如何使用 kustomize
### 如何使用 kustomize
_staging_ 的 [variant] 包含一个 configMap 的 [patch]
<!-- @showMapPatch @testAgainstLatestRelease -->
```
cat $OVERLAYS/staging/map.yaml
```
@@ -121,6 +128,7 @@ cat $OVERLAYS/staging/map.yaml
在 ConfigMapGenerator 中声明 ConfigMap 的修改。
<!-- @showMapBase @testAgainstLatestRelease -->
```
grep -C 4 configMapGenerator $BASE/kustomization.yaml
```
@@ -130,6 +138,7 @@ grep -C 4 configMapGenerator $BASE/kustomization.yaml
但是文件中指定的名称值不是群集中使用的名称值。根据设计kustomize 修改从 ConfigMapGenerator 声明的 ConfigMaps 的名称。要查看最终在群集中使用的名称,只需运行 kustomize
<!-- @grepStagingName @testAgainstLatestRelease -->
```
kustomize build $OVERLAYS/staging |\
grep -B 8 -A 1 staging-the-map
@@ -141,7 +150,8 @@ kustomize build $OVERLAYS/staging |\
configMap 名称的后缀是由 map 内容的哈希生成的 - 在这种情况下,名称后缀是 _5276h4th55_
<!-- @grepStagingHash -->
<!-- @grepStagingHash @testAgainstLatestRelease -->
```
kustomize build $OVERLAYS/staging | grep 5276h4th55
```
@@ -149,6 +159,7 @@ kustomize build $OVERLAYS/staging | grep 5276h4th55
现在修改 map patch ,更改该服务将使用的问候消息:
<!-- @changeMap @testAgainstLatestRelease -->
```
sed -i.bak 's/pineapple/kiwi/' $OVERLAYS/staging/map.yaml
```
@@ -163,6 +174,7 @@ kustomize build $OVERLAYS/staging |\
再次运行 kustomize 查看新的 configMap 名称:
<!-- @grepStagingName @testAgainstLatestRelease -->
```
kustomize build $OVERLAYS/staging |\
grep -B 8 -A 1 staging-the-map
@@ -170,7 +182,8 @@ kustomize build $OVERLAYS/staging |\
确认 configMap 内容的更改将会生成以 _c2g8fcbf88_ 结尾的三个新名称 - 一个在 configMap 的名称中,另两个在使用 ConfigMap 的 deployment 中:
<!-- @countHashes -->
<!-- @countHashes @testAgainstLatestRelease -->
```
test 3 == \
$(kustomize build $OVERLAYS/staging | grep c2g8fcbf88 | wc -l); \

View File

@@ -89,7 +89,7 @@ cat kustomization.yaml
1. 通过 patch 添加一个环境变量
2. 将文件添加到 ConfigMap 中
<!-- @customizeConfigMap @testAgainstLatestRelease -->
<!-- @customizeConfigMap -->
```
cat <<EOF >$DEMO_HOME/patch.yaml
apiVersion: apps/v1
@@ -106,7 +106,7 @@ spec:
value: prod
EOF
kustomize edit add patch patch.yaml
kustomize edit add patch --path patch.yaml --name sbdemo --kind Deployment --group apps --version v1
cat <<EOF >$DEMO_HOME/application-prod.properties
spring.jpa.hibernate.ddl-auto=update
@@ -257,23 +257,38 @@ cat $DEMO_HOME/healthcheck_patch.yaml
将这些 patch 添加到 `kustomization.yaml` 中:
<!-- @addPatch @testAgainstLatestRelease -->
<!-- @addPatch -->
```
cd $DEMO_HOME
kustomize edit add patch memorylimit_patch.yaml
kustomize edit add patch healthcheck_patch.yaml
kustomize edit add patch --path memorylimit_patch.yaml --name sbdemo --kind Deployment --group apps --version v1
kustomize edit add patch --path healthcheck_patch.yaml --name sbdemo --kind Deployment --group apps --version v1
```
执行上面的命令后,`kustomization.yaml` 的 patchesStrategicMerge 字段如下:
执行上面的命令后,`kustomization.yaml` 的 patches 字段如下:
> ```
> patchesStrategicMerge:
> - patch.yaml
> - memorylimit_patch.yaml
> - healthcheck_patch.yaml
> patches:
> - path: patch.yaml
> target:
> group: apps
> version: v1
> kind: Deployment
> name: sbdemo
> - path: memorylimit_patch.yaml
> target:
> group: apps
> version: v1
> kind: Deployment
> name: sbdemo
> - path: healthcheck_patch.yaml
> target:
> group: apps
> version: v1
> kind: Deployment
> name: sbdemo
> ```
现在就可以将完整的配置输出并在集群中部署(将结果通过管道输出给 `kubectl apply`在生产环境创建Spring Boot 应用。
现在就可以将完整的配置输出并在集群中部署(将结果通过管道输出给 `kubectl apply`),在生产环境创建 Spring Boot 应用。
<!-- @finalBuild @testAgainstLatestRelease -->
```

76
hack/install_kpt.sh Executable file
View File

@@ -0,0 +1,76 @@
#!/bin/bash
# If no arguments are given -> Downloads the most recently released
# kpt binary to your current working directory.
# (e.g. 'install_kpt.sh')
#
# If one argument is given -> Downloads the specified version of the
# kpt binary to your current working directory.
# (e.g. 'install_kpt.sh 0.34.0')
#
# If two arguments are given -> Downloads the specified version of the
# kpt binary to the specified directory.
# (e.g. 'install_kpt.sh 0.34.0 $(go env GOPATH)/bin')
#
# Fails if the file already exists.
if [ -z "$1" ]; then
version=""
else
version=$1
fi
if [ -z "$2" ]; then
where=$PWD
else
where=$2
fi
if [ -f $where/kpt ]; then
echo "A file named kpt already exists (remove it first)."
exit 1
fi
tmpDir=`mktemp -d`
if [[ ! "$tmpDir" || ! -d "$tmpDir" ]]; then
echo "Could not create temp dir."
exit 1
fi
function cleanup {
rm -rf "$tmpDir"
}
trap cleanup EXIT
pushd $tmpDir >& /dev/null
opsys=windows
if [[ "$OSTYPE" == linux* ]]; then
opsys=linux
elif [[ "$OSTYPE" == darwin* ]]; then
opsys=darwin
fi
curl -s https://api.github.com/repos/GoogleContainerTools/kpt/releases |\
grep browser_download |\
grep $opsys |\
cut -d '"' -f 4 |\
grep /kpt/releases/download/v$version |\
sort | tail -n 1 |\
xargs curl -s -O -L
if [ -e ./kpt_${opsys}_amd64-*.tar.gz ]; then
tar xzf ./kpt_${opsys}_amd64-*.tar.gz
else
echo "Error: kpt binary with the version $version does not exist!"
exit 1
fi
cp ./kpt $where
popd >& /dev/null
$where/kpt version
echo kpt installed to specified directory.

View File

@@ -1,67 +0,0 @@
#!/usr/bin/env bash
# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
#
# In general, pin modules to a specific version of the
# kustomize API before a release of that module, and
# unpin the module after the module release so that
# development proceeds against the API's HEAD.
#
# E.g. for the kustomize CLI module, do this before
# releasing the CLI:
#
# ./hack/pinUnpin.sh pin kustomize v0.3.1
#
# where v0.3.1 is the most recently released version of
# the API, and do the following afterwards:
#
# ./hack/pinUnpin.sh unPin kustomize
set -o nounset
set -o pipefail
if [ "$#" -lt 2 ]; then
echo "usage:"
echo " ./hack/pinUnpin.sh pin kustomize v0.3.1"
echo " or "
echo " ./hack/pinUnpin.sh unPin kustomize"
exit 1
fi
operation=$1
if [[ ("$operation" != "pin") && ("$operation" != "unPin") ]]; then
echo "unknown operation $operation"
exit 1
fi
module=$2
if [ ! -d "$module" ]; then
echo "directory $module doesn't exist"
exit 1
fi
version="unnecessary"
if [ "$operation" == "pin" ]; then
if [ "$#" -le 2 ]; then
echo "Specify version to pin, e.g. '$0 $module pin v0.2.0'"
exit 1
fi
version=$3
fi
function unPin {
oldV=$(grep -m 1 sigs.k8s.io/kustomize/api go.mod | awk '{print $NF}')
go mod edit -replace=sigs.k8s.io/kustomize/api@${oldV}=../api
go mod tidy
}
function pin {
oldV=$(grep -m 1 sigs.k8s.io/kustomize/api go.mod | awk '{print $NF}')
go mod edit -dropreplace=sigs.k8s.io/kustomize/api@${oldV}
go mod edit -require=sigs.k8s.io/kustomize/api@$version
go mod tidy
}
pushd $module >& /dev/null
$operation
popd >& /dev/null

View File

@@ -1,107 +0,0 @@
#!/usr/bin/env bash
# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
#
# To fix all plugin dependence to a particular
# released version of the kustomize API,
# run this from the repo root:
#
# ./hack/pinUnpinPluginApiDep.sh pin api v0.2.0
#
# To replace fixed dependence with
# dependence on local filesystem (HEAD)
# run this from the repo root:
#
# ./hack/pinUnpinPluginApiDep.sh unPin api
#
# All plugins, even plugins not written in Go,
# have a unit test written in Go that depends
# on a particular version of the api for a test
# harness. The plugins written in Go, either
# as exec or Go-plugin style plugins,
# will likely depend directly on the kustomize
# API, and any number of other 3rd party packages.
#
# The Go plugins in the `builtin` directory
# are in practice converted to static libraries
# in the API, so should remain unpinned (dependent
# on HEAD). The other example plugins can be pinned
# or unpinned on a case by case basis, since
# they are just examples - but likely should
# remain unpinned too. Nothing in the outside
# world should depend on these plugin modules,
# so there's no reason for them to be pinned.
set -o errexit
set -o nounset
#set -o pipefail
function doUnPin {
oldV=$(grep -m 1 sigs.k8s.io/kustomize/${module} go.mod | awk '{print $NF}')
if [ ! -z $oldV ]; then
go mod edit -replace=sigs.k8s.io/kustomize/${module}@${oldV}=$1
fi
go mod tidy
}
function doPin {
oldV=$(grep -m 1 sigs.k8s.io/kustomize/${module} go.mod | awk '{print $NF}')
if [ ! -z $oldV ]; then
go mod edit -dropreplace=sigs.k8s.io/kustomize/${module}@${oldV}
go mod edit -require=sigs.k8s.io/kustomize/${module}@$1
fi
go mod tidy
}
function forEachGoMod {
for goMod in $(find $2 -name 'go.mod'); do
d=$(dirname "${goMod}")
echo "$1 $d"
(cd $d; $1 $3)
done
}
function unPin {
echo "Unpinning $module"
forEachGoMod doUnPin ./plugin/builtin ../../../${module}
forEachGoMod doUnPin ./plugin/someteam.example.com/v1 ../../../../${module}
}
function pin {
echo "Pinning $module to $version"
forEachGoMod doPin ./plugin/builtin ${version}
forEachGoMod doPin ./plugin/someteam.example.com/v1 ${version}
}
if [ "$#" -eq 0 ]; then
echo "Pin or unpin plugins, e.g."
echo " "
echo " ./hack/pinUnpinPluginApiDep.sh pin api v0.2.0"
echo " "
echo " ./hack/pinUnpinPluginApiDep.sh unPin api"
echo " "
exit 1
fi
operation=$1
if [[ ("$operation" != "pin") && ("$operation" != "unPin") ]]; then
echo "unknown operation $operation"
exit 1
fi
module=$2
if [[ ("$module" != "api") && ("$module" != "kyaml") ]]; then
echo "unknown module $module"
exit 1
fi
version="unnecessary"
if [ "$operation" == "pin" ]; then
if [ "$#" -le 2 ]; then
echo "Specify version to pin, e.g. '$0 pin v0.2.0'"
exit 1
fi
version=$3
fi
$operation

18
kustomize.Dockerfile Normal file
View File

@@ -0,0 +1,18 @@
# build
FROM golang:alpine as builder
ARG VERSION
ARG COMMIT
ARG DATE
RUN mkdir /build
ADD . /build/
WORKDIR /build/kustomize
RUN CGO_ENABLED=0 GO111MODULE=on go build \
-ldflags="-s -X sigs.k8s.io/kustomize/api/provenance.version=${VERSION} \
-X sigs.k8s.io/kustomize/api/provenance.gitCommit=${COMMIT} \
-X sigs.k8s.io/kustomize/api/provenance.buildDate=${DATE}"
# only copy binary
FROM alpine
COPY --from=builder /build/kustomize /app/
WORKDIR /app
ENTRYPOINT ["./kustomize"]

View File

@@ -8,8 +8,9 @@ require (
github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.5
k8s.io/client-go v0.17.3
sigs.k8s.io/kustomize/api v0.6.2
sigs.k8s.io/kustomize/cmd/config v0.8.1
sigs.k8s.io/kustomize/api v0.6.3
sigs.k8s.io/kustomize/cmd/config v0.8.4
sigs.k8s.io/kustomize/kyaml v0.9.3
sigs.k8s.io/yaml v1.2.0
)
@@ -19,4 +20,4 @@ exclude (
sigs.k8s.io/kustomize/cmd/config v0.2.0
)
replace sigs.k8s.io/kustomize/api v0.6.2 => ../api
replace sigs.k8s.io/kustomize/api v0.6.3 => ../api

View File

@@ -3,8 +3,6 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
github.com/360EntSecGroup-Skylar/excelize v1.4.1/go.mod h1:vnax29X2usfl7HHkBrX5EvSCJcmH3dT9luvxzu8iGAE=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs=
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 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU=
@@ -19,9 +17,6 @@ github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6L
github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU=
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=
@@ -48,64 +43,41 @@ github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
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/bombsimon/wsl v1.2.5/go.mod h1:43lEF/i0kpXbLCeDXL9LMT8c92HyBywXb0AsgMHYngM=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8=
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0 h1:w3NnFcKR5241cfmQU5ZZAsf0xcpId6mWOupTvJlUX2U=
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustmop/soup v1.1.2-0.20190516214245-38228baa104e/go.mod h1:CgNC6SGbT+Xb8wGGvzilttZL1mc5sQ/5KkcxsZttMIk=
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M=
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1/YsqVWoWNLQO+fusocsw354rqGTZtAgw=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@@ -123,8 +95,6 @@ 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-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/zapr v0.1.0 h1:h+WVe9j6HAA01niTJPA/kKH0i7e0rLZBCwauQFcRE54=
github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
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=
@@ -179,7 +149,6 @@ github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tF
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
github.com/go-openapi/validate v0.19.8 h1:YFzsdWIDfVuLvIOF+ZmKjVg1MbPJ1QgY9PihMwei1ys=
github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
@@ -205,13 +174,11 @@ github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09Vjb
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
@@ -231,9 +198,6 @@ github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlS
github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI=
github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4=
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ=
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8=
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -256,29 +220,17 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k=
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 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o=
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/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.3.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
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-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0=
@@ -290,15 +242,11 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
@@ -320,10 +268,9 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
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.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
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=
@@ -334,11 +281,8 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN
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/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
@@ -350,8 +294,6 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -366,26 +308,21 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/
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/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
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/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.4.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/paulmach/orb v0.1.3/go.mod h1:VFlX/8C+IQ1p6FTRRKzKoOPJnvEtA5G0Veuqwbu//Vk=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
@@ -398,31 +335,19 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete/v2 v2.0.1-alpha.12 h1:0wvkuDfHb5vSZlNBYgpEH4XQHpF46MjLPHav8XC77Nc=
github.com/posener/complete/v2 v2.0.1-alpha.12/go.mod h1://JlL91cS2JV7rOl6LVHrRqBXoBUecJu3ILQPgbJiMQ=
github.com/posener/script v1.0.4 h1:nSuXW5ZdmFnQIueLB2s0qvs4oNsUloM1Zydzh75v42w=
github.com/posener/script v1.0.4/go.mod h1:Rg3ijooqulo05aGLyGsHoLmIOUzHUVK19WVgrYBPU/E=
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d h1:K6eOUihrFLdZjZnA4XlRp864fmWXv9YTIk7VPLhRacA=
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d/go.mod h1:7DPO4domFU579Ga6E61sB9VFNaniPVwJP5C4bBCu3wA=
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
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/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
@@ -440,20 +365,17 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
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/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
@@ -469,10 +391,11 @@ 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.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
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/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
@@ -480,24 +403,19 @@ github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok=
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/uudashr/gocognit v0.0.0-20190926065955-1655d0de0517/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8=
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI=
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yujunz/go-getter v1.4.1-lite h1:FhvNc94AXMZkfqUwfMKhnQEC9phkphSGdPTL7tIdhOM=
github.com/yujunz/go-getter v1.4.1-lite/go.mod h1:sbmqxXjyLunH1PkF3n7zSlnVeMvmYUuIl9ZVs/7NyCc=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.2 h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA=
@@ -506,15 +424,10 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.starlark.net v0.0.0-20190528202925-30ae18b8564f/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg=
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -528,20 +441,15 @@ golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
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/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -549,7 +457,6 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -559,12 +466,12 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-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-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
@@ -574,9 +481,7 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180117170059-2c42eef0765b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -586,7 +491,6 @@ golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5h
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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -595,13 +499,13 @@ golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c h1:Vco5b+cuG5NNfORVxZy6bYZQ7rsigisU1WQFkvQ0L5E=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
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.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20171227012246-e19ae1496984/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -614,32 +518,25 @@ golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/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-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/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=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -648,30 +545,24 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.0.0/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -681,90 +572,38 @@ gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo=
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
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.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI=
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.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
k8s.io/apimachinery v0.17.3 h1:f+uZV6rm4/tHE7xXgLyToprg6xWairaClGVkm2t8omg=
k8s.io/apimachinery v0.17.3/go.mod h1:gxLnyZcGNdZTCLnq3fgzyg2A5BVCHTNDFrw8AmuJ+0g=
k8s.io/apiserver v0.0.0-20190918160949-bfa5e2e684ad/go.mod h1:XPCXEwhjaFN29a8NldXA901ElnKeKLrLtREO9ZhFyhg=
k8s.io/apiserver v0.17.2/go.mod h1:lBmw/TtQdtxvrTk0e2cgtOxHizXI+d0mmGQURIHQZlo=
k8s.io/cli-runtime v0.0.0-20191214191754-e6dc6d5c8724/go.mod h1:wzlq80lvjgHW9if6MlE4OIGC86MDKsy5jtl9nxz/IYY=
k8s.io/cli-runtime v0.17.2/go.mod h1:aa8t9ziyQdbkuizkNLAw3qe3srSyWh9zlSB7zTqRNPI=
k8s.io/cli-runtime v0.17.3 h1:0ZlDdJgJBKsu77trRUynNiWsRuAvAVPBNaQfnt/1qtc=
k8s.io/cli-runtime v0.17.3/go.mod h1:X7idckYphH4SZflgNpOOViSxetiMj6xI0viMAjM81TA=
k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90/go.mod h1:J69/JveO6XESwVgG53q3Uz5OSfgsv4uxpScmmyYOOlk=
k8s.io/client-go v0.0.0-20191214190045-a32a6f7a3052/go.mod h1:tAaoc/sYuIL0+njJefSAmE28CIcxyaFV4kbIujBlY2s=
k8s.io/client-go v0.0.0-20191219150334-0b8da7416048/go.mod h1:ZEe8ZASDUAuqVGJ+UN0ka0PfaR+b6a6E1PGsSNZRui8=
k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k=
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-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kubectl v0.0.0-20191219154910-1528d4eea6dd h1:nZX5+wEqTu/EBIYjrZlFOA63z4+Zcy96lDkCZPU9a9c=
k8s.io/kubectl v0.0.0-20191219154910-1528d4eea6dd/go.mod h1:9ehGcuUGjXVZh0qbYSB0vvofQw2JQe6c6cO0k4wu/Oo=
k8s.io/metrics v0.0.0-20191214191643-6b1944c9f765/go.mod h1:5V7rewilItwK0cz4nomU0b3XCcees2Ka5EBYWS1HBeM=
k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo=
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/cli-utils v0.20.2 h1:jNMu4ExtvFXlmKqZMDJqySqK55vGtVRqoLht6eIMffw=
sigs.k8s.io/cli-utils v0.20.2/go.mod h1:uT5cVxMrOoRplL8umtrJx5R51ZWsIKD7lQfPtot80uA=
sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9NPsg=
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
sigs.k8s.io/kustomize/cmd/config v0.8.1 h1:VURvPtiIBfzJ1lp5K0Oj6iHLobhbI6HJR1lECuuUJE8=
sigs.k8s.io/kustomize/cmd/config v0.8.1/go.mod h1:6+jNbGFOfz2fTq4NoLJcCp7A9JIgwtzq5wP5j1kCi6o=
sigs.k8s.io/kustomize/kyaml v0.8.1/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
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/kustomize/cmd/config v0.8.4 h1:Lo26VjENBVfAOJu0v6w6C1cv5Zp9K8XRs39/0cb87+k=
sigs.k8s.io/kustomize/cmd/config v0.8.4/go.mod h1:1+URiyIJrjdxCdCNDuh2SLyf+I36txRgubFI3PIg2Gc=
sigs.k8s.io/kustomize/kyaml v0.9.3 h1:kZ5HnNmmnbndSXFivrAVM6u3Ik1dwu4kbpaV8KNwy8I=
sigs.k8s.io/kustomize/kyaml v0.9.3/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-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=
sigs.k8s.io/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/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=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI=

View File

@@ -15,10 +15,11 @@ import (
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/k8sdeps/validator"
"sigs.k8s.io/kustomize/api/konfig"
shell_complete "sigs.k8s.io/kustomize/cmd/config/complete"
"sigs.k8s.io/kustomize/cmd/config/completion"
"sigs.k8s.io/kustomize/kustomize/v3/internal/commands/build"
"sigs.k8s.io/kustomize/kustomize/v3/internal/commands/create"
"sigs.k8s.io/kustomize/kustomize/v3/internal/commands/edit"
"sigs.k8s.io/kustomize/kustomize/v3/internal/commands/openapi"
"sigs.k8s.io/kustomize/kustomize/v3/internal/commands/version"
)
@@ -38,11 +39,12 @@ See https://sigs.k8s.io/kustomize
uf := kunstruct.NewKunstructuredFactoryImpl()
v := validator.NewKustValidator()
c.AddCommand(
shell_complete.NewCommand(),
completion.NewCommand(),
build.NewCmdBuild(stdOut),
edit.NewCmdEdit(fSys, v, uf),
create.NewCmdCreate(fSys, uf),
version.NewCmdVersion(stdOut),
openapi.NewCmdOpenAPI(stdOut),
)
configcobra.AddCommands(c, "kustomize")

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