From 8231b17c319c872687521cf4555e845afac00b96 Mon Sep 17 00:00:00 2001 From: Marc Brugger Date: Thu, 7 Nov 2019 16:30:01 +0100 Subject: [PATCH 01/81] print gvk information on existing resource conflict Signed-off-by: Marc Brugger --- pkg/action/validate.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/action/validate.go b/pkg/action/validate.go index 526a4c7fc..30a1d1197 100644 --- a/pkg/action/validate.go +++ b/pkg/action/validate.go @@ -33,7 +33,8 @@ func existingResourceConflict(resources kube.ResourceList) error { } helper := resource.NewHelper(info.Client, info.Mapping) - if _, err := helper.Get(info.Namespace, info.Name, info.Export); err != nil { + existing, err := helper.Get(info.Namespace, info.Name, info.Export) + if err != nil { if apierrors.IsNotFound(err) { return nil } @@ -41,7 +42,7 @@ func existingResourceConflict(resources kube.ResourceList) error { return errors.Wrap(err, "could not get information about the resource") } - return fmt.Errorf("existing resource conflict: kind: %s, namespace: %s, name: %s", info.Mapping.GroupVersionKind.Kind, info.Namespace, info.Name) + return fmt.Errorf("existing resource conflict: namespace: %s, name: %s, existing: [gvk: %s, ] / new: [gvk: %s]", info.Namespace, info.Name, existing.GetObjectKind().GroupVersionKind(), info.Mapping.GroupVersionKind) }) return err } From d2ab24c7bffd9a518d37ae6cdd1c5c5456b9fe0b Mon Sep 17 00:00:00 2001 From: Dean Coakley Date: Sun, 17 Nov 2019 00:02:05 +0000 Subject: [PATCH 02/81] Add s390x build target Signed-off-by: Dean Coakley --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e48a20fd5..0185b249a 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ BINDIR := $(CURDIR)/bin DIST_DIRS := find * -type d -exec -TARGETS := darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64le windows/amd64 +TARGETS := darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64le linux/s390x windows/amd64 BINNAME ?= helm GOPATH = $(shell go env GOPATH) From 67e57a5fbb7b210e534157b8f67c15ffc3445453 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Tue, 29 Oct 2019 11:17:54 -0700 Subject: [PATCH 03/81] feat(install): introduce --disable-openapi-validation When enabled, during the rendering process, this feature flag will not validate rendered templates against the Kubernetes OpenAPI Schema. Signed-off-by: Matthew Fisher --- cmd/helm/install.go | 1 + pkg/action/install.go | 37 +++++++++++++++++++------------------ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/cmd/helm/install.go b/cmd/helm/install.go index 176250f84..56b1bca2f 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -138,6 +138,7 @@ func addInstallFlags(f *pflag.FlagSet, client *action.Install, valueOpts *values f.StringVar(&client.Description, "description", "", "add a custom description") f.BoolVar(&client.Devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored") f.BoolVar(&client.DependencyUpdate, "dependency-update", false, "run helm dependency update before installing the chart") + f.BoolVar(&client.DisableOpenAPIValidation, "disable-openapi-validation", false, "if set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema") f.BoolVar(&client.Atomic, "atomic", false, "if set, installation process purges chart on fail. The --wait flag will be set automatically if --atomic is used") f.BoolVar(&client.SkipCRDs, "skip-crds", false, "if set, no CRDs will be installed. By default, CRDs are installed if not already present") f.BoolVar(&client.SubNotes, "render-subchart-notes", false, "if set, render subchart notes along with the parent") diff --git a/pkg/action/install.go b/pkg/action/install.go index 89a343a6f..c48b9e930 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -67,23 +67,24 @@ type Install struct { ChartPathOptions - ClientOnly bool - DryRun bool - DisableHooks bool - Replace bool - Wait bool - Devel bool - DependencyUpdate bool - Timeout time.Duration - Namespace string - ReleaseName string - GenerateName bool - NameTemplate string - Description string - OutputDir string - Atomic bool - SkipCRDs bool - SubNotes bool + ClientOnly bool + DryRun bool + DisableHooks bool + Replace bool + Wait bool + Devel bool + DependencyUpdate bool + Timeout time.Duration + Namespace string + ReleaseName string + GenerateName bool + NameTemplate string + Description string + OutputDir string + Atomic bool + SkipCRDs bool + SubNotes bool + DisableOpenAPIValidation bool // APIVersions allows a manual set of supported API Versions to be passed // (for things like templating). These are ignored if ClientOnly is false APIVersions chartutil.VersionSet @@ -232,7 +233,7 @@ func (i *Install) Run(chrt *chart.Chart, vals map[string]interface{}) (*release. // Mark this release as in-progress rel.SetStatus(release.StatusPendingInstall, "Initial install underway") - resources, err := i.cfg.KubeClient.Build(bytes.NewBufferString(rel.Manifest), true) + resources, err := i.cfg.KubeClient.Build(bytes.NewBufferString(rel.Manifest), !i.DisableOpenAPIValidation) if err != nil { return nil, errors.Wrap(err, "unable to build kubernetes objects from release manifest") } From 4d8160eedf43db8ed137906a8af0c5d67e03e4fe Mon Sep 17 00:00:00 2001 From: Andreas Sommer Date: Wed, 30 Oct 2019 22:22:42 +0100 Subject: [PATCH 04/81] feat(template): process manifests in file path order, then in order found in each file (before sorting manifests) Signed-off-by: Andreas Sommer --- cmd/helm/helm_test.go | 39 ++-- cmd/helm/template_test.go | 8 + cmd/helm/testdata/output/object-order.txt | 191 ++++++++++++++++++ .../testcharts/object-order/Chart.yaml | 5 + .../object-order/templates/01-a.yml | 57 ++++++ .../object-order/templates/02-b.yml | 143 +++++++++++++ .../testcharts/object-order/values.yaml | 0 pkg/releaseutil/kind_sorter.go | 8 +- pkg/releaseutil/kind_sorter_test.go | 8 +- pkg/releaseutil/manifest.go | 18 +- pkg/releaseutil/manifest_sorter.go | 29 ++- 11 files changed, 472 insertions(+), 34 deletions(-) create mode 100644 cmd/helm/testdata/output/object-order.txt create mode 100644 cmd/helm/testdata/testcharts/object-order/Chart.yaml create mode 100644 cmd/helm/testdata/testcharts/object-order/templates/01-a.yml create mode 100644 cmd/helm/testdata/testcharts/object-order/templates/02-b.yml create mode 100644 cmd/helm/testdata/testcharts/object-order/values.yaml diff --git a/cmd/helm/helm_test.go b/cmd/helm/helm_test.go index 924e8e9d3..a08720e7a 100644 --- a/cmd/helm/helm_test.go +++ b/cmd/helm/helm_test.go @@ -47,24 +47,26 @@ func init() { func runTestCmd(t *testing.T, tests []cmdTestCase) { t.Helper() for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - defer resetEnv()() - - storage := storageFixture() - for _, rel := range tt.rels { - if err := storage.Create(rel); err != nil { - t.Fatal(err) + for i := 0; i <= tt.repeat; i++ { + t.Run(tt.name, func(t *testing.T) { + defer resetEnv()() + + storage := storageFixture() + for _, rel := range tt.rels { + if err := storage.Create(rel); err != nil { + t.Fatal(err) + } } - } - t.Log("running cmd: ", tt.cmd) - _, out, err := executeActionCommandC(storage, tt.cmd) - if (err != nil) != tt.wantError { - t.Errorf("expected error, got '%v'", err) - } - if tt.golden != "" { - test.AssertGoldenString(t, out, tt.golden) - } - }) + t.Logf("running cmd (attempt %d): %s", i+1, tt.cmd) + _, out, err := executeActionCommandC(storage, tt.cmd) + if (err != nil) != tt.wantError { + t.Errorf("expected error, got '%v'", err) + } + if tt.golden != "" { + test.AssertGoldenString(t, out, tt.golden) + } + }) + } } } @@ -124,6 +126,9 @@ type cmdTestCase struct { wantError bool // Rels are the available releases at the start of the test. rels []*release.Release + // Number of repeats (in case a feature was previously flaky and the test checks + // it's now stably producing identical results). 0 means test is run exactly once. + repeat int } func executeActionCommand(cmd string) (*cobra.Command, string, error) { diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go index 735829432..35a8e996b 100644 --- a/cmd/helm/template_test.go +++ b/cmd/helm/template_test.go @@ -84,6 +84,14 @@ func TestTemplateCmd(t *testing.T) { cmd: fmt.Sprintf("template '%s' --include-crds", chartPath), golden: "output/template-with-crds.txt", }, + { + name: "sorted output of manifests (order of filenames, then order of objects within each YAML file)", + cmd: fmt.Sprintf("template '%s'", "testdata/testcharts/object-order"), + golden: "output/object-order.txt", + // Helm previously used random file order. Repeat the test so we + // don't accidentally get the expected result. + repeat: 10, + }, } runTestCmd(t, tests) } diff --git a/cmd/helm/testdata/output/object-order.txt b/cmd/helm/testdata/output/object-order.txt new file mode 100644 index 000000000..307f928f2 --- /dev/null +++ b/cmd/helm/testdata/output/object-order.txt @@ -0,0 +1,191 @@ +--- +# Source: object-order/templates/01-a.yml +# 1 +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: first +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress +--- +# Source: object-order/templates/01-a.yml +# 2 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: second +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress +--- +# Source: object-order/templates/01-a.yml +# 3 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: third +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress +--- +# Source: object-order/templates/02-b.yml +# 5 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: fifth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress +--- +# Source: object-order/templates/02-b.yml +# 7 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: seventh +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress +--- +# Source: object-order/templates/02-b.yml +# 8 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: eighth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress +--- +# Source: object-order/templates/02-b.yml +# 9 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: ninth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress +--- +# Source: object-order/templates/02-b.yml +# 10 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: tenth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress +--- +# Source: object-order/templates/02-b.yml +# 11 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: eleventh +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress +--- +# Source: object-order/templates/02-b.yml +# 12 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: twelfth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress +--- +# Source: object-order/templates/02-b.yml +# 13 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: thirteenth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress +--- +# Source: object-order/templates/02-b.yml +# 14 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: fourteenth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress +--- +# Source: object-order/templates/02-b.yml +# 15 (11th object within 02-b.yml, in order to test `SplitManifests` which assigns `manifest-10` +# to this object which should then come *after* `manifest-9`) +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: fifteenth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress +--- +# Source: object-order/templates/01-a.yml +# 4 (Deployment should come after all NetworkPolicy manifests, since 'helm template' outputs in install order) +apiVersion: apps/v1 +kind: Deployment +metadata: + name: fourth +spec: + selector: + matchLabels: + pod: fourth + replicas: 1 + template: + metadata: + labels: + pod: fourth + spec: + containers: + - name: hello-world + image: gcr.io/google-samples/node-hello:1.0 +--- +# Source: object-order/templates/02-b.yml +# 6 (implementation detail: currently, 'helm template' outputs hook manifests last; and yes, NetworkPolicy won't make a reasonable hook, this is just a dummy unit test manifest) +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + annotations: + "helm.sh/hook": pre-install + name: sixth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress diff --git a/cmd/helm/testdata/testcharts/object-order/Chart.yaml b/cmd/helm/testdata/testcharts/object-order/Chart.yaml new file mode 100644 index 000000000..d2eb42fd7 --- /dev/null +++ b/cmd/helm/testdata/testcharts/object-order/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: object-order +description: Test ordering of manifests in output +type: application +version: 0.1.0 diff --git a/cmd/helm/testdata/testcharts/object-order/templates/01-a.yml b/cmd/helm/testdata/testcharts/object-order/templates/01-a.yml new file mode 100644 index 000000000..32aa4a475 --- /dev/null +++ b/cmd/helm/testdata/testcharts/object-order/templates/01-a.yml @@ -0,0 +1,57 @@ +# 1 +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: first +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress + +--- + +# 2 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: second +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress + +--- + +# 3 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: third +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress + +--- + +# 4 (Deployment should come after all NetworkPolicy manifests, since 'helm template' outputs in install order) +apiVersion: apps/v1 +kind: Deployment +metadata: + name: fourth +spec: + selector: + matchLabels: + pod: fourth + replicas: 1 + template: + metadata: + labels: + pod: fourth + spec: + containers: + - name: hello-world + image: gcr.io/google-samples/node-hello:1.0 diff --git a/cmd/helm/testdata/testcharts/object-order/templates/02-b.yml b/cmd/helm/testdata/testcharts/object-order/templates/02-b.yml new file mode 100644 index 000000000..895db8cf7 --- /dev/null +++ b/cmd/helm/testdata/testcharts/object-order/templates/02-b.yml @@ -0,0 +1,143 @@ +# 5 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: fifth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress + +--- + +# 6 (implementation detail: currently, 'helm template' outputs hook manifests last; and yes, NetworkPolicy won't make a reasonable hook, this is just a dummy unit test manifest) +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + annotations: + "helm.sh/hook": pre-install + name: sixth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress + +--- + +# 7 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: seventh +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress + +--- + +# 8 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: eighth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress + +--- + +# 9 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: ninth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress + +--- + +# 10 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: tenth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress + +--- + +# 11 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: eleventh +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress + +--- + +# 12 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: twelfth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress + +--- + +# 13 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: thirteenth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress + +--- + +# 14 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: fourteenth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress + +--- + +# 15 (11th object within 02-b.yml, in order to test `SplitManifests` which assigns `manifest-10` +# to this object which should then come *after* `manifest-9`) +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: fifteenth +spec: + podSelector: {} + policyTypes: + - Egress + - Ingress diff --git a/cmd/helm/testdata/testcharts/object-order/values.yaml b/cmd/helm/testdata/testcharts/object-order/values.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/pkg/releaseutil/kind_sorter.go b/pkg/releaseutil/kind_sorter.go index a5110a100..874a47c2a 100644 --- a/pkg/releaseutil/kind_sorter.go +++ b/pkg/releaseutil/kind_sorter.go @@ -101,10 +101,10 @@ var UninstallOrder KindSortOrder = []string{ // sortByKind does an in-place sort of manifests by Kind. // -// Results are sorted by 'ordering' +// Results are sorted by 'ordering', keeping order of items with equal kind/priority func sortByKind(manifests []Manifest, ordering KindSortOrder) []Manifest { ks := newKindSorter(manifests, ordering) - sort.Sort(ks) + sort.Stable(ks) return ks.manifests } @@ -134,13 +134,11 @@ func (k *kindSorter) Less(i, j int) bool { b := k.manifests[j] first, aok := k.ordering[a.Head.Kind] second, bok := k.ordering[b.Head.Kind] - // if same kind (including unknown) sub sort alphanumeric if first == second { // if both are unknown and of different kind sort by kind alphabetically if !aok && !bok && a.Head.Kind != b.Head.Kind { return a.Head.Kind < b.Head.Kind } - return a.Name < b.Name } // unknown kind is last if !aok { @@ -149,6 +147,6 @@ func (k *kindSorter) Less(i, j int) bool { if !bok { return true } - // sort different kinds + // sort different kinds, keep original order if same priority return first < second } diff --git a/pkg/releaseutil/kind_sorter_test.go b/pkg/releaseutil/kind_sorter_test.go index 93d8ae782..e1dfc39cc 100644 --- a/pkg/releaseutil/kind_sorter_test.go +++ b/pkg/releaseutil/kind_sorter_test.go @@ -185,8 +185,8 @@ func TestKindSorter(t *testing.T) { } } -// TestKindSorterSubSort verifies manifests of same kind are also sorted alphanumeric -func TestKindSorterSubSort(t *testing.T) { +// TestKindSorterKeepOriginalOrder verifies manifests of same kind are kept in original order +func TestKindSorterKeepOriginalOrder(t *testing.T) { manifests := []Manifest{ { Name: "a", @@ -230,8 +230,8 @@ func TestKindSorterSubSort(t *testing.T) { order KindSortOrder expected string }{ - // expectation is sorted by kind (unknown is last) and then sub sorted alphabetically within each group - {"cm,clusterRole,clusterRoleBinding,Unknown,Unknown2", InstallOrder, "01Aa!zu1u2t3"}, + // expectation is sorted by kind (unknown is last) and within each group of same kind, the order is kept + {"cm,clusterRole,clusterRoleBinding,Unknown,Unknown2", InstallOrder, "01aAz!u2u1t3"}, } { var buf bytes.Buffer t.Run(test.description, func(t *testing.T) { diff --git a/pkg/releaseutil/manifest.go b/pkg/releaseutil/manifest.go index 37503b390..0b04a4599 100644 --- a/pkg/releaseutil/manifest.go +++ b/pkg/releaseutil/manifest.go @@ -19,6 +19,7 @@ package releaseutil import ( "fmt" "regexp" + "strconv" "strings" ) @@ -37,8 +38,9 @@ var sep = regexp.MustCompile("(?:^|\\s*\n)---\\s*") // SplitManifests takes a string of manifest and returns a map contains individual manifests func SplitManifests(bigFile string) map[string]string { // Basically, we're quickly splitting a stream of YAML documents into an - // array of YAML docs. In the current implementation, the file name is just - // a place holder, and doesn't have any further meaning. + // array of YAML docs. The file name is just a place holder, but should be + // integer-sortable so that manifests get output in the same order as the + // input (see `BySplitManifestsOrder`). tpl := "manifest-%d" res := map[string]string{} // Making sure that any extra whitespace in YAML stream doesn't interfere in splitting documents correctly. @@ -56,3 +58,15 @@ func SplitManifests(bigFile string) map[string]string { } return res } + +// BySplitManifestsOrder sorts by in-file manifest order, as provided in function `SplitManifests` +type BySplitManifestsOrder []string + +func (a BySplitManifestsOrder) Len() int { return len(a) } +func (a BySplitManifestsOrder) Less(i, j int) bool { + // Split `manifest-%d` + anum, _ := strconv.ParseInt(a[i][len("manifest-"):], 10, 0) + bnum, _ := strconv.ParseInt(a[j][len("manifest-"):], 10, 0) + return anum < bnum +} +func (a BySplitManifestsOrder) Swap(i, j int) { a[i], a[j] = a[j], a[i] } diff --git a/pkg/releaseutil/manifest_sorter.go b/pkg/releaseutil/manifest_sorter.go index 5f4b4e8d9..24b0c3c95 100644 --- a/pkg/releaseutil/manifest_sorter.go +++ b/pkg/releaseutil/manifest_sorter.go @@ -19,6 +19,7 @@ package releaseutil import ( "log" "path" + "sort" "strconv" "strings" @@ -74,10 +75,17 @@ var events = map[string]release.HookEvent{ // // Files that do not parse into the expected format are simply placed into a map and // returned. -func SortManifests(files map[string]string, apis chartutil.VersionSet, sort KindSortOrder) ([]*release.Hook, []Manifest, error) { +func SortManifests(files map[string]string, apis chartutil.VersionSet, ordering KindSortOrder) ([]*release.Hook, []Manifest, error) { result := &result{} - for filePath, c := range files { + var sortedFilePaths []string + for filePath := range files { + sortedFilePaths = append(sortedFilePaths, filePath) + } + sort.Strings(sortedFilePaths) + + for _, filePath := range sortedFilePaths { + content := files[filePath] // Skip partials. We could return these as a separate map, but there doesn't // seem to be any need for that at this time. @@ -85,12 +93,12 @@ func SortManifests(files map[string]string, apis chartutil.VersionSet, sort Kind continue } // Skip empty files and log this. - if strings.TrimSpace(c) == "" { + if strings.TrimSpace(content) == "" { continue } manifestFile := &manifestFile{ - entries: SplitManifests(c), + entries: SplitManifests(content), path: filePath, apis: apis, } @@ -100,7 +108,7 @@ func SortManifests(files map[string]string, apis chartutil.VersionSet, sort Kind } } - return result.hooks, sortByKind(result.generic, sort), nil + return result.hooks, sortByKind(result.generic, ordering), nil } // sort takes a manifestFile object which may contain multiple resource definition @@ -123,7 +131,16 @@ func SortManifests(files map[string]string, apis chartutil.VersionSet, sort Kind // annotations: // helm.sh/hook-delete-policy: hook-succeeded func (file *manifestFile) sort(result *result) error { - for _, m := range file.entries { + // Go through manifests in order found in file (function `SplitManifests` creates integer-sortable keys) + var sortedEntryKeys []string + for entryKey := range file.entries { + sortedEntryKeys = append(sortedEntryKeys, entryKey) + } + sort.Sort(BySplitManifestsOrder(sortedEntryKeys)) + + for _, entryKey := range sortedEntryKeys { + m := file.entries[entryKey] + var entry SimpleHead if err := yaml.Unmarshal([]byte(m), &entry); err != nil { return errors.Wrapf(err, "YAML parse error on %s", file.path) From 1c6424cb189817c46dc7ea3e3812f7f75df52cff Mon Sep 17 00:00:00 2001 From: Vibhav Bobade Date: Tue, 17 Dec 2019 01:30:41 +0530 Subject: [PATCH 05/81] fix(install) crd install with apiextensions.k8s.io/v1 Signed-off-by: Vibhav Bobade --- pkg/kube/client.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index ab1f600ff..1811a6bfb 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -30,6 +30,7 @@ import ( "github.com/pkg/errors" batch "k8s.io/api/batch/v1" v1 "k8s.io/api/core/v1" + apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -60,6 +61,10 @@ func New(getter genericclioptions.RESTClientGetter) *Client { getter = genericclioptions.NewConfigFlags(true) } // Add CRDs to the scheme. They are missing by default. + if err := apiextv1.AddToScheme(scheme.Scheme); err != nil { + // This should never happen. + panic(err) + } if err := apiextv1beta1.AddToScheme(scheme.Scheme); err != nil { // This should never happen. panic(err) From 3973fa877f766f8aa113db0e04fb070bc5e4dd96 Mon Sep 17 00:00:00 2001 From: Jakub Bielecki Date: Fri, 15 Nov 2019 12:07:10 +0100 Subject: [PATCH 06/81] doc(helmpath) move licensing info out of godoc Add intervening line into lazypath.go, so that license is not treated by godoc as a package description. Standardize license comment for xdg package. Add missing package descriptions. Signed-off-by: Jakub Bielecki --- pkg/helmpath/home.go | 1 + pkg/helmpath/lazypath.go | 1 + pkg/helmpath/xdg/xdg.go | 26 ++++++++++++++++---------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/pkg/helmpath/home.go b/pkg/helmpath/home.go index 0b0f110a5..760d068a6 100644 --- a/pkg/helmpath/home.go +++ b/pkg/helmpath/home.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package helmpath calculates filesystem paths to Helm's configuration, cache and data. package helmpath // This helper builds paths to Helm's configuration, cache and data paths. diff --git a/pkg/helmpath/lazypath.go b/pkg/helmpath/lazypath.go index 5fecfc75f..0b9068671 100644 --- a/pkg/helmpath/lazypath.go +++ b/pkg/helmpath/lazypath.go @@ -10,6 +10,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. + package helmpath import ( diff --git a/pkg/helmpath/xdg/xdg.go b/pkg/helmpath/xdg/xdg.go index 010e1138b..eaa3e6864 100644 --- a/pkg/helmpath/xdg/xdg.go +++ b/pkg/helmpath/xdg/xdg.go @@ -1,16 +1,22 @@ -// Copyright The Helm Authors. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at +/* +Copyright The Helm Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 +http://www.apache.org/licenses/LICENSE-2.0 -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Package xdg holds constants pertaining to XDG Base Directory Specification. +// +// The XDG Base Directory Specification https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html +// specifies the environment variables that define user-specific base directories for various categories of files. package xdg const ( From d564d4bf2d6c6a9781439db231c4aaa1d7a916f8 Mon Sep 17 00:00:00 2001 From: raffaelespazzoli Date: Tue, 22 Oct 2019 03:00:26 +0000 Subject: [PATCH 07/81] first lookup template function implementation Signed-off-by: raffaelespazzoli --- pkg/engine/funcs.go | 1 + pkg/engine/lookup_func.go | 118 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 pkg/engine/lookup_func.go diff --git a/pkg/engine/funcs.go b/pkg/engine/funcs.go index dac105e74..eb4a398f4 100644 --- a/pkg/engine/funcs.go +++ b/pkg/engine/funcs.go @@ -53,6 +53,7 @@ func funcMap() template.FuncMap { "fromYaml": fromYAML, "toJson": toJSON, "fromJson": fromJSON, + "lookup" : lookup, // This is a placeholder for the "include" function, which is // late-bound to a template. By declaring it here, we preserve the diff --git a/pkg/engine/lookup_func.go b/pkg/engine/lookup_func.go new file mode 100644 index 000000000..fe127d8f3 --- /dev/null +++ b/pkg/engine/lookup_func.go @@ -0,0 +1,118 @@ +package engine + +import ( + "flag" + "log" + "os" + "path/filepath" + "strings" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/discovery" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" +) + +var config *rest.Config +var addLookupFunction = false + +func init() { + // try the out-cluster config, this will default to the in-cluster config is not successful + var kubeconfig *string + if home := homeDir(); home != "" { + kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file") + } else { + kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file") + } + flag.Parse() + + // use the current context in kubeconfig + config1, err := clientcmd.BuildConfigFromFlags("", *kubeconfig) + if err == nil { + addLookupFunction = true + config = config1 + } + return +} + +func homeDir() string { + if h := os.Getenv("HOME"); h != "" { + return h + } + return os.Getenv("USERPROFILE") // windows +} + +func lookup(apiversion string, resource string, namespace string, name string) (map[string]interface{}, error) { + var client dynamic.ResourceInterface + c, err := getDynamicClientOnKind(apiversion, resource) + if err != nil { + return map[string]interface{}{}, err + } + if namespace != "" { + client = c.Namespace(namespace) + } else { + client = c + } + if name != "" { + //this will return a single object + obj, err := client.Get(name, metav1.GetOptions{}) + if err != nil { + return map[string]interface{}{}, err + } + return obj.Object, nil + } + //this will return a list + obj, err := client.List(metav1.ListOptions{}) + if err != nil { + return map[string]interface{}{}, err + } + return obj.Object, nil + +} + +// GetDynamicClientOnUnstructured returns a dynamic client on an Unstructured type. This client can be further namespaced. +func getDynamicClientOnKind(apiversion string, kind string) (dynamic.NamespaceableResourceInterface, error) { + gvk := schema.FromAPIVersionAndKind(apiversion, kind) + apiRes, err := getAPIReourceForGVK(gvk) + if err != nil { + log.Printf("[ERROR] unable to get apiresource from unstructured: %s , error %s", gvk.String(), err) + return nil, err + } + gvr := schema.GroupVersionResource{ + Group: apiRes.Group, + Version: apiRes.Version, + Resource: apiRes.Name, + } + intf, err := dynamic.NewForConfig(config) + if err != nil { + log.Printf("[ERROR] unable to get dynamic client %s", err) + return nil, err + } + res := intf.Resource(gvr) + return res, nil +} + +func getAPIReourceForGVK(gvk schema.GroupVersionKind) (metav1.APIResource, error) { + res := metav1.APIResource{} + discoveryClient, err := discovery.NewDiscoveryClientForConfig(config) + if err != nil { + log.Printf("[ERROR] unable to create discovery client %s", err) + return res, err + } + resList, err := discoveryClient.ServerResourcesForGroupVersion(gvk.GroupVersion().String()) + if err != nil { + log.Printf("[ERROR] unable to retrieve resouce list for: %s , error: %s", gvk.GroupVersion().String(), err) + return res, err + } + for _, resource := range resList.APIResources { + if resource.Kind == gvk.Kind && !strings.Contains(resource.Name, "/") { + res = resource + res.Group = gvk.Group + res.Version = gvk.Version + break + } + } + return res, nil +} From 30d245a0e30804b154574a90a23e697ab3724dca Mon Sep 17 00:00:00 2001 From: raffaelespazzoli Date: Wed, 23 Oct 2019 06:33:27 -0400 Subject: [PATCH 08/81] added check on namespaced resource Signed-off-by: raffaelespazzoli --- pkg/engine/lookup_func.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/engine/lookup_func.go b/pkg/engine/lookup_func.go index fe127d8f3..fd3768292 100644 --- a/pkg/engine/lookup_func.go +++ b/pkg/engine/lookup_func.go @@ -46,11 +46,11 @@ func homeDir() string { func lookup(apiversion string, resource string, namespace string, name string) (map[string]interface{}, error) { var client dynamic.ResourceInterface - c, err := getDynamicClientOnKind(apiversion, resource) + c, namespaced, err := getDynamicClientOnKind(apiversion, resource) if err != nil { return map[string]interface{}{}, err } - if namespace != "" { + if namespaced && namespace != "" { client = c.Namespace(namespace) } else { client = c @@ -73,12 +73,12 @@ func lookup(apiversion string, resource string, namespace string, name string) ( } // GetDynamicClientOnUnstructured returns a dynamic client on an Unstructured type. This client can be further namespaced. -func getDynamicClientOnKind(apiversion string, kind string) (dynamic.NamespaceableResourceInterface, error) { +func getDynamicClientOnKind(apiversion string, kind string) (dynamic.NamespaceableResourceInterface, bool, error) { gvk := schema.FromAPIVersionAndKind(apiversion, kind) apiRes, err := getAPIReourceForGVK(gvk) if err != nil { log.Printf("[ERROR] unable to get apiresource from unstructured: %s , error %s", gvk.String(), err) - return nil, err + return nil, false, err } gvr := schema.GroupVersionResource{ Group: apiRes.Group, @@ -88,10 +88,10 @@ func getDynamicClientOnKind(apiversion string, kind string) (dynamic.Namespaceab intf, err := dynamic.NewForConfig(config) if err != nil { log.Printf("[ERROR] unable to get dynamic client %s", err) - return nil, err + return nil, false, err } res := intf.Resource(gvr) - return res, nil + return res, apiRes.Namespaced, nil } func getAPIReourceForGVK(gvk schema.GroupVersionKind) (metav1.APIResource, error) { From 02ce01b2415fe270a760c984f2e0158b18476573 Mon Sep 17 00:00:00 2001 From: raffaelespazzoli Date: Wed, 23 Oct 2019 07:51:53 -0400 Subject: [PATCH 09/81] fixed circle ci issues Signed-off-by: raffaelespazzoli --- pkg/engine/funcs.go | 2 +- pkg/engine/lookup_func.go | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/pkg/engine/funcs.go b/pkg/engine/funcs.go index eb4a398f4..6ff10ea72 100644 --- a/pkg/engine/funcs.go +++ b/pkg/engine/funcs.go @@ -53,7 +53,7 @@ func funcMap() template.FuncMap { "fromYaml": fromYAML, "toJson": toJSON, "fromJson": fromJSON, - "lookup" : lookup, + "lookup": lookup, // This is a placeholder for the "include" function, which is // late-bound to a template. By declaring it here, we preserve the diff --git a/pkg/engine/lookup_func.go b/pkg/engine/lookup_func.go index fd3768292..75b822f86 100644 --- a/pkg/engine/lookup_func.go +++ b/pkg/engine/lookup_func.go @@ -16,7 +16,6 @@ import ( ) var config *rest.Config -var addLookupFunction = false func init() { // try the out-cluster config, this will default to the in-cluster config is not successful @@ -31,10 +30,8 @@ func init() { // use the current context in kubeconfig config1, err := clientcmd.BuildConfigFromFlags("", *kubeconfig) if err == nil { - addLookupFunction = true config = config1 } - return } func homeDir() string { @@ -103,7 +100,7 @@ func getAPIReourceForGVK(gvk schema.GroupVersionKind) (metav1.APIResource, error } resList, err := discoveryClient.ServerResourcesForGroupVersion(gvk.GroupVersion().String()) if err != nil { - log.Printf("[ERROR] unable to retrieve resouce list for: %s , error: %s", gvk.GroupVersion().String(), err) + log.Printf("[ERROR] unable to retrieve resource list for: %s , error: %s", gvk.GroupVersion().String(), err) return res, err } for _, resource := range resList.APIResources { From b3495c73530af98d95783d371dc8a577d1c5c65f Mon Sep 17 00:00:00 2001 From: raffaelespazzoli Date: Wed, 23 Oct 2019 08:13:02 -0400 Subject: [PATCH 10/81] added license header Signed-off-by: raffaelespazzoli --- pkg/engine/lookup_func.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pkg/engine/lookup_func.go b/pkg/engine/lookup_func.go index 75b822f86..f8a47ac38 100644 --- a/pkg/engine/lookup_func.go +++ b/pkg/engine/lookup_func.go @@ -1,3 +1,19 @@ +/* +Copyright The Helm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package engine import ( From e98cd621f0c16cf1ee3a53e8324e18bb0f0cc297 Mon Sep 17 00:00:00 2001 From: raffaelespazzoli Date: Mon, 4 Nov 2019 15:24:52 -0500 Subject: [PATCH 11/81] added rest client passed with action configuration Signed-off-by: raffaelespazzoli --- pkg/action/install.go | 7 +++- pkg/engine/engine.go | 15 +++++++ pkg/engine/funcs.go | 1 - pkg/engine/lookup_func.go | 86 +++++++++++++++------------------------ 4 files changed, 54 insertions(+), 55 deletions(-) diff --git a/pkg/action/install.go b/pkg/action/install.go index dc5941810..8f865ddf9 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -436,7 +436,12 @@ func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values } } - files, err := engine.Render(ch, values) + rest, err := c.RESTClientGetter.ToRESTConfig() + if err != nil { + return hs, b, "", err + } + + files, err := engine.RenderWithClient(ch, values, rest) if err != nil { return hs, b, "", err } diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 5a7d54993..c4d5ee5a7 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -27,6 +27,7 @@ import ( "text/template" "github.com/pkg/errors" + "k8s.io/client-go/rest" "helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chartutil" @@ -39,6 +40,8 @@ type Engine struct { Strict bool // In LintMode, some 'required' template values may be missing, so don't fail LintMode bool + // the rest config to connect to te kubernetes api + config *rest.Config } // Render takes a chart, optional values, and value overrides, and attempts to render the Go templates. @@ -71,6 +74,15 @@ func Render(chrt *chart.Chart, values chartutil.Values) (map[string]string, erro return new(Engine).Render(chrt, values) } +// RenderWithClient takes a chart, optional values, and value overrides, and attempts to +// render the Go templates using the default options. This engine is client aware and so can have template +// functions that interact with the client +func RenderWithClient(chrt *chart.Chart, values chartutil.Values, config *rest.Config) (map[string]string, error) { + return Engine{ + config: config, + }.Render(chrt, values) +} + // renderable is an object that can be rendered. type renderable struct { // tpl is the current template. @@ -157,6 +169,9 @@ func (e Engine) initFunMap(t *template.Template, referenceTpls map[string]render } return val, nil } + if e.config != nil { + funcMap["lookup"] = NewLookupFunction(e.config) + } t.Funcs(funcMap) } diff --git a/pkg/engine/funcs.go b/pkg/engine/funcs.go index 6ff10ea72..dac105e74 100644 --- a/pkg/engine/funcs.go +++ b/pkg/engine/funcs.go @@ -53,7 +53,6 @@ func funcMap() template.FuncMap { "fromYaml": fromYAML, "toJson": toJSON, "fromJson": fromJSON, - "lookup": lookup, // This is a placeholder for the "include" function, which is // late-bound to a template. By declaring it here, we preserve the diff --git a/pkg/engine/lookup_func.go b/pkg/engine/lookup_func.go index f8a47ac38..7c5dc78f1 100644 --- a/pkg/engine/lookup_func.go +++ b/pkg/engine/lookup_func.go @@ -17,10 +17,7 @@ limitations under the License. package engine import ( - "flag" "log" - "os" - "path/filepath" "strings" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -28,67 +25,50 @@ import ( "k8s.io/client-go/discovery" "k8s.io/client-go/dynamic" "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" ) -var config *rest.Config +type lookupFunc = func(apiversion string, resource string, namespace string, name string) (map[string]interface{}, error) -func init() { - // try the out-cluster config, this will default to the in-cluster config is not successful - var kubeconfig *string - if home := homeDir(); home != "" { - kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file") - } else { - kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file") - } - flag.Parse() - - // use the current context in kubeconfig - config1, err := clientcmd.BuildConfigFromFlags("", *kubeconfig) - if err == nil { - config = config1 - } -} - -func homeDir() string { - if h := os.Getenv("HOME"); h != "" { - return h - } - return os.Getenv("USERPROFILE") // windows -} - -func lookup(apiversion string, resource string, namespace string, name string) (map[string]interface{}, error) { - var client dynamic.ResourceInterface - c, namespaced, err := getDynamicClientOnKind(apiversion, resource) - if err != nil { - return map[string]interface{}{}, err - } - if namespaced && namespace != "" { - client = c.Namespace(namespace) - } else { - client = c - } - if name != "" { - //this will return a single object - obj, err := client.Get(name, metav1.GetOptions{}) +func NewLookupFunction(config *rest.Config) lookupFunc { + return func(apiversion string, resource string, namespace string, name string) (map[string]interface{}, error) { + var client dynamic.ResourceInterface + c, namespaced, err := getDynamicClientOnKind(apiversion, resource, config) + if err != nil { + return map[string]interface{}{}, err + } + if namespaced && namespace != "" { + client = c.Namespace(namespace) + } else { + client = c + } + if name != "" { + //this will return a single object + obj, err := client.Get(name, metav1.GetOptions{}) + if err != nil { + return map[string]interface{}{}, err + } + return obj.Object, nil + } + //this will return a list + obj, err := client.List(metav1.ListOptions{}) if err != nil { return map[string]interface{}{}, err } return obj.Object, nil } - //this will return a list - obj, err := client.List(metav1.ListOptions{}) - if err != nil { - return map[string]interface{}{}, err - } - return obj.Object, nil - } +// func homeDir() string { +// if h := os.Getenv("HOME"); h != "" { +// return h +// } +// return os.Getenv("USERPROFILE") // windows +// } + // GetDynamicClientOnUnstructured returns a dynamic client on an Unstructured type. This client can be further namespaced. -func getDynamicClientOnKind(apiversion string, kind string) (dynamic.NamespaceableResourceInterface, bool, error) { +func getDynamicClientOnKind(apiversion string, kind string, config *rest.Config) (dynamic.NamespaceableResourceInterface, bool, error) { gvk := schema.FromAPIVersionAndKind(apiversion, kind) - apiRes, err := getAPIReourceForGVK(gvk) + apiRes, err := getAPIReourceForGVK(gvk, config) if err != nil { log.Printf("[ERROR] unable to get apiresource from unstructured: %s , error %s", gvk.String(), err) return nil, false, err @@ -107,7 +87,7 @@ func getDynamicClientOnKind(apiversion string, kind string) (dynamic.Namespaceab return res, apiRes.Namespaced, nil } -func getAPIReourceForGVK(gvk schema.GroupVersionKind) (metav1.APIResource, error) { +func getAPIReourceForGVK(gvk schema.GroupVersionKind, config *rest.Config) (metav1.APIResource, error) { res := metav1.APIResource{} discoveryClient, err := discovery.NewDiscoveryClientForConfig(config) if err != nil { From 8e088fc4a2a616354872b21d9ceb84e9d55a40de Mon Sep 17 00:00:00 2001 From: raffaelespazzoli Date: Mon, 4 Nov 2019 15:39:09 -0500 Subject: [PATCH 12/81] fixed test issue Signed-off-by: raffaelespazzoli --- pkg/action/install.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/pkg/action/install.go b/pkg/action/install.go index 8f865ddf9..1a1ebeeac 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -436,13 +436,21 @@ func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values } } - rest, err := c.RESTClientGetter.ToRESTConfig() - if err != nil { - return hs, b, "", err + var files map[string]string + var err2 error + + if c.RESTClientGetter != nil { + rest, err := c.RESTClientGetter.ToRESTConfig() + if err != nil { + files, err2 = engine.Render(ch, values) + } else { + files, err2 = engine.RenderWithClient(ch, values, rest) + } + } else { + files, err2 = engine.Render(ch, values) } - files, err := engine.RenderWithClient(ch, values, rest) - if err != nil { + if err2 != nil { return hs, b, "", err } From 0bb4eaace77687e8226113df6cafef5791940999 Mon Sep 17 00:00:00 2001 From: raffaelespazzoli Date: Wed, 11 Dec 2019 20:53:29 -0500 Subject: [PATCH 13/81] addressing some feedback from @thomastaylor312 Signed-off-by: raffaelespazzoli --- pkg/engine/lookup_func.go | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/pkg/engine/lookup_func.go b/pkg/engine/lookup_func.go index 7c5dc78f1..747ebee0a 100644 --- a/pkg/engine/lookup_func.go +++ b/pkg/engine/lookup_func.go @@ -47,25 +47,18 @@ func NewLookupFunction(config *rest.Config) lookupFunc { if err != nil { return map[string]interface{}{}, err } - return obj.Object, nil + return obj.UnstructuredContent(), nil } //this will return a list obj, err := client.List(metav1.ListOptions{}) if err != nil { return map[string]interface{}{}, err } - return obj.Object, nil + return obj.UnstructuredContent(), nil } } -// func homeDir() string { -// if h := os.Getenv("HOME"); h != "" { -// return h -// } -// return os.Getenv("USERPROFILE") // windows -// } - -// GetDynamicClientOnUnstructured returns a dynamic client on an Unstructured type. This client can be further namespaced. +// getDynamicClientOnUnstructured returns a dynamic client on an Unstructured type. This client can be further namespaced. func getDynamicClientOnKind(apiversion string, kind string, config *rest.Config) (dynamic.NamespaceableResourceInterface, bool, error) { gvk := schema.FromAPIVersionAndKind(apiversion, kind) apiRes, err := getAPIReourceForGVK(gvk, config) @@ -100,6 +93,7 @@ func getAPIReourceForGVK(gvk schema.GroupVersionKind, config *rest.Config) (meta return res, err } for _, resource := range resList.APIResources { + //if a resource contains a "/" it's referencing a subresource. we don't support suberesource for now. if resource.Kind == gvk.Kind && !strings.Contains(resource.Name, "/") { res = resource res.Group = gvk.Group From a62ba049624d3212619005bc87fec410a248ca22 Mon Sep 17 00:00:00 2001 From: raffaelespazzoli Date: Tue, 17 Dec 2019 08:31:02 -0500 Subject: [PATCH 14/81] additional fixes based on @thomastaylor312 comment Signed-off-by: raffaelespazzoli --- pkg/action/install.go | 5 ++--- pkg/engine/lookup_func.go | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/action/install.go b/pkg/action/install.go index 1a1ebeeac..e185e581b 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -442,10 +442,9 @@ func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values if c.RESTClientGetter != nil { rest, err := c.RESTClientGetter.ToRESTConfig() if err != nil { - files, err2 = engine.Render(ch, values) - } else { - files, err2 = engine.RenderWithClient(ch, values, rest) + return hs, b, "", err } + files, err2 = engine.RenderWithClient(ch, values, rest) } else { files, err2 = engine.Render(ch, values) } diff --git a/pkg/engine/lookup_func.go b/pkg/engine/lookup_func.go index 747ebee0a..c70dda424 100644 --- a/pkg/engine/lookup_func.go +++ b/pkg/engine/lookup_func.go @@ -20,6 +20,7 @@ import ( "log" "strings" + "github.com/pkg/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/discovery" @@ -64,7 +65,7 @@ func getDynamicClientOnKind(apiversion string, kind string, config *rest.Config) apiRes, err := getAPIReourceForGVK(gvk, config) if err != nil { log.Printf("[ERROR] unable to get apiresource from unstructured: %s , error %s", gvk.String(), err) - return nil, false, err + return nil, false, errors.Wrapf(err, "unable to get apiresource from unstructured: %s , error %s", gvk.String()) } gvr := schema.GroupVersionResource{ Group: apiRes.Group, From fa643cfa31af72f06b6d041c310a29bed18f0ac4 Mon Sep 17 00:00:00 2001 From: raffaelespazzoli Date: Tue, 17 Dec 2019 08:37:17 -0500 Subject: [PATCH 15/81] fixed golint Signed-off-by: raffaelespazzoli --- pkg/engine/lookup_func.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/engine/lookup_func.go b/pkg/engine/lookup_func.go index c70dda424..14f2351b4 100644 --- a/pkg/engine/lookup_func.go +++ b/pkg/engine/lookup_func.go @@ -65,7 +65,7 @@ func getDynamicClientOnKind(apiversion string, kind string, config *rest.Config) apiRes, err := getAPIReourceForGVK(gvk, config) if err != nil { log.Printf("[ERROR] unable to get apiresource from unstructured: %s , error %s", gvk.String(), err) - return nil, false, errors.Wrapf(err, "unable to get apiresource from unstructured: %s , error %s", gvk.String()) + return nil, false, errors.Wrapf(err, "unable to get apiresource from unstructured: %s", gvk.String()) } gvr := schema.GroupVersionResource{ Group: apiRes.Group, From f3249b5ee26a913d2cf32c1fce76f8c500fa5259 Mon Sep 17 00:00:00 2001 From: Dean Coakley Date: Wed, 18 Dec 2019 12:08:57 +0000 Subject: [PATCH 16/81] Add new Makefile targets Signed-off-by: Dean Coakley --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d5e36bcd1..fdfacca52 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ BINDIR := $(CURDIR)/bin DIST_DIRS := find * -type d -exec TARGETS := darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64le linux/s390x windows/amd64 -TARGET_OBJS ?= darwin-amd64.tar.gz darwin-amd64.tar.gz.sha256 linux-amd64.tar.gz linux-amd64.tar.gz.sha256 linux-386.tar.gz linux-386.tar.gz.sha256 linux-arm.tar.gz linux-arm.tar.gz.sha256 linux-arm64.tar.gz linux-arm64.tar.gz.sha256 linux-ppc64le.tar.gz linux-ppc64le.tar.gz.sha256 windows-amd64.zip windows-amd64.zip.sha256 +TARGET_OBJS ?= darwin-amd64.tar.gz darwin-amd64.tar.gz.sha256 linux-amd64.tar.gz linux-amd64.tar.gz.sha256 linux-386.tar.gz linux-386.tar.gz.sha256 linux-arm.tar.gz linux-arm.tar.gz.sha256 linux-arm64.tar.gz linux-arm64.tar.gz.sha256 linux-ppc64le.tar.gz linux-ppc64le.tar.gz.sha256 linux-s390x.tar.gz linux-s390x.tar.gz.sha256 windows-amd64.zip windows-amd64.zip.sha256 BINNAME ?= helm GOPATH = $(shell go env GOPATH) From afa612df9d132180837e7c122088d44b1c72df1e Mon Sep 17 00:00:00 2001 From: Adrian Gonzalez-Martin Date: Thu, 19 Dec 2019 13:58:02 +0000 Subject: [PATCH 17/81] Add back fix for CRD patch creation Signed-off-by: Adrian Gonzalez-Martin --- pkg/kube/client.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 96179d19d..07962faac 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -355,7 +355,12 @@ func createPatch(target *resource.Info, current runtime.Object) ([]byte, types.P // returned from ConvertToVersion. Anything that's unstructured should // use the jsonpatch.CreateMergePatch. Strategic Merge Patch is not supported // on objects like CRDs. - if _, ok := versionedObject.(runtime.Unstructured); ok { + _, isUnstructured := versionedObject.(runtime.Unstructured) + + // On newer K8s versions, CRDs aren't unstructured but has this dedicated type + _, isCRD := versionedObject.(*apiextv1beta1.CustomResourceDefinition) + + if isUnstructured || isCRD { // fall back to generic JSON merge patch patch, err := jsonpatch.CreateMergePatch(oldData, newData) return patch, types.MergePatchType, err From a2bbb67839722713d48b3c775d9402efba12c108 Mon Sep 17 00:00:00 2001 From: Jan Heylen Date: Fri, 20 Dec 2019 16:03:53 +0100 Subject: [PATCH 18/81] fix(helm): add .orig as typical backup file Mercurial VCS (hg) backout's can generate '.orig' files to avoid these being picked, generate a .helmignore where also the .orig files are ignored. Signed-off-by: Jan Heylen --- pkg/chartutil/create.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index c67cde04f..4ca813593 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -170,6 +170,7 @@ const defaultIgnore = `# Patterns to ignore when building packages. *.swp *.bak *.tmp +*.orig *~ # Various IDEs .project From 36c06141f8e21ba59f45871a0909ae003c31a277 Mon Sep 17 00:00:00 2001 From: Pierre Humberdroz Date: Fri, 20 Dec 2019 22:35:27 +0100 Subject: [PATCH 19/81] docs: point users to helm hub Signed-off-by: Pierre Humberdroz --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 73fd189d7..745a60c2b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Helm is a tool for managing Charts. Charts are packages of pre-configured Kubern Use Helm to: -- Find and use [popular software packaged as Helm Charts](https://github.com/helm/charts) to run in Kubernetes +- Find and use [popular software packaged as Helm Charts](https://hub.helm.sh) to run in Kubernetes - Share your own applications as Helm Charts - Create reproducible builds of your Kubernetes applications - Intelligently manage your Kubernetes manifest files From cedd48019966d1aad49f386baf9f9808143d419b Mon Sep 17 00:00:00 2001 From: Guangwen Feng Date: Mon, 23 Dec 2019 20:53:10 +0800 Subject: [PATCH 20/81] Add corresponding unit test to the function in resource.go. Signed-off-by: Guangwen Feng --- pkg/kube/resource_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/kube/resource_test.go b/pkg/kube/resource_test.go index 2e13c3253..3c906ceca 100644 --- a/pkg/kube/resource_test.go +++ b/pkg/kube/resource_test.go @@ -37,6 +37,10 @@ func TestResourceList(t *testing.T) { r1 = []*resource.Info{info("foo"), info("bar")} r2 = []*resource.Info{info("bar")} + if r1.Get(info("bar")).Mapping.Resource.Resource != "pod" { + t.Error("expected get pod") + } + diff := r1.Difference(r2) if len(diff) != 1 { t.Error("expected 1 result") From b47a5b746d57e0ca93c9e31066a2c4ef6fa9cdc4 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Wed, 25 Dec 2019 16:07:48 -0500 Subject: [PATCH 21/81] fix(tests): Use relative path to acceptance tests With Helm using go modules, its git repo need not reside under $GOPATH/src/helm.sh anymore. In fact it may be desirable for a user to move it to another location (e.g., to get the debugger to work). In the same train of thought, the acceptance-testing repo, which is not even a go program, need not be in the GOPATH. This commit reduces the requirement on the location of the acceptance-testing repo to a relative path to the helm repo, instead of an absolute path within GOPATH. Signed-off-by: Marc Khouzam --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 611222e28..1e977d3dd 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ DEP = $(GOPATH)/bin/dep GOX = $(GOPATH)/bin/gox GOIMPORTS = $(GOPATH)/bin/goimports -ACCEPTANCE_DIR:=$(GOPATH)/src/helm.sh/acceptance-testing +ACCEPTANCE_DIR:=../acceptance-testing # To specify the subset of acceptance tests to run. '.' means all tests ACCEPTANCE_RUN_TESTS=. From 2eab781b35019ce452738012092f9df4ce9fdf00 Mon Sep 17 00:00:00 2001 From: Frank Lin PIAT Date: Sat, 28 Dec 2019 22:34:21 +0100 Subject: [PATCH 22/81] fix(comp): tail cannot open +2 for reading Signed-off-by: Frank Lin PIAT --- cmd/helm/root.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/helm/root.go b/cmd/helm/root.go index 443d718d5..3405299fd 100644 --- a/cmd/helm/root.go +++ b/cmd/helm/root.go @@ -69,7 +69,7 @@ __helm_override_flags_to_kubectl_flags() __helm_get_repos() { - eval $(__helm_binary_name) repo list 2>/dev/null | \tail +2 | \cut -f1 + eval $(__helm_binary_name) repo list 2>/dev/null | \tail -n +2 | \cut -f1 } __helm_get_contexts() @@ -236,7 +236,7 @@ __helm_list_plugins() __helm_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" local out # Use eval in case helm_binary_name contains a variable (e.g., $HOME/bin/h3) - if out=$(eval $(__helm_binary_name) plugin list 2>/dev/null | \tail +2 | \cut -f1); then + if out=$(eval $(__helm_binary_name) plugin list 2>/dev/null | \tail -n +2 | \cut -f1); then COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) ) fi } From 3eb8df0c5ee5b6e9753cf99440644423e392073e Mon Sep 17 00:00:00 2001 From: Hu Shuai Date: Tue, 31 Dec 2019 13:52:19 +0800 Subject: [PATCH 23/81] Fix a typo "the the" -> "the" Signed-off-by: Hu Shuai --- internal/monocular/search.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/monocular/search.go b/internal/monocular/search.go index 61695f554..10e1f2136 100644 --- a/internal/monocular/search.go +++ b/internal/monocular/search.go @@ -58,7 +58,7 @@ type Chart struct { Icon string `json:"icon"` } -// Repo contains the name in monocular the the url for the repository +// Repo contains the name in monocular the url for the repository type Repo struct { Name string `json:"name"` URL string `json:"url"` From 600970459ebda95116f6e029e61f3a0e0117e9c9 Mon Sep 17 00:00:00 2001 From: Phil Grayson Date: Wed, 1 Jan 2020 21:32:25 +0000 Subject: [PATCH 24/81] Do not delete templated CRDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes issue #7279. Prevent the deletion of CRDs that were defined in the `templates/` directory. This makes CRD deletion behaviour consistent with Helm documentation: > CRDs are never deleted. Deleting a CRD automatically deletes all of the > CRD’s contents across all namespaces in the cluster. Consequently, Helm > will not delete CRDs. Previous the documentation only applied to CRDs that were defined in the `crds/` directory. It did not consider that Charts could have CRDs in the `templates/` directory (for example charts that were written before the `crds/` directory feature or if the Chart author needed templated CRDs). Signed-off-by: Phil Grayson --- pkg/kube/client.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 07962faac..be13f237d 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -197,6 +197,11 @@ func (c *Client) Update(original, target ResourceList, force bool) (*Result, err } for _, info := range original.Difference(target) { + if info.Mapping.GroupVersionKind.Kind == "CustomResourceDefinition" { + c.Log("Skipping the deletion of CustomResourceDefinition %q", info.Name) + continue + } + c.Log("Deleting %q in %s...", info.Name, info.Namespace) res.Deleted = append(res.Deleted, info) if err := deleteResource(info); err != nil { @@ -219,6 +224,11 @@ func (c *Client) Delete(resources ResourceList) (*Result, []error) { var errs []error res := &Result{} err := perform(resources, func(info *resource.Info) error { + if info.Mapping.GroupVersionKind.Kind == "CustomResourceDefinition" { + c.Log("Skipping the deletion of CustomResourceDefinition %q", info.Name) + return nil + } + c.Log("Starting delete for %q %s", info.Name, info.Mapping.GroupVersionKind.Kind) if err := c.skipIfNotFound(deleteResource(info)); err != nil { // Collect the error and continue on From a58430a944454ff8e5a560a9d3d70f5e05385310 Mon Sep 17 00:00:00 2001 From: Anton Kvashenkin Date: Thu, 2 Jan 2020 19:32:50 +0400 Subject: [PATCH 25/81] Fix typo in --values cmd flag Fix a small typo in `--values` flag in `helm install/upgrade --help` output. Signed-off-by: Anton Kvashenkin --- cmd/helm/flags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/flags.go b/cmd/helm/flags.go index 467abbd6e..aa22603f4 100644 --- a/cmd/helm/flags.go +++ b/cmd/helm/flags.go @@ -31,7 +31,7 @@ import ( const outputFlag = "output" func addValueOptionsFlags(f *pflag.FlagSet, v *values.Options) { - f.StringSliceVarP(&v.ValueFiles, "values", "f", []string{}, "specify values in a YAML file or a URL(can specify multiple)") + f.StringSliceVarP(&v.ValueFiles, "values", "f", []string{}, "specify values in a YAML file or a URL (can specify multiple)") f.StringArrayVar(&v.Values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringArrayVar(&v.StringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringArrayVar(&v.FileValues, "set-file", []string{}, "set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)") From 476200ed061fff0030c4c3f2918a581735b731eb Mon Sep 17 00:00:00 2001 From: Guangwen Feng Date: Fri, 3 Jan 2020 18:05:23 +0800 Subject: [PATCH 26/81] Add corresponding unit test to the function in resolver.go Signed-off-by: Guangwen Feng --- internal/resolver/resolver_test.go | 58 ++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/internal/resolver/resolver_test.go b/internal/resolver/resolver_test.go index 3828771cc..d93d616ee 100644 --- a/internal/resolver/resolver_test.go +++ b/internal/resolver/resolver_test.go @@ -216,3 +216,61 @@ func TestHashReq(t *testing.T) { }) } } + +func TestGetLocalPath(t *testing.T) { + tests := []struct { + name string + repo string + chartpath string + expect string + err bool + }{ + { + name: "absolute path", + repo: "file:////proc", + expect: "/proc", + }, + { + name: "relative path", + repo: "file://../../../../cmd/helm/testdata/testcharts/signtest", + chartpath: "foo/bar", + expect: "../../cmd/helm/testdata/testcharts/signtest", + }, + { + name: "current directory path", + repo: "../charts/localdependency", + chartpath: "testdata/chartpath/charts", + expect: "testdata/chartpath/charts/localdependency", + }, + { + name: "invalid local path", + repo: "file://../testdata/notexist", + chartpath: "testdata/chartpath", + err: true, + }, + { + name: "invalid path under current directory", + repo: "../charts/nonexistentdependency", + chartpath: "testdata/chartpath/charts", + err: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p, err := GetLocalPath(tt.repo, tt.chartpath) + if err != nil { + if tt.err { + return + } + t.Fatal(err) + } + if tt.err { + t.Fatalf("Expected error in test %q", tt.name) + } + if p != tt.expect { + t.Errorf("%q: expected %q, got %q", tt.name, tt.expect, p) + } + }) + } +} From 40df2f2a636be4a061e252715db6867796c0c5f1 Mon Sep 17 00:00:00 2001 From: Xiang Dai <764524258@qq.com> Date: Mon, 6 Jan 2020 19:33:07 +0800 Subject: [PATCH 27/81] Improve description for `--all` flag (#7144) * Improve description for `--all` flag Signed-off-by: Xiang Dai <764524258@qq.com> * feedback Signed-off-by: Xiang Dai <764524258@qq.com> --- cmd/helm/list.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/helm/list.go b/cmd/helm/list.go index 0da0c21d3..57fc4be3c 100644 --- a/cmd/helm/list.go +++ b/cmd/helm/list.go @@ -32,7 +32,7 @@ import ( ) var listHelp = ` -This command lists all of the releases. +This command lists all of the releases for a specified namespace (uses current namespace context if namespace not specified). By default, it lists only releases that are deployed or failed. Flags like '--uninstalled' and '--all' will alter this behavior. Such flags can be combined: @@ -96,7 +96,7 @@ func newListCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f.BoolVarP(&client.Short, "short", "q", false, "output short (quiet) listing format") f.BoolVarP(&client.ByDate, "date", "d", false, "sort by release date") f.BoolVarP(&client.SortReverse, "reverse", "r", false, "reverse the sort order") - f.BoolVarP(&client.All, "all", "a", false, "show all releases, not just the ones marked deployed or failed") + f.BoolVarP(&client.All, "all", "a", false, "show all releases without any filter applied") f.BoolVar(&client.Uninstalled, "uninstalled", false, "show uninstalled releases (if 'helm uninstall --keep-history' was used)") f.BoolVar(&client.Superseded, "superseded", false, "show superseded releases") f.BoolVar(&client.Uninstalling, "uninstalling", false, "show releases that are currently being uninstalled") From 29cc5efc1853488a1e0cde1c5336063f3297fc85 Mon Sep 17 00:00:00 2001 From: Nguyen Hai Truong Date: Mon, 6 Jan 2020 22:54:47 +0700 Subject: [PATCH 28/81] Remove duplicated words (#7336) Although it is spelling mistakes, it might make an affects while reading. Signed-off-by: Nguyen Hai Truong --- internal/third_party/dep/fs/fs_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/third_party/dep/fs/fs_test.go b/internal/third_party/dep/fs/fs_test.go index bf4b803f8..a9678d8c1 100644 --- a/internal/third_party/dep/fs/fs_test.go +++ b/internal/third_party/dep/fs/fs_test.go @@ -170,7 +170,7 @@ func TestCopyDir(t *testing.T) { func TestCopyDirFail_SrcInaccessible(t *testing.T) { if runtime.GOOS == "windows" { // XXX: setting permissions works differently in - // Microsoft Windows. Skipping this this until a + // Microsoft Windows. Skipping this until a // compatible implementation is provided. t.Skip("skipping on windows") } @@ -209,7 +209,7 @@ func TestCopyDirFail_SrcInaccessible(t *testing.T) { func TestCopyDirFail_DstInaccessible(t *testing.T) { if runtime.GOOS == "windows" { // XXX: setting permissions works differently in - // Microsoft Windows. Skipping this this until a + // Microsoft Windows. Skipping this until a // compatible implementation is provided. t.Skip("skipping on windows") } @@ -309,7 +309,7 @@ func TestCopyDirFailOpen(t *testing.T) { // Microsoft Windows. os.Chmod(..., 0222) below is not // enough for the file to be readonly, and os.Chmod(..., // 0000) returns an invalid argument error. Skipping - // this this until a compatible implementation is + // this until a compatible implementation is // provided. t.Skip("skipping on windows") } @@ -478,7 +478,7 @@ func TestCopyFileSymlink(t *testing.T) { func TestCopyFileFail(t *testing.T) { if runtime.GOOS == "windows" { // XXX: setting permissions works differently in - // Microsoft Windows. Skipping this this until a + // Microsoft Windows. Skipping this until a // compatible implementation is provided. t.Skip("skipping on windows") } @@ -521,7 +521,7 @@ func TestCopyFileFail(t *testing.T) { } // setupInaccessibleDir creates a temporary location with a single -// directory in it, in such a way that that directory is not accessible +// directory in it, in such a way that directory is not accessible // after this function returns. // // op is called with the directory as argument, so that it can create From ad07bb690dbf34e7067171235861a3c0fb9897b6 Mon Sep 17 00:00:00 2001 From: "Jorge I. Gasca" <42793610+jorge-gasca@users.noreply.github.com> Date: Tue, 7 Jan 2020 12:25:15 -0500 Subject: [PATCH 29/81] fix(cmd): Fixes logging on action conf init error (#6909) * fix(cmd): Fixes logging on action conf init error Errors relating to initializing the action config cause helm to exit silently, except when in debug mode. This now emits the useful error. Closes #6863 Signed-off-by: Jorge Gasca * Remove unnecessary formatting of err struct Signed-off-by: Jorge Gasca --- cmd/helm/helm.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index 2c3c9e401..112d5123f 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -68,8 +68,7 @@ func main() { cmd := newRootCmd(actionConfig, os.Stdout, os.Args[1:]) if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), debug); err != nil { - debug("%+v", err) - os.Exit(1) + log.Fatal(err) } if err := cmd.Execute(); err != nil { From de9118b87961c3ec15370d6b77293d6fe36fa88a Mon Sep 17 00:00:00 2001 From: Hu Shuai Date: Wed, 8 Jan 2020 17:19:00 +0800 Subject: [PATCH 30/81] Fix a typo "update" -> "updates" (#7346) Signed-off-by: Hu Shuai --- pkg/storage/storage.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go index 58a7eb06f..6528c48ba 100644 --- a/pkg/storage/storage.go +++ b/pkg/storage/storage.go @@ -66,7 +66,7 @@ func (s *Storage) Create(rls *rspb.Release) error { return s.Driver.Create(makeKey(rls.Name, rls.Version), rls) } -// Update update the release in storage. An error is returned if the +// Update updates the release in storage. An error is returned if the // storage backend fails to update the release or if the release // does not exist. func (s *Storage) Update(rls *rspb.Release) error { From ff0257de29e589f9550aa6c04bc3283d652dc976 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Wed, 8 Jan 2020 09:41:30 -0800 Subject: [PATCH 31/81] fix(tests): use sigs.k8s.io/yaml Signed-off-by: Matthew Fisher --- cmd/helm/repo_add_test.go | 2 +- go.mod | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cmd/helm/repo_add_test.go b/cmd/helm/repo_add_test.go index 1ac61fba8..4dbd0f435 100644 --- a/cmd/helm/repo_add_test.go +++ b/cmd/helm/repo_add_test.go @@ -23,7 +23,7 @@ import ( "sync" "testing" - "gopkg.in/yaml.v2" + "sigs.k8s.io/yaml" "helm.sh/helm/v3/internal/test/ensure" "helm.sh/helm/v3/pkg/repo" diff --git a/go.mod b/go.mod index 8e972fdfe..ed074074d 100644 --- a/go.mod +++ b/go.mod @@ -59,7 +59,6 @@ require ( google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6 // indirect google.golang.org/grpc v1.24.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.2.4 k8s.io/api v0.0.0-20191016110408-35e52d86657a k8s.io/apiextensions-apiserver v0.0.0-20191016113550-5357c4baaf65 k8s.io/apimachinery v0.0.0-20191004115801-a2eda9f80ab8 From ab905010fd3ce671f9e0cd74f4d8ca3bc944c130 Mon Sep 17 00:00:00 2001 From: bakito Date: Wed, 8 Jan 2020 18:42:49 +0100 Subject: [PATCH 32/81] fix error output Signed-off-by: Marc Brugger --- pkg/action/validate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/action/validate.go b/pkg/action/validate.go index 30a1d1197..6bbfc5e8d 100644 --- a/pkg/action/validate.go +++ b/pkg/action/validate.go @@ -42,7 +42,7 @@ func existingResourceConflict(resources kube.ResourceList) error { return errors.Wrap(err, "could not get information about the resource") } - return fmt.Errorf("existing resource conflict: namespace: %s, name: %s, existing: [gvk: %s, ] / new: [gvk: %s]", info.Namespace, info.Name, existing.GetObjectKind().GroupVersionKind(), info.Mapping.GroupVersionKind) + return fmt.Errorf("existing resource conflict: namespace: %s, name: %s, existing_kind: %s, new_kind: %s", info.Namespace, info.Name, existing.GetObjectKind().GroupVersionKind(), info.Mapping.GroupVersionKind) }) return err } From 1230df8822b028177ea265002f6b556c5888ad63 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Wed, 8 Jan 2020 09:46:14 -0800 Subject: [PATCH 33/81] chore(go.sum): run `go mod tidy` Signed-off-by: Matthew Fisher --- go.sum | 4 ---- 1 file changed, 4 deletions(-) diff --git a/go.sum b/go.sum index fb11fdbc4..629d466c2 100644 --- a/go.sum +++ b/go.sum @@ -25,12 +25,8 @@ github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e h1:eb0Pzkt15Bm github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.0.1 h1:2kKm5lb7dKVrt5TYUiAavE6oFc1cFT0057UVGT+JqLk= -github.com/Masterminds/semver/v3 v3.0.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.0.3 h1:znjIyLfpXEDQjOIEWh+ehwpTU14UzUPub3c3sm36u14= github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/sprig/v3 v3.0.0 h1:KSQz7Nb08/3VU9E4ns29dDxcczhOD1q7O1UfM4G3t3g= -github.com/Masterminds/sprig/v3 v3.0.0/go.mod h1:NEUY/Qq8Gdm2xgYA+NwJM6wmfdRV9xkh8h/Rld20R0U= github.com/Masterminds/sprig/v3 v3.0.2 h1:wz22D0CiSctrliXiI9ZO3HoNApweeRGftyDN+BQa3B8= github.com/Masterminds/sprig/v3 v3.0.2/go.mod h1:oesJ8kPONMONaZgtiHNzUShJbksypC5kWczhZAf6+aU= github.com/Masterminds/vcs v1.13.0 h1:USF5TvZGYgIpcbNAEMLfFhHqP08tFZVlUVrmTSpqnyA= From 08663e6bb3c5694726aac665d71be26494475781 Mon Sep 17 00:00:00 2001 From: Daniel Strobusch <1847260+dastrobu@users.noreply.github.com> Date: Wed, 8 Jan 2020 18:54:08 +0100 Subject: [PATCH 34/81] fix(helm): move ServiceAccount before Secret in InstallOrder. Service accounts must be installed before secrets when service account tokens (secrets) are be managed by Helm. Otherwise Kubernetes will delete any service account token right after creation, since there is no service account mounting the token (see https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/#token-controller) Closes #7159. Signed-off-by: Daniel Strobusch <1847260+dastrobu@users.noreply.github.com> --- pkg/releaseutil/kind_sorter.go | 4 ++-- pkg/releaseutil/kind_sorter_test.go | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pkg/releaseutil/kind_sorter.go b/pkg/releaseutil/kind_sorter.go index a5110a100..0402b8bb1 100644 --- a/pkg/releaseutil/kind_sorter.go +++ b/pkg/releaseutil/kind_sorter.go @@ -31,12 +31,12 @@ var InstallOrder KindSortOrder = []string{ "LimitRange", "PodSecurityPolicy", "PodDisruptionBudget", + "ServiceAccount", "Secret", "ConfigMap", "StorageClass", "PersistentVolume", "PersistentVolumeClaim", - "ServiceAccount", "CustomResourceDefinition", "ClusterRole", "ClusterRoleList", @@ -85,12 +85,12 @@ var UninstallOrder KindSortOrder = []string{ "ClusterRoleList", "ClusterRole", "CustomResourceDefinition", - "ServiceAccount", "PersistentVolumeClaim", "PersistentVolume", "StorageClass", "ConfigMap", "Secret", + "ServiceAccount", "PodDisruptionBudget", "PodSecurityPolicy", "LimitRange", diff --git a/pkg/releaseutil/kind_sorter_test.go b/pkg/releaseutil/kind_sorter_test.go index 93d8ae782..1b42383a5 100644 --- a/pkg/releaseutil/kind_sorter_test.go +++ b/pkg/releaseutil/kind_sorter_test.go @@ -40,7 +40,7 @@ func TestKindSorter(t *testing.T) { Head: &SimpleHead{Kind: "ClusterRoleBindingList"}, }, { - Name: "e", + Name: "f", Head: &SimpleHead{Kind: "ConfigMap"}, }, { @@ -84,11 +84,11 @@ func TestKindSorter(t *testing.T) { Head: &SimpleHead{Kind: "NetworkPolicy"}, }, { - Name: "f", + Name: "g", Head: &SimpleHead{Kind: "PersistentVolume"}, }, { - Name: "g", + Name: "h", Head: &SimpleHead{Kind: "PersistentVolumeClaim"}, }, { @@ -132,7 +132,7 @@ func TestKindSorter(t *testing.T) { Head: &SimpleHead{Kind: "RoleBindingList"}, }, { - Name: "d", + Name: "e", Head: &SimpleHead{Kind: "Secret"}, }, { @@ -140,7 +140,7 @@ func TestKindSorter(t *testing.T) { Head: &SimpleHead{Kind: "Service"}, }, { - Name: "h", + Name: "d", Head: &SimpleHead{Kind: "ServiceAccount"}, }, { @@ -166,8 +166,8 @@ func TestKindSorter(t *testing.T) { order KindSortOrder expected string }{ - {"install", InstallOrder, "aAbcC3de1fgh2iIjJkKlLmnopqrxstuvw!"}, - {"uninstall", UninstallOrder, "wvmutsxrqponLlKkJjIi2hgf1ed3CcbAa!"}, + {"install", InstallOrder, "aAbcC3def1gh2iIjJkKlLmnopqrxstuvw!"}, + {"uninstall", UninstallOrder, "wvmutsxrqponLlKkJjIi2hg1fed3CcbAa!"}, } { var buf bytes.Buffer t.Run(test.description, func(t *testing.T) { From a963736f6675e972448bf7a5fd141628fd0ae4df Mon Sep 17 00:00:00 2001 From: Naseem Date: Thu, 9 Jan 2020 09:04:02 -0500 Subject: [PATCH 35/81] [helm create] Include serviceAccount.annotations value (#7246) * Include serviceAccount.annotations value Signed-off-by: Naseem * Add comment about service account annotations Signed-off-by: Naseem --- pkg/chartutil/create.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 4ca813593..390f12f4c 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -103,6 +103,8 @@ fullnameOverride: "" serviceAccount: # Specifies whether a service account should be created create: true + # Annotations to add to the service account + annotations: {} # The name of the service account to use. # If not set and create is true, a name is generated using the fullname template name: @@ -303,6 +305,10 @@ metadata: name: {{ include ".serviceAccountName" . }} labels: {{ include ".labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} {{- end -}} ` From 985827d09a0456551e116805a7c41c32800c85c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=B7=E7=9A=84=E6=BE=9C=E8=89=B2?= <33822635+zwwhdls@users.noreply.github.com> Date: Fri, 10 Jan 2020 23:01:59 +0800 Subject: [PATCH 36/81] stop with an error immediately if a file or directory with that name already exists (#7187) * fix #7182 Signed-off-by: zwwhdls * fix testcase Signed-off-by: zwwhdls * update error message Signed-off-by: zwwhdls * complete testCase when file/dir existed. Signed-off-by: zwwhdls * fix the case with current directory Signed-off-by: zwwhdls * fix conflict subdirectory when untardir is the clashing directory Signed-off-by: zwwhdls * update comment Signed-off-by: zwwhdls * add case when destination exists. Signed-off-by: zwwhdls --- cmd/helm/pull_test.go | 39 +++++++++++++++++++++++++++++++++++++-- pkg/action/pull.go | 16 ++++++++++++---- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/cmd/helm/pull_test.go b/cmd/helm/pull_test.go index 248195774..1aca66100 100644 --- a/cmd/helm/pull_test.go +++ b/cmd/helm/pull_test.go @@ -41,7 +41,10 @@ func TestPullCmd(t *testing.T) { tests := []struct { name string args string + existFile string + existDir string wantError bool + wantErrorMsg string failExpect string expectFile string expectDir bool @@ -87,10 +90,24 @@ func TestPullCmd(t *testing.T) { expectFile: "./signtest", expectDir: true, }, + { + name: "Fetch untar when file with same name existed", + args: "test/test1 --untar --untardir test1", + existFile: "test1", + wantError: true, + wantErrorMsg: fmt.Sprintf("failed to untar: a file or directory with the name %s already exists", filepath.Join(srv.Root(), "test1")), + }, + { + name: "Fetch untar when dir with same name existed", + args: "test/test2 --untar --untardir test2", + existDir: "test2", + wantError: true, + wantErrorMsg: fmt.Sprintf("failed to untar: a file or directory with the name %s already exists", filepath.Join(srv.Root(), "test2")), + }, { name: "Fetch, verify, untar", - args: "test/signtest --verify --keyring=testdata/helm-test-key.pub --untar --untardir signtest", - expectFile: "./signtest", + args: "test/signtest --verify --keyring=testdata/helm-test-key.pub --untar --untardir signtest2", + expectFile: "./signtest2", expectDir: true, expectVerify: true, }, @@ -127,9 +144,27 @@ func TestPullCmd(t *testing.T) { filepath.Join(outdir, "repositories.yaml"), outdir, ) + // Create file or Dir before helm pull --untar, see: https://github.com/helm/helm/issues/7182 + if tt.existFile != "" { + file := filepath.Join(outdir, tt.existFile) + _, err := os.Create(file) + if err != nil { + t.Fatal("err") + } + } + if tt.existDir != "" { + file := filepath.Join(outdir, tt.existDir) + err := os.Mkdir(file, 0755) + if err != nil { + t.Fatal(err) + } + } _, out, err := executeActionCommand(cmd) if err != nil { if tt.wantError { + if tt.wantErrorMsg != "" && tt.wantErrorMsg == err.Error() { + t.Fatalf("Actual error %s, not equal to expected error %s", err, tt.wantErrorMsg) + } return } t.Fatalf("%q reported error: %s", tt.name, err) diff --git a/pkg/action/pull.go b/pkg/action/pull.go index b0a3d2598..4ff5f5c3e 100644 --- a/pkg/action/pull.go +++ b/pkg/action/pull.go @@ -110,13 +110,21 @@ func (p *Pull) Run(chartRef string) (string, error) { if !filepath.IsAbs(ud) { ud = filepath.Join(p.DestDir, ud) } - if fi, err := os.Stat(ud); err != nil { - if err := os.MkdirAll(ud, 0755); err != nil { + // Let udCheck to check conflict file/dir without replacing ud when untarDir is the current directory(.). + udCheck := ud + if udCheck == "." { + _, udCheck = filepath.Split(chartRef) + } else { + _, chartName := filepath.Split(chartRef) + udCheck = filepath.Join(udCheck, chartName) + } + if _, err := os.Stat(udCheck); err != nil { + if err := os.MkdirAll(udCheck, 0755); err != nil { return out.String(), errors.Wrap(err, "failed to untar (mkdir)") } - } else if !fi.IsDir() { - return out.String(), errors.Errorf("failed to untar: %s is not a directory", ud) + } else { + return out.String(), errors.Errorf("failed to untar: a file or directory with the name %s already exists", udCheck) } return out.String(), chartutil.ExpandFile(ud, saved) From 6f11334d61caaf7ccbdba64ed2731fea6a70c52b Mon Sep 17 00:00:00 2001 From: Joe Lanford Date: Fri, 10 Jan 2020 11:36:42 -0500 Subject: [PATCH 37/81] go.mod,go.sum: bump Kubernetes dependencies 1.17.0 Signed-off-by: Joe Lanford --- go.mod | 21 +++----- go.sum | 149 +++++++++++++++++++++++++++++++++------------------------ 2 files changed, 92 insertions(+), 78 deletions(-) diff --git a/go.mod b/go.mod index ed074074d..bff4fed0e 100644 --- a/go.mod +++ b/go.mod @@ -19,26 +19,20 @@ require ( github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect github.com/emicklei/go-restful v2.11.1+incompatible // indirect github.com/evanphx/json-patch v4.5.0+incompatible - github.com/ghodss/yaml v1.0.0 // indirect - github.com/go-openapi/jsonreference v0.19.3 // indirect github.com/go-openapi/spec v0.19.4 // indirect github.com/gobwas/glob v0.2.3 github.com/gofrs/flock v0.7.1 github.com/gogo/protobuf v1.3.1 // indirect github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect - github.com/google/btree v1.0.0 // indirect github.com/google/go-cmp v0.3.1 // indirect github.com/googleapis/gnostic v0.3.1 // indirect github.com/gosuri/uitable v0.0.1 github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f // indirect github.com/hashicorp/golang-lru v0.5.3 // indirect github.com/imdario/mergo v0.3.8 // indirect - github.com/mailru/easyjson v0.7.0 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect github.com/mattn/go-shellwords v1.0.5 github.com/mitchellh/copystructure v1.0.0 - github.com/onsi/ginkgo v1.10.1 // indirect - github.com/onsi/gomega v1.7.0 // indirect github.com/opencontainers/go-digest v1.0.0-rc1 github.com/opencontainers/image-spec v1.0.1 github.com/pkg/errors v0.8.1 @@ -58,16 +52,13 @@ require ( google.golang.org/appengine v1.6.5 // indirect google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6 // indirect google.golang.org/grpc v1.24.0 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - k8s.io/api v0.0.0-20191016110408-35e52d86657a - k8s.io/apiextensions-apiserver v0.0.0-20191016113550-5357c4baaf65 - k8s.io/apimachinery v0.0.0-20191004115801-a2eda9f80ab8 - k8s.io/cli-runtime v0.0.0-20191016114015-74ad18325ed5 - k8s.io/client-go v0.0.0-20191016111102-bec269661e48 + k8s.io/api v0.17.0 + k8s.io/apiextensions-apiserver v0.17.0 + k8s.io/apimachinery v0.17.1-beta.0 + k8s.io/cli-runtime v0.17.0 + k8s.io/client-go v0.17.0 k8s.io/klog v1.0.0 - k8s.io/kube-openapi v0.0.0-20190918143330-0270cf2f1c1d // indirect - k8s.io/kubectl v0.0.0-20191016120415-2ed914427d51 - k8s.io/utils v0.0.0-20191010214722-8d271d903fe4 // indirect + k8s.io/kubectl v0.17.0 sigs.k8s.io/yaml v1.1.0 ) diff --git a/go.sum b/go.sum index 629d466c2..bbad3e1b7 100644 --- a/go.sum +++ b/go.sum @@ -47,10 +47,12 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= @@ -61,6 +63,7 @@ github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs= @@ -78,17 +81,14 @@ github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tj 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/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/containerd/containerd v1.3.0-beta.2.0.20190823190603-4a2f61c4f2b4 h1:aMyA5J7j6D07U7pf8BFEY67BKoDcz0zWleAbQj3zVng= github.com/containerd/containerd v1.3.0-beta.2.0.20190823190603-4a2f61c4f2b4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.0 h1:xjvXQWABwS2uiv3TWgQt5Uth60Gu86LTGZXMJkjc7rY= github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/continuity v0.0.0-20181203112020-004b46473808 h1:4BX8f882bXEDKfWIf0wa8HRvpnBoPszJJXL+TVbBw4M= github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/coreos/bbolt v1.3.1-coreos.6 h1:uTXKg9gY70s9jMAKdfljFQcuh4e/BXOM+V+d00KFj3A= -github.com/coreos/bbolt v1.3.1-coreos.6/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 h1:+9RjdC18gMxNQVvSiXvObLu29mOFmkgdsB4cRTlV+EE= -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= @@ -96,10 +96,13 @@ github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmf github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 h1:u9SHYsPQNyt5tgDm3YN7+9dYrpK96E5wFilTFWIDZOM= 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 h1:n2Ltr3SrfQlf/9nOna1DoGKxLx3qTSI8Ttl6Xrqp6mw= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -134,6 +137,8 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZ github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c h1:ZfSZ3P3BedhKGUhzj7BQlPSU4OvT6tfOKe3DVHzOA7s= github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/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/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -148,12 +153,12 @@ github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc= github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= @@ -171,6 +176,7 @@ github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpR github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.19.2 h1:ophLETFestFZHk3ji7niPEL4d466QjW+0Tdg5VyDq7E= github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.19.2 h1:a2kIyV3w+OS3S97zxUndRVD46+FhGOUBDFY7nmu4CsY= @@ -194,20 +200,24 @@ github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.2 h1:rf5ArTHmIJxyV5Oiks+Su0mUens1+AjpkPoWr5xFRcI= github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk= github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= github.com/go-openapi/runtime v0.19.0 h1:sU6pp4dSV2sGlNKKyHxZzi1m1kG4WnYtWcJ+HYbygjE= github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.19.2 h1:SStNd1jRcYtfKCN7R0laGNs80WYYvn5CbBjM2sOmCrE= github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo= github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.19.0 h1:0Dn9qy1G9+UJfRU7TR8bmdGxb4uifB7HNrJjOnV0yPk= github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= +github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= @@ -218,6 +228,7 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.19.2 h1:ky5l57HjyVRrsJfd2+Ro5Z9PjGuKbsmftwyMtk8H7js= 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-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= @@ -275,18 +286,18 @@ github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZs github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U= github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gosuri/uitable v0.0.1 h1:M9sMNgSZPyAu1FJZJLpJ16ofL8q5ko2EDUkICsynvlY= github.com/gosuri/uitable v0.0.1/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= -github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f h1:ShTPMJQes6tubcjzGMODIVG5hlrCeImaBnZzKF2N8SM= github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79 h1:lR9ssWAqp9qL0bALxqEEkuudiP1eweOdv9jsRK3e7lE= -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.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= 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.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -310,6 +321,8 @@ github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBv github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 h1:PJPDf8OUfOK1bb/NeTKd4f1QXZItOX389VN3B6qC8ro= @@ -338,6 +351,9 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-shellwords v1.0.5 h1:JhhFTIOslh5ZsPrpa3Wdg8bF0WI3b44EMblmU9wIsXc= @@ -367,18 +383,16 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE= github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= 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 h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/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 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= -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.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= -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 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= @@ -429,13 +443,14 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8= github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= 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 h1:09wy7WZk4AqO03yH85Ex1X+Uo3vDsil3Fa9AgF8Emss= -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/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -446,6 +461,7 @@ github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/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 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= 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= @@ -460,9 +476,12 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0 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/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8 h1:ndzgwNDnKIqyCvHTXaCqh9KlOWKvBry6nuXMJmonVsE= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= @@ -472,8 +491,8 @@ github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4m github.com/xenolf/lego v0.0.0-20160613233155-a9d8cec0e656/go.mod h1:fwiGnfsIjG7OHPfOvgK7Y/Qo6+2Ox0iozjNTkZICKbY= github.com/xenolf/lego v0.3.2-0.20160613233155-a9d8cec0e656 h1:BTvU+npm3/yjuBd53EvgiFLl5+YLikf2WvHsjRQ4KrY= github.com/xenolf/lego v0.3.2-0.20160613233155-a9d8cec0e656/go.mod h1:fwiGnfsIjG7OHPfOvgK7Y/Qo6+2Ox0iozjNTkZICKbY= -github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18 h1:MPPkRncZLN9Kh4MEFmbnK4h3BD7AUmskWv2+EeZJCCs= -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/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940 h1:p7OofyZ509h8DmPLh8Hn+EIIZm/xYhdZHJ9GnXHdr6U= github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= @@ -481,13 +500,15 @@ github.com/yvasiyarov/gorelic v0.0.6 h1:qMJQYPNdtJ7UNYHjX38KXZtltKTqimMuoQjNnSVI github.com/yvasiyarov/gorelic v0.0.6/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= +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/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569 h1:nSQar3Y0E3VQF/VdZ8PTAilaXpER+d7ypdABCrpwMdg= -go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df h1:shvkWr0NAZkg4nPuE3XrKP0VuBPijjk3TfX6Y6acFNg= -go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15 h1:Z2sc4+v0JHV6Mn4kX1f2a5nruNjmV+Th32sugE8zwz8= -go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -495,6 +516,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 h1:0hQKqeLdqlt5iIwVOBErRisrHJAN57yOiPRQItI20fU= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191028145041-f83a4685e152 h1:ZC1Xn5A1nlpSmQCIva4bZ3ob3lmhYIefc+GU+DLg1Ow= @@ -517,6 +540,7 @@ golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -524,9 +548,10 @@ golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/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-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68= -golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 h1:N66aaryRB3Ax92gH0v3hp1QYZ3zWWCCUR/j8Ifh45Ss= golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -544,6 +569,7 @@ golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -554,6 +580,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191028164358-195ce5e7f934 h1:u/E0NqCIWRDAo9WCFo6Ko49njPFDLSd3z+X1HgWDMpE= golang.org/x/sys v0.0.0-20191028164358-195ce5e7f934/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -562,8 +589,10 @@ golang.org/x/text v0.3.0/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 h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -572,6 +601,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-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= @@ -579,8 +609,9 @@ golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac h1:MQEvx39qSf8vyrx3XRaOe+j1UDIzKwkYOVObRgGPVqI= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/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-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485 h1:OB/uP/Puiu5vS5QMRPrXCDWUPb+kt8f1KW8oQzFejQw= 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= @@ -605,26 +636,26 @@ google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9M google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= 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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/inf.v0 v0.9.0 h1:3zYtXIO92bvsdS3ggAdA8Gb4Azj0YU+TVY1uGYNFA8o= -gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= 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.v1 v1.1.2 h1:/5jmADZB+RiKtZGr4HxsEFOEfbfsjTKsVnqpThUpE30= gopkg.in/square/go-jose.v1 v1.1.2/go.mod h1:QpYS+a4WhS+DTlyQIi6Ka7MS3SuR9a055rgXNEe6EiA= gopkg.in/square/go-jose.v2 v2.2.2 h1:orlkJ3myw8CN1nVQHBFfloD+L3egixIa4FvUP6RosSA= 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.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -636,43 +667,35 @@ honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.0.0-20191016110408-35e52d86657a h1:VVUE9xTCXP6KUPMf92cQmN88orz600ebexcRRaBTepQ= -k8s.io/api v0.0.0-20191016110408-35e52d86657a/go.mod h1:/L5qH+AD540e7Cetbui1tuJeXdmNhO8jM6VkXeDdDhQ= -k8s.io/apiextensions-apiserver v0.0.0-20191016113550-5357c4baaf65 h1:kThoiqgMsSwBdMK/lPgjtYTsEjbUU9nXCA9DyU3feok= -k8s.io/apiextensions-apiserver v0.0.0-20191016113550-5357c4baaf65/go.mod h1:5BINdGqggRXXKnDgpwoJ7PyQH8f+Ypp02fvVNcIFy9s= -k8s.io/apimachinery v0.0.0-20191004115801-a2eda9f80ab8 h1:Iieh/ZEgT3BWwbLD5qEKcY06jKuPEl6zC7gPSehoLw4= -k8s.io/apimachinery v0.0.0-20191004115801-a2eda9f80ab8/go.mod h1:llRdnznGEAqC3DcNm6yEj472xaFVfLM7hnYofMb12tQ= -k8s.io/apiserver v0.0.0-20191016112112-5190913f932d h1:leksCBKKBrPJmW1jV4dZUvwqmVtXpKdzpHsqXfFS094= -k8s.io/apiserver v0.0.0-20191016112112-5190913f932d/go.mod h1:7OqfAolfWxUM/jJ/HBLyE+cdaWFBUoo5Q5pHgJVj2ws= -k8s.io/cli-runtime v0.0.0-20191016114015-74ad18325ed5 h1:8ZfMjkMBzcXEawLsYHg9lDM7aLEVso3NiVKfUTnN56A= -k8s.io/cli-runtime v0.0.0-20191016114015-74ad18325ed5/go.mod h1:sDl6WKSQkDM6zS1u9F49a0VooQ3ycYFBFLqd2jf2Xfo= -k8s.io/client-go v0.0.0-20191016111102-bec269661e48 h1:C2XVy2z0dV94q9hSSoCuTPp1KOG7IegvbdXuz9VGxoU= -k8s.io/client-go v0.0.0-20191016111102-bec269661e48/go.mod h1:hrwktSwYGI4JK+TJA3dMaFyyvHVi/aLarVHpbs8bgCU= -k8s.io/code-generator v0.0.0-20191004115455-8e001e5d1894 h1:NMYlxaF7rYQJk2E2IyrUhaX81zX24+dmoZdkPw0gJqI= -k8s.io/code-generator v0.0.0-20191004115455-8e001e5d1894/go.mod h1:mJUgkl06XV4kstAnLHAIzJPVCOzVR+ZcfPIv4fUsFCY= -k8s.io/component-base v0.0.0-20191016111319-039242c015a9 h1:2D+G/CCNVdYc0h9D+tX+0SmtcyQmby6uzNityrps1s0= -k8s.io/component-base v0.0.0-20191016111319-039242c015a9/go.mod h1:SuWowIgd/dtU/m/iv8OD9eOxp3QZBBhTIiWMsBQvKjI= +k8s.io/api v0.17.0 h1:H9d/lw+VkZKEVIUc8F3wgiQ+FUXTTr21M87jXLU7yqM= +k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI= +k8s.io/apiextensions-apiserver v0.17.0 h1:+XgcGxqaMztkbbvsORgCmHIb4uImHKvTjNyu7b8gRnA= +k8s.io/apiextensions-apiserver v0.17.0/go.mod h1:XiIFUakZywkUl54fVXa7QTEHcqQz9HG55nHd1DCoHj8= +k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= +k8s.io/apimachinery v0.17.1-beta.0 h1:0Wl/KpAiFOMe9to5h8x2Y6JnjV+BEWJiTcUk1Vx7zdE= +k8s.io/apimachinery v0.17.1-beta.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= +k8s.io/apiserver v0.17.0/go.mod h1:ABM+9x/prjINN6iiffRVNCBR2Wk7uY4z+EtEGZD48cg= +k8s.io/cli-runtime v0.17.0 h1:XEuStbJBHCQlEKFyTQmceDKEWOSYHZkcYWKp3SsQ9Hk= +k8s.io/cli-runtime v0.17.0/go.mod h1:1E5iQpMODZq2lMWLUJELwRu2MLWIzwvMgDBpn3Y81Qo= +k8s.io/client-go v0.17.0 h1:8QOGvUGdqDMFrm9sD6IUFl256BcffynGoe80sxgTEDg= +k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k= +k8s.io/code-generator v0.17.0/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= +k8s.io/component-base v0.17.0 h1:BnDFcmBDq+RPpxXjmuYnZXb59XNN9CaFrX8ba9+3xrA= +k8s.io/component-base v0.17.0/go.mod h1:rKuRAokNMY2nn2A6LP/MiwpoaMRHpfRnrPaUJJj1Yoc= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190822140433-26a664648505 h1:ZY6yclUKVbZ+SdWnkfY+Je5vrMpKOxmGeKRbsXVmqYM= 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 h1:lCJCxf/LIowc2IGS9TPjWDyXY4nOmdGdfcwwDQCOURQ= -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 h1:EYm5AW/UUDbnmnI+gK0TJDVK9qPLhM+sRHYanNKw0EQ= -k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= -k8s.io/kube-openapi v0.0.0-20190918143330-0270cf2f1c1d h1:Xpe6sK+RY4ZgCTyZ3y273UmFmURhjtoJiwOMbQsXitY= -k8s.io/kube-openapi v0.0.0-20190918143330-0270cf2f1c1d/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= -k8s.io/kubectl v0.0.0-20191016120415-2ed914427d51 h1:RBkTKVMF+xsNsSOVc0+HdC0B5gD1sr6s6Cu5w9qNbuQ= -k8s.io/kubectl v0.0.0-20191016120415-2ed914427d51/go.mod h1:gL826ZTIfD4vXTGlmzgTbliCAT9NGiqpCqK2aNYv5MQ= -k8s.io/metrics v0.0.0-20191016113814-3b1a734dba6e h1:VbAmCGT95GvCZaGtW3oLhf7d2FXT+lnWiTtPE8hzPVo= -k8s.io/metrics v0.0.0-20191016113814-3b1a734dba6e/go.mod h1:ve7/vMWeY5lEBkZf6Bt5TTbGS3b8wAxwGbdXAsufjRs= -k8s.io/utils v0.0.0-20190801114015-581e00157fb1 h1:+ySTxfHnfzZb9ys375PXNlLhkJPLKgHajBU0N62BDvE= -k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20191010214722-8d271d903fe4 h1:Gi+/O1saihwDqnlmC8Vhv1M5Sp4+rbOmK9TbsLn8ZEA= -k8s.io/utils v0.0.0-20191010214722-8d271d903fe4/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +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.17.0 h1:xD4EWlL+epc/JTO1gvSjmV9yiYF0Z2wiHK2DIek6URY= +k8s.io/kubectl v0.17.0/go.mod h1:jIPrUAW656Vzn9wZCCe0PC+oTcu56u2HgFD21Xbfk1s= +k8s.io/metrics v0.17.0/go.mod h1:EH1D3YAwN6d7bMelrElnLhLg72l/ERStyv2SIQVt6Do= +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= @@ -681,7 +704,7 @@ modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= -sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca h1:6dsH6AYQWbyZmtttJNe8Gq1cXOeS1BdV3eW37zHilAQ= -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/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= From d3a8cc4713ddeb5f3b6e698e6e3d295e26d1eb84 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Sat, 11 Jan 2020 20:43:35 -0500 Subject: [PATCH 38/81] feat(chore): Remove unused code Signed-off-by: Marc Khouzam --- pkg/repo/index.go | 47 ------------------- pkg/repo/index_test.go | 20 -------- pkg/repo/testdata/unversioned-index.yaml | 60 ------------------------ 3 files changed, 127 deletions(-) delete mode 100644 pkg/repo/testdata/unversioned-index.yaml diff --git a/pkg/repo/index.go b/pkg/repo/index.go index a7fea673b..36386665e 100644 --- a/pkg/repo/index.go +++ b/pkg/repo/index.go @@ -17,8 +17,6 @@ limitations under the License. package repo import ( - "encoding/json" - "fmt" "io/ioutil" "os" "path" @@ -290,48 +288,3 @@ func loadIndex(data []byte) (*IndexFile, error) { } return i, nil } - -// unversionedEntry represents a deprecated pre-Alpha.5 format. -// -// This will be removed prior to v2.0.0 -type unversionedEntry struct { - Checksum string `json:"checksum"` - URL string `json:"url"` - Chartfile *chart.Metadata `json:"chartfile"` -} - -// loadUnversionedIndex loads a pre-Alpha.5 index.yaml file. -// -// This format is deprecated. This function will be removed prior to v2.0.0. -func loadUnversionedIndex(data []byte) (*IndexFile, error) { - fmt.Fprintln(os.Stderr, "WARNING: Deprecated index file format. Try 'helm repo update'") - i := map[string]unversionedEntry{} - - // This gets around an error in the YAML parser. Instead of parsing as YAML, - // we convert to JSON, and then decode again. - var err error - data, err = yaml.YAMLToJSON(data) - if err != nil { - return nil, err - } - if err := json.Unmarshal(data, &i); err != nil { - return nil, err - } - - if len(i) == 0 { - return nil, ErrNoAPIVersion - } - ni := NewIndexFile() - for n, item := range i { - if item.Chartfile == nil || item.Chartfile.Name == "" { - parts := strings.Split(n, "-") - ver := "" - if len(parts) > 1 { - ver = strings.TrimSuffix(parts[1], ".tgz") - } - item.Chartfile = &chart.Metadata{Name: parts[0], Version: ver} - } - ni.Add(item.Chartfile, item.URL, "", item.Checksum) - } - return ni, nil -} diff --git a/pkg/repo/index_test.go b/pkg/repo/index_test.go index c830a339e..b5119166a 100644 --- a/pkg/repo/index_test.go +++ b/pkg/repo/index_test.go @@ -361,26 +361,6 @@ func TestIndexDirectory(t *testing.T) { } } -func TestLoadUnversionedIndex(t *testing.T) { - data, err := ioutil.ReadFile("testdata/unversioned-index.yaml") - if err != nil { - t.Fatal(err) - } - - ind, err := loadUnversionedIndex(data) - if err != nil { - t.Fatal(err) - } - - if l := len(ind.Entries); l != 2 { - t.Fatalf("Expected 2 entries, got %d", l) - } - - if l := len(ind.Entries["mysql"]); l != 3 { - t.Fatalf("Expected 3 mysql versions, got %d", l) - } -} - func TestIndexAdd(t *testing.T) { i := NewIndexFile() i.Add(&chart.Metadata{Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890") diff --git a/pkg/repo/testdata/unversioned-index.yaml b/pkg/repo/testdata/unversioned-index.yaml deleted file mode 100644 index 1d814c7ae..000000000 --- a/pkg/repo/testdata/unversioned-index.yaml +++ /dev/null @@ -1,60 +0,0 @@ -memcached-0.1.0: - name: memcached - url: https://mumoshu.github.io/charts/memcached-0.1.0.tgz - created: 2016-08-04 02:05:02.259205055 +0000 UTC - checksum: ce9b76576c4b4eb74286fa30a978c56d69e7a522 - chartfile: - name: memcached - home: http://https://hub.docker.com/_/memcached/ - sources: [] - version: 0.1.0 - description: A simple Memcached cluster - keywords: [] - maintainers: - - name: Matt Butcher - email: mbutcher@deis.com -mysql-0.2.0: - name: mysql - url: https://mumoshu.github.io/charts/mysql-0.2.0.tgz - created: 2016-08-04 00:42:47.517342022 +0000 UTC - checksum: aa5edd2904d639b0b6295f1c7cf4c0a8e4f77dd3 - chartfile: - name: mysql - home: https://www.mysql.com/ - sources: [] - version: 0.2.0 - description: Chart running MySQL. - keywords: [] - maintainers: - - name: Matt Fisher - email: mfisher@deis.com -mysql-0.2.1: - name: mysql - url: https://mumoshu.github.io/charts/mysql-0.2.1.tgz - created: 2016-08-04 02:40:29.717829534 +0000 UTC - checksum: 9d9f056171beefaaa04db75680319ca4edb6336a - chartfile: - name: mysql - home: https://www.mysql.com/ - sources: [] - version: 0.2.1 - description: Chart running MySQL. - keywords: [] - maintainers: - - name: Matt Fisher - email: mfisher@deis.com -mysql-0.2.2: - name: mysql - url: https://mumoshu.github.io/charts/mysql-0.2.2.tgz - created: 2016-08-04 02:40:29.71841952 +0000 UTC - checksum: 6d6810e76a5987943faf0040ec22990d9fb141c7 - chartfile: - name: mysql - home: https://www.mysql.com/ - sources: [] - version: 0.2.2 - description: Chart running MySQL. - keywords: [] - maintainers: - - name: Matt Fisher - email: mfisher@deis.com From f437b4d6c9755c30dc2e57a79c79e73bbda2fff3 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Sat, 11 Jan 2020 21:46:27 -0500 Subject: [PATCH 39/81] feat(comp): Speed up completion of charts The completion of charts was using 'helm search repo' which can be quite slow as it must parse the entire yaml of every repo cache file. Using completion for a chart name can end up triggering multiple calls to 'helm search'; this makes the user experience poor, as there is a delay of over a second at every press. This commit creates a cache file for each repo which contains the list of charts for that repo. The completion logic then uses this new cache file directly and obtains the chart names very quickly. With only the stable repo configured, this optimization makes the completion of charts about 85 times faster, going from 1.2 seconds to 0.014 seconds; such a difference gives a much better user experience when completing chart names. On the other hand, adding the creation of the chart list cache file to 'helm repo update' or 'helm repo add' is pretty much negligible compared to the downloading of the index file. It is also worth noting that when more repos are configured, 'helm search repo' only becomes slower, while the completion logic that uses the new chart list cache file will not be affected as it only looks for the single relevant repo file. Signed-off-by: Marc Khouzam --- cmd/helm/repo_add_test.go | 16 +++++++++++- cmd/helm/repo_remove.go | 7 +++++- cmd/helm/repo_remove_test.go | 11 +++++++-- cmd/helm/root.go | 16 ++++++++++-- pkg/helmpath/home.go | 11 ++++++++- pkg/repo/chartrepo.go | 13 +++++++++- pkg/repo/index_test.go | 47 ++++++++++++++++++++++++++++++++++++ 7 files changed, 113 insertions(+), 8 deletions(-) diff --git a/cmd/helm/repo_add_test.go b/cmd/helm/repo_add_test.go index 4dbd0f435..d1b9bc0fc 100644 --- a/cmd/helm/repo_add_test.go +++ b/cmd/helm/repo_add_test.go @@ -19,6 +19,7 @@ package main import ( "fmt" "io/ioutil" + "os" "path/filepath" "sync" "testing" @@ -26,6 +27,8 @@ import ( "sigs.k8s.io/yaml" "helm.sh/helm/v3/internal/test/ensure" + "helm.sh/helm/v3/pkg/helmpath" + "helm.sh/helm/v3/pkg/helmpath/xdg" "helm.sh/helm/v3/pkg/repo" "helm.sh/helm/v3/pkg/repo/repotest" ) @@ -55,7 +58,8 @@ func TestRepoAdd(t *testing.T) { } defer ts.Stop() - repoFile := filepath.Join(ensure.TempDir(t), "repositories.yaml") + rootDir := ensure.TempDir(t) + repoFile := filepath.Join(rootDir, "repositories.yaml") const testRepoName = "test-name" @@ -65,6 +69,7 @@ func TestRepoAdd(t *testing.T) { noUpdate: true, repoFile: repoFile, } + os.Setenv(xdg.CacheHomeEnvVar, rootDir) if err := o.run(ioutil.Discard); err != nil { t.Error(err) @@ -79,6 +84,15 @@ func TestRepoAdd(t *testing.T) { t.Errorf("%s was not successfully inserted into %s", testRepoName, repoFile) } + idx := filepath.Join(helmpath.CachePath("repository"), helmpath.CacheIndexFile(testRepoName)) + if _, err := os.Stat(idx); os.IsNotExist(err) { + t.Errorf("Error cache index file was not created for repository %s", testRepoName) + } + idx = filepath.Join(helmpath.CachePath("repository"), helmpath.CacheChartsFile(testRepoName)) + if _, err := os.Stat(idx); os.IsNotExist(err) { + t.Errorf("Error cache charts file was not created for repository %s", testRepoName) + } + o.noUpdate = false if err := o.run(ioutil.Discard); err != nil { diff --git a/cmd/helm/repo_remove.go b/cmd/helm/repo_remove.go index c1ecb1829..ea7a5db24 100644 --- a/cmd/helm/repo_remove.go +++ b/cmd/helm/repo_remove.go @@ -76,7 +76,12 @@ func (o *repoRemoveOptions) run(out io.Writer) error { } func removeRepoCache(root, name string) error { - idx := filepath.Join(root, helmpath.CacheIndexFile(name)) + idx := filepath.Join(root, helmpath.CacheChartsFile(name)) + if _, err := os.Stat(idx); err == nil { + os.Remove(idx) + } + + idx = filepath.Join(root, helmpath.CacheIndexFile(name)) if _, err := os.Stat(idx); os.IsNotExist(err) { return nil } else if err != nil { diff --git a/cmd/helm/repo_remove_test.go b/cmd/helm/repo_remove_test.go index 3fdcbe9c3..85c76bb92 100644 --- a/cmd/helm/repo_remove_test.go +++ b/cmd/helm/repo_remove_test.go @@ -63,10 +63,13 @@ func TestRepoRemove(t *testing.T) { } idx := filepath.Join(rootDir, helmpath.CacheIndexFile(testRepoName)) - mf, _ := os.Create(idx) mf.Close() + idx2 := filepath.Join(rootDir, helmpath.CacheChartsFile(testRepoName)) + mf, _ = os.Create(idx2) + mf.Close() + b.Reset() if err := rmOpts.run(b); err != nil { @@ -77,7 +80,11 @@ func TestRepoRemove(t *testing.T) { } if _, err := os.Stat(idx); err == nil { - t.Errorf("Error cache file was not removed for repository %s", testRepoName) + t.Errorf("Error cache index file was not removed for repository %s", testRepoName) + } + + if _, err := os.Stat(idx2); err == nil { + t.Errorf("Error cache chart file was not removed for repository %s", testRepoName) } f, err := repo.LoadFile(repoFile) diff --git a/cmd/helm/root.go b/cmd/helm/root.go index 3405299fd..bba3ff643 100644 --- a/cmd/helm/root.go +++ b/cmd/helm/root.go @@ -139,13 +139,25 @@ __helm_zsh_comp_nospace() { __helm_list_charts() { __helm_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" - local repo url file out=() nospace=0 wantFiles=$1 + local prefix chart repo url file out=() nospace=0 wantFiles=$1 # Handle completions for repos for repo in $(__helm_get_repos); do if [[ "${cur}" =~ ^${repo}/.* ]]; then # We are doing completion from within a repo - out=$(eval $(__helm_binary_name) search repo ${cur} 2>/dev/null | \cut -f1 | \grep ^${cur}) + local cacheFile=$(eval $(__helm_binary_name) env 2>/dev/null | \grep HELM_REPOSITORY_CACHE | \cut -d= -f2 | \sed s/\"//g)/${repo}-charts.txt + if [ -f "$cacheFile" ]; then + # Get the list of charts from the cached file + prefix=${cur#${repo}/} + for chart in $(\grep ^$prefix $cacheFile); do + out+=(${repo}/${chart}) + done + else + # If there is no cached list file, fallback to helm search, which is much slower + # This will happen after the caching feature is first installed but before the user + # does a 'helm repo update' to generate the cached list file. + out=$(eval $(__helm_binary_name) search repo ${cur} 2>/dev/null | \cut -f1 | \grep ^${cur}) + fi nospace=0 elif [[ ${repo} =~ ^${cur}.* ]]; then # We are completing a repo name diff --git a/pkg/helmpath/home.go b/pkg/helmpath/home.go index 0b0f110a5..b3f14c558 100644 --- a/pkg/helmpath/home.go +++ b/pkg/helmpath/home.go @@ -25,10 +25,19 @@ func CachePath(elem ...string) string { return lp.cachePath(elem...) } // DataPath returns the path where Helm stores data. func DataPath(elem ...string) string { return lp.dataPath(elem...) } -// CacheIndex returns the path to an index for the given named repository. +// CacheIndexFile returns the path to an index for the given named repository. func CacheIndexFile(name string) string { if name != "" { name += "-" } return name + "index.yaml" } + +// CacheChartsFile returns the path to a text file listing all the charts +// within the given named repository. +func CacheChartsFile(name string) string { + if name != "" { + name += "-" + } + return name + "charts.txt" +} diff --git a/pkg/repo/chartrepo.go b/pkg/repo/chartrepo.go index c8d0d6a3d..38b6b8fb0 100644 --- a/pkg/repo/chartrepo.go +++ b/pkg/repo/chartrepo.go @@ -133,10 +133,21 @@ func (r *ChartRepository) DownloadIndexFile() (string, error) { return "", err } - if _, err := loadIndex(index); err != nil { + indexFile, err := loadIndex(index) + if err != nil { return "", err } + // Create the chart list file in the cache directory + var charts strings.Builder + for name := range indexFile.Entries { + fmt.Fprintln(&charts, name) + } + chartsFile := filepath.Join(r.CachePath, helmpath.CacheChartsFile(r.Config.Name)) + os.MkdirAll(filepath.Dir(chartsFile), 0755) + ioutil.WriteFile(chartsFile, []byte(charts.String()), 0644) + + // Create the index file in the cache directory fname := filepath.Join(r.CachePath, helmpath.CacheIndexFile(r.Config.Name)) os.MkdirAll(filepath.Dir(fname), 0755) return fname, ioutil.WriteFile(fname, index, 0644) diff --git a/pkg/repo/index_test.go b/pkg/repo/index_test.go index c830a339e..ab998ba54 100644 --- a/pkg/repo/index_test.go +++ b/pkg/repo/index_test.go @@ -17,14 +17,19 @@ limitations under the License. package repo import ( + "bufio" + "bytes" "io/ioutil" "net/http" "os" + "path/filepath" + "sort" "strings" "testing" "helm.sh/helm/v3/pkg/cli" "helm.sh/helm/v3/pkg/getter" + "helm.sh/helm/v3/pkg/helmpath" "helm.sh/helm/v3/pkg/chart" ) @@ -178,6 +183,18 @@ func TestDownloadIndexFile(t *testing.T) { t.Fatalf("Index %q failed to parse: %s", testfile, err) } verifyLocalIndex(t, i) + + // Check that charts file is also created + idx = filepath.Join(r.CachePath, helmpath.CacheChartsFile(r.Config.Name)) + if _, err := os.Stat(idx); err != nil { + t.Fatalf("error finding created charts file: %#v", err) + } + + b, err = ioutil.ReadFile(idx) + if err != nil { + t.Fatalf("error reading charts file: %#v", err) + } + verifyLocalChartsFile(t, b, i) }) t.Run("should not decode the path in the repo url while downloading index", func(t *testing.T) { @@ -224,6 +241,18 @@ func TestDownloadIndexFile(t *testing.T) { t.Fatalf("Index %q failed to parse: %s", testfile, err) } verifyLocalIndex(t, i) + + // Check that charts file is also created + idx = filepath.Join(r.CachePath, helmpath.CacheChartsFile(r.Config.Name)) + if _, err := os.Stat(idx); err != nil { + t.Fatalf("error finding created charts file: %#v", err) + } + + b, err = ioutil.ReadFile(idx) + if err != nil { + t.Fatalf("error reading charts file: %#v", err) + } + verifyLocalChartsFile(t, b, i) }) } @@ -322,6 +351,24 @@ func verifyLocalIndex(t *testing.T, i *IndexFile) { } } +func verifyLocalChartsFile(t *testing.T, chartsContent []byte, indexContent *IndexFile) { + var expected, real []string + for chart := range indexContent.Entries { + expected = append(expected, chart) + } + sort.Strings(expected) + + scanner := bufio.NewScanner(bytes.NewReader(chartsContent)) + for scanner.Scan() { + real = append(real, scanner.Text()) + } + sort.Strings(real) + + if strings.Join(expected, " ") != strings.Join(real, " ") { + t.Errorf("Cached charts file content unexpected. Expected:\n%s\ngot:\n%s", expected, real) + } +} + func TestIndexDirectory(t *testing.T) { dir := "testdata/repository" index, err := IndexDirectory(dir, "http://localhost:8080") From e2e21342fdb19aecb4373fc355edddeb1f7fc3db Mon Sep 17 00:00:00 2001 From: etashsingh Date: Mon, 13 Jan 2020 11:59:31 +0530 Subject: [PATCH 40/81] Refactored alpine-pod.yaml file to make the example work in accordance to the Values.yaml file Signed-off-by: etashsingh --- cmd/helm/testdata/testcharts/alpine/templates/alpine-pod.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/testdata/testcharts/alpine/templates/alpine-pod.yaml b/cmd/helm/testdata/testcharts/alpine/templates/alpine-pod.yaml index ae19a1127..a1a44e53f 100644 --- a/cmd/helm/testdata/testcharts/alpine/templates/alpine-pod.yaml +++ b/cmd/helm/testdata/testcharts/alpine/templates/alpine-pod.yaml @@ -14,7 +14,7 @@ metadata: app.kubernetes.io/version: {{ .Chart.AppVersion }} # This makes it easy to audit chart usage. helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}" - values: {{.Values.test.Name}} + values: {{.Values.Name}} spec: # This shows how to use a simple value. This will look for a passed-in value # called restartPolicy. If it is not found, it will use the default value. From 16f62050044d8eaca1ee794ab1903a719895662f Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Mon, 13 Jan 2020 10:25:31 -0500 Subject: [PATCH 41/81] fix(test): Make resetEnv() properly reset settings Because the 'settings' variable is a pointer, it cannot be used to store the original envSettings and then restore them. Instead, this commit creates an entirely new envSettings, after having set the environment variables, which may affect it. Signed-off-by: Marc Khouzam --- cmd/helm/helm_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/helm/helm_test.go b/cmd/helm/helm_test.go index a08720e7a..b7156daf3 100644 --- a/cmd/helm/helm_test.go +++ b/cmd/helm/helm_test.go @@ -31,6 +31,7 @@ import ( "helm.sh/helm/v3/internal/test" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chartutil" + "helm.sh/helm/v3/pkg/cli" kubefake "helm.sh/helm/v3/pkg/kube/fake" "helm.sh/helm/v3/pkg/release" "helm.sh/helm/v3/pkg/storage" @@ -136,14 +137,14 @@ func executeActionCommand(cmd string) (*cobra.Command, string, error) { } func resetEnv() func() { - origSettings, origEnv := settings, os.Environ() + origEnv := os.Environ() return func() { os.Clearenv() - settings = origSettings for _, pair := range origEnv { kv := strings.SplitN(pair, "=", 2) os.Setenv(kv[0], kv[1]) } + settings = cli.New() } } From 0cdbbf287f04e10f6b44faf1bf9185b48ca7f3fa Mon Sep 17 00:00:00 2001 From: Guangwen Feng Date: Tue, 14 Jan 2020 14:11:08 +0800 Subject: [PATCH 42/81] Fix typo in comment for func IsReachable Signed-off-by: Guangwen Feng --- pkg/kube/fake/printer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/kube/fake/printer.go b/pkg/kube/fake/printer.go index ec75aa790..58b389ab5 100644 --- a/pkg/kube/fake/printer.go +++ b/pkg/kube/fake/printer.go @@ -33,7 +33,7 @@ type PrintingKubeClient struct { Out io.Writer } -// isReachable checks if the cluster is reachable +// IsReachable checks if the cluster is reachable func (p *PrintingKubeClient) IsReachable() error { return nil } From e2946c7e343f0b0404b5f4e9ecabdccd970a87c8 Mon Sep 17 00:00:00 2001 From: Bradley Skuse Date: Thu, 19 Dec 2019 16:21:24 +0800 Subject: [PATCH 43/81] Fix: helm3 - kind sorter incorrectly compares unknown and namespace Signed-off-by: Bradley Skuse Fix style error from CI Signed-off-by: Bradley Skuse Fix: helm3 - kind sorter incorrectly compares unknown and namespace Fix: helm3 - kind sorter incorrectly compares unknown and namespace Fix: helm3 - kind sorter incorrectly compares unknown and namespace --- pkg/releaseutil/kind_sorter.go | 8 +++++--- pkg/releaseutil/kind_sorter_test.go | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/pkg/releaseutil/kind_sorter.go b/pkg/releaseutil/kind_sorter.go index 3ab8ab2a4..92ffa03f2 100644 --- a/pkg/releaseutil/kind_sorter.go +++ b/pkg/releaseutil/kind_sorter.go @@ -134,11 +134,13 @@ func (k *kindSorter) Less(i, j int) bool { b := k.manifests[j] first, aok := k.ordering[a.Head.Kind] second, bok := k.ordering[b.Head.Kind] - if first == second { - // if both are unknown and of different kind sort by kind alphabetically - if !aok && !bok && a.Head.Kind != b.Head.Kind { + + if !aok && !bok { + // if both are unknown then sort alphabetically by kind, keep original order if same kind + if a.Head.Kind != b.Head.Kind { return a.Head.Kind < b.Head.Kind } + return first < second } // unknown kind is last if !aok { diff --git a/pkg/releaseutil/kind_sorter_test.go b/pkg/releaseutil/kind_sorter_test.go index f29065f73..4747e8252 100644 --- a/pkg/releaseutil/kind_sorter_test.go +++ b/pkg/releaseutil/kind_sorter_test.go @@ -245,3 +245,24 @@ func TestKindSorterKeepOriginalOrder(t *testing.T) { }) } } + +func TestKindSorterNamespaceAgainstUnknown(t *testing.T) { + unknown := Manifest{ + Name: "a", + Head: &SimpleHead{Kind: "Unknown"}, + } + namespace := Manifest{ + Name: "b", + Head: &SimpleHead{Kind: "Namespace"}, + } + + manifests := []Manifest{unknown, namespace} + sortByKind(manifests, InstallOrder) + + expectedOrder := []Manifest{namespace, unknown} + for i, manifest := range manifests { + if expectedOrder[i].Name != manifest.Name { + t.Errorf("Expected %s, got %s", expectedOrder[i].Name, manifest.Name) + } + } +} From e868cb23c0939647dd37d53b1b4e0d5ffe99d65b Mon Sep 17 00:00:00 2001 From: Simon Alling Date: Wed, 15 Jan 2020 16:51:04 +0100 Subject: [PATCH 44/81] ref(pkg/storage): Refactor Deployed and DeployedAll (#7374) The error returned from DeployedAll will never contain "not found". The error returned at the end of Deployed is already known to be nil, and we never want to return ls[0] together with a non-nil error anyway. Signed-off-by: Simon Alling --- pkg/storage/storage.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go index 6528c48ba..56881493b 100644 --- a/pkg/storage/storage.go +++ b/pkg/storage/storage.go @@ -112,9 +112,6 @@ func (s *Storage) ListDeployed() ([]*rspb.Release, error) { func (s *Storage) Deployed(name string) (*rspb.Release, error) { ls, err := s.DeployedAll(name) if err != nil { - if strings.Contains(err.Error(), "not found") { - return nil, errors.Errorf("%q has no deployed releases", name) - } return nil, err } @@ -122,7 +119,7 @@ func (s *Storage) Deployed(name string) (*rspb.Release, error) { return nil, errors.Errorf("%q has no deployed releases", name) } - return ls[0], err + return ls[0], nil } // DeployedAll returns all deployed releases with the provided name, or From c365c8dcdc99e1fa294fa985d802b20e94b9c30a Mon Sep 17 00:00:00 2001 From: Joe Lanford Date: Wed, 15 Jan 2020 11:46:59 -0500 Subject: [PATCH 45/81] go.mod,go.sum: bump to k8s v1.17.1 Signed-off-by: Joe Lanford --- go.mod | 12 ++++++------ go.sum | 35 +++++++++++++++++------------------ 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index bff4fed0e..c7b25ac13 100644 --- a/go.mod +++ b/go.mod @@ -52,13 +52,13 @@ require ( google.golang.org/appengine v1.6.5 // indirect google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6 // indirect google.golang.org/grpc v1.24.0 // indirect - k8s.io/api v0.17.0 - k8s.io/apiextensions-apiserver v0.17.0 - k8s.io/apimachinery v0.17.1-beta.0 - k8s.io/cli-runtime v0.17.0 - k8s.io/client-go v0.17.0 + k8s.io/api v0.17.1 + k8s.io/apiextensions-apiserver v0.17.1 + k8s.io/apimachinery v0.17.1 + k8s.io/cli-runtime v0.17.1 + k8s.io/client-go v0.17.1 k8s.io/klog v1.0.0 - k8s.io/kubectl v0.17.0 + k8s.io/kubectl v0.17.1 sigs.k8s.io/yaml v1.1.0 ) diff --git a/go.sum b/go.sum index bbad3e1b7..312152e1f 100644 --- a/go.sum +++ b/go.sum @@ -667,21 +667,20 @@ honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.17.0 h1:H9d/lw+VkZKEVIUc8F3wgiQ+FUXTTr21M87jXLU7yqM= -k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI= -k8s.io/apiextensions-apiserver v0.17.0 h1:+XgcGxqaMztkbbvsORgCmHIb4uImHKvTjNyu7b8gRnA= -k8s.io/apiextensions-apiserver v0.17.0/go.mod h1:XiIFUakZywkUl54fVXa7QTEHcqQz9HG55nHd1DCoHj8= -k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= -k8s.io/apimachinery v0.17.1-beta.0 h1:0Wl/KpAiFOMe9to5h8x2Y6JnjV+BEWJiTcUk1Vx7zdE= -k8s.io/apimachinery v0.17.1-beta.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= -k8s.io/apiserver v0.17.0/go.mod h1:ABM+9x/prjINN6iiffRVNCBR2Wk7uY4z+EtEGZD48cg= -k8s.io/cli-runtime v0.17.0 h1:XEuStbJBHCQlEKFyTQmceDKEWOSYHZkcYWKp3SsQ9Hk= -k8s.io/cli-runtime v0.17.0/go.mod h1:1E5iQpMODZq2lMWLUJELwRu2MLWIzwvMgDBpn3Y81Qo= -k8s.io/client-go v0.17.0 h1:8QOGvUGdqDMFrm9sD6IUFl256BcffynGoe80sxgTEDg= -k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k= -k8s.io/code-generator v0.17.0/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= -k8s.io/component-base v0.17.0 h1:BnDFcmBDq+RPpxXjmuYnZXb59XNN9CaFrX8ba9+3xrA= -k8s.io/component-base v0.17.0/go.mod h1:rKuRAokNMY2nn2A6LP/MiwpoaMRHpfRnrPaUJJj1Yoc= +k8s.io/api v0.17.1 h1:i46MidoDOE9tvQ0TTEYggf3ka/pziP1+tHI/GFVeJao= +k8s.io/api v0.17.1/go.mod h1:zxiAc5y8Ngn4fmhWUtSxuUlkfz1ixT7j9wESokELzOg= +k8s.io/apiextensions-apiserver v0.17.1 h1:Gw6zQgmKyyNrFMtVpRBNEKE8p35sDBI7Tq1ImxGS+zU= +k8s.io/apiextensions-apiserver v0.17.1/go.mod h1:DRIFH5x3jalE4rE7JP0MQKby9zdYk9lUJQuMmp+M/L0= +k8s.io/apimachinery v0.17.1 h1:zUjS3szTxoUjTDYNvdFkYt2uMEXLcthcbp+7uZvWhYM= +k8s.io/apimachinery v0.17.1/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= +k8s.io/apiserver v0.17.1/go.mod h1:BQEUObJv8H6ZYO7DeKI5vb50tjk6paRJ4ZhSyJsiSco= +k8s.io/cli-runtime v0.17.1 h1:VoZRWJNRyrxuM5SIRozYhT/EtcZ6jiS+KBCxRw66p1g= +k8s.io/cli-runtime v0.17.1/go.mod h1:e5847Iy85W9uWH3rZofXTG/9nOUyGKGTVnObYF7zSik= +k8s.io/client-go v0.17.1 h1:LbbuZ5tI7OYx4et5DfRFcJuoojvpYO0c7vps2rgJsHY= +k8s.io/client-go v0.17.1/go.mod h1:HZtHJSC/VuSHcETN9QA5QDZky1tXiYrkF/7t7vRpO1A= +k8s.io/code-generator v0.17.1/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= +k8s.io/component-base v0.17.1 h1:lK/lUzZZQK+DlH0XD+gq610OUEmjWOyDuUYOTGetw10= +k8s.io/component-base v0.17.1/go.mod h1:LrBPZkXtlvGjBzDJa0+b7E5Ij4VoAAKrOGudRC5z2eY= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190822140433-26a664648505 h1:ZY6yclUKVbZ+SdWnkfY+Je5vrMpKOxmGeKRbsXVmqYM= k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= @@ -691,9 +690,9 @@ 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= -k8s.io/kubectl v0.17.0 h1:xD4EWlL+epc/JTO1gvSjmV9yiYF0Z2wiHK2DIek6URY= -k8s.io/kubectl v0.17.0/go.mod h1:jIPrUAW656Vzn9wZCCe0PC+oTcu56u2HgFD21Xbfk1s= -k8s.io/metrics v0.17.0/go.mod h1:EH1D3YAwN6d7bMelrElnLhLg72l/ERStyv2SIQVt6Do= +k8s.io/kubectl v0.17.1 h1:+gI5hPZVEXN5wWybrzX3tu3f9af54sUNcALhg86upCY= +k8s.io/kubectl v0.17.1/go.mod h1:ZmbAdEQm+SLA/3s3eWJ3g+liXb5eT6mA85jYj52LMXw= +k8s.io/metrics v0.17.1/go.mod h1:dphDhzjA1KR/nQXtXEQzoQyQXk5ViSJO85Ky8QKwBPM= 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= From 9240e7812464c1eb07c6a4b6c4459d5d3b1aef01 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 31 Dec 2019 08:42:12 -0500 Subject: [PATCH 46/81] feat(comp): Dynamic completion of arguments in Go Signed-off-by: Marc Khouzam --- cmd/helm/get_all.go | 9 ++ cmd/helm/get_hooks.go | 9 ++ cmd/helm/get_manifest.go | 9 ++ cmd/helm/get_notes.go | 9 ++ cmd/helm/get_values.go | 9 ++ cmd/helm/history.go | 9 ++ cmd/helm/install.go | 14 ++ cmd/helm/list.go | 24 ++++ cmd/helm/plugin_list.go | 15 ++ cmd/helm/plugin_uninstall.go | 11 ++ cmd/helm/plugin_update.go | 11 ++ cmd/helm/pull.go | 9 ++ cmd/helm/release_testing.go | 9 ++ cmd/helm/repo_list.go | 16 +++ cmd/helm/repo_remove.go | 10 ++ cmd/helm/rollback.go | 9 ++ cmd/helm/root.go | 247 ++++++-------------------------- cmd/helm/search_repo.go | 114 +++++++++++++++ cmd/helm/show.go | 12 ++ cmd/helm/status.go | 9 ++ cmd/helm/template.go | 6 + cmd/helm/uninstall.go | 9 ++ cmd/helm/upgrade.go | 12 ++ internal/completion/complete.go | 201 ++++++++++++++++++++++++++ 24 files changed, 589 insertions(+), 203 deletions(-) create mode 100644 internal/completion/complete.go diff --git a/cmd/helm/get_all.go b/cmd/helm/get_all.go index 8e9ab4d6b..678b85f25 100644 --- a/cmd/helm/get_all.go +++ b/cmd/helm/get_all.go @@ -22,6 +22,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli/output" ) @@ -56,6 +57,14 @@ func newGetAllCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) != 0 { + return nil, completion.BashCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }) + f := cmd.Flags() f.IntVar(&client.Version, "revision", 0, "get the named release with revision") f.StringVar(&template, "template", "", "go template for formatting the output, eg: {{.Release.Name}}") diff --git a/cmd/helm/get_hooks.go b/cmd/helm/get_hooks.go index 0c50c8833..84ef0c1fc 100644 --- a/cmd/helm/get_hooks.go +++ b/cmd/helm/get_hooks.go @@ -23,6 +23,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" ) @@ -52,6 +53,14 @@ func newGetHooksCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) != 0 { + return nil, completion.BashCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }) + cmd.Flags().IntVar(&client.Version, "revision", 0, "get the named release with revision") return cmd diff --git a/cmd/helm/get_manifest.go b/cmd/helm/get_manifest.go index d8fcd2e2c..1860025cd 100644 --- a/cmd/helm/get_manifest.go +++ b/cmd/helm/get_manifest.go @@ -23,6 +23,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" ) @@ -52,6 +53,14 @@ func newGetManifestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command }, } + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) != 0 { + return nil, completion.BashCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }) + cmd.Flags().IntVar(&client.Version, "revision", 0, "get the named release with revision") return cmd diff --git a/cmd/helm/get_notes.go b/cmd/helm/get_notes.go index 1b0128989..de3adf498 100644 --- a/cmd/helm/get_notes.go +++ b/cmd/helm/get_notes.go @@ -23,6 +23,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" ) @@ -50,6 +51,14 @@ func newGetNotesCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) != 0 { + return nil, completion.BashCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }) + f := cmd.Flags() f.IntVar(&client.Version, "revision", 0, "get the named release with revision") diff --git a/cmd/helm/get_values.go b/cmd/helm/get_values.go index 2cccaeace..898db8929 100644 --- a/cmd/helm/get_values.go +++ b/cmd/helm/get_values.go @@ -23,6 +23,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli/output" ) @@ -54,6 +55,14 @@ func newGetValuesCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) != 0 { + return nil, completion.BashCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }) + f := cmd.Flags() f.IntVar(&client.Version, "revision", 0, "get the named release with revision") f.BoolVarP(&client.AllValues, "all", "a", false, "dump all (computed) values") diff --git a/cmd/helm/history.go b/cmd/helm/history.go index aa873db1e..739848c1c 100644 --- a/cmd/helm/history.go +++ b/cmd/helm/history.go @@ -25,6 +25,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/cli/output" @@ -69,6 +70,14 @@ func newHistoryCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) != 0 { + return nil, completion.BashCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }) + f := cmd.Flags() f.IntVar(&client.Max, "max", 256, "maximum number of revision to include in history") bindOutputFlag(cmd, &outfmt) diff --git a/cmd/helm/install.go b/cmd/helm/install.go index b75dfce74..701048151 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -26,6 +26,7 @@ import ( "github.com/spf13/pflag" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart/loader" @@ -122,6 +123,11 @@ func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + return compInstall(args, toComplete) + }) + addInstallFlags(cmd.Flags(), client, valueOpts) bindOutputFlag(cmd, &outfmt) @@ -225,3 +231,11 @@ func isChartInstallable(ch *chart.Chart) (bool, error) { } return false, errors.Errorf("%s charts are not installable", ch.Metadata.Type) } + +// Provide dynamic auto-completion for the install and template commands +func compInstall(args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) == 1 { + return compListCharts(toComplete, true) + } + return nil, completion.BashCompDirectiveNoFileComp +} diff --git a/cmd/helm/list.go b/cmd/helm/list.go index 57fc4be3c..4b652088d 100644 --- a/cmd/helm/list.go +++ b/cmd/helm/list.go @@ -26,6 +26,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli/output" "helm.sh/helm/v3/pkg/release" @@ -164,3 +165,26 @@ func (r *releaseListWriter) WriteJSON(out io.Writer) error { func (r *releaseListWriter) WriteYAML(out io.Writer) error { return output.EncodeYAML(out, r.releases) } + +// Provide dynamic auto-completion for release names +func compListReleases(toComplete string, cfg *action.Configuration) ([]string, completion.BashCompDirective) { + completion.CompDebugln(fmt.Sprintf("compListReleases with toComplete %s", toComplete)) + + client := action.NewList(cfg) + client.All = true + client.Limit = 0 + client.Filter = fmt.Sprintf("^%s", toComplete) + + client.SetStateMask() + results, err := client.Run() + if err != nil { + return nil, completion.BashCompDirectiveDefault + } + + var choices []string + for _, res := range results { + choices = append(choices, res.Name) + } + + return choices, completion.BashCompDirectiveNoFileComp +} diff --git a/cmd/helm/plugin_list.go b/cmd/helm/plugin_list.go index 2f37a8028..0440b0b5e 100644 --- a/cmd/helm/plugin_list.go +++ b/cmd/helm/plugin_list.go @@ -18,6 +18,7 @@ package main import ( "fmt" "io" + "strings" "github.com/gosuri/uitable" "github.com/spf13/cobra" @@ -46,3 +47,17 @@ func newPluginListCmd(out io.Writer) *cobra.Command { } return cmd } + +// Provide dynamic auto-completion for plugin names +func compListPlugins(toComplete string) []string { + var pNames []string + plugins, err := findPlugins(settings.PluginsDirectory) + if err == nil { + for _, p := range plugins { + if strings.HasPrefix(p.Metadata.Name, toComplete) { + pNames = append(pNames, p.Metadata.Name) + } + } + } + return pNames +} diff --git a/cmd/helm/plugin_uninstall.go b/cmd/helm/plugin_uninstall.go index 30f9bc91d..f703ddcfb 100644 --- a/cmd/helm/plugin_uninstall.go +++ b/cmd/helm/plugin_uninstall.go @@ -24,6 +24,7 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/plugin" ) @@ -33,6 +34,7 @@ type pluginUninstallOptions struct { func newPluginUninstallCmd(out io.Writer) *cobra.Command { o := &pluginUninstallOptions{} + cmd := &cobra.Command{ Use: "uninstall ...", Aliases: []string{"rm", "remove"}, @@ -44,6 +46,15 @@ func newPluginUninstallCmd(out io.Writer) *cobra.Command { return o.run(out) }, } + + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) != 0 { + return nil, completion.BashCompDirectiveNoFileComp + } + return compListPlugins(toComplete), completion.BashCompDirectiveNoFileComp + }) + return cmd } diff --git a/cmd/helm/plugin_update.go b/cmd/helm/plugin_update.go index 64e8bd6c7..a24e80518 100644 --- a/cmd/helm/plugin_update.go +++ b/cmd/helm/plugin_update.go @@ -24,6 +24,7 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/plugin" "helm.sh/helm/v3/pkg/plugin/installer" ) @@ -34,6 +35,7 @@ type pluginUpdateOptions struct { func newPluginUpdateCmd(out io.Writer) *cobra.Command { o := &pluginUpdateOptions{} + cmd := &cobra.Command{ Use: "update ...", Aliases: []string{"up"}, @@ -45,6 +47,15 @@ func newPluginUpdateCmd(out io.Writer) *cobra.Command { return o.run(out) }, } + + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) != 0 { + return nil, completion.BashCompDirectiveNoFileComp + } + return compListPlugins(toComplete), completion.BashCompDirectiveNoFileComp + }) + return cmd } diff --git a/cmd/helm/pull.go b/cmd/helm/pull.go index 3b00e9bca..16cd10467 100644 --- a/cmd/helm/pull.go +++ b/cmd/helm/pull.go @@ -23,6 +23,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" ) @@ -68,6 +69,14 @@ func newPullCmd(out io.Writer) *cobra.Command { }, } + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) != 0 { + return nil, completion.BashCompDirectiveNoFileComp + } + return compListCharts(toComplete, false) + }) + f := cmd.Flags() f.BoolVar(&client.Devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.") f.BoolVar(&client.Untar, "untar", false, "if set to true, will untar the chart after downloading it") diff --git a/cmd/helm/release_testing.go b/cmd/helm/release_testing.go index 7190ec736..e4690b9d4 100644 --- a/cmd/helm/release_testing.go +++ b/cmd/helm/release_testing.go @@ -24,6 +24,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli/output" ) @@ -71,6 +72,14 @@ func newReleaseTestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command }, } + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) != 0 { + return nil, completion.BashCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }) + f := cmd.Flags() f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation (like Jobs for hooks)") f.BoolVar(&outputLogs, "logs", false, "Dump the logs from test pods (this runs after all tests are complete, but before any cleanup)") diff --git a/cmd/helm/repo_list.go b/cmd/helm/repo_list.go index 2ff6162d1..25316bafc 100644 --- a/cmd/helm/repo_list.go +++ b/cmd/helm/repo_list.go @@ -18,6 +18,7 @@ package main import ( "io" + "strings" "github.com/gosuri/uitable" "github.com/pkg/errors" @@ -95,3 +96,18 @@ func (r *repoListWriter) encodeByFormat(out io.Writer, format output.Format) err // WriteJSON and WriteYAML, we shouldn't get invalid types return nil } + +// Provide dynamic auto-completion for repo names +func compListRepos(prefix string) []string { + var rNames []string + + f, err := repo.LoadFile(settings.RepositoryConfig) + if err == nil && len(f.Repositories) > 0 { + for _, repo := range f.Repositories { + if strings.HasPrefix(repo.Name, prefix) { + rNames = append(rNames, repo.Name) + } + } + } + return rNames +} diff --git a/cmd/helm/repo_remove.go b/cmd/helm/repo_remove.go index ea7a5db24..e8c0ec027 100644 --- a/cmd/helm/repo_remove.go +++ b/cmd/helm/repo_remove.go @@ -26,6 +26,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/helmpath" "helm.sh/helm/v3/pkg/repo" ) @@ -38,6 +39,7 @@ type repoRemoveOptions struct { func newRepoRemoveCmd(out io.Writer) *cobra.Command { o := &repoRemoveOptions{} + cmd := &cobra.Command{ Use: "remove [NAME]", Aliases: []string{"rm"}, @@ -51,6 +53,14 @@ func newRepoRemoveCmd(out io.Writer) *cobra.Command { }, } + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) != 0 { + return nil, completion.BashCompDirectiveNoFileComp + } + return compListRepos(toComplete), completion.BashCompDirectiveNoFileComp + }) + return cmd } diff --git a/cmd/helm/rollback.go b/cmd/helm/rollback.go index d44ef14f4..745e910b2 100644 --- a/cmd/helm/rollback.go +++ b/cmd/helm/rollback.go @@ -25,6 +25,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" ) @@ -64,6 +65,14 @@ func newRollbackCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) != 0 { + return nil, completion.BashCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }) + f := cmd.Flags() f.BoolVar(&client.DryRun, "dry-run", false, "simulate a rollback") f.BoolVar(&client.Recreate, "recreate-pods", false, "performs pods restart for the resource if applicable") diff --git a/cmd/helm/root.go b/cmd/helm/root.go index bba3ff643..e02723a6f 100644 --- a/cmd/helm/root.go +++ b/cmd/helm/root.go @@ -24,6 +24,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/internal/experimental/registry" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli/output" @@ -67,11 +68,6 @@ __helm_override_flags_to_kubectl_flags() echo "$1" | \sed s/kube-context/context/ } -__helm_get_repos() -{ - eval $(__helm_binary_name) repo list 2>/dev/null | \tail -n +2 | \cut -f1 -} - __helm_get_contexts() { __helm_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" @@ -103,209 +99,45 @@ __helm_output_options() COMPREPLY+=( $( compgen -W "%[1]s" -- "$cur" ) ) } -__helm_binary_name() +__helm_custom_func() { - local helm_binary - helm_binary="${words[0]}" - __helm_debug "${FUNCNAME[0]}: helm_binary is ${helm_binary}" - echo ${helm_binary} -} - -# This function prevents the zsh shell from adding a space after -# a completion by adding a second, fake completion -__helm_zsh_comp_nospace() { - __helm_debug "${FUNCNAME[0]}: in is ${in[*]}" + __helm_debug "${FUNCNAME[0]}: c is $c, words[@] is ${words[@]}, #words[@] is ${#words[@]}" + __helm_debug "${FUNCNAME[0]}: cur is ${cur}, cword is ${cword}, words is ${words}" - local out in=("$@") + local out requestComp + requestComp="${words[0]} %[2]s ${words[@]:1}" - # The shell will normally add a space after these completions. - # To avoid that we should use "compopt -o nospace". However, it is not - # available in zsh. - # Instead, we trick the shell by pretending there is a second, longer match. - # We only do this if there is a single choice left for completion - # to reduce the times the user could be presented with the fake completion choice. - - out=($(echo ${in[*]} | \tr " " "\n" | \grep "^${cur}")) - __helm_debug "${FUNCNAME[0]}: out is ${out[*]}" - - [ ${#out[*]} -eq 1 ] && out+=("${out}.") - - __helm_debug "${FUNCNAME[0]}: out is now ${out[*]}" - - echo "${out[*]}" -} + if [ -z "${cur}" ]; then + # If the last parameter is complete (there is a space following it) + # We add an extra empty parameter so we can indicate this to the go method. + __helm_debug "${FUNCNAME[0]}: Adding extra empty parameter" + requestComp="${requestComp} \"\"" + fi -# $1 = 1 if the completion should include local charts (which means file completion) -__helm_list_charts() -{ - __helm_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" - local prefix chart repo url file out=() nospace=0 wantFiles=$1 - - # Handle completions for repos - for repo in $(__helm_get_repos); do - if [[ "${cur}" =~ ^${repo}/.* ]]; then - # We are doing completion from within a repo - local cacheFile=$(eval $(__helm_binary_name) env 2>/dev/null | \grep HELM_REPOSITORY_CACHE | \cut -d= -f2 | \sed s/\"//g)/${repo}-charts.txt - if [ -f "$cacheFile" ]; then - # Get the list of charts from the cached file - prefix=${cur#${repo}/} - for chart in $(\grep ^$prefix $cacheFile); do - out+=(${repo}/${chart}) - done - else - # If there is no cached list file, fallback to helm search, which is much slower - # This will happen after the caching feature is first installed but before the user - # does a 'helm repo update' to generate the cached list file. - out=$(eval $(__helm_binary_name) search repo ${cur} 2>/dev/null | \cut -f1 | \grep ^${cur}) + __helm_debug "${FUNCNAME[0]}: calling ${requestComp}" + # Use eval to handle any environment variables and such + out=$(eval ${requestComp} 2>/dev/null) + directive=$? + + if [ $((${directive} & %[3]d)) -ne 0 ]; then + __helm_debug "${FUNCNAME[0]}: received error, completion failed" + else + if [ $((${directive} & %[4]d)) -ne 0 ]; then + if [[ $(type -t compopt) = "builtin" ]]; then + compopt -o nospace fi - nospace=0 - elif [[ ${repo} =~ ^${cur}.* ]]; then - # We are completing a repo name - out+=(${repo}/) - nospace=1 - fi - done - __helm_debug "${FUNCNAME[0]}: out after repos is ${out[*]}" - - # Handle completions for url prefixes - for url in https:// http:// file://; do - if [[ "${cur}" =~ ^${url}.* ]]; then - # The user already put in the full url prefix. Return it - # back as a completion to avoid the shell doing path completion - out="${cur}" - nospace=1 - elif [[ ${url} =~ ^${cur}.* ]]; then - # We are completing a url prefix - out+=(${url}) - nospace=1 fi - done - __helm_debug "${FUNCNAME[0]}: out after urls is ${out[*]}" - - # Handle completion for files. - # We only do this if: - # 1- There are other completions found (if there are no completions, - # the shell will do file completion itself) - # 2- If there is some input from the user (or else we will end up - # listing the entire content of the current directory which will - # be too many choices for the user to find the real repos) - if [ $wantFiles -eq 1 ] && [ -n "${out[*]}" ] && [ -n "${cur}" ]; then - for file in $(\ls); do - if [[ ${file} =~ ^${cur}.* ]]; then - # We are completing a file prefix - out+=(${file}) - nospace=1 + if [ $((${directive} & %[5]d)) -ne 0 ]; then + if [[ $(type -t compopt) = "builtin" ]]; then + compopt +o default fi - done - fi - __helm_debug "${FUNCNAME[0]}: out after files is ${out[*]}" - - # If the user didn't provide any input to completion, - # we provide a hint that a path can also be used - [ $wantFiles -eq 1 ] && [ -z "${cur}" ] && out+=(./ /) - - __helm_debug "${FUNCNAME[0]}: out after checking empty input is ${out[*]}" - - if [ $nospace -eq 1 ]; then - if [[ -n "${ZSH_VERSION}" ]]; then - # Don't let the shell add a space after the completion - local tmpout=$(__helm_zsh_comp_nospace "${out[@]}") - unset out - out=$tmpout - elif [[ $(type -t compopt) = "builtin" ]]; then - compopt -o nospace fi - fi - - __helm_debug "${FUNCNAME[0]}: final out is ${out[*]}" - COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) ) -} -__helm_list_releases() -{ - __helm_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" - local out filter - # Use ^ to map from the start of the release name - filter="^${words[c]}" - # Use eval in case helm_binary_name or __helm_override_flags contains a variable (e.g., $HOME/bin/h3) - if out=$(eval $(__helm_binary_name) list $(__helm_override_flags) -a -q -m 1000 -f ${filter} 2>/dev/null); then - COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) ) + while IFS='' read -r comp; do + COMPREPLY+=("$comp") + done < <(compgen -W "${out[*]}" -- "$cur") fi } - -__helm_list_repos() -{ - __helm_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" - local out - # Use eval in case helm_binary_name contains a variable (e.g., $HOME/bin/h3) - if out=$(__helm_get_repos); then - COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) ) - fi -} - -__helm_list_plugins() -{ - __helm_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" - local out - # Use eval in case helm_binary_name contains a variable (e.g., $HOME/bin/h3) - if out=$(eval $(__helm_binary_name) plugin list 2>/dev/null | \tail -n +2 | \cut -f1); then - COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) ) - fi -} - -__helm_list_charts_after_name() { - __helm_debug "${FUNCNAME[0]}: last_command is $last_command" - if [[ ${#nouns[@]} -eq 1 ]]; then - __helm_list_charts 1 - fi -} - -__helm_list_releases_then_charts() { - __helm_debug "${FUNCNAME[0]}: last_command is $last_command" - if [[ ${#nouns[@]} -eq 0 ]]; then - __helm_list_releases - elif [[ ${#nouns[@]} -eq 1 ]]; then - __helm_list_charts 1 - fi -} - -__helm_custom_func() -{ - __helm_debug "${FUNCNAME[0]}: last_command is $last_command" - case ${last_command} in - helm_pull) - __helm_list_charts 0 - return - ;; - helm_show_*) - __helm_list_charts 1 - return - ;; - helm_install | helm_template) - __helm_list_charts_after_name - return - ;; - helm_upgrade) - __helm_list_releases_then_charts - return - ;; - helm_uninstall | helm_history | helm_status | helm_test |\ - helm_rollback | helm_get_*) - __helm_list_releases - return - ;; - helm_repo_remove) - __helm_list_repos - return - ;; - helm_plugin_uninstall | helm_plugin_update) - __helm_list_plugins - return - ;; - *) - ;; - esac -} ` ) @@ -359,12 +191,18 @@ By default, the default directories depend on the Operating System. The defaults func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string) *cobra.Command { cmd := &cobra.Command{ - Use: "helm", - Short: "The Helm package manager for Kubernetes.", - Long: globalUsage, - SilenceUsage: true, - Args: require.NoArgs, - BashCompletionFunction: fmt.Sprintf(bashCompletionFunc, strings.Join(output.Formats(), " ")), + Use: "helm", + Short: "The Helm package manager for Kubernetes.", + Long: globalUsage, + SilenceUsage: true, + Args: require.NoArgs, + BashCompletionFunction: fmt.Sprintf( + bashCompletionFunc, + strings.Join(output.Formats(), " "), + completion.CompRequestCmd, + completion.BashCompDirectiveError, + completion.BashCompDirectiveNoSpace, + completion.BashCompDirectiveNoFileComp), } flags := cmd.PersistentFlags() @@ -409,6 +247,9 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string // Hidden documentation generator command: 'helm docs' newDocsCmd(out), + + // Setup the special hidden __complete command to allow for dynamic auto-completion + completion.NewCompleteCmd(settings), ) // Add annotation to flags for which we can generate completion choices diff --git a/cmd/helm/search_repo.go b/cmd/helm/search_repo.go index 063a72a27..a57ad135b 100644 --- a/cmd/helm/search_repo.go +++ b/cmd/helm/search_repo.go @@ -19,6 +19,7 @@ package main import ( "fmt" "io" + "io/ioutil" "path/filepath" "strings" @@ -28,6 +29,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/search" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/cli/output" "helm.sh/helm/v3/pkg/helmpath" "helm.sh/helm/v3/pkg/repo" @@ -246,3 +248,115 @@ func (r *repoSearchWriter) encodeByFormat(out io.Writer, format output.Format) e // WriteJSON and WriteYAML, we shouldn't get invalid types return nil } + +// Provides the list of charts that are part of the specified repo, and that starts with 'prefix'. +func compListChartsOfRepo(repoName string, prefix string) []string { + f := filepath.Join(settings.RepositoryCache, helmpath.CacheIndexFile(repoName)) + var charts []string + if indexFile, err := repo.LoadIndexFile(f); err == nil { + for name := range indexFile.Entries { + fullName := fmt.Sprintf("%s/%s", repoName, name) + if strings.HasPrefix(fullName, prefix) { + charts = append(charts, fullName) + } + } + } + return charts +} + +// Provide dynamic auto-completion for commands that operate on charts (e.g., helm show) +// When true, the includeFiles argument indicates that completion should include local files (e.g., local charts) +func compListCharts(toComplete string, includeFiles bool) ([]string, completion.BashCompDirective) { + completion.CompDebugln(fmt.Sprintf("compListCharts with toComplete %s", toComplete)) + + noSpace := false + noFile := false + var completions []string + + // First check completions for repos + repos := compListRepos("") + for _, repo := range repos { + repoWithSlash := fmt.Sprintf("%s/", repo) + if strings.HasPrefix(toComplete, repoWithSlash) { + // Must complete with charts within the specified repo + completions = append(completions, compListChartsOfRepo(repo, toComplete)...) + noSpace = false + break + } else if strings.HasPrefix(repo, toComplete) { + // Must complete the repo name + completions = append(completions, repoWithSlash) + noSpace = true + } + } + completion.CompDebugln(fmt.Sprintf("Completions after repos: %v", completions)) + + // Now handle completions for url prefixes + for _, url := range []string{"https://", "http://", "file://"} { + if strings.HasPrefix(toComplete, url) { + // The user already put in the full url prefix; we don't have + // anything to add, but make sure the shell does not default + // to file completion since we could be returning an empty array. + noFile = true + noSpace = true + } else if strings.HasPrefix(url, toComplete) { + // We are completing a url prefix + completions = append(completions, url) + noSpace = true + } + } + completion.CompDebugln(fmt.Sprintf("Completions after urls: %v", completions)) + + // Finally, provide file completion if we need to. + // We only do this if: + // 1- There are other completions found (if there are no completions, + // the shell will do file completion itself) + // 2- If there is some input from the user (or else we will end up + // listing the entire content of the current directory which will + // be too many choices for the user to find the real repos) + if includeFiles && len(completions) > 0 && len(toComplete) > 0 { + if files, err := ioutil.ReadDir("."); err == nil { + for _, file := range files { + if strings.HasPrefix(file.Name(), toComplete) { + // We are completing a file prefix + completions = append(completions, file.Name()) + } + } + } + } + completion.CompDebugln(fmt.Sprintf("Completions after files: %v", completions)) + + // If the user didn't provide any input to completion, + // we provide a hint that a path can also be used + if includeFiles && len(toComplete) == 0 { + completions = append(completions, "./", "/") + } + completion.CompDebugln(fmt.Sprintf("Completions after checking empty input: %v", completions)) + + directive := completion.BashCompDirectiveDefault + if noFile { + directive = directive | completion.BashCompDirectiveNoFileComp + } + if noSpace { + directive = directive | completion.BashCompDirectiveNoSpace + // The completion.BashCompDirective flags do not work for zsh right now. + // We handle it ourselves instead. + completions = compEnforceNoSpace(completions) + } + return completions, directive +} + +// This function prevents the shell from adding a space after +// a completion by adding a second, fake completion. +// It is only needed for zsh, but we cannot tell which shell +// is being used here, so we do the fake completion all the time; +// there are no real downsides to doing this for bash as well. +func compEnforceNoSpace(completions []string) []string { + // To prevent the shell from adding space after the completion, + // we trick it by pretending there is a second, longer match. + // We only do this if there is a single choice for completion. + if len(completions) == 1 { + completions = append(completions, completions[0]+".") + completion.CompDebugln(fmt.Sprintf("compEnforceNoSpace: completions now are %v", completions)) + } + return completions +} diff --git a/cmd/helm/show.go b/cmd/helm/show.go index e9e9cca8b..a82ad2777 100644 --- a/cmd/helm/show.go +++ b/cmd/helm/show.go @@ -23,6 +23,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" ) @@ -61,6 +62,14 @@ func newShowCmd(out io.Writer) *cobra.Command { Args: require.NoArgs, } + // Function providing dynamic auto-completion + validArgsFunc := func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) != 0 { + return nil, completion.BashCompDirectiveNoFileComp + } + return compListCharts(toComplete, true) + } + all := &cobra.Command{ Use: "all [CHART]", Short: "shows all information of the chart", @@ -145,6 +154,9 @@ func newShowCmd(out io.Writer) *cobra.Command { for _, subCmd := range cmds { addChartPathOptionsFlags(subCmd.Flags(), &client.ChartPathOptions) showCommand.AddCommand(subCmd) + + // Register the completion function for each subcommand + completion.RegisterValidArgsFunc(subCmd, validArgsFunc) } return showCommand diff --git a/cmd/helm/status.go b/cmd/helm/status.go index 92a947c26..8f172f66a 100644 --- a/cmd/helm/status.go +++ b/cmd/helm/status.go @@ -25,6 +25,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chartutil" "helm.sh/helm/v3/pkg/cli/output" @@ -65,6 +66,14 @@ func newStatusCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) != 0 { + return nil, completion.BashCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }) + f := cmd.PersistentFlags() f.IntVar(&client.Version, "revision", 0, "if set, display the status of the named release with revision") bindOutputFlag(cmd, &outfmt) diff --git a/cmd/helm/template.go b/cmd/helm/template.go index a47631c0d..fbd6f57e2 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -29,6 +29,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chartutil" "helm.sh/helm/v3/pkg/cli/values" @@ -123,6 +124,11 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + return compInstall(args, toComplete) + }) + f := cmd.Flags() addInstallFlags(f, client, valueOpts) f.StringArrayVarP(&showFiles, "show-only", "s", []string{}, "only show manifests rendered from the given templates") diff --git a/cmd/helm/uninstall.go b/cmd/helm/uninstall.go index 7096d7873..85fa822bd 100644 --- a/cmd/helm/uninstall.go +++ b/cmd/helm/uninstall.go @@ -24,6 +24,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" ) @@ -64,6 +65,14 @@ func newUninstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) != 0 { + return nil, completion.BashCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }) + f := cmd.Flags() f.BoolVar(&client.DryRun, "dry-run", false, "simulate a uninstall") f.BoolVar(&client.DisableHooks, "no-hooks", false, "prevent hooks from running during uninstallation") diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index acfc23198..6c967b796 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -25,6 +25,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart/loader" "helm.sh/helm/v3/pkg/cli/output" @@ -144,6 +145,17 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } + // Function providing dynamic auto-completion + completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) == 0 { + return compListReleases(toComplete, cfg) + } + if len(args) == 1 { + return compListCharts(toComplete, true) + } + return nil, completion.BashCompDirectiveNoFileComp + }) + f := cmd.Flags() f.BoolVarP(&client.Install, "install", "i", false, "if a release by this name doesn't already exist, run an install") f.BoolVar(&client.Devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored") diff --git a/internal/completion/complete.go b/internal/completion/complete.go new file mode 100644 index 000000000..435fdcc23 --- /dev/null +++ b/internal/completion/complete.go @@ -0,0 +1,201 @@ +/* +Copyright The Helm Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package completion + +import ( + "fmt" + "log" + "os" + "strings" + + "github.com/spf13/cobra" + + "helm.sh/helm/v3/cmd/helm/require" + "helm.sh/helm/v3/pkg/cli" +) + +// ================================================================================== +// The below code supports dynamic shell completion in Go. +// This should ultimately be pushed down into Cobra. +// ================================================================================== + +// CompRequestCmd Hidden command to request completion results from the program. +// Used by the shell completion script. +const CompRequestCmd = "__complete" + +// Global map allowing to find completion functions for commands. +var validArgsFunctions = map[*cobra.Command]func(cmd *cobra.Command, args []string, toComplete string) ([]string, BashCompDirective){} + +// BashCompDirective is a bit map representing the different behaviors the shell +// can be instructed to have once completions have been provided. +type BashCompDirective int + +const ( + // BashCompDirectiveError indicates an error occurred and completions should be ignored. + BashCompDirectiveError BashCompDirective = 1 << iota + + // BashCompDirectiveNoSpace indicates that the shell should not add a space + // after the completion even if there is a single completion provided. + BashCompDirectiveNoSpace + + // BashCompDirectiveNoFileComp indicates that the shell should not provide + // file completion even when no completion is provided. + // This currently does not work for zsh or bash < 4 + BashCompDirectiveNoFileComp + + // BashCompDirectiveDefault indicates to let the shell perform its default + // behavior after completions have been provided. + BashCompDirectiveDefault BashCompDirective = 0 +) + +// RegisterValidArgsFunc should be called to register a function to provide argument completion for a command +func RegisterValidArgsFunc(cmd *cobra.Command, f func(cmd *cobra.Command, args []string, toComplete string) ([]string, BashCompDirective)) { + if _, exists := validArgsFunctions[cmd]; exists { + log.Fatal(fmt.Sprintf("RegisterValidArgsFunc: command '%s' already registered", cmd.Name())) + } + validArgsFunctions[cmd] = f +} + +var debug = true + +// Returns a string listing the different directive enabled in the specified parameter +func (d BashCompDirective) string() string { + var directives []string + if d&BashCompDirectiveError != 0 { + directives = append(directives, "BashCompDirectiveError") + } + if d&BashCompDirectiveNoSpace != 0 { + directives = append(directives, "BashCompDirectiveNoSpace") + } + if d&BashCompDirectiveNoFileComp != 0 { + directives = append(directives, "BashCompDirectiveNoFileComp") + } + if len(directives) == 0 { + directives = append(directives, "BashCompDirectiveDefault") + } + + if d > BashCompDirectiveError+BashCompDirectiveNoSpace+BashCompDirectiveNoFileComp { + return fmt.Sprintf("ERROR: unexpected BashCompDirective value: %d", d) + } + return strings.Join(directives, ", ") +} + +// NewCompleteCmd add a special hidden command that an be used to request completions +func NewCompleteCmd(settings *cli.EnvSettings) *cobra.Command { + debug = settings.Debug + return &cobra.Command{ + Use: fmt.Sprintf("%s [command-line]", CompRequestCmd), + DisableFlagsInUseLine: true, + Hidden: true, + DisableFlagParsing: true, + Args: require.MinimumNArgs(2), + Short: "Request shell completion choices for the specified command-line", + Long: fmt.Sprintf("%s is a special command that is used by the shell completion logic\n%s", + CompRequestCmd, "to request completion choices for the specified command-line."), + Run: func(cmd *cobra.Command, args []string) { + CompDebugln(fmt.Sprintf("%s was called with args %v", cmd.Name(), args)) + + trimmedArgs := args[:len(args)-1] + toComplete := args[len(args)-1] + + // Find the real command for which completion must be performed + finalCmd, finalArgs, err := cmd.Root().Find(trimmedArgs) + if err != nil { + // Unable to find the real command. E.g., helm invalidCmd + os.Exit(int(BashCompDirectiveError)) + } + + CompDebugln(fmt.Sprintf("Found final command '%s', with finalArgs %v", finalCmd.Name(), finalArgs)) + + // Parse the flags and extract the arguments to prepare for calling the completion function + if err = finalCmd.ParseFlags(finalArgs); err != nil { + CompErrorln(fmt.Sprintf("Error while parsing flags from args %v: %s", finalArgs, err.Error())) + return + } + argsWoFlags := finalCmd.Flags().Args() + CompDebugln(fmt.Sprintf("Args without flags are '%v' with length %d", argsWoFlags, len(argsWoFlags))) + + // Find completion function for the command + completionFn, ok := validArgsFunctions[finalCmd] + if !ok { + CompErrorln(fmt.Sprintf("Dynamic completion not supported/needed for flag or command: %s", finalCmd.Name())) + return + } + + CompDebugln(fmt.Sprintf("Calling completion method for subcommand '%s' with args '%v' and toComplete '%s'", finalCmd.Name(), argsWoFlags, toComplete)) + completions, directive := completionFn(finalCmd, argsWoFlags, toComplete) + for _, comp := range completions { + // Print each possible completion to stdout for the completion script to consume. + fmt.Println(comp) + } + + // Print some helpful info to stderr for the user to see. + // Output from stderr should be ignored from the completion script. + fmt.Fprintf(os.Stderr, "Completion ended with directive: %s\n", directive.string()) + os.Exit(int(directive)) + }, + } +} + +// CompDebug prints the specified string to the same file as where the +// completion script prints its logs. +// Note that completion printouts should never be on stdout as they would +// be wrongly interpreted as actual completion choices by the completion script. +func CompDebug(msg string) { + msg = fmt.Sprintf("[Debug] %s", msg) + + // Such logs are only printed when the user has set the environment + // variable BASH_COMP_DEBUG_FILE to the path of some file to be used. + if path := os.Getenv("BASH_COMP_DEBUG_FILE"); path != "" { + f, err := os.OpenFile(path, + os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err == nil { + defer f.Close() + f.WriteString(msg) + } + } + + if debug { + // Must print to stderr for this not to be read by the completion script. + fmt.Fprintf(os.Stderr, msg) + } +} + +// CompDebugln prints the specified string with a newline at the end +// to the same file as where the completion script prints its logs. +// Such logs are only printed when the user has set the environment +// variable BASH_COMP_DEBUG_FILE to the path of some file to be used. +func CompDebugln(msg string) { + CompDebug(fmt.Sprintf("%s\n", msg)) +} + +// CompError prints the specified completion message to stderr. +func CompError(msg string) { + msg = fmt.Sprintf("[Error] %s", msg) + + CompDebug(msg) + + // If not already printed by the call to CompDebug(). + if !debug { + // Must print to stderr for this not to be read by the completion script. + fmt.Fprintf(os.Stderr, msg) + } +} + +// CompErrorln prints the specified completion message to stderr with a newline at the end. +func CompErrorln(msg string) { + CompError(fmt.Sprintf("%s\n", msg)) +} From 62c9c34d493a63f80c06337c60871858df60ea3a Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 31 Dec 2019 08:54:20 -0500 Subject: [PATCH 47/81] feat(comp): Dynamic completion of flags in Go Conflicts: cmd/helm/completion/complete.go cmd/helm/root.go Conflicts: cmd/helm/root.go Signed-off-by: Marc Khouzam --- cmd/helm/flags.go | 17 ++++- cmd/helm/root.go | 103 +++++++++---------------- internal/completion/complete.go | 131 ++++++++++++++++++++++++++++++-- 3 files changed, 174 insertions(+), 77 deletions(-) diff --git a/cmd/helm/flags.go b/cmd/helm/flags.go index aa22603f4..b9473a5a7 100644 --- a/cmd/helm/flags.go +++ b/cmd/helm/flags.go @@ -23,6 +23,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" + "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli/output" "helm.sh/helm/v3/pkg/cli/values" @@ -52,10 +53,20 @@ func addChartPathOptionsFlags(f *pflag.FlagSet, c *action.ChartPathOptions) { // bindOutputFlag will add the output flag to the given command and bind the // value to the given format pointer func bindOutputFlag(cmd *cobra.Command, varRef *output.Format) { - cmd.Flags().VarP(newOutputValue(output.Table, varRef), outputFlag, "o", + f := cmd.Flags() + f.VarP(newOutputValue(output.Table, varRef), outputFlag, "o", fmt.Sprintf("prints the output in the specified format. Allowed values: %s", strings.Join(output.Formats(), ", "))) - // Setup shell completion for the flag - cmd.MarkFlagCustom(outputFlag, "__helm_output_options") + + flag := f.Lookup(outputFlag) + completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + var formatNames []string + for _, format := range output.Formats() { + if strings.HasPrefix(format, toComplete) { + formatNames = append(formatNames, format) + } + } + return formatNames, completion.BashCompDirectiveDefault + }) } type outputValue output.Format diff --git a/cmd/helm/root.go b/cmd/helm/root.go index e02723a6f..ab7b01c90 100644 --- a/cmd/helm/root.go +++ b/cmd/helm/root.go @@ -23,51 +23,16 @@ import ( "github.com/spf13/cobra" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "helm.sh/helm/v3/cmd/helm/require" "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/internal/experimental/registry" "helm.sh/helm/v3/pkg/action" - "helm.sh/helm/v3/pkg/cli/output" ) const ( bashCompletionFunc = ` -__helm_override_flag_list=(--kubeconfig --kube-context --namespace -n) -__helm_override_flags() -{ - local ${__helm_override_flag_list[*]##*-} two_word_of of var - for w in "${words[@]}"; do - if [ -n "${two_word_of}" ]; then - eval "${two_word_of##*-}=\"${two_word_of}=\${w}\"" - two_word_of= - continue - fi - for of in "${__helm_override_flag_list[@]}"; do - case "${w}" in - ${of}=*) - eval "${of##*-}=\"${w}\"" - ;; - ${of}) - two_word_of="${of}" - ;; - esac - done - done - for var in "${__helm_override_flag_list[@]##*-}"; do - if eval "test -n \"\$${var}\""; then - eval "echo \${${var}}" - fi - done -} - -__helm_override_flags_to_kubectl_flags() -{ - # --kubeconfig, -n, --namespace stay the same for kubectl - # --kube-context becomes --context for kubectl - __helm_debug "${FUNCNAME[0]}: flags to convert: $1" - echo "$1" | \sed s/kube-context/context/ -} - __helm_get_contexts() { __helm_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" @@ -78,36 +43,19 @@ __helm_get_contexts() fi } -__helm_get_namespaces() -{ - __helm_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" - local template out - template="{{ range .items }}{{ .metadata.name }} {{ end }}" - - flags=$(__helm_override_flags_to_kubectl_flags "$(__helm_override_flags)") - __helm_debug "${FUNCNAME[0]}: override flags for kubectl are: $flags" - - # Must use eval in case the flags contain a variable such as $HOME - if out=$(eval kubectl get ${flags} -o template --template=\"${template}\" namespace 2>/dev/null); then - COMPREPLY+=( $( compgen -W "${out[*]}" -- "$cur" ) ) - fi -} - -__helm_output_options() -{ - __helm_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" - COMPREPLY+=( $( compgen -W "%[1]s" -- "$cur" ) ) -} - __helm_custom_func() { __helm_debug "${FUNCNAME[0]}: c is $c, words[@] is ${words[@]}, #words[@] is ${#words[@]}" __helm_debug "${FUNCNAME[0]}: cur is ${cur}, cword is ${cword}, words is ${words}" - local out requestComp - requestComp="${words[0]} %[2]s ${words[@]:1}" + local out requestComp lastParam lastChar + requestComp="${words[0]} %[1]s ${words[@]:1}" - if [ -z "${cur}" ]; then + lastParam=${words[$((${#words[@]}-1))]} + lastChar=${lastParam:$((${#lastParam}-1)):1} + __helm_debug "${FUNCNAME[0]}: lastParam ${lastParam}, lastChar ${lastChar}" + + if [ -z "${cur}" ] && [ "${lastChar}" != "=" ]; then # If the last parameter is complete (there is a space following it) # We add an extra empty parameter so we can indicate this to the go method. __helm_debug "${FUNCNAME[0]}: Adding extra empty parameter" @@ -119,15 +67,15 @@ __helm_custom_func() out=$(eval ${requestComp} 2>/dev/null) directive=$? - if [ $((${directive} & %[3]d)) -ne 0 ]; then + if [ $((${directive} & %[2]d)) -ne 0 ]; then __helm_debug "${FUNCNAME[0]}: received error, completion failed" else - if [ $((${directive} & %[4]d)) -ne 0 ]; then + if [ $((${directive} & %[3]d)) -ne 0 ]; then if [[ $(type -t compopt) = "builtin" ]]; then compopt -o nospace fi fi - if [ $((${directive} & %[5]d)) -ne 0 ]; then + if [ $((${directive} & %[4]d)) -ne 0 ]; then if [[ $(type -t compopt) = "builtin" ]]; then compopt +o default fi @@ -145,7 +93,8 @@ var ( // Mapping of global flags that can have dynamic completion and the // completion function to be used. bashCompletionFlags = map[string]string{ - "namespace": "__helm_get_namespaces", + // Cannot convert the kube-context flag to Go completion yet because + // an incomplete kube-context will make actionConfig.Init() fail at the very start "kube-context": "__helm_get_contexts", } ) @@ -198,7 +147,6 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string Args: require.NoArgs, BashCompletionFunction: fmt.Sprintf( bashCompletionFunc, - strings.Join(output.Formats(), " "), completion.CompRequestCmd, completion.BashCompDirectiveError, completion.BashCompDirectiveNoSpace, @@ -208,6 +156,29 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string settings.AddFlags(flags) + flag := flags.Lookup("namespace") + // Setup shell completion for the namespace flag + completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if client, err := actionConfig.KubernetesClientSet(); err == nil { + // Choose a long enough timeout that the user notices somethings is not working + // but short enough that the user is not made to wait very long + to := int64(3) + completion.CompDebugln(fmt.Sprintf("About to call kube client for namespaces with timeout of: %d", to)) + + nsNames := []string{} + // TODO can we request only the namespace with request.prefix? + if namespaces, err := client.CoreV1().Namespaces().List(metav1.ListOptions{TimeoutSeconds: &to}); err == nil { + for _, ns := range namespaces.Items { + if strings.HasPrefix(ns.Name, toComplete) { + nsNames = append(nsNames, ns.Name) + } + } + return nsNames, completion.BashCompDirectiveNoFileComp + } + } + return nil, completion.BashCompDirectiveDefault + }) + // We can safely ignore any errors that flags.Parse encounters since // those errors will be caught later during the call to cmd.Execution. // This call is required to gather configuration information prior to diff --git a/internal/completion/complete.go b/internal/completion/complete.go index 435fdcc23..c0fabda1b 100644 --- a/internal/completion/complete.go +++ b/internal/completion/complete.go @@ -22,6 +22,7 @@ import ( "strings" "github.com/spf13/cobra" + "github.com/spf13/pflag" "helm.sh/helm/v3/cmd/helm/require" "helm.sh/helm/v3/pkg/cli" @@ -36,8 +37,8 @@ import ( // Used by the shell completion script. const CompRequestCmd = "__complete" -// Global map allowing to find completion functions for commands. -var validArgsFunctions = map[*cobra.Command]func(cmd *cobra.Command, args []string, toComplete string) ([]string, BashCompDirective){} +// Global map allowing to find completion functions for commands or flags. +var validArgsFunctions = map[interface{}]func(cmd *cobra.Command, args []string, toComplete string) ([]string, BashCompDirective){} // BashCompDirective is a bit map representing the different behaviors the shell // can be instructed to have once completions have been provided. @@ -69,6 +70,21 @@ func RegisterValidArgsFunc(cmd *cobra.Command, f func(cmd *cobra.Command, args [ validArgsFunctions[cmd] = f } +// RegisterFlagCompletionFunc should be called to register a function to provide completion for a flag +func RegisterFlagCompletionFunc(flag *pflag.Flag, f func(cmd *cobra.Command, args []string, toComplete string) ([]string, BashCompDirective)) { + if _, exists := validArgsFunctions[flag]; exists { + log.Fatal(fmt.Sprintf("RegisterFlagCompletionFunc: flag '%s' already registered", flag.Name)) + } + validArgsFunctions[flag] = f + + // Make sure the completion script call the __helm_custom_func for the registered flag. + // This is essential to make the = form work. E.g., helm -n= or helm status --output= + if flag.Annotations == nil { + flag.Annotations = map[string][]string{} + } + flag.Annotations[cobra.BashCompCustom] = []string{"__helm_custom_func"} +} + var debug = true // Returns a string listing the different directive enabled in the specified parameter @@ -101,15 +117,14 @@ func NewCompleteCmd(settings *cli.EnvSettings) *cobra.Command { DisableFlagsInUseLine: true, Hidden: true, DisableFlagParsing: true, - Args: require.MinimumNArgs(2), + Args: require.MinimumNArgs(1), Short: "Request shell completion choices for the specified command-line", Long: fmt.Sprintf("%s is a special command that is used by the shell completion logic\n%s", CompRequestCmd, "to request completion choices for the specified command-line."), Run: func(cmd *cobra.Command, args []string) { CompDebugln(fmt.Sprintf("%s was called with args %v", cmd.Name(), args)) - trimmedArgs := args[:len(args)-1] - toComplete := args[len(args)-1] + flag, trimmedArgs, toComplete := checkIfFlagCompletion(cmd.Root(), args[:len(args)-1], args[len(args)-1]) // Find the real command for which completion must be performed finalCmd, finalArgs, err := cmd.Root().Find(trimmedArgs) @@ -128,10 +143,20 @@ func NewCompleteCmd(settings *cli.EnvSettings) *cobra.Command { argsWoFlags := finalCmd.Flags().Args() CompDebugln(fmt.Sprintf("Args without flags are '%v' with length %d", argsWoFlags, len(argsWoFlags))) - // Find completion function for the command - completionFn, ok := validArgsFunctions[finalCmd] + var key interface{} + var keyStr string + if flag != nil { + key = flag + keyStr = flag.Name + } else { + key = finalCmd + keyStr = finalCmd.Name() + } + + // Find completion function for the flag or command + completionFn, ok := validArgsFunctions[key] if !ok { - CompErrorln(fmt.Sprintf("Dynamic completion not supported/needed for flag or command: %s", finalCmd.Name())) + CompErrorln(fmt.Sprintf("Dynamic completion not supported/needed for flag or command: %s", keyStr)) return } @@ -150,6 +175,96 @@ func NewCompleteCmd(settings *cli.EnvSettings) *cobra.Command { } } +func isFlag(arg string) bool { + return len(arg) > 0 && arg[0] == '-' +} + +func checkIfFlagCompletion(rootCmd *cobra.Command, args []string, lastArg string) (*pflag.Flag, []string, string) { + var flagName string + trimmedArgs := args + flagWithEqual := false + if isFlag(lastArg) { + if index := strings.Index(lastArg, "="); index >= 0 { + flagName = strings.TrimLeft(lastArg[:index], "-") + lastArg = lastArg[index+1:] + flagWithEqual = true + } else { + CompErrorln("Unexpected completion request for flag") + os.Exit(int(BashCompDirectiveError)) + } + } + + if len(flagName) == 0 { + if len(args) > 0 { + prevArg := args[len(args)-1] + if isFlag(prevArg) { + // If the flag contains an = it means it has already been fully processed + if index := strings.Index(prevArg, "="); index < 0 { + flagName = strings.TrimLeft(prevArg, "-") + + // Remove the uncompleted flag or else Cobra could complain about + // an invalid value for that flag e.g., helm status --output j + trimmedArgs = args[:len(args)-1] + } + } + } + } + + if len(flagName) == 0 { + // Not doing flag completion + return nil, trimmedArgs, lastArg + } + + // Find the real command for which completion must be performed + finalCmd, _, err := rootCmd.Find(trimmedArgs) + if err != nil { + // Unable to find the real command. E.g., helm invalidCmd + os.Exit(int(BashCompDirectiveError)) + } + + CompDebugln(fmt.Sprintf("checkIfFlagCompletion: found final command '%s'", finalCmd.Name())) + + flag := findFlag(finalCmd, flagName) + if flag == nil { + // Flag not supported by this command, nothing to complete + CompDebugln(fmt.Sprintf("Subcommand '%s' does not support flag '%s'", finalCmd.Name(), flagName)) + os.Exit(int(BashCompDirectiveNoFileComp)) + } + + if !flagWithEqual { + if len(flag.NoOptDefVal) != 0 { + // We had assumed dealing with a two-word flag but the flag is a boolean flag. + // In that case, there is no value following it, so we are not really doing flag completion. + // Reset everything to do argument completion. + trimmedArgs = args + flag = nil + } + } + + return flag, trimmedArgs, lastArg +} + +func findFlag(cmd *cobra.Command, name string) *pflag.Flag { + flagSet := cmd.Flags() + if len(name) == 1 { + // First convert the short flag into a long flag + // as the cmd.Flag() search only accepts long flags + if short := flagSet.ShorthandLookup(name); short != nil { + CompDebugln(fmt.Sprintf("checkIfFlagCompletion: found flag '%s' which we will change to '%s'", name, short.Name)) + name = short.Name + } else { + set := cmd.InheritedFlags() + if short = set.ShorthandLookup(name); short != nil { + CompDebugln(fmt.Sprintf("checkIfFlagCompletion: found inherited flag '%s' which we will change to '%s'", name, short.Name)) + name = short.Name + } else { + return nil + } + } + } + return cmd.Flag(name) +} + // CompDebug prints the specified string to the same file as where the // completion script prints its logs. // Note that completion printouts should never be on stdout as they would From de1ca6784afe52762880d74bfd3732437399ac7b Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 31 Dec 2019 08:59:10 -0500 Subject: [PATCH 48/81] feat(comp): Support --generate-name in completion Signed-off-by: Marc Khouzam --- cmd/helm/install.go | 10 +++++++--- cmd/helm/template.go | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/cmd/helm/install.go b/cmd/helm/install.go index 701048151..0f548c90c 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -125,7 +125,7 @@ func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { // Function providing dynamic auto-completion completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - return compInstall(args, toComplete) + return compInstall(args, toComplete, client) }) addInstallFlags(cmd.Flags(), client, valueOpts) @@ -233,8 +233,12 @@ func isChartInstallable(ch *chart.Chart) (bool, error) { } // Provide dynamic auto-completion for the install and template commands -func compInstall(args []string, toComplete string) ([]string, completion.BashCompDirective) { - if len(args) == 1 { +func compInstall(args []string, toComplete string, client *action.Install) ([]string, completion.BashCompDirective) { + requiredArgs := 1 + if client.GenerateName { + requiredArgs = 0 + } + if len(args) == requiredArgs { return compListCharts(toComplete, true) } return nil, completion.BashCompDirectiveNoFileComp diff --git a/cmd/helm/template.go b/cmd/helm/template.go index fbd6f57e2..1c34d7245 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -126,7 +126,7 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { // Function providing dynamic auto-completion completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - return compInstall(args, toComplete) + return compInstall(args, toComplete, client) }) f := cmd.Flags() From d5d741dfed59d82f2b350bdb0c97d05f83f4abd1 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Wed, 1 Jan 2020 15:57:51 -0500 Subject: [PATCH 49/81] feat(comp): Support completion for --revision flag Signed-off-by: Marc Khouzam --- cmd/helm/get_all.go | 8 ++++++++ cmd/helm/get_hooks.go | 10 +++++++++- cmd/helm/get_manifest.go | 10 +++++++++- cmd/helm/get_notes.go | 7 +++++++ cmd/helm/get_values.go | 7 +++++++ cmd/helm/history.go | 14 ++++++++++++++ cmd/helm/status.go | 9 +++++++++ 7 files changed, 63 insertions(+), 2 deletions(-) diff --git a/cmd/helm/get_all.go b/cmd/helm/get_all.go index 678b85f25..7d893d7e0 100644 --- a/cmd/helm/get_all.go +++ b/cmd/helm/get_all.go @@ -67,6 +67,14 @@ func newGetAllCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f := cmd.Flags() f.IntVar(&client.Version, "revision", 0, "get the named release with revision") + flag := f.Lookup("revision") + completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) == 1 { + return compListRevisions(cfg, args[0]) + } + return nil, completion.BashCompDirectiveNoFileComp + }) + f.StringVar(&template, "template", "", "go template for formatting the output, eg: {{.Release.Name}}") return cmd diff --git a/cmd/helm/get_hooks.go b/cmd/helm/get_hooks.go index 84ef0c1fc..c2087b1ba 100644 --- a/cmd/helm/get_hooks.go +++ b/cmd/helm/get_hooks.go @@ -61,7 +61,15 @@ func newGetHooksCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { return compListReleases(toComplete, cfg) }) - cmd.Flags().IntVar(&client.Version, "revision", 0, "get the named release with revision") + f := cmd.Flags() + f.IntVar(&client.Version, "revision", 0, "get the named release with revision") + flag := f.Lookup("revision") + completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) == 1 { + return compListRevisions(cfg, args[0]) + } + return nil, completion.BashCompDirectiveNoFileComp + }) return cmd } diff --git a/cmd/helm/get_manifest.go b/cmd/helm/get_manifest.go index 1860025cd..f332befd9 100644 --- a/cmd/helm/get_manifest.go +++ b/cmd/helm/get_manifest.go @@ -61,7 +61,15 @@ func newGetManifestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command return compListReleases(toComplete, cfg) }) - cmd.Flags().IntVar(&client.Version, "revision", 0, "get the named release with revision") + f := cmd.Flags() + f.IntVar(&client.Version, "revision", 0, "get the named release with revision") + flag := f.Lookup("revision") + completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) == 1 { + return compListRevisions(cfg, args[0]) + } + return nil, completion.BashCompDirectiveNoFileComp + }) return cmd } diff --git a/cmd/helm/get_notes.go b/cmd/helm/get_notes.go index de3adf498..4491bd9ba 100644 --- a/cmd/helm/get_notes.go +++ b/cmd/helm/get_notes.go @@ -61,6 +61,13 @@ func newGetNotesCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f := cmd.Flags() f.IntVar(&client.Version, "revision", 0, "get the named release with revision") + flag := f.Lookup("revision") + completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) == 1 { + return compListRevisions(cfg, args[0]) + } + return nil, completion.BashCompDirectiveNoFileComp + }) return cmd } diff --git a/cmd/helm/get_values.go b/cmd/helm/get_values.go index 898db8929..a8c5acc5e 100644 --- a/cmd/helm/get_values.go +++ b/cmd/helm/get_values.go @@ -65,6 +65,13 @@ func newGetValuesCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f := cmd.Flags() f.IntVar(&client.Version, "revision", 0, "get the named release with revision") + flag := f.Lookup("revision") + completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) == 1 { + return compListRevisions(cfg, args[0]) + } + return nil, completion.BashCompDirectiveNoFileComp + }) f.BoolVarP(&client.AllValues, "all", "a", false, "dump all (computed) values") bindOutputFlag(cmd, &outfmt) diff --git a/cmd/helm/history.go b/cmd/helm/history.go index 739848c1c..3ef542e58 100644 --- a/cmd/helm/history.go +++ b/cmd/helm/history.go @@ -19,6 +19,7 @@ package main import ( "fmt" "io" + "strconv" "time" "github.com/gosuri/uitable" @@ -185,3 +186,16 @@ func min(x, y int) int { } return y } + +func compListRevisions(cfg *action.Configuration, releaseName string) ([]string, completion.BashCompDirective) { + client := action.NewHistory(cfg) + + var revisions []string + if hist, err := client.Run(releaseName); err == nil { + for _, release := range hist { + revisions = append(revisions, strconv.Itoa(release.Version)) + } + return revisions, completion.BashCompDirectiveDefault + } + return nil, completion.BashCompDirectiveError +} diff --git a/cmd/helm/status.go b/cmd/helm/status.go index 8f172f66a..34543c6cb 100644 --- a/cmd/helm/status.go +++ b/cmd/helm/status.go @@ -75,7 +75,16 @@ func newStatusCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }) f := cmd.PersistentFlags() + f.IntVar(&client.Version, "revision", 0, "if set, display the status of the named release with revision") + flag := f.Lookup("revision") + completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + if len(args) == 1 { + return compListRevisions(cfg, args[0]) + } + return nil, completion.BashCompDirectiveNoFileComp + }) + bindOutputFlag(cmd, &outfmt) return cmd From 90548c591d9f2662c2db303b4cb09feaab33a02d Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 9 Jan 2020 20:28:46 -0500 Subject: [PATCH 50/81] feat(comp): Don't use error codes for completion To use error codes to indicate completion directive to the completion script had us use os.Exit() in the __complete command. This prevented go tests calling the __complete command from succeeding. Another option was to return an error containing an error code (like is done for helm plugins) instead of calling os.Exit(). However such an approach requires a change in how helm handles the returned error of a Cobra command; although we can do this for Helm, it would be an annoying requirement for other programs if we ever push this completion logic into Cobra. The chosen solution instead is to printout the directive at the end of the list of completions, and have the completion script extract it. Note that we print both the completions and directive to stdout. It would have been interesting to print the completions to stdout and the directive to stderr; however, it is very complicated for the completion script to extract both stdout and stderr to different variables, and even if possible, such code would not be portable to many shells. Printing both to stdout is much simpler. Signed-off-by: Marc Khouzam --- cmd/helm/root.go | 14 ++++++++++++- internal/completion/complete.go | 35 +++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/cmd/helm/root.go b/cmd/helm/root.go index ab7b01c90..bf98e72fe 100644 --- a/cmd/helm/root.go +++ b/cmd/helm/root.go @@ -65,18 +65,30 @@ __helm_custom_func() __helm_debug "${FUNCNAME[0]}: calling ${requestComp}" # Use eval to handle any environment variables and such out=$(eval ${requestComp} 2>/dev/null) - directive=$? + + # Extract the directive int at the very end of the output following a : + directive=${out##*:} + # Remove the directive + out=${out%%:*} + if [ "${directive}" = "${out}" ]; then + # There is not directive specified + directive=0 + fi + __helm_debug "${FUNCNAME[0]}: the completion directive is: ${directive}" + __helm_debug "${FUNCNAME[0]}: the completions are: ${out[*]}" if [ $((${directive} & %[2]d)) -ne 0 ]; then __helm_debug "${FUNCNAME[0]}: received error, completion failed" else if [ $((${directive} & %[3]d)) -ne 0 ]; then if [[ $(type -t compopt) = "builtin" ]]; then + __helm_debug "${FUNCNAME[0]}: activating no space" compopt -o nospace fi fi if [ $((${directive} & %[4]d)) -ne 0 ]; then if [[ $(type -t compopt) = "builtin" ]]; then + __helm_debug "${FUNCNAME[0]}: activating no file completion" compopt +o default fi fi diff --git a/internal/completion/complete.go b/internal/completion/complete.go index c0fabda1b..d13c7f5bd 100644 --- a/internal/completion/complete.go +++ b/internal/completion/complete.go @@ -16,6 +16,7 @@ limitations under the License. package completion import ( + "errors" "fmt" "log" "os" @@ -124,13 +125,17 @@ func NewCompleteCmd(settings *cli.EnvSettings) *cobra.Command { Run: func(cmd *cobra.Command, args []string) { CompDebugln(fmt.Sprintf("%s was called with args %v", cmd.Name(), args)) - flag, trimmedArgs, toComplete := checkIfFlagCompletion(cmd.Root(), args[:len(args)-1], args[len(args)-1]) - + flag, trimmedArgs, toComplete, err := checkIfFlagCompletion(cmd.Root(), args[:len(args)-1], args[len(args)-1]) + if err != nil { + // Error while attempting to parse flags + CompErrorln(err.Error()) + return + } // Find the real command for which completion must be performed finalCmd, finalArgs, err := cmd.Root().Find(trimmedArgs) if err != nil { // Unable to find the real command. E.g., helm invalidCmd - os.Exit(int(BashCompDirectiveError)) + return } CompDebugln(fmt.Sprintf("Found final command '%s', with finalArgs %v", finalCmd.Name(), finalArgs)) @@ -167,10 +172,15 @@ func NewCompleteCmd(settings *cli.EnvSettings) *cobra.Command { fmt.Println(comp) } - // Print some helpful info to stderr for the user to see. + // As the last printout, print the completion directive for the + // completion script to parse. + // The directive integer must be that last character following a single : + // The completion script expects :directive + fmt.Printf("\n:%d\n", directive) + + // Print some helpful info to stderr for the user to understand. // Output from stderr should be ignored from the completion script. fmt.Fprintf(os.Stderr, "Completion ended with directive: %s\n", directive.string()) - os.Exit(int(directive)) }, } } @@ -179,7 +189,7 @@ func isFlag(arg string) bool { return len(arg) > 0 && arg[0] == '-' } -func checkIfFlagCompletion(rootCmd *cobra.Command, args []string, lastArg string) (*pflag.Flag, []string, string) { +func checkIfFlagCompletion(rootCmd *cobra.Command, args []string, lastArg string) (*pflag.Flag, []string, string, error) { var flagName string trimmedArgs := args flagWithEqual := false @@ -189,8 +199,7 @@ func checkIfFlagCompletion(rootCmd *cobra.Command, args []string, lastArg string lastArg = lastArg[index+1:] flagWithEqual = true } else { - CompErrorln("Unexpected completion request for flag") - os.Exit(int(BashCompDirectiveError)) + return nil, nil, "", errors.New("Unexpected completion request for flag") } } @@ -212,14 +221,14 @@ func checkIfFlagCompletion(rootCmd *cobra.Command, args []string, lastArg string if len(flagName) == 0 { // Not doing flag completion - return nil, trimmedArgs, lastArg + return nil, trimmedArgs, lastArg, nil } // Find the real command for which completion must be performed finalCmd, _, err := rootCmd.Find(trimmedArgs) if err != nil { // Unable to find the real command. E.g., helm invalidCmd - os.Exit(int(BashCompDirectiveError)) + return nil, nil, "", errors.New("Unable to find final command for completion") } CompDebugln(fmt.Sprintf("checkIfFlagCompletion: found final command '%s'", finalCmd.Name())) @@ -227,8 +236,8 @@ func checkIfFlagCompletion(rootCmd *cobra.Command, args []string, lastArg string flag := findFlag(finalCmd, flagName) if flag == nil { // Flag not supported by this command, nothing to complete - CompDebugln(fmt.Sprintf("Subcommand '%s' does not support flag '%s'", finalCmd.Name(), flagName)) - os.Exit(int(BashCompDirectiveNoFileComp)) + err = fmt.Errorf("Subcommand '%s' does not support flag '%s'", finalCmd.Name(), flagName) + return nil, nil, "", err } if !flagWithEqual { @@ -241,7 +250,7 @@ func checkIfFlagCompletion(rootCmd *cobra.Command, args []string, lastArg string } } - return flag, trimmedArgs, lastArg + return flag, trimmedArgs, lastArg, nil } func findFlag(cmd *cobra.Command, name string) *pflag.Flag { From 0095e320012b606d70f0fa52f5bb4084275a2ffa Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Wed, 8 Jan 2020 15:04:07 -0500 Subject: [PATCH 51/81] feat(test): add some completion tests Signed-off-by: Marc Khouzam --- cmd/helm/flags_test.go | 88 +++++++++++++++++++ cmd/helm/get_all_test.go | 4 + cmd/helm/get_hooks_test.go | 4 + cmd/helm/get_manifest_test.go | 4 + cmd/helm/get_notes_test.go | 4 + cmd/helm/get_values_test.go | 8 ++ cmd/helm/helm_test.go | 29 ++++++ cmd/helm/history_test.go | 40 +++++++++ cmd/helm/install_test.go | 4 + cmd/helm/list_test.go | 4 + cmd/helm/repo_list_test.go | 25 ++++++ cmd/helm/root.go | 2 +- cmd/helm/search_hub_test.go | 3 + cmd/helm/search_repo_test.go | 4 + cmd/helm/status_test.go | 63 +++++++++++++ cmd/helm/testdata/output/output-comp.txt | 4 + cmd/helm/testdata/output/revision-comp.txt | 5 ++ .../output/revision-wrong-args-comp.txt | 1 + cmd/helm/testdata/output/status-comp.txt | 3 + .../output/status-wrong-args-comp.txt | 1 + cmd/helm/upgrade_test.go | 4 + internal/completion/complete.go | 7 +- 22 files changed, 307 insertions(+), 4 deletions(-) create mode 100644 cmd/helm/flags_test.go create mode 100644 cmd/helm/repo_list_test.go create mode 100644 cmd/helm/testdata/output/output-comp.txt create mode 100644 cmd/helm/testdata/output/revision-comp.txt create mode 100644 cmd/helm/testdata/output/revision-wrong-args-comp.txt create mode 100644 cmd/helm/testdata/output/status-comp.txt create mode 100644 cmd/helm/testdata/output/status-wrong-args-comp.txt diff --git a/cmd/helm/flags_test.go b/cmd/helm/flags_test.go new file mode 100644 index 000000000..d5576fe9f --- /dev/null +++ b/cmd/helm/flags_test.go @@ -0,0 +1,88 @@ +/* +Copyright The Helm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "fmt" + "testing" + + "helm.sh/helm/v3/pkg/chart" + "helm.sh/helm/v3/pkg/release" + helmtime "helm.sh/helm/v3/pkg/time" +) + +func outputFlagCompletionTest(t *testing.T, cmdName string) { + releasesMockWithStatus := func(info *release.Info, hooks ...*release.Hook) []*release.Release { + info.LastDeployed = helmtime.Unix(1452902400, 0).UTC() + return []*release.Release{{ + Name: "athos", + Namespace: "default", + Info: info, + Chart: &chart.Chart{}, + Hooks: hooks, + }, { + Name: "porthos", + Namespace: "default", + Info: info, + Chart: &chart.Chart{}, + Hooks: hooks, + }, { + Name: "aramis", + Namespace: "default", + Info: info, + Chart: &chart.Chart{}, + Hooks: hooks, + }, { + Name: "dartagnan", + Namespace: "gascony", + Info: info, + Chart: &chart.Chart{}, + Hooks: hooks, + }} + } + + tests := []cmdTestCase{{ + name: "completion for output flag long and before arg", + cmd: fmt.Sprintf("__complete %s --output ''", cmdName), + golden: "output/output-comp.txt", + rels: releasesMockWithStatus(&release.Info{ + Status: release.StatusDeployed, + }), + }, { + name: "completion for output flag long and after arg", + cmd: fmt.Sprintf("__complete %s aramis --output ''", cmdName), + golden: "output/output-comp.txt", + rels: releasesMockWithStatus(&release.Info{ + Status: release.StatusDeployed, + }), + }, { + name: "completion for output flag short and before arg", + cmd: fmt.Sprintf("__complete %s -o ''", cmdName), + golden: "output/output-comp.txt", + rels: releasesMockWithStatus(&release.Info{ + Status: release.StatusDeployed, + }), + }, { + name: "completion for output flag short and after arg", + cmd: fmt.Sprintf("__complete %s aramis -o ''", cmdName), + golden: "output/output-comp.txt", + rels: releasesMockWithStatus(&release.Info{ + Status: release.StatusDeployed, + }), + }} + runTestCmd(t, tests) +} diff --git a/cmd/helm/get_all_test.go b/cmd/helm/get_all_test.go index 0b026fca4..a213ac583 100644 --- a/cmd/helm/get_all_test.go +++ b/cmd/helm/get_all_test.go @@ -41,3 +41,7 @@ func TestGetCmd(t *testing.T) { }} runTestCmd(t, tests) } + +func TestGetAllRevisionCompletion(t *testing.T) { + revisionFlagCompletionTest(t, "get all") +} diff --git a/cmd/helm/get_hooks_test.go b/cmd/helm/get_hooks_test.go index f843f7d59..7b9142d12 100644 --- a/cmd/helm/get_hooks_test.go +++ b/cmd/helm/get_hooks_test.go @@ -36,3 +36,7 @@ func TestGetHooks(t *testing.T) { }} runTestCmd(t, tests) } + +func TestGetHooksRevisionCompletion(t *testing.T) { + revisionFlagCompletionTest(t, "get hooks") +} diff --git a/cmd/helm/get_manifest_test.go b/cmd/helm/get_manifest_test.go index be54d4a5b..bd0ffc5d6 100644 --- a/cmd/helm/get_manifest_test.go +++ b/cmd/helm/get_manifest_test.go @@ -36,3 +36,7 @@ func TestGetManifest(t *testing.T) { }} runTestCmd(t, tests) } + +func TestGetManifestRevisionCompletion(t *testing.T) { + revisionFlagCompletionTest(t, "get manifest") +} diff --git a/cmd/helm/get_notes_test.go b/cmd/helm/get_notes_test.go index a3ddea9a7..a59120b77 100644 --- a/cmd/helm/get_notes_test.go +++ b/cmd/helm/get_notes_test.go @@ -36,3 +36,7 @@ func TestGetNotesCmd(t *testing.T) { }} runTestCmd(t, tests) } + +func TestGetNotesRevisionCompletion(t *testing.T) { + revisionFlagCompletionTest(t, "get notes") +} diff --git a/cmd/helm/get_values_test.go b/cmd/helm/get_values_test.go index da3cc9e39..ecd92d354 100644 --- a/cmd/helm/get_values_test.go +++ b/cmd/helm/get_values_test.go @@ -52,3 +52,11 @@ func TestGetValuesCmd(t *testing.T) { }} runTestCmd(t, tests) } + +func TestGetValuesRevisionCompletion(t *testing.T) { + revisionFlagCompletionTest(t, "get values") +} + +func TestGetValuesOutputCompletion(t *testing.T) { + outputFlagCompletionTest(t, "get values") +} diff --git a/cmd/helm/helm_test.go b/cmd/helm/helm_test.go index b7156daf3..5f9d80a3a 100644 --- a/cmd/helm/helm_test.go +++ b/cmd/helm/helm_test.go @@ -18,6 +18,7 @@ package main import ( "bytes" + "fmt" "io/ioutil" "os" "os/exec" @@ -96,11 +97,39 @@ func storageFixture() *storage.Storage { return storage.Init(driver.NewMemory()) } +// go-shellwords does not handle empty arguments properly +// https://github.com/mattn/go-shellwords/issues/5#issuecomment-573431458 +// +// This method checks if the last argument was an empty one, +// and if go-shellwords missed it, we add it ourselves. +// +// This is important for completion tests as completion often +// uses an empty last parameter. +func checkLastEmpty(in string, out []string) []string { + lastIndex := len(in) - 1 + + if lastIndex >= 1 && (in[lastIndex] == '"' && in[lastIndex-1] == '"' || + in[lastIndex] == '\'' && in[lastIndex-1] == '\'') { + // The last parameter of 'in' was empty ("" or ''), let's make sure it was detected. + if len(out) > 0 && out[len(out)-1] != "" { + // Bug from go-shellwords: + // 'out' does not have the empty parameter. We add it ourselves as a workaround. + out = append(out, "") + } else { + fmt.Println("WARNING: go-shellwords seems to have been fixed. This workaround can be removed.") + } + } + return out +} + func executeActionCommandC(store *storage.Storage, cmd string) (*cobra.Command, string, error) { args, err := shellwords.Parse(cmd) if err != nil { return nil, "", err } + // Workaround the bug in shellwords + args = checkLastEmpty(cmd, args) + buf := new(bytes.Buffer) actionConfig := &action.Configuration{ diff --git a/cmd/helm/history_test.go b/cmd/helm/history_test.go index 3e750cefc..c9bfb648e 100644 --- a/cmd/helm/history_test.go +++ b/cmd/helm/history_test.go @@ -17,6 +17,7 @@ limitations under the License. package main import ( + "fmt" "testing" "helm.sh/helm/v3/pkg/release" @@ -68,3 +69,42 @@ func TestHistoryCmd(t *testing.T) { }} runTestCmd(t, tests) } + +func TestHistoryOutputCompletion(t *testing.T) { + outputFlagCompletionTest(t, "history") +} + +func revisionFlagCompletionTest(t *testing.T, cmdName string) { + mk := func(name string, vers int, status release.Status) *release.Release { + return release.Mock(&release.MockReleaseOptions{ + Name: name, + Version: vers, + Status: status, + }) + } + + releases := []*release.Release{ + mk("musketeers", 11, release.StatusDeployed), + mk("musketeers", 10, release.StatusSuperseded), + mk("musketeers", 9, release.StatusSuperseded), + mk("musketeers", 8, release.StatusSuperseded), + } + + tests := []cmdTestCase{{ + name: "completion for revision flag", + cmd: fmt.Sprintf("__complete %s musketeers --revision ''", cmdName), + rels: releases, + golden: "output/revision-comp.txt", + }, { + name: "completion for revision flag with too few args", + cmd: fmt.Sprintf("__complete %s --revision ''", cmdName), + rels: releases, + golden: "output/revision-wrong-args-comp.txt", + }, { + name: "completion for revision flag with too many args", + cmd: fmt.Sprintf("__complete %s three musketeers --revision ''", cmdName), + rels: releases, + golden: "output/revision-wrong-args-comp.txt", + }} + runTestCmd(t, tests) +} diff --git a/cmd/helm/install_test.go b/cmd/helm/install_test.go index e8b573dfc..57972024f 100644 --- a/cmd/helm/install_test.go +++ b/cmd/helm/install_test.go @@ -193,3 +193,7 @@ func TestInstall(t *testing.T) { runTestActionCmd(t, tests) } + +func TestInstallOutputCompletion(t *testing.T) { + outputFlagCompletionTest(t, "install") +} diff --git a/cmd/helm/list_test.go b/cmd/helm/list_test.go index b5833fd72..127a8a980 100644 --- a/cmd/helm/list_test.go +++ b/cmd/helm/list_test.go @@ -206,3 +206,7 @@ func TestListCmd(t *testing.T) { }} runTestCmd(t, tests) } + +func TestListOutputCompletion(t *testing.T) { + outputFlagCompletionTest(t, "list") +} diff --git a/cmd/helm/repo_list_test.go b/cmd/helm/repo_list_test.go new file mode 100644 index 000000000..f371452f2 --- /dev/null +++ b/cmd/helm/repo_list_test.go @@ -0,0 +1,25 @@ +/* +Copyright The Helm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "testing" +) + +func TestRepoListOutputCompletion(t *testing.T) { + outputFlagCompletionTest(t, "repo list") +} diff --git a/cmd/helm/root.go b/cmd/helm/root.go index bf98e72fe..c6c055993 100644 --- a/cmd/helm/root.go +++ b/cmd/helm/root.go @@ -232,7 +232,7 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string newDocsCmd(out), // Setup the special hidden __complete command to allow for dynamic auto-completion - completion.NewCompleteCmd(settings), + completion.NewCompleteCmd(settings, out), ) // Add annotation to flags for which we can generate completion choices diff --git a/cmd/helm/search_hub_test.go b/cmd/helm/search_hub_test.go index dfe0cacc2..7b0f3a389 100644 --- a/cmd/helm/search_hub_test.go +++ b/cmd/helm/search_hub_test.go @@ -49,5 +49,8 @@ func TestSearchHubCmd(t *testing.T) { t.Log(out) t.Log(expected) } +} +func TestSearchHubOutputCompletion(t *testing.T) { + outputFlagCompletionTest(t, "search hub") } diff --git a/cmd/helm/search_repo_test.go b/cmd/helm/search_repo_test.go index 6ece55505..402ef2970 100644 --- a/cmd/helm/search_repo_test.go +++ b/cmd/helm/search_repo_test.go @@ -83,3 +83,7 @@ func TestSearchRepositoriesCmd(t *testing.T) { } runTestCmd(t, tests) } + +func TestSearchRepoOutputCompletion(t *testing.T) { + outputFlagCompletionTest(t, "search repo") +} diff --git a/cmd/helm/status_test.go b/cmd/helm/status_test.go index 91a008e5a..0d2500e65 100644 --- a/cmd/helm/status_test.go +++ b/cmd/helm/status_test.go @@ -108,3 +108,66 @@ func mustParseTime(t string) helmtime.Time { res, _ := helmtime.Parse(time.RFC3339, t) return res } + +func TestStatusCompletion(t *testing.T) { + releasesMockWithStatus := func(info *release.Info, hooks ...*release.Hook) []*release.Release { + info.LastDeployed = helmtime.Unix(1452902400, 0).UTC() + return []*release.Release{{ + Name: "athos", + Namespace: "default", + Info: info, + Chart: &chart.Chart{}, + Hooks: hooks, + }, { + Name: "porthos", + Namespace: "default", + Info: info, + Chart: &chart.Chart{}, + Hooks: hooks, + }, { + Name: "aramis", + Namespace: "default", + Info: info, + Chart: &chart.Chart{}, + Hooks: hooks, + }, { + Name: "dartagnan", + Namespace: "gascony", + Info: info, + Chart: &chart.Chart{}, + Hooks: hooks, + }} + } + + tests := []cmdTestCase{{ + name: "completion for status", + cmd: "__complete status a", + golden: "output/status-comp.txt", + rels: releasesMockWithStatus(&release.Info{ + Status: release.StatusDeployed, + }), + }, { + name: "completion for status with too many arguments", + cmd: "__complete status dartagnan ''", + golden: "output/status-wrong-args-comp.txt", + rels: releasesMockWithStatus(&release.Info{ + Status: release.StatusDeployed, + }), + }, { + name: "completion for status with too many arguments", + cmd: "__complete status --debug a", + golden: "output/status-comp.txt", + rels: releasesMockWithStatus(&release.Info{ + Status: release.StatusDeployed, + }), + }} + runTestCmd(t, tests) +} + +func TestStatusRevisionCompletion(t *testing.T) { + revisionFlagCompletionTest(t, "status") +} + +func TestStatusOutputCompletion(t *testing.T) { + outputFlagCompletionTest(t, "status") +} diff --git a/cmd/helm/testdata/output/output-comp.txt b/cmd/helm/testdata/output/output-comp.txt new file mode 100644 index 000000000..de5f16f1d --- /dev/null +++ b/cmd/helm/testdata/output/output-comp.txt @@ -0,0 +1,4 @@ +table +json +yaml +:0 diff --git a/cmd/helm/testdata/output/revision-comp.txt b/cmd/helm/testdata/output/revision-comp.txt new file mode 100644 index 000000000..b4799f059 --- /dev/null +++ b/cmd/helm/testdata/output/revision-comp.txt @@ -0,0 +1,5 @@ +8 +9 +10 +11 +:0 diff --git a/cmd/helm/testdata/output/revision-wrong-args-comp.txt b/cmd/helm/testdata/output/revision-wrong-args-comp.txt new file mode 100644 index 000000000..b6f867176 --- /dev/null +++ b/cmd/helm/testdata/output/revision-wrong-args-comp.txt @@ -0,0 +1 @@ +:4 diff --git a/cmd/helm/testdata/output/status-comp.txt b/cmd/helm/testdata/output/status-comp.txt new file mode 100644 index 000000000..c97882964 --- /dev/null +++ b/cmd/helm/testdata/output/status-comp.txt @@ -0,0 +1,3 @@ +aramis +athos +:4 diff --git a/cmd/helm/testdata/output/status-wrong-args-comp.txt b/cmd/helm/testdata/output/status-wrong-args-comp.txt new file mode 100644 index 000000000..b6f867176 --- /dev/null +++ b/cmd/helm/testdata/output/status-wrong-args-comp.txt @@ -0,0 +1 @@ +:4 diff --git a/cmd/helm/upgrade_test.go b/cmd/helm/upgrade_test.go index bd1ccec35..3cecbe6d3 100644 --- a/cmd/helm/upgrade_test.go +++ b/cmd/helm/upgrade_test.go @@ -258,3 +258,7 @@ func prepareMockRelease(releaseName string, t *testing.T) (func(n string, v int, return relMock, ch, chartPath } + +func TestUpgradeOutputCompletion(t *testing.T) { + outputFlagCompletionTest(t, "upgrade") +} diff --git a/internal/completion/complete.go b/internal/completion/complete.go index d13c7f5bd..ccc868a59 100644 --- a/internal/completion/complete.go +++ b/internal/completion/complete.go @@ -18,6 +18,7 @@ package completion import ( "errors" "fmt" + "io" "log" "os" "strings" @@ -111,7 +112,7 @@ func (d BashCompDirective) string() string { } // NewCompleteCmd add a special hidden command that an be used to request completions -func NewCompleteCmd(settings *cli.EnvSettings) *cobra.Command { +func NewCompleteCmd(settings *cli.EnvSettings, out io.Writer) *cobra.Command { debug = settings.Debug return &cobra.Command{ Use: fmt.Sprintf("%s [command-line]", CompRequestCmd), @@ -169,14 +170,14 @@ func NewCompleteCmd(settings *cli.EnvSettings) *cobra.Command { completions, directive := completionFn(finalCmd, argsWoFlags, toComplete) for _, comp := range completions { // Print each possible completion to stdout for the completion script to consume. - fmt.Println(comp) + fmt.Fprintln(out, comp) } // As the last printout, print the completion directive for the // completion script to parse. // The directive integer must be that last character following a single : // The completion script expects :directive - fmt.Printf("\n:%d\n", directive) + fmt.Fprintln(out, fmt.Sprintf(":%d", directive)) // Print some helpful info to stderr for the user to understand. // Output from stderr should be ignored from the completion script. From fc618b4b6e579ba5582f50ceb7f9c9e14735ec78 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Wed, 15 Jan 2020 19:01:54 -0500 Subject: [PATCH 52/81] feat(comp): Use cached charts file for speed Signed-off-by: Marc Khouzam --- cmd/helm/search_repo.go | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/cmd/helm/search_repo.go b/cmd/helm/search_repo.go index a57ad135b..9f5af1e3c 100644 --- a/cmd/helm/search_repo.go +++ b/cmd/helm/search_repo.go @@ -17,6 +17,8 @@ limitations under the License. package main import ( + "bufio" + "bytes" "fmt" "io" "io/ioutil" @@ -251,17 +253,39 @@ func (r *repoSearchWriter) encodeByFormat(out io.Writer, format output.Format) e // Provides the list of charts that are part of the specified repo, and that starts with 'prefix'. func compListChartsOfRepo(repoName string, prefix string) []string { - f := filepath.Join(settings.RepositoryCache, helmpath.CacheIndexFile(repoName)) var charts []string - if indexFile, err := repo.LoadIndexFile(f); err == nil { - for name := range indexFile.Entries { - fullName := fmt.Sprintf("%s/%s", repoName, name) + + path := filepath.Join(settings.RepositoryCache, helmpath.CacheChartsFile(repoName)) + content, err := ioutil.ReadFile(path) + if err == nil { + scanner := bufio.NewScanner(bytes.NewReader(content)) + for scanner.Scan() { + fullName := fmt.Sprintf("%s/%s", repoName, scanner.Text()) if strings.HasPrefix(fullName, prefix) { charts = append(charts, fullName) } } + return charts } - return charts + + if isNotExist(err) { + // If there is no cached charts file, fallback to the full index file. + // This is much slower but can happen after the caching feature is first + // installed but before the user does a 'helm repo update' to generate the + // first cached charts file. + path = filepath.Join(settings.RepositoryCache, helmpath.CacheIndexFile(repoName)) + if indexFile, err := repo.LoadIndexFile(path); err == nil { + for name := range indexFile.Entries { + fullName := fmt.Sprintf("%s/%s", repoName, name) + if strings.HasPrefix(fullName, prefix) { + charts = append(charts, fullName) + } + } + return charts + } + } + + return []string{} } // Provide dynamic auto-completion for commands that operate on charts (e.g., helm show) From a8369db802d47f0b60f7d84602da85d28bc79be4 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Wed, 15 Jan 2020 19:30:04 -0500 Subject: [PATCH 53/81] feat(comp): Isolate go completion framework better Signed-off-by: Marc Khouzam --- cmd/helm/root.go | 75 +++------------------------------ internal/completion/complete.go | 70 ++++++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 72 deletions(-) diff --git a/cmd/helm/root.go b/cmd/helm/root.go index c6c055993..a3e4da746 100644 --- a/cmd/helm/root.go +++ b/cmd/helm/root.go @@ -32,7 +32,7 @@ import ( ) const ( - bashCompletionFunc = ` + contextCompFunc = ` __helm_get_contexts() { __helm_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" @@ -42,62 +42,6 @@ __helm_get_contexts() COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) ) fi } - -__helm_custom_func() -{ - __helm_debug "${FUNCNAME[0]}: c is $c, words[@] is ${words[@]}, #words[@] is ${#words[@]}" - __helm_debug "${FUNCNAME[0]}: cur is ${cur}, cword is ${cword}, words is ${words}" - - local out requestComp lastParam lastChar - requestComp="${words[0]} %[1]s ${words[@]:1}" - - lastParam=${words[$((${#words[@]}-1))]} - lastChar=${lastParam:$((${#lastParam}-1)):1} - __helm_debug "${FUNCNAME[0]}: lastParam ${lastParam}, lastChar ${lastChar}" - - if [ -z "${cur}" ] && [ "${lastChar}" != "=" ]; then - # If the last parameter is complete (there is a space following it) - # We add an extra empty parameter so we can indicate this to the go method. - __helm_debug "${FUNCNAME[0]}: Adding extra empty parameter" - requestComp="${requestComp} \"\"" - fi - - __helm_debug "${FUNCNAME[0]}: calling ${requestComp}" - # Use eval to handle any environment variables and such - out=$(eval ${requestComp} 2>/dev/null) - - # Extract the directive int at the very end of the output following a : - directive=${out##*:} - # Remove the directive - out=${out%%:*} - if [ "${directive}" = "${out}" ]; then - # There is not directive specified - directive=0 - fi - __helm_debug "${FUNCNAME[0]}: the completion directive is: ${directive}" - __helm_debug "${FUNCNAME[0]}: the completions are: ${out[*]}" - - if [ $((${directive} & %[2]d)) -ne 0 ]; then - __helm_debug "${FUNCNAME[0]}: received error, completion failed" - else - if [ $((${directive} & %[3]d)) -ne 0 ]; then - if [[ $(type -t compopt) = "builtin" ]]; then - __helm_debug "${FUNCNAME[0]}: activating no space" - compopt -o nospace - fi - fi - if [ $((${directive} & %[4]d)) -ne 0 ]; then - if [[ $(type -t compopt) = "builtin" ]]; then - __helm_debug "${FUNCNAME[0]}: activating no file completion" - compopt +o default - fi - fi - - while IFS='' read -r comp; do - COMPREPLY+=("$comp") - done < <(compgen -W "${out[*]}" -- "$cur") - fi -} ` ) @@ -152,17 +96,12 @@ By default, the default directories depend on the Operating System. The defaults func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string) *cobra.Command { cmd := &cobra.Command{ - Use: "helm", - Short: "The Helm package manager for Kubernetes.", - Long: globalUsage, - SilenceUsage: true, - Args: require.NoArgs, - BashCompletionFunction: fmt.Sprintf( - bashCompletionFunc, - completion.CompRequestCmd, - completion.BashCompDirectiveError, - completion.BashCompDirectiveNoSpace, - completion.BashCompDirectiveNoFileComp), + Use: "helm", + Short: "The Helm package manager for Kubernetes.", + Long: globalUsage, + SilenceUsage: true, + Args: require.NoArgs, + BashCompletionFunction: fmt.Sprintf("%s%s", contextCompFunc, completion.GetBashCustomFunction()), } flags := cmd.PersistentFlags() diff --git a/internal/completion/complete.go b/internal/completion/complete.go index ccc868a59..a24390fc0 100644 --- a/internal/completion/complete.go +++ b/internal/completion/complete.go @@ -35,9 +35,9 @@ import ( // This should ultimately be pushed down into Cobra. // ================================================================================== -// CompRequestCmd Hidden command to request completion results from the program. +// compRequestCmd Hidden command to request completion results from the program. // Used by the shell completion script. -const CompRequestCmd = "__complete" +const compRequestCmd = "__complete" // Global map allowing to find completion functions for commands or flags. var validArgsFunctions = map[interface{}]func(cmd *cobra.Command, args []string, toComplete string) ([]string, BashCompDirective){} @@ -64,6 +64,68 @@ const ( BashCompDirectiveDefault BashCompDirective = 0 ) +// GetBashCustomFunction returns the bash code to handle custom go completion +// This should eventually be provided by Cobra +func GetBashCustomFunction() string { + return fmt.Sprintf(` +__helm_custom_func() +{ + __helm_debug "${FUNCNAME[0]}: c is $c, words[@] is ${words[@]}, #words[@] is ${#words[@]}" + __helm_debug "${FUNCNAME[0]}: cur is ${cur}, cword is ${cword}, words is ${words}" + + local out requestComp lastParam lastChar + requestComp="${words[0]} %[1]s ${words[@]:1}" + + lastParam=${words[$((${#words[@]}-1))]} + lastChar=${lastParam:$((${#lastParam}-1)):1} + __helm_debug "${FUNCNAME[0]}: lastParam ${lastParam}, lastChar ${lastChar}" + + if [ -z "${cur}" ] && [ "${lastChar}" != "=" ]; then + # If the last parameter is complete (there is a space following it) + # We add an extra empty parameter so we can indicate this to the go method. + __helm_debug "${FUNCNAME[0]}: Adding extra empty parameter" + requestComp="${requestComp} \"\"" + fi + + __helm_debug "${FUNCNAME[0]}: calling ${requestComp}" + # Use eval to handle any environment variables and such + out=$(eval ${requestComp} 2>/dev/null) + + # Extract the directive int at the very end of the output following a : + directive=${out##*:} + # Remove the directive + out=${out%%:*} + if [ "${directive}" = "${out}" ]; then + # There is not directive specified + directive=0 + fi + __helm_debug "${FUNCNAME[0]}: the completion directive is: ${directive}" + __helm_debug "${FUNCNAME[0]}: the completions are: ${out[*]}" + + if [ $((${directive} & %[2]d)) -ne 0 ]; then + __helm_debug "${FUNCNAME[0]}: received error, completion failed" + else + if [ $((${directive} & %[3]d)) -ne 0 ]; then + if [[ $(type -t compopt) = "builtin" ]]; then + __helm_debug "${FUNCNAME[0]}: activating no space" + compopt -o nospace + fi + fi + if [ $((${directive} & %[4]d)) -ne 0 ]; then + if [[ $(type -t compopt) = "builtin" ]]; then + __helm_debug "${FUNCNAME[0]}: activating no file completion" + compopt +o default + fi + fi + + while IFS='' read -r comp; do + COMPREPLY+=("$comp") + done < <(compgen -W "${out[*]}" -- "$cur") + fi +} +`, compRequestCmd, BashCompDirectiveError, BashCompDirectiveNoSpace, BashCompDirectiveNoFileComp) +} + // RegisterValidArgsFunc should be called to register a function to provide argument completion for a command func RegisterValidArgsFunc(cmd *cobra.Command, f func(cmd *cobra.Command, args []string, toComplete string) ([]string, BashCompDirective)) { if _, exists := validArgsFunctions[cmd]; exists { @@ -115,14 +177,14 @@ func (d BashCompDirective) string() string { func NewCompleteCmd(settings *cli.EnvSettings, out io.Writer) *cobra.Command { debug = settings.Debug return &cobra.Command{ - Use: fmt.Sprintf("%s [command-line]", CompRequestCmd), + Use: fmt.Sprintf("%s [command-line]", compRequestCmd), DisableFlagsInUseLine: true, Hidden: true, DisableFlagParsing: true, Args: require.MinimumNArgs(1), Short: "Request shell completion choices for the specified command-line", Long: fmt.Sprintf("%s is a special command that is used by the shell completion logic\n%s", - CompRequestCmd, "to request completion choices for the specified command-line."), + compRequestCmd, "to request completion choices for the specified command-line."), Run: func(cmd *cobra.Command, args []string) { CompDebugln(fmt.Sprintf("%s was called with args %v", cmd.Name(), args)) From d4c37d33d1a186d8b271b4f4276da434da6a20e0 Mon Sep 17 00:00:00 2001 From: Ahmad Kazemi Date: Thu, 16 Jan 2020 12:04:22 +1100 Subject: [PATCH 54/81] Signed-off-by: Ahmad Kazemi log.Printf replaced to fix the log issue. --- pkg/kube/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index cdd996925..144218793 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -418,7 +418,7 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object, if err != nil { return errors.Wrap(err, "failed to replace object") } - log.Printf("Replaced %q with kind %s for kind %s\n", target.Name, currentObj.GetObjectKind().GroupVersionKind().Kind, kind) + c.Log("Replaced %q with kind %s for kind %s\n", target.Name, currentObj.GetObjectKind().GroupVersionKind().Kind, kind) } else { // send patch to server obj, err = helper.Patch(target.Namespace, target.Name, patchType, patch, nil) From 91432239323f64521f2096c2eee06cc4d8857412 Mon Sep 17 00:00:00 2001 From: Ahmad Kazemi Date: Thu, 16 Jan 2020 12:19:30 +1100 Subject: [PATCH 55/81] unnecessary import removed Signed-off-by: Ahmad Kazemi unnecessary import removed --- pkg/kube/client.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 144218793..fe3caaca3 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -21,7 +21,6 @@ import ( "encoding/json" "fmt" "io" - "log" "strings" "sync" "time" From 1f0582cadc1ba222c5d7a7f9977a091edd55f6af Mon Sep 17 00:00:00 2001 From: Cristian Klein Date: Wed, 1 Jan 2020 20:44:06 +0100 Subject: [PATCH 56/81] fix(helm): improve handling of corrupted storage Helm does not yet properly handle concurrent executions (see #7322), and invoking Helm concurrently on the same release lead to corrupted storage. Specifically, several Releases may be marked as DEPLOYED. This patch improved handling of such situations, by taking the latest DEPLOYED Release. Eventually, the storage will clean itself out, after the corrupted Releases are deleted due to --history-max. This is a port to Helm v3 of #7319. Signed-off-by: Cristian Klein --- pkg/storage/storage.go | 4 ++++ pkg/storage/storage_test.go | 40 +++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go index 56881493b..89183355f 100644 --- a/pkg/storage/storage.go +++ b/pkg/storage/storage.go @@ -119,6 +119,10 @@ func (s *Storage) Deployed(name string) (*rspb.Release, error) { return nil, errors.Errorf("%q has no deployed releases", name) } + // If executed concurrently, Helm's database gets corrupted + // and multiple releases are DEPLOYED. Take the latest. + relutil.Reverse(ls, relutil.SortByRevision) + return ls[0], nil } diff --git a/pkg/storage/storage_test.go b/pkg/storage/storage_test.go index b8c333d24..ee9c68b80 100644 --- a/pkg/storage/storage_test.go +++ b/pkg/storage/storage_test.go @@ -205,6 +205,46 @@ func TestStorageDeployed(t *testing.T) { } } +func TestStorageDeployedWithCorruption(t *testing.T) { + storage := Init(driver.NewMemory()) + + const name = "angry-bird" + const vers = int(4) + + // setup storage with test releases + setup := func() { + // release records (notice odd order and corruption) + rls0 := ReleaseTestData{Name: name, Version: 1, Status: rspb.StatusSuperseded}.ToRelease() + rls1 := ReleaseTestData{Name: name, Version: 4, Status: rspb.StatusDeployed}.ToRelease() + rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.StatusSuperseded}.ToRelease() + rls3 := ReleaseTestData{Name: name, Version: 2, Status: rspb.StatusDeployed}.ToRelease() + + // create the release records in the storage + assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)") + assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)") + assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)") + assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)") + } + + setup() + + rls, err := storage.Deployed(name) + if err != nil { + t.Fatalf("Failed to query for deployed release: %s\n", err) + } + + switch { + case rls == nil: + t.Fatalf("Release is nil") + case rls.Name != name: + t.Fatalf("Expected release name %q, actual %q\n", name, rls.Name) + case rls.Version != vers: + t.Fatalf("Expected release version %d, actual %d\n", vers, rls.Version) + case rls.Info.Status != rspb.StatusDeployed: + t.Fatalf("Expected release status 'DEPLOYED', actual %s\n", rls.Info.Status.String()) + } +} + func TestStorageHistory(t *testing.T) { storage := Init(driver.NewMemory()) From 9d6f2ed10764014375751f1ed78f5d009af34f4d Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Thu, 16 Jan 2020 10:12:00 -0800 Subject: [PATCH 57/81] feat(version): show "unreleased" when built from a branch Signed-off-by: Matthew Fisher --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 31e1f4374..0a3b08548 100644 --- a/Makefile +++ b/Makefile @@ -40,10 +40,13 @@ ifneq ($(BINARY_VERSION),) LDFLAGS += -X helm.sh/helm/v3/internal/version.version=${BINARY_VERSION} endif +VERSION_METADATA = unreleased # Clear the "unreleased" string in BuildMetadata ifneq ($(GIT_TAG),) - LDFLAGS += -X helm.sh/helm/v3/internal/version.metadata= + VERSION_METADATA = endif + +LDFLAGS += -X helm.sh/helm/v3/internal/version.metadata=${VERSION_METADATA} LDFLAGS += -X helm.sh/helm/v3/internal/version.gitCommit=${GIT_COMMIT} LDFLAGS += -X helm.sh/helm/v3/internal/version.gitTreeState=${GIT_DIRTY} From 6cc039ea79a435c9f335d677b78d9be574b8e770 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Thu, 16 Jan 2020 13:54:22 -0700 Subject: [PATCH 58/81] fix: catch one additional discovery client warning (#7176) Signed-off-by: Matt Butcher --- pkg/action/action.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/action/action.go b/pkg/action/action.go index 16c5d3546..9405cc401 100644 --- a/pkg/action/action.go +++ b/pkg/action/action.go @@ -167,8 +167,8 @@ func (c *Configuration) releaseContent(name string, version int) (*release.Relea // GetVersionSet retrieves a set of available k8s API versions func GetVersionSet(client discovery.ServerResourcesInterface) (chartutil.VersionSet, error) { groups, resources, err := client.ServerGroupsAndResources() - if err != nil { - return chartutil.DefaultVersionSet, err + if err != nil && !discovery.IsGroupDiscoveryFailedError(err) { + return chartutil.DefaultVersionSet, errors.Wrap(err, "could not get apiVersions from Kubernetes") } // FIXME: The Kubernetes test fixture for cli appears to always return nil From 77b900106f923bf1d9b787f5e1d2c6c85be9722f Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 16 Jan 2020 21:29:30 -0500 Subject: [PATCH 59/81] fix(comp): Update based on review comments Signed-off-by: Marc Khouzam --- cmd/helm/flags.go | 3 +-- cmd/helm/root.go | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/cmd/helm/flags.go b/cmd/helm/flags.go index b9473a5a7..65575a5c1 100644 --- a/cmd/helm/flags.go +++ b/cmd/helm/flags.go @@ -54,10 +54,9 @@ func addChartPathOptionsFlags(f *pflag.FlagSet, c *action.ChartPathOptions) { // value to the given format pointer func bindOutputFlag(cmd *cobra.Command, varRef *output.Format) { f := cmd.Flags() - f.VarP(newOutputValue(output.Table, varRef), outputFlag, "o", + flag := f.VarPF(newOutputValue(output.Table, varRef), outputFlag, "o", fmt.Sprintf("prints the output in the specified format. Allowed values: %s", strings.Join(output.Formats(), ", "))) - flag := f.Lookup(outputFlag) completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { var formatNames []string for _, format := range output.Formats() { diff --git a/cmd/helm/root.go b/cmd/helm/root.go index a3e4da746..6ce1dcbf4 100644 --- a/cmd/helm/root.go +++ b/cmd/helm/root.go @@ -117,7 +117,6 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string completion.CompDebugln(fmt.Sprintf("About to call kube client for namespaces with timeout of: %d", to)) nsNames := []string{} - // TODO can we request only the namespace with request.prefix? if namespaces, err := client.CoreV1().Namespaces().List(metav1.ListOptions{TimeoutSeconds: &to}); err == nil { for _, ns := range namespaces.Items { if strings.HasPrefix(ns.Name, toComplete) { From 82823a6634be4b43a1130b244ee1a1d9c83a1ec6 Mon Sep 17 00:00:00 2001 From: Vivian Kong Date: Fri, 17 Jan 2020 10:39:26 -0500 Subject: [PATCH 60/81] Allow tests to run on s390x (#7096) Signed-off-by: Vivian Kong --- Makefile | 5 +++++ pkg/plugin/plugin_test.go | 3 +++ 2 files changed, 8 insertions(+) diff --git a/Makefile b/Makefile index 0a3b08548..7d254e919 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ GOPATH = $(shell go env GOPATH) DEP = $(GOPATH)/bin/dep GOX = $(GOPATH)/bin/gox GOIMPORTS = $(GOPATH)/bin/goimports +ARCH = $(shell uname -p) ACCEPTANCE_DIR:=../acceptance-testing # To specify the subset of acceptance tests to run. '.' means all tests @@ -67,7 +68,11 @@ $(BINDIR)/$(BINNAME): $(SRC) .PHONY: test test: build +ifeq ($(ARCH),s390x) +test: TESTFLAGS += -v +else test: TESTFLAGS += -race -v +endif test: test-style test: test-unit diff --git a/pkg/plugin/plugin_test.go b/pkg/plugin/plugin_test.go index f637eca28..076ae1187 100644 --- a/pkg/plugin/plugin_test.go +++ b/pkg/plugin/plugin_test.go @@ -87,6 +87,7 @@ func TestPlatformPrepareCommand(t *testing.T) { PlatformCommand: []PlatformCommand{ {OperatingSystem: "linux", Architecture: "i386", Command: "echo -n linux-i386"}, {OperatingSystem: "linux", Architecture: "amd64", Command: "echo -n linux-amd64"}, + {OperatingSystem: "linux", Architecture: "s390x", Command: "echo -n linux-s390x"}, {OperatingSystem: "windows", Architecture: "amd64", Command: "echo -n win-64"}, }, }, @@ -98,6 +99,8 @@ func TestPlatformPrepareCommand(t *testing.T) { osStrCmp = "linux-i386" } else if os == "linux" && arch == "amd64" { osStrCmp = "linux-amd64" + } else if os == "linux" && arch == "s390x" { + osStrCmp = "linux-s390x" } else if os == "windows" && arch == "amd64" { osStrCmp = "win-64" } else { From 88f42929d779e145b24dad12657d6984d755dd2c Mon Sep 17 00:00:00 2001 From: Martin Hickey Date: Fri, 17 Jan 2020 15:56:56 +0000 Subject: [PATCH 61/81] Remove references to protobuf (#7425) Remove references to protobuf and update description of release object stored representation to Helm v3. Signed-off-by: Martin Hickey --- pkg/chartutil/chartfile_test.go | 1 - pkg/chartutil/doc.go | 4 ++-- pkg/storage/driver/cfgmaps.go | 4 ++-- pkg/storage/driver/secrets.go | 4 ++-- pkg/storage/driver/util.go | 11 +++++------ 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/pkg/chartutil/chartfile_test.go b/pkg/chartutil/chartfile_test.go index 9a6e608f6..fb5f15376 100644 --- a/pkg/chartutil/chartfile_test.go +++ b/pkg/chartutil/chartfile_test.go @@ -39,7 +39,6 @@ func verifyChartfile(t *testing.T, f *chart.Metadata, name string) { t.Fatal("Failed verifyChartfile because f is nil") } - // Api instead of API because it was generated via protobuf. if f.APIVersion != chart.APIVersionV1 { t.Errorf("Expected API Version %q, got %q", chart.APIVersionV1, f.APIVersion) } diff --git a/pkg/chartutil/doc.go b/pkg/chartutil/doc.go index efcda2cfa..8f06bcc9a 100644 --- a/pkg/chartutil/doc.go +++ b/pkg/chartutil/doc.go @@ -16,7 +16,7 @@ limitations under the License. /*Package chartutil contains tools for working with charts. -Charts are described in the protocol buffer definition (pkg/proto/charts). +Charts are described in the chart package (pkg/chart). This package provides utilities for serializing and deserializing charts. A chart can be represented on the file system in one of two ways: @@ -38,7 +38,7 @@ For accepting raw compressed tar file data from an io.Reader, the 'loader.LoadArchive()' will read in the data, uncompress it, and unpack it into a Chart. -When creating charts in memory, use the 'helm.sh/helm/pkg/proto/chart' +When creating charts in memory, use the 'helm.sh/helm/pkg/chart' package directly. */ package chartutil // import "helm.sh/helm/v3/pkg/chartutil" diff --git a/pkg/storage/driver/cfgmaps.go b/pkg/storage/driver/cfgmaps.go index 1b630f407..cc2e2416a 100644 --- a/pkg/storage/driver/cfgmaps.go +++ b/pkg/storage/driver/cfgmaps.go @@ -217,14 +217,14 @@ func (cfgmaps *ConfigMaps) Delete(key string) (rls *rspb.Release, err error) { // newConfigMapsObject constructs a kubernetes ConfigMap object // to store a release. Each configmap data entry is the base64 -// encoded string of a release's binary protobuf encoding. +// encoded gzipped string of a release. // // The following labels are used within each configmap: // // "modifiedAt" - timestamp indicating when this configmap was last modified. (set in Update) // "createdAt" - timestamp indicating when this configmap was created. (set in Create) // "version" - version of the release. -// "status" - status of the release (see proto/hapi/release.status.pb.go for variants) +// "status" - status of the release (see pkg/release/status.go for variants) // "owner" - owner of the configmap, currently "helm". // "name" - name of the release. // diff --git a/pkg/storage/driver/secrets.go b/pkg/storage/driver/secrets.go index dc55cf458..dcb2ecfcf 100644 --- a/pkg/storage/driver/secrets.go +++ b/pkg/storage/driver/secrets.go @@ -198,14 +198,14 @@ func (secrets *Secrets) Delete(key string) (rls *rspb.Release, err error) { // newSecretsObject constructs a kubernetes Secret object // to store a release. Each secret data entry is the base64 -// encoded string of a release's binary protobuf encoding. +// encoded gzipped string of a release. // // The following labels are used within each secret: // // "modifiedAt" - timestamp indicating when this secret was last modified. (set in Update) // "createdAt" - timestamp indicating when this secret was created. (set in Create) // "version" - version of the release. -// "status" - status of the release (see proto/hapi/release.status.pb.go for variants) +// "status" - status of the release (see pkg/release/status.go for variants) // "owner" - owner of the secret, currently "helm". // "name" - name of the release. // diff --git a/pkg/storage/driver/util.go b/pkg/storage/driver/util.go index 6cde74cd3..a87002ab4 100644 --- a/pkg/storage/driver/util.go +++ b/pkg/storage/driver/util.go @@ -31,7 +31,7 @@ var b64 = base64.StdEncoding var magicGzip = []byte{0x1f, 0x8b, 0x08} // encodeRelease encodes a release returning a base64 encoded -// gzipped binary protobuf encoding representation, or error. +// gzipped string representation, or error. func encodeRelease(rls *rspb.Release) (string, error) { b, err := json.Marshal(rls) if err != nil { @@ -50,10 +50,9 @@ func encodeRelease(rls *rspb.Release) (string, error) { return b64.EncodeToString(buf.Bytes()), nil } -// decodeRelease decodes the bytes in data into a release -// type. Data must contain a base64 encoded string of a -// valid protobuf encoding of a release, otherwise -// an error is returned. +// decodeRelease decodes the bytes of data into a release +// type. Data must contain a base64 encoded gzipped string of a +// valid release, otherwise an error is returned. func decodeRelease(data string) (*rspb.Release, error) { // base64 decode string b, err := b64.DecodeString(data) @@ -77,7 +76,7 @@ func decodeRelease(data string) (*rspb.Release, error) { } var rls rspb.Release - // unmarshal protobuf bytes + // unmarshal release object bytes if err := json.Unmarshal(b, &rls); err != nil { return nil, err } From 8fe2097ffeb0d5a6d898b6850738c14fdca0991e Mon Sep 17 00:00:00 2001 From: Jakub Bielecki Date: Tue, 17 Dec 2019 05:48:54 +0100 Subject: [PATCH 62/81] fix(kube) only add to scheme.Scheme once Closes #6566 Signed-off-by: Jakub Bielecki --- pkg/kube/client.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index cdd996925..adf195e34 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -57,20 +57,23 @@ type Client struct { Log func(string, ...interface{}) } +var addToScheme sync.Once + // New creates a new Client. func New(getter genericclioptions.RESTClientGetter) *Client { if getter == nil { getter = genericclioptions.NewConfigFlags(true) } // Add CRDs to the scheme. They are missing by default. - if err := apiextv1.AddToScheme(scheme.Scheme); err != nil { - // This should never happen. - panic(err) - } - if err := apiextv1beta1.AddToScheme(scheme.Scheme); err != nil { - // This should never happen. - panic(err) - } + addToScheme.Do(func() { + if err := apiextv1.AddToScheme(scheme.Scheme); err != nil { + // This should never happen. + panic(err) + } + if err := apiextv1beta1.AddToScheme(scheme.Scheme); err != nil { + panic(err) + } + }) return &Client{ Factory: cmdutil.NewFactory(getter), Log: nopLogger, From 559c4053620352f76953a8ef7adbeed50c5fef32 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Sun, 19 Jan 2020 15:43:57 -0500 Subject: [PATCH 63/81] fix(test): Remove invalid subcommand in test The 'home' command was removed for v3, so this commit adapts the tests. Having an invalid subcommand does not cause problems currently, but will start causing failures on newer versions of Cobra, which complain on invalid subcommands. Signed-off-by: Marc Khouzam --- cmd/helm/root_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/helm/root_test.go b/cmd/helm/root_test.go index f3eef8b6d..df592a96d 100644 --- a/cmd/helm/root_test.go +++ b/cmd/helm/root_test.go @@ -35,23 +35,23 @@ func TestRootCmd(t *testing.T) { }{ { name: "defaults", - args: "home", + args: "env", }, { name: "with $XDG_CACHE_HOME set", - args: "home", + args: "env", envvars: map[string]string{xdg.CacheHomeEnvVar: "/bar"}, cachePath: "/bar/helm", }, { name: "with $XDG_CONFIG_HOME set", - args: "home", + args: "env", envvars: map[string]string{xdg.ConfigHomeEnvVar: "/bar"}, configPath: "/bar/helm", }, { name: "with $XDG_DATA_HOME set", - args: "home", + args: "env", envvars: map[string]string{xdg.DataHomeEnvVar: "/bar"}, dataPath: "/bar/helm", }, From 4eda4fa06d70a26ad8c2e2c4108e00f5c317a5c0 Mon Sep 17 00:00:00 2001 From: zwwhdls Date: Tue, 21 Jan 2020 21:46:34 +0800 Subject: [PATCH 64/81] allow limited recursion in templates Signed-off-by: zwwhdls --- pkg/engine/engine.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index d0261dca2..57ea04ef7 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -83,6 +83,7 @@ type renderable struct { const warnStartDelim = "HELM_ERR_START" const warnEndDelim = "HELM_ERR_END" +const recursionMaxNums = 1000 var warnRegex = regexp.MustCompile(warnStartDelim + `(.*)` + warnEndDelim) @@ -93,19 +94,20 @@ func warnWrap(warn string) string { // initFunMap creates the Engine's FuncMap and adds context-specific functions. func (e Engine) initFunMap(t *template.Template, referenceTpls map[string]renderable) { funcMap := funcMap() - includedNames := make([]string, 0) + includedNames := make(map[string]int) // Add the 'include' function here so we can close over t. funcMap["include"] = func(name string, data interface{}) (string, error) { var buf strings.Builder - for _, n := range includedNames { - if n == name { + if v, ok := includedNames[name]; ok { + if v > recursionMaxNums { return "", errors.Wrapf(fmt.Errorf("unable to execute template"), "rendering template has a nested reference name: %s", name) } + includedNames[name] ++ + } else { + includedNames[name] = 1 } - includedNames = append(includedNames, name) err := t.ExecuteTemplate(&buf, name, data) - includedNames = includedNames[:len(includedNames)-1] return buf.String(), err } From 16a85f757066c44aff6dacd8c598ac7a9d699eaa Mon Sep 17 00:00:00 2001 From: zwwhdls Date: Tue, 21 Jan 2020 22:04:13 +0800 Subject: [PATCH 65/81] fix test-style Signed-off-by: zwwhdls --- pkg/engine/engine.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 57ea04ef7..f777c5428 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -103,7 +103,7 @@ func (e Engine) initFunMap(t *template.Template, referenceTpls map[string]render if v > recursionMaxNums { return "", errors.Wrapf(fmt.Errorf("unable to execute template"), "rendering template has a nested reference name: %s", name) } - includedNames[name] ++ + includedNames[name]++ } else { includedNames[name] = 1 } From 5e3c7d7eb86a9fe6aad9174434415b9c42e78478 Mon Sep 17 00:00:00 2001 From: Anshul Verma Date: Thu, 23 Jan 2020 17:16:18 +0530 Subject: [PATCH 66/81] Friendly error message for non-existent Chart while packaging (#7127) * Fixes #6713 Friedly error message Signed-off-by: Anshul Verma * Fixes #6713 Friedly error message Signed-off-by: Anshul Verma * chaging error to no such file or directory Signed-off-by: Anshul Verma * changed it for the wider stat error messages which comes directly from go standard library. Signed-off-by: Anshul Verma * changed it for the wider stat error messages which comes directly from go standard library. Signed-off-by: Anshul Verma --- cmd/helm/package.go | 4 ++++ cmd/helm/package_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/cmd/helm/package.go b/cmd/helm/package.go index 9f7961f95..20cde6e4c 100644 --- a/cmd/helm/package.go +++ b/cmd/helm/package.go @@ -20,6 +20,7 @@ import ( "fmt" "io" "io/ioutil" + "os" "path/filepath" "github.com/pkg/errors" @@ -80,6 +81,9 @@ func newPackageCmd(out io.Writer) *cobra.Command { if err != nil { return err } + if _, err := os.Stat(args[i]); err != nil { + return err + } if client.DependencyUpdate { downloadManager := &downloader.Manager{ diff --git a/cmd/helm/package_test.go b/cmd/helm/package_test.go index 739857fa9..38938b4af 100644 --- a/cmd/helm/package_test.go +++ b/cmd/helm/package_test.go @@ -296,6 +296,41 @@ func TestPackageValues(t *testing.T) { } } +func TestNonExistentDirAndBadPermission(t *testing.T) { + nonExistentDir := "testdata/testcharts/non-existent-directory" + + tests := []struct { + name string + flags map[string]string + args []string + expect string + hasfile string + err bool + }{ + { + name: "package testdata/testcharts/non-existent-directory", + args: []string{"testdata/testcharts/non-existent-directory"}, + expect: fmt.Sprintf("stat %s: no such file or directory", nonExistentDir), + err: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var buf bytes.Buffer + c := newPackageCmd(&buf) + re := regexp.MustCompile(tt.expect) + err := c.RunE(c, tt.args) + if err != nil { + if tt.err && re.MatchString(err.Error()) { + return + } + t.Fatalf("%q: expected error %q, got %q", tt.name, tt.expect, err) + } + }) + } +} + func createValuesFile(t *testing.T, data string) string { outputDir := ensure.TempDir(t) From 0beb9f70407bed715e67dc28eaf6e6eb3c3263e1 Mon Sep 17 00:00:00 2001 From: Shota Nakamura <59258152+sukimoyoi@users.noreply.github.com> Date: Mon, 27 Jan 2020 20:00:26 +0900 Subject: [PATCH 67/81] fix(chartutil): remove empty lines and a space from rendered chart templates (#7455) Signed-off-by: sukimoyoi --- pkg/chartutil/create.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 390f12f4c..496f20166 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -304,7 +304,7 @@ kind: ServiceAccount metadata: name: {{ include ".serviceAccountName" . }} labels: -{{ include ".labels" . | nindent 4 }} + {{- include ".labels" . | nindent 4 }} {{- with .Values.serviceAccount.annotations }} annotations: {{- toYaml . | nindent 4 }} @@ -405,7 +405,7 @@ kind: Pod metadata: name: "{{ include ".fullname" . }}-test-connection" labels: -{{ include ".labels" . | nindent 4 }} + {{- include ".labels" . | nindent 4 }} annotations: "helm.sh/hook": test-success spec: @@ -413,7 +413,7 @@ spec: - name: wget image: busybox command: ['wget'] - args: ['{{ include ".fullname" . }}:{{ .Values.service.port }}'] + args: ['{{ include ".fullname" . }}:{{ .Values.service.port }}'] restartPolicy: Never ` From 50dcd39ba5a3c50bd046b5b539c2c7e6ac68aea1 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Tue, 10 Dec 2019 13:42:35 -0800 Subject: [PATCH 68/81] fix(package): remove --set, --values, etc. flags These flags snuck in through a feature that was reverted and removed in Helm 2, but snuck into Helm 3. They were never hooked up or used, so they were a no-op. This shouldn't affect anyone. Signed-off-by: Matthew Fisher --- cmd/helm/package.go | 1 - cmd/helm/package_test.go | 170 --------------------------------------- pkg/action/package.go | 6 -- pkg/chartutil/save.go | 23 +++--- 4 files changed, 12 insertions(+), 188 deletions(-) diff --git a/cmd/helm/package.go b/cmd/helm/package.go index 20cde6e4c..00fe0ef11 100644 --- a/cmd/helm/package.go +++ b/cmd/helm/package.go @@ -118,7 +118,6 @@ func newPackageCmd(out io.Writer) *cobra.Command { f.StringVar(&client.AppVersion, "app-version", "", "set the appVersion on the chart to this version") f.StringVarP(&client.Destination, "destination", "d", ".", "location to write the chart.") f.BoolVarP(&client.DependencyUpdate, "dependency-update", "u", false, `update dependencies from "Chart.yaml" to dir "charts/" before packaging`) - addValueOptionsFlags(f, valueOpts) return cmd } diff --git a/cmd/helm/package_test.go b/cmd/helm/package_test.go index 38938b4af..e0a5fabd6 100644 --- a/cmd/helm/package_test.go +++ b/cmd/helm/package_test.go @@ -17,13 +17,9 @@ package main import ( "bytes" - "fmt" - "io/ioutil" "os" "path/filepath" "regexp" - "runtime" - "strings" "testing" "github.com/spf13/cobra" @@ -31,15 +27,9 @@ import ( "helm.sh/helm/v3/internal/test/ensure" "helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart/loader" - "helm.sh/helm/v3/pkg/chartutil" ) func TestPackage(t *testing.T) { - statFileMsg := "no such file or directory" - if runtime.GOOS == "windows" { - statFileMsg = "The system cannot find the file specified." - } - tests := []struct { name string flags map[string]string @@ -108,13 +98,6 @@ func TestPackage(t *testing.T) { hasfile: "chart-missing-deps-0.1.0.tgz", err: true, }, - { - name: "package --values does-not-exist", - args: []string{"testdata/testcharts/alpine"}, - flags: map[string]string{"values": "does-not-exist"}, - expect: fmt.Sprintf("does-not-exist: %s", statFileMsg), - err: true, - }, { name: "package testdata/testcharts/chart-bad-type", args: []string{"testdata/testcharts/chart-bad-type"}, @@ -213,159 +196,6 @@ func TestSetAppVersion(t *testing.T) { } } -func TestPackageValues(t *testing.T) { - defer resetEnv()() - - repoFile := "testdata/helmhome/helm/repositories.yaml" - - testCases := []struct { - desc string - args []string - valuefilesContents []string - flags map[string]string - expected []string - }{ - { - desc: "helm package, single values file", - args: []string{"testdata/testcharts/alpine"}, - flags: map[string]string{"repository-config": repoFile}, - valuefilesContents: []string{"Name: chart-name-foo"}, - expected: []string{"Name: chart-name-foo"}, - }, - { - desc: "helm package, multiple values files", - args: []string{"testdata/testcharts/alpine"}, - flags: map[string]string{"repository-config": repoFile}, - valuefilesContents: []string{"Name: chart-name-foo", "foo: bar"}, - expected: []string{"Name: chart-name-foo", "foo: bar"}, - }, - { - desc: "helm package, with set option", - args: []string{"testdata/testcharts/alpine"}, - flags: map[string]string{"set": "Name=chart-name-foo", "repository-config": repoFile}, - expected: []string{"Name: chart-name-foo"}, - }, - { - desc: "helm package, set takes precedence over value file", - args: []string{"testdata/testcharts/alpine"}, - valuefilesContents: []string{"Name: chart-name-foo"}, - flags: map[string]string{"set": "Name=chart-name-bar", "repository-config": repoFile}, - expected: []string{"Name: chart-name-bar"}, - }, - } - - for _, tc := range testCases { - var files []string - for _, contents := range tc.valuefilesContents { - f := createValuesFile(t, contents) - files = append(files, f) - } - valueFiles := strings.Join(files, ",") - - expected, err := chartutil.ReadValues([]byte(strings.Join(tc.expected, "\n"))) - if err != nil { - t.Errorf("unexpected error parsing values: %q", err) - } - - outputDir := ensure.TempDir(t) - - if len(tc.flags) == 0 { - tc.flags = make(map[string]string) - } - tc.flags["destination"] = outputDir - - if len(valueFiles) > 0 { - tc.flags["values"] = valueFiles - } - - cmd := newPackageCmd(&bytes.Buffer{}) - setFlags(cmd, tc.flags) - if err := cmd.RunE(cmd, tc.args); err != nil { - t.Fatalf("unexpected error: %q", err) - } - - outputFile := filepath.Join(outputDir, "alpine-0.1.0.tgz") - verifyOutputChartExists(t, outputFile) - - actual, err := getChartValues(outputFile) - if err != nil { - t.Fatalf("unexpected error extracting chart values: %q", err) - } - - verifyValues(t, actual, expected) - } -} - -func TestNonExistentDirAndBadPermission(t *testing.T) { - nonExistentDir := "testdata/testcharts/non-existent-directory" - - tests := []struct { - name string - flags map[string]string - args []string - expect string - hasfile string - err bool - }{ - { - name: "package testdata/testcharts/non-existent-directory", - args: []string{"testdata/testcharts/non-existent-directory"}, - expect: fmt.Sprintf("stat %s: no such file or directory", nonExistentDir), - err: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - var buf bytes.Buffer - c := newPackageCmd(&buf) - re := regexp.MustCompile(tt.expect) - err := c.RunE(c, tt.args) - if err != nil { - if tt.err && re.MatchString(err.Error()) { - return - } - t.Fatalf("%q: expected error %q, got %q", tt.name, tt.expect, err) - } - }) - } -} - -func createValuesFile(t *testing.T, data string) string { - outputDir := ensure.TempDir(t) - - outputFile := filepath.Join(outputDir, "values.yaml") - if err := ioutil.WriteFile(outputFile, []byte(data), 0644); err != nil { - t.Fatalf("err: %s", err) - } - return outputFile -} - -func getChartValues(chartPath string) (chartutil.Values, error) { - chart, err := loader.Load(chartPath) - if err != nil { - return nil, err - } - return chart.Values, nil -} - -func verifyValues(t *testing.T, actual, expected chartutil.Values) { - t.Helper() - for key, value := range expected.AsMap() { - if got := actual[key]; got != value { - t.Errorf("Expected %q, got %q (%v)", value, got, actual) - } - } -} - -func verifyOutputChartExists(t *testing.T, chartPath string) { - if chartFile, err := os.Stat(chartPath); err != nil { - t.Errorf("expected file %q, got err %q", chartPath, err) - } else if chartFile.Size() == 0 { - t.Errorf("file %q has zero bytes.", chartPath) - } -} - func setFlags(cmd *cobra.Command, flags map[string]string) { dest := cmd.Flags() for f, v := range flags { diff --git a/pkg/action/package.go b/pkg/action/package.go index 5c85ebe0d..b48fc65f0 100644 --- a/pkg/action/package.go +++ b/pkg/action/package.go @@ -60,12 +60,6 @@ func (p *Package) Run(path string, vals map[string]interface{}) (string, error) return "", err } - combinedVals, err := chartutil.CoalesceValues(ch, vals) - if err != nil { - return "", err - } - ch.Values = combinedVals - // If version is set, modify the version. if p.Version != "" { if err := setVersion(ch, p.Version); err != nil { diff --git a/pkg/chartutil/save.go b/pkg/chartutil/save.go index fb985bb59..be0dfdc24 100644 --- a/pkg/chartutil/save.go +++ b/pkg/chartutil/save.go @@ -50,11 +50,12 @@ func SaveDir(c *chart.Chart, dest string) error { } // Save values.yaml - if c.Values != nil { - vf := filepath.Join(outdir, ValuesfileName) - b, _ := yaml.Marshal(c.Values) - if err := writeFile(vf, b); err != nil { - return err + for _, f := range c.Raw { + if f.Name == ValuesfileName { + vf := filepath.Join(outdir, ValuesfileName) + if err := writeFile(vf, f.Data); err != nil { + return err + } } } @@ -161,12 +162,12 @@ func writeTarContents(out *tar.Writer, c *chart.Chart, prefix string) error { } // Save values.yaml - ydata, err := yaml.Marshal(c.Values) - if err != nil { - return err - } - if err := writeToTar(out, filepath.Join(base, ValuesfileName), ydata); err != nil { - return err + for _, f := range c.Raw { + if f.Name == ValuesfileName { + if err := writeToTar(out, filepath.Join(base, ValuesfileName), f.Data); err != nil { + return err + } + } } // Save values.schema.json if it exists From a704ba7e203b1ba6336d7b7b4e39094e9079bca0 Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Tue, 28 Jan 2020 10:58:27 -0500 Subject: [PATCH 69/81] Adding security file This file: - Shows up in the GitHub UI under the new security tab - Points to our common process documented in the community repo. This follows the same pattern we use for the code of conduct Signed-off-by: Matt Farina --- SECURITY.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..c84a6f866 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,3 @@ +# Helm Security Reporting and Policy + +The Helm project has [a common process and policy that can be found here](https://github.com/helm/community/blob/master/SECURITY.md). \ No newline at end of file From 4f4779ca3a456468851f446fd978c4c71563fa96 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Sat, 25 Jan 2020 12:42:21 -0500 Subject: [PATCH 70/81] fix(comp): Allow zsh completion to handle -n flag When doing zsh completion, the -n flag would not be handled properly. Doing helm -n would not add the space after the -n. This was caused by the fact that the -n flag was being swallowed by the echo command. To fix this, we use printf instead. Signed-off-by: Marc Khouzam --- cmd/helm/completion.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/helm/completion.go b/cmd/helm/completion.go index a44140d9f..1601cb448 100644 --- a/cmd/helm/completion.go +++ b/cmd/helm/completion.go @@ -139,7 +139,10 @@ __helm_compgen() { fi for w in "${completions[@]}"; do if [[ "${w}" = "$1"* ]]; then - echo "${w}" + # Use printf instead of echo beause it is possible that + # the value to print is -n, which would be interpreted + # as a flag to echo + printf "%s\n" "${w}" fi done } From 8d566c0aded8cc4ab57d6e4d27e121ea836d2ef0 Mon Sep 17 00:00:00 2001 From: Ilya Shaisultanov Date: Wed, 29 Jan 2020 10:27:33 +0100 Subject: [PATCH 71/81] When no resources were created, do not try to clean them up Fixes #7481 Signed-off-by: Ilya Shaisultanov --- pkg/action/upgrade.go | 2 +- pkg/action/upgrade_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/pkg/action/upgrade.go b/pkg/action/upgrade.go index cdc40eaaa..1db4184ff 100644 --- a/pkg/action/upgrade.go +++ b/pkg/action/upgrade.go @@ -291,7 +291,7 @@ func (u *Upgrade) failRelease(rel *release.Release, created kube.ResourceList, e rel.Info.Status = release.StatusFailed rel.Info.Description = msg u.cfg.recordRelease(rel) - if u.CleanupOnFail { + if u.CleanupOnFail && len(created) > 0 { u.cfg.Log("Cleanup on fail set, cleaning up %d resources", len(created)) _, errs := u.cfg.KubeClient.Delete(created) if errs != nil { diff --git a/pkg/action/upgrade_test.go b/pkg/action/upgrade_test.go index e7bfeefc5..f25d115c4 100644 --- a/pkg/action/upgrade_test.go +++ b/pkg/action/upgrade_test.go @@ -60,6 +60,31 @@ func TestUpgradeRelease_Wait(t *testing.T) { is.Equal(res.Info.Status, release.StatusFailed) } +func TestUpgradeRelease_CleanupOnFail(t *testing.T) { + is := assert.New(t) + req := require.New(t) + + upAction := upgradeAction(t) + rel := releaseStub() + rel.Name = "come-fail-away" + rel.Info.Status = release.StatusDeployed + upAction.cfg.Releases.Create(rel) + + failer := upAction.cfg.KubeClient.(*kubefake.FailingKubeClient) + failer.WaitError = fmt.Errorf("I timed out") + failer.DeleteError = fmt.Errorf("I tried to delete nil") + upAction.cfg.KubeClient = failer + upAction.Wait = true + upAction.CleanupOnFail = true + vals := map[string]interface{}{} + + res, err := upAction.Run(rel.Name, buildChart(), vals) + req.Error(err) + is.NotContains(err.Error(), "unable to cleanup resources") + is.Contains(res.Info.Description, "I timed out") + is.Equal(res.Info.Status, release.StatusFailed) +} + func TestUpgradeRelease_Atomic(t *testing.T) { is := assert.New(t) req := require.New(t) From 1d79ed2c189da65315a597d51a92f0213f224126 Mon Sep 17 00:00:00 2001 From: LongKB Date: Thu, 30 Jan 2020 18:19:10 +0700 Subject: [PATCH 72/81] Fix some spelling errors in comment (#7492) Although it is spelling mistakes, it might make an affects while reading. Signed-off-by: Kim Bao Long --- pkg/action/list.go | 2 +- pkg/getter/getter.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/action/list.go b/pkg/action/list.go index 5d3417203..5be60ac42 100644 --- a/pkg/action/list.go +++ b/pkg/action/list.go @@ -26,7 +26,7 @@ import ( // ListStates represents zero or more status codes that a list item may have set // -// Because this is used as a bitmask filter, more than one one bit can be flipped +// Because this is used as a bitmask filter, more than one bit can be flipped // in the ListStates. type ListStates uint diff --git a/pkg/getter/getter.go b/pkg/getter/getter.go index e11dbfcae..68638c2ca 100644 --- a/pkg/getter/getter.go +++ b/pkg/getter/getter.go @@ -64,7 +64,7 @@ func WithUserAgent(userAgent string) Option { } } -// WithTLSClientConfig sets the client client auth with the provided credentials. +// WithTLSClientConfig sets the client auth with the provided credentials. func WithTLSClientConfig(certFile, keyFile, caFile string) Option { return func(opts *options) { opts.certFile = certFile From e483dce2895dd23400816b7852405edbf726e396 Mon Sep 17 00:00:00 2001 From: Lee Bontecou Date: Thu, 30 Jan 2020 05:24:09 -0600 Subject: [PATCH 73/81] fix(template): helm template "--show-only" flag producing duplicates when flag used more than once (#7204) * bugfix template show-only duplicates Signed-off-by: Lee Bontecou * 7203 - add unittests Signed-off-by: Lee Bontecou * attempt formatting fix Signed-off-by: Lee Bontecou * gofmt-ed with -s Signed-off-by: Lee Bontecou * goimports-ed with -local helm.sh/helm/v3 and gofmt-ed with -s -w Signed-off-by: Lee Bontecou * Update template_test.go Signed-off-by: Lee Bontecou * Update template_test.go Signed-off-by: Lee Bontecou --- cmd/helm/template.go | 6 +-- cmd/helm/template_test.go | 10 +++++ .../output/template-show-only-multiple.txt | 39 +++++++++++++++++++ .../output/template-show-only-one.txt | 22 +++++++++++ go.mod | 1 + go.sum | 9 +++++ 6 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 cmd/helm/testdata/output/template-show-only-multiple.txt create mode 100644 cmd/helm/testdata/output/template-show-only-one.txt diff --git a/cmd/helm/template.go b/cmd/helm/template.go index 1c34d7245..dc62c6e95 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -112,9 +112,9 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { if missing { return fmt.Errorf("could not find template %s in chart", f) } - for _, m := range manifestsToRender { - fmt.Fprintf(out, "---\n%s\n", m) - } + } + for _, m := range manifestsToRender { + fmt.Fprintf(out, "---\n%s\n", m) } } else { fmt.Fprintf(out, "%s", manifests.String()) diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go index 35a8e996b..dc7987d01 100644 --- a/cmd/helm/template_test.go +++ b/cmd/helm/template_test.go @@ -84,6 +84,16 @@ func TestTemplateCmd(t *testing.T) { cmd: fmt.Sprintf("template '%s' --include-crds", chartPath), golden: "output/template-with-crds.txt", }, + { + name: "template with show-only one", + cmd: fmt.Sprintf("template '%s' --show-only templates/service.yaml", chartPath), + golden: "output/template-show-only-one.txt", + }, + { + name: "template with show-only multiple", + cmd: fmt.Sprintf("template '%s' --show-only templates/service.yaml --show-only charts/subcharta/templates/service.yaml", chartPath), + golden: "output/template-show-only-multiple.txt", + }, { name: "sorted output of manifests (order of filenames, then order of objects within each YAML file)", cmd: fmt.Sprintf("template '%s'", "testdata/testcharts/object-order"), diff --git a/cmd/helm/testdata/output/template-show-only-multiple.txt b/cmd/helm/testdata/output/template-show-only-multiple.txt new file mode 100644 index 000000000..abb9a2e10 --- /dev/null +++ b/cmd/helm/testdata/output/template-show-only-multiple.txt @@ -0,0 +1,39 @@ +--- +# Source: subchart1/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: subchart1 + labels: + helm.sh/chart: "subchart1-0.1.0" + app.kubernetes.io/instance: "RELEASE-NAME" + kube-version/major: "1" + kube-version/minor: "16" + kube-version/version: "v1.16.0" + kube-api-version/test: v1 +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: nginx + selector: + app.kubernetes.io/name: subchart1 +--- +# Source: subchart1/charts/subcharta/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: subcharta + labels: + helm.sh/chart: "subcharta-0.1.0" +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: apache + selector: + app.kubernetes.io/name: subcharta diff --git a/cmd/helm/testdata/output/template-show-only-one.txt b/cmd/helm/testdata/output/template-show-only-one.txt new file mode 100644 index 000000000..f0dd0834e --- /dev/null +++ b/cmd/helm/testdata/output/template-show-only-one.txt @@ -0,0 +1,22 @@ +--- +# Source: subchart1/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: subchart1 + labels: + helm.sh/chart: "subchart1-0.1.0" + app.kubernetes.io/instance: "RELEASE-NAME" + kube-version/major: "1" + kube-version/minor: "16" + kube-version/version: "v1.16.0" + kube-api-version/test: v1 +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: nginx + selector: + app.kubernetes.io/name: subchart1 diff --git a/go.mod b/go.mod index c7b25ac13..626df86bb 100644 --- a/go.mod +++ b/go.mod @@ -49,6 +49,7 @@ require ( golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 // indirect golang.org/x/sys v0.0.0-20191028164358-195ce5e7f934 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect + golang.org/x/tools v0.0.0-20191218225520-84f0c7cf60ea // indirect google.golang.org/appengine v1.6.5 // indirect google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6 // indirect google.golang.org/grpc v1.24.0 // indirect diff --git a/go.sum b/go.sum index 312152e1f..914ccd116 100644 --- a/go.sum +++ b/go.sum @@ -520,6 +520,7 @@ 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-20190911031432-227b76d455e7 h1:0hQKqeLdqlt5iIwVOBErRisrHJAN57yOiPRQItI20fU= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191028145041-f83a4685e152 h1:ZC1Xn5A1nlpSmQCIva4bZ3ob3lmhYIefc+GU+DLg1Ow= golang.org/x/crypto v0.0.0-20191028145041-f83a4685e152/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -532,6 +533,7 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx 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.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/net v0.0.0-20170114055629-f2499483f923/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,6 +551,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190603091049-60506f45cf65/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 h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68= +golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -609,6 +613,11 @@ golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac h1:MQEvx39qSf8vyrx3XRaOe+j1UDIzKwkYOVObRgGPVqI= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191218225520-84f0c7cf60ea h1:mtRJM/ln5qwEigajtnZtuARALEPOooGf5lwkM5a9tt4= +golang.org/x/tools v0.0.0-20191218225520-84f0c7cf60ea/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 45d986327a544689d9199b2d71183d7d9f21e696 Mon Sep 17 00:00:00 2001 From: Martin Hickey Date: Thu, 30 Jan 2020 12:00:57 +0000 Subject: [PATCH 74/81] Tidy up go dependencies (#7494) Signed-off-by: Martin Hickey --- go.mod | 1 - go.sum | 9 --------- 2 files changed, 10 deletions(-) diff --git a/go.mod b/go.mod index 626df86bb..c7b25ac13 100644 --- a/go.mod +++ b/go.mod @@ -49,7 +49,6 @@ require ( golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 // indirect golang.org/x/sys v0.0.0-20191028164358-195ce5e7f934 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect - golang.org/x/tools v0.0.0-20191218225520-84f0c7cf60ea // indirect google.golang.org/appengine v1.6.5 // indirect google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6 // indirect google.golang.org/grpc v1.24.0 // indirect diff --git a/go.sum b/go.sum index 914ccd116..312152e1f 100644 --- a/go.sum +++ b/go.sum @@ -520,7 +520,6 @@ 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-20190911031432-227b76d455e7 h1:0hQKqeLdqlt5iIwVOBErRisrHJAN57yOiPRQItI20fU= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191028145041-f83a4685e152 h1:ZC1Xn5A1nlpSmQCIva4bZ3ob3lmhYIefc+GU+DLg1Ow= golang.org/x/crypto v0.0.0-20191028145041-f83a4685e152/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -533,7 +532,6 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx 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.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/net v0.0.0-20170114055629-f2499483f923/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= @@ -551,8 +549,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190603091049-60506f45cf65/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 h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68= -golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -613,11 +609,6 @@ golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac h1:MQEvx39qSf8vyrx3XRaOe+j1UDIzKwkYOVObRgGPVqI= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20191218225520-84f0c7cf60ea h1:mtRJM/ln5qwEigajtnZtuARALEPOooGf5lwkM5a9tt4= -golang.org/x/tools v0.0.0-20191218225520-84f0c7cf60ea/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From d70b50b3a11b62efe942d0429d1d7c54f8656a52 Mon Sep 17 00:00:00 2001 From: Jon Huhn Date: Thu, 30 Jan 2020 09:50:59 -0600 Subject: [PATCH 75/81] Fix typo Signed-off-by: Jon Huhn --- pkg/chart/chart.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/chart/chart.go b/pkg/chart/chart.go index c3e99eae6..5eb4d4d94 100644 --- a/pkg/chart/chart.go +++ b/pkg/chart/chart.go @@ -33,7 +33,7 @@ type Chart struct { Raw []*File `json:"-"` // Metadata is the contents of the Chartfile. Metadata *Metadata `json:"metadata"` - // LocK is the contents of Chart.lock. + // Lock is the contents of Chart.lock. Lock *Lock `json:"lock"` // Templates for this chart. Templates []*File `json:"templates"` From 1b1d6bba9cec81a6bbc77dd948779a45bc8a63c8 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Mon, 27 Jan 2020 14:44:12 -0800 Subject: [PATCH 76/81] fix(lookup_func): do not return error when object is not found Signed-off-by: Matthew Fisher --- pkg/engine/lookup_func.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/pkg/engine/lookup_func.go b/pkg/engine/lookup_func.go index 14f2351b4..5dde29443 100644 --- a/pkg/engine/lookup_func.go +++ b/pkg/engine/lookup_func.go @@ -21,6 +21,7 @@ import ( "strings" "github.com/pkg/errors" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/discovery" @@ -30,6 +31,8 @@ import ( type lookupFunc = func(apiversion string, resource string, namespace string, name string) (map[string]interface{}, error) +// NewLookupFunction returns a function for looking up objects in the cluster. If the resource does not exist, no error +// is raised. func NewLookupFunction(config *rest.Config) lookupFunc { return func(apiversion string, resource string, namespace string, name string) (map[string]interface{}, error) { var client dynamic.ResourceInterface @@ -43,9 +46,14 @@ func NewLookupFunction(config *rest.Config) lookupFunc { client = c } if name != "" { - //this will return a single object + // this will return a single object obj, err := client.Get(name, metav1.GetOptions{}) if err != nil { + if apierrors.IsNotFound(err) { + // Just return an empty interface when the object was not found. + // That way, users can use `if not (lookup ...)` in their templates. + return map[string]interface{}{}, nil + } return map[string]interface{}{}, err } return obj.UnstructuredContent(), nil @@ -53,6 +61,11 @@ func NewLookupFunction(config *rest.Config) lookupFunc { //this will return a list obj, err := client.List(metav1.ListOptions{}) if err != nil { + if apierrors.IsNotFound(err) { + // Just return an empty interface when the object was not found. + // That way, users can use `if not (lookup ...)` in their templates. + return map[string]interface{}{}, nil + } return map[string]interface{}{}, err } return obj.UnstructuredContent(), nil From df20164cd27f12d8f4cadda608ca1caea5c25759 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Fri, 31 Jan 2020 04:59:35 -0500 Subject: [PATCH 77/81] Fix tests on arm64 and ppc64le (#7500) Signed-off-by: Yaakov Selkowitz --- pkg/plugin/plugin_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/plugin/plugin_test.go b/pkg/plugin/plugin_test.go index 076ae1187..c869e4c86 100644 --- a/pkg/plugin/plugin_test.go +++ b/pkg/plugin/plugin_test.go @@ -87,6 +87,8 @@ func TestPlatformPrepareCommand(t *testing.T) { PlatformCommand: []PlatformCommand{ {OperatingSystem: "linux", Architecture: "i386", Command: "echo -n linux-i386"}, {OperatingSystem: "linux", Architecture: "amd64", Command: "echo -n linux-amd64"}, + {OperatingSystem: "linux", Architecture: "arm64", Command: "echo -n linux-arm64"}, + {OperatingSystem: "linux", Architecture: "ppc64le", Command: "echo -n linux-ppc64le"}, {OperatingSystem: "linux", Architecture: "s390x", Command: "echo -n linux-s390x"}, {OperatingSystem: "windows", Architecture: "amd64", Command: "echo -n win-64"}, }, @@ -99,6 +101,10 @@ func TestPlatformPrepareCommand(t *testing.T) { osStrCmp = "linux-i386" } else if os == "linux" && arch == "amd64" { osStrCmp = "linux-amd64" + } else if os == "linux" && arch == "arm64" { + osStrCmp = "linux-arm64" + } else if os == "linux" && arch == "ppc64le" { + osStrCmp = "linux-ppc64le" } else if os == "linux" && arch == "s390x" { osStrCmp = "linux-s390x" } else if os == "windows" && arch == "amd64" { From 6cfcc96cea4344b9b1003eafbf4cbe670494d5b0 Mon Sep 17 00:00:00 2001 From: Karuppiah Natarajan Date: Sat, 1 Feb 2020 14:26:50 +0530 Subject: [PATCH 78/81] fix(test) use newly created index instead of ignoring it Signed-off-by: Karuppiah Natarajan --- cmd/helm/repo_index_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/helm/repo_index_test.go b/cmd/helm/repo_index_test.go index 51c5db80a..e04ae1b59 100644 --- a/cmd/helm/repo_index_test.go +++ b/cmd/helm/repo_index_test.go @@ -119,7 +119,7 @@ func TestRepoIndexCmd(t *testing.T) { t.Error(err) } - _, err = repo.LoadIndexFile(destIndex) + index, err = repo.LoadIndexFile(destIndex) if err != nil { t.Fatal(err) } @@ -130,8 +130,8 @@ func TestRepoIndexCmd(t *testing.T) { } vs = index.Entries["compressedchart"] - if len(vs) != 3 { - t.Errorf("expected 3 versions, got %d: %#v", len(vs), vs) + if len(vs) != 1 { + t.Errorf("expected 1 versions, got %d: %#v", len(vs), vs) } expectedVersion = "0.3.0" From 1897d4d60a387f4b516c2382b5ae2f36abde844c Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Sun, 2 Feb 2020 15:10:32 -0500 Subject: [PATCH 79/81] fix(tests): Make tests pass on MacOS This newly added tests was failing on MacOS because /proc does not exist. This commit replaces /proc with /tmp to achieve the same result. Signed-off-by: Marc Khouzam --- internal/resolver/resolver_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/resolver/resolver_test.go b/internal/resolver/resolver_test.go index d93d616ee..bb3d3e6ac 100644 --- a/internal/resolver/resolver_test.go +++ b/internal/resolver/resolver_test.go @@ -227,8 +227,8 @@ func TestGetLocalPath(t *testing.T) { }{ { name: "absolute path", - repo: "file:////proc", - expect: "/proc", + repo: "file:////tmp", + expect: "/tmp", }, { name: "relative path", From 084ab20f671438ac92d37d8a084735975562cbed Mon Sep 17 00:00:00 2001 From: Martin Hickey Date: Tue, 4 Feb 2020 17:27:38 +0100 Subject: [PATCH 80/81] feat(template): Allow template output to use release name (#7503) * Allow template output to use release name helm template output command uses the chart name only when writing templates to disk. This changes will also use the release name to avoid colloiding the path when output nore than one release of smae chart. Signed-off-by: Martin Hickey * Update after review Comment: - https://github.com/helm/helm/pull/7503/files#r374130090 Signed-off-by: Martin Hickey --- cmd/helm/template.go | 1 + pkg/action/install.go | 13 ++++++++++--- pkg/action/install_test.go | 40 ++++++++++++++++++++++++++++++++++++++ pkg/action/upgrade.go | 2 +- 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/cmd/helm/template.go b/cmd/helm/template.go index dc62c6e95..36c029e69 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -137,6 +137,7 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f.BoolVar(&includeCrds, "include-crds", false, "include CRDs in the templated output") f.BoolVar(&client.IsUpgrade, "is-upgrade", false, "set .Release.IsUpgrade instead of .Release.IsInstall") f.StringArrayVarP(&extraAPIs, "api-versions", "a", []string{}, "Kubernetes api versions used for Capabilities.APIVersions") + f.BoolVar(&client.UseReleaseName, "release-name", false, "use release name in the output-dir path.") return cmd } diff --git a/pkg/action/install.go b/pkg/action/install.go index 292a7ec27..80bd9c88f 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -89,6 +89,9 @@ type Install struct { APIVersions chartutil.VersionSet // Used by helm template to render charts with .Release.IsUpgrade. Ignored if Dry-Run is false IsUpgrade bool + // Used by helm template to add the release as part of OutputDir path + // OutputDir/ + UseReleaseName bool } // ChartPathOptions captures common options used for controlling chart paths @@ -217,7 +220,7 @@ func (i *Install) Run(chrt *chart.Chart, vals map[string]interface{}) (*release. rel := i.createRelease(chrt, vals) var manifestDoc *bytes.Buffer - rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.OutputDir, i.SubNotes) + rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.SubNotes, i.UseReleaseName) // Even for errors, attach this if available if manifestDoc != nil { rel.Manifest = manifestDoc.String() @@ -421,7 +424,7 @@ func (i *Install) replaceRelease(rel *release.Release) error { } // renderResources renders the templates in a chart -func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, outputDir string, subNotes bool) ([]*release.Hook, *bytes.Buffer, string, error) { +func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, releaseName string, outputDir string, subNotes, useReleaseName bool) ([]*release.Hook, *bytes.Buffer, string, error) { hs := []*release.Hook{} b := bytes.NewBuffer(nil) @@ -498,7 +501,11 @@ func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values if outputDir == "" { fmt.Fprintf(b, "---\n# Source: %s\n%s\n", m.Name, m.Content) } else { - err = writeToFile(outputDir, m.Name, m.Content, fileWritten[m.Name]) + newDir := outputDir + if useReleaseName { + newDir = filepath.Join(outputDir, releaseName) + } + err = writeToFile(newDir, m.Name, m.Content, fileWritten[m.Name]) if err != nil { return hs, b, "", err } diff --git a/pkg/action/install_test.go b/pkg/action/install_test.go index d6f1c88cd..ba350819d 100644 --- a/pkg/action/install_test.go +++ b/pkg/action/install_test.go @@ -471,6 +471,46 @@ func TestInstallReleaseOutputDir(t *testing.T) { is.True(os.IsNotExist(err)) } +func TestInstallOutputDirWithReleaseName(t *testing.T) { + is := assert.New(t) + instAction := installAction(t) + vals := map[string]interface{}{} + + dir, err := ioutil.TempDir("", "output-dir") + if err != nil { + log.Fatal(err) + } + defer os.RemoveAll(dir) + + instAction.OutputDir = dir + instAction.UseReleaseName = true + instAction.ReleaseName = "madra" + + newDir := filepath.Join(dir, instAction.ReleaseName) + + _, err = instAction.Run(buildChart(withSampleTemplates(), withMultipleManifestTemplate()), vals) + if err != nil { + t.Fatalf("Failed install: %s", err) + } + + _, err = os.Stat(filepath.Join(newDir, "hello/templates/goodbye")) + is.NoError(err) + + _, err = os.Stat(filepath.Join(newDir, "hello/templates/hello")) + is.NoError(err) + + _, err = os.Stat(filepath.Join(newDir, "hello/templates/with-partials")) + is.NoError(err) + + _, err = os.Stat(filepath.Join(newDir, "hello/templates/rbac")) + is.NoError(err) + + test.AssertGoldenFile(t, filepath.Join(newDir, "hello/templates/rbac"), "rbac.txt") + + _, err = os.Stat(filepath.Join(newDir, "hello/templates/empty")) + is.True(os.IsNotExist(err)) +} + func TestNameAndChart(t *testing.T) { is := assert.New(t) instAction := installAction(t) diff --git a/pkg/action/upgrade.go b/pkg/action/upgrade.go index 1db4184ff..ad3a235e6 100644 --- a/pkg/action/upgrade.go +++ b/pkg/action/upgrade.go @@ -161,7 +161,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[strin return nil, nil, err } - hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", u.SubNotes) + hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", u.SubNotes, false) if err != nil { return nil, nil, err } From 7ce29e12fa8ac7195613ffa1a76b2914150ff756 Mon Sep 17 00:00:00 2001 From: Josh Dolitsky <393494+jdolitsky@users.noreply.github.com> Date: Tue, 4 Feb 2020 13:54:13 -0600 Subject: [PATCH 81/81] ref(go.mod): oras v0.8.1 (#6862) * ref(go.mod): oras v0.8.1 Signed-off-by: Josh Dolitsky <393494+jdolitsky@users.noreply.github.com> * update various module versions Signed-off-by: Josh Dolitsky <393494+jdolitsky@users.noreply.github.com> * upgrade oras v0.8.1 Signed-off-by: Josh Dolitsky <393494+jdolitsky@users.noreply.github.com> * upgrade to oras 0.8.1 release Signed-off-by: Josh Dolitsky <393494+jdolitsky@users.noreply.github.com> * lock to oras release (0.8.1) Signed-off-by: Josh Dolitsky <393494+jdolitsky@users.noreply.github.com> --- go.mod | 71 +--- go.sum | 374 ++++++++---------- internal/experimental/registry/client.go | 3 +- internal/experimental/registry/client_test.go | 3 +- pkg/action/action_test.go | 3 +- 5 files changed, 194 insertions(+), 260 deletions(-) diff --git a/go.mod b/go.mod index c7b25ac13..696c2b6d2 100644 --- a/go.mod +++ b/go.mod @@ -4,79 +4,42 @@ go 1.13 require ( github.com/BurntSushi/toml v0.3.1 - github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e // indirect github.com/Masterminds/semver/v3 v3.0.3 github.com/Masterminds/sprig/v3 v3.0.2 - github.com/Masterminds/vcs v1.13.0 - github.com/Microsoft/go-winio v0.4.12 // indirect - github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a - github.com/containerd/containerd v1.3.0 + github.com/Masterminds/vcs v1.13.1 + github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 + github.com/containerd/containerd v1.3.2 github.com/cyphar/filepath-securejoin v0.2.2 - github.com/deislabs/oras v0.7.0 + github.com/deislabs/oras v0.8.1 github.com/docker/distribution v2.7.1+incompatible - github.com/docker/docker v1.4.2-0.20181221150755-2cb26cfe9cbf + github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce github.com/docker/go-units v0.4.0 - github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect - github.com/emicklei/go-restful v2.11.1+incompatible // indirect github.com/evanphx/json-patch v4.5.0+incompatible - github.com/go-openapi/spec v0.19.4 // indirect github.com/gobwas/glob v0.2.3 github.com/gofrs/flock v0.7.1 - github.com/gogo/protobuf v1.3.1 // indirect - github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect - github.com/google/go-cmp v0.3.1 // indirect - github.com/googleapis/gnostic v0.3.1 // indirect - github.com/gosuri/uitable v0.0.1 - github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f // indirect - github.com/hashicorp/golang-lru v0.5.3 // indirect - github.com/imdario/mergo v0.3.8 // indirect - github.com/mattn/go-runewidth v0.0.4 // indirect - github.com/mattn/go-shellwords v1.0.5 + github.com/gosuri/uitable v0.0.4 + github.com/mattn/go-shellwords v1.0.9 github.com/mitchellh/copystructure v1.0.0 github.com/opencontainers/go-digest v1.0.0-rc1 github.com/opencontainers/image-spec v1.0.1 - github.com/pkg/errors v0.8.1 - github.com/prometheus/client_golang v1.2.1 // indirect + github.com/pkg/errors v0.9.1 github.com/sirupsen/logrus v1.4.2 github.com/spf13/cobra v0.0.5 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.4.0 - github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.1.0 - github.com/xenolf/lego v0.3.2-0.20160613233155-a9d8cec0e656 // indirect - golang.org/x/crypto v0.0.0-20191028145041-f83a4685e152 - golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 // indirect - golang.org/x/sys v0.0.0-20191028164358-195ce5e7f934 // indirect - golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect - google.golang.org/appengine v1.6.5 // indirect - google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6 // indirect - google.golang.org/grpc v1.24.0 // indirect - k8s.io/api v0.17.1 - k8s.io/apiextensions-apiserver v0.17.1 - k8s.io/apimachinery v0.17.1 - k8s.io/cli-runtime v0.17.1 - k8s.io/client-go v0.17.1 + golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d + k8s.io/api v0.17.2 + k8s.io/apiextensions-apiserver v0.17.2 + k8s.io/apimachinery v0.17.2 + k8s.io/cli-runtime v0.17.2 + k8s.io/client-go v0.17.2 k8s.io/klog v1.0.0 - k8s.io/kubectl v0.17.1 + k8s.io/kubectl v0.17.2 sigs.k8s.io/yaml v1.1.0 ) replace ( - // github.com/Azure/go-autorest/autorest has different versions for the Go - // modules than it does for releases on the repository. Note the correct - // version when updating. - github.com/Azure/go-autorest/autorest => github.com/Azure/go-autorest/autorest v0.9.0 - github.com/docker/docker => github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309 - - // Kubernetes imports github.com/miekg/dns at a newer version but it is used - // by a package Helm does not need. Go modules resolves all packages rather - // than just those in use (like Glide and dep do). This sets the version - // to the one oras needs. If oras is updated the version should be updated - // as well. - github.com/miekg/dns => github.com/miekg/dns v0.0.0-20181005163659-0d29b283ac0f - gopkg.in/inf.v0 v0.9.1 => github.com/go-inf/inf v0.9.1 - gopkg.in/square/go-jose.v2 v2.3.0 => github.com/square/go-jose v2.3.0+incompatible - - rsc.io/letsencrypt => github.com/dmcgowan/letsencrypt v0.0.0-20160928181947-1847a81d2087 + github.com/Azure/go-autorest => github.com/Azure/go-autorest v13.3.2+incompatible + github.com/docker/distribution => github.com/docker/distribution v0.0.0-20191216044856-a8371794149d ) diff --git a/go.sum b/go.sum index 312152e1f..cc6b8dd9c 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,13 @@ +bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= 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 v13.3.2+incompatible h1:VxzPyuhtnlBOzc4IWCZHqpyH2d+QMLQEuy3wREyY4oc= +github.com/Azure/go-autorest v13.3.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= 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= @@ -20,23 +24,20 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= 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/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e h1:eb0Pzkt15Bm7f2FFYv7sjY7NPFi3cPkS3tv1CcrFBWA= -github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.0.3 h1:znjIyLfpXEDQjOIEWh+ehwpTU14UzUPub3c3sm36u14= github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/sprig/v3 v3.0.2 h1:wz22D0CiSctrliXiI9ZO3HoNApweeRGftyDN+BQa3B8= github.com/Masterminds/sprig/v3 v3.0.2/go.mod h1:oesJ8kPONMONaZgtiHNzUShJbksypC5kWczhZAf6+aU= -github.com/Masterminds/vcs v1.13.0 h1:USF5TvZGYgIpcbNAEMLfFhHqP08tFZVlUVrmTSpqnyA= -github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= -github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc= -github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/hcsshim v0.8.6 h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA= -github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= -github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 h1:lsxEuwrXEAokXB9qhlbKWPpo3KMLZQ5WB5WLQRW1uq0= +github.com/Masterminds/vcs v1.13.1 h1:NL3G1X7/7xduQtA2sJLpVpfHTNBALVNSjob6KEjPXNQ= +github.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= +github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA= +github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/hcsshim v0.8.7 h1:ptnOoufxGSzauVTsdE+wMYnCWA301PdoN4xg5oRdZpg= +github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -49,56 +50,58 @@ github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/O github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= +github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 h1:zV3ejI06GQ59hwDQAvmK1qxOQGB3WuVTRoY0okPTAv0= +github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= -github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs= +github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bshuster-repo/logrus-logstash-hook v0.4.1 h1:pgAtgj+A31JBVtEHu2uHuEx0n+2ukqUJnS2vVe5pQNA= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= -github.com/bugsnag/bugsnag-go v1.5.0 h1:tP8hiPv1pGGW3LA6LKy5lW6WG+y9J2xWUdPd3WC452k= -github.com/bugsnag/bugsnag-go v1.5.0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= -github.com/bugsnag/panicwrap v1.2.0 h1:OzrKrRvXis8qEvOkfcxNcYbOd2O7xXS2nnKMEMABFQA= -github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= -github.com/cespare/xxhash/v2 v2.1.0 h1:yTUvW7Vhb89inJ+8irsUqiWjh8iT6sQPZiQzI6ReGkA= -github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM= -github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8= +github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng= +github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= 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/containerd/containerd v1.3.0-beta.2.0.20190823190603-4a2f61c4f2b4 h1:aMyA5J7j6D07U7pf8BFEY67BKoDcz0zWleAbQj3zVng= -github.com/containerd/containerd v1.3.0-beta.2.0.20190823190603-4a2f61c4f2b4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.0 h1:xjvXQWABwS2uiv3TWgQt5Uth60Gu86LTGZXMJkjc7rY= -github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/continuity v0.0.0-20181203112020-004b46473808 h1:4BX8f882bXEDKfWIf0wa8HRvpnBoPszJJXL+TVbBw4M= -github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s= +github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= +github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= +github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.2 h1:ForxmXkA6tPIvffbrDAcPUIB32QgXkt2XFj+F0UxetA= +github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41 h1:kIFnQBO7rQ0XkMe6xEwbybYHBEaWmh/f++laI6Emt7M= +github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY= +github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/coreos/etcd v3.3.10+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 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 h1:u9SHYsPQNyt5tgDm3YN7+9dYrpK96E5wFilTFWIDZOM= 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 h1:n2Ltr3SrfQlf/9nOna1DoGKxLx3qTSI8Ttl6Xrqp6mw= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= @@ -110,33 +113,33 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs 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/deislabs/oras v0.7.0 h1:RnDoFd3tQYODMiUqxgQ8JxlrlWL0/VMKIKRD01MmNYk= -github.com/deislabs/oras v0.7.0/go.mod h1:sqMKPG3tMyIX9xwXUBRLhZ24o+uT4y6jgBD2RzUTKDM= +github.com/deislabs/oras v0.8.1 h1:If674KraJVpujYR00rzdi0QAmW4BxzMJPVAZJKuhQ0c= +github.com/deislabs/oras v0.8.1/go.mod h1:Mx0rMSbBNaNfY9hjpccEnxkOqJL6KGjtxNHPLC4G4As= +github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= +github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= 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/dmcgowan/letsencrypt v0.0.0-20160928181947-1847a81d2087 h1:8AJxBXuUPcBVAvoz6fi3fpSyozBxvF2DgQ0f/yn9nkE= -github.com/dmcgowan/letsencrypt v0.0.0-20160928181947-1847a81d2087/go.mod h1:pRqVcLnLZeet910LRIAzx73MR48LxCRA84OcsivAkSs= -github.com/docker/cli v0.0.0-20190506213505-d88565df0c2d h1:qdD+BtyCE1XXpDyhvn0yZVcZOLILdj9Cw4pKu0kQbPQ= -github.com/docker/cli v0.0.0-20190506213505-d88565df0c2d/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= -github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker-credential-helpers v0.6.1 h1:Dq4iIfcM7cNtddhLVWe9h4QDjsi4OER3Z8voPu/I52g= -github.com/docker/docker-credential-helpers v0.6.1/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= +github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492 h1:FwssHbCDJD025h+BchanCwE1Q8fyMgqDr2mOQAWOLGw= +github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v0.0.0-20191216044856-a8371794149d h1:jC8tT/S0OGx2cswpeUTn4gOIea8P08lD3VFQT0cOZ50= +github.com/docker/distribution v0.0.0-20191216044856-a8371794149d/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= +github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce h1:KXS1Jg+ddGcWA8e1N7cupxaHHZhit5rB9tfDU+mfjyY= +github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ= +github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82 h1:X0fj836zx99zFu83v/M79DuBn84IL/Syx1SY6Y5ZEMA= -github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= -github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk= +github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916 h1:yWHOI+vFjEsAakUTSrtqc/SAHrhSkmn48pqjidZX3QA= +github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= -github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= +github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= -github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c h1:ZfSZ3P3BedhKGUhzj7BQlPSU4OvT6tfOKe3DVHzOA7s= -github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/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/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M= @@ -144,116 +147,95 @@ github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkg 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/emicklei/go-restful v2.11.1+incompatible h1:CjKsv3uWcCMvySPQYKxO8XX3f9zD4FeZRsW4G0B4ffE= -github.com/emicklei/go-restful v2.11.1+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 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 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc= -github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7 h1:LofdAjjjqCSXMwLGgOgnE+rdPuvX9DxCqaHwKy7i/ko= +github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 h1:DujepqpGd1hyOd7aW59XpK7Qymp8iy83xq74fLr21is= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/go-inf/inf v0.9.1 h1:F4sloU4SED74gTeM3mWLrf8yyMAgVCV0puw3vhtKWrk= -github.com/go-inf/inf v0.9.1/go.mod h1:ZWwB6rTV+0pO94RdIMKue59tExzQp6/pj/BMuPQkXaA= +github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= -github.com/go-openapi/analysis v0.19.2 h1:ophLETFestFZHk3ji7niPEL4d466QjW+0Tdg5VyDq7E= github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= -github.com/go-openapi/errors v0.19.2 h1:a2kIyV3w+OS3S97zxUndRVD46+FhGOUBDFY7nmu4CsY= github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.19.2 h1:rf5ArTHmIJxyV5Oiks+Su0mUens1+AjpkPoWr5xFRcI= github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk= github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= -github.com/go-openapi/runtime v0.19.0 h1:sU6pp4dSV2sGlNKKyHxZzi1m1kG4WnYtWcJ+HYbygjE= github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.19.2 h1:SStNd1jRcYtfKCN7R0laGNs80WYYvn5CbBjM2sOmCrE= github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= +github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo= -github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= -github.com/go-openapi/strfmt v0.19.0 h1:0Dn9qy1G9+UJfRU7TR8bmdGxb4uifB7HNrJjOnV0yPk= github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= 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 h1:ky5l57HjyVRrsJfd2+Ro5Z9PjGuKbsmftwyMtk8H7js= 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-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc= github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= -github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= 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.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -264,10 +246,9 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -277,32 +258,29 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d 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/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA= -github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= -github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U= -github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33 h1:893HsJqtxp9z1SF76gg6hY70hRY1wVlTSnC/h1yUDCo= +github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I= +github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gosuri/uitable v0.0.1 h1:M9sMNgSZPyAu1FJZJLpJ16ofL8q5ko2EDUkICsynvlY= -github.com/gosuri/uitable v0.0.1/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= +github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= +github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= +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/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f h1:ShTPMJQes6tubcjzGMODIVG5hlrCeImaBnZzKF2N8SM= -github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= 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 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= -github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -311,22 +289,19 @@ github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63 github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= -github.com/imdario/mergo v0.3.8/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/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= 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 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 h1:PJPDf8OUfOK1bb/NeTKd4f1QXZItOX389VN3B6qC8ro= -github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -346,33 +321,31 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= +github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-runewidth v0.0.2 h1:UnlwIPBGaTZfPQ6T1IGzPI0EkYAQmT9fAEJ/poFC63o= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-shellwords v1.0.5 h1:JhhFTIOslh5ZsPrpa3Wdg8bF0WI3b44EMblmU9wIsXc= -github.com/mattn/go-shellwords v1.0.5/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-shellwords v1.0.9 h1:eaB5JspOwiKKcHdqcjbfe5lA9cNn/4NRRtddXJCimqk= +github.com/mattn/go-shellwords v1.0.9/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v0.0.0-20181005163659-0d29b283ac0f h1:wVzAD6PG9MIDNQMZ6zc2YpzE/9hhJ3EN+b+a4B1thVs= -github.com/miekg/dns v0.0.0-20181005163659-0d29b283ac0f/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f h1:2+myh5ml7lgEU/51gbeLHfKGNfgEQQIWrlbdaOsidbQ= +github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309 h1:cvy4lBOYN3gKfKj8Lzz5Q9TfviP+L7koMHY7SvkyTKs= -github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -380,13 +353,13 @@ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lN github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE= -github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= 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 h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -395,50 +368,47 @@ github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= 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 v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= +github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/phayes/freeport v0.0.0-20171002181615-b8543db493a5 h1:rZQtoozkfsiNs36c7Tdv/gyGNzD1X1XWKO8rptVNZuM= -github.com/phayes/freeport v0.0.0-20171002181615-b8543db493a5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= +github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= +github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740= -github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI= -github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= +github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190129233650-316cf8ccfec5 h1:Etei0Wx6pooT/DeOKcGTr1M/01ggz95Ajq8BBwCOKBU= -github.com/prometheus/procfs v0.0.0-20190129233650-316cf8ccfec5/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8= github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= @@ -446,23 +416,28 @@ github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uY github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/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-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= 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= @@ -472,32 +447,30 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= 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/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8 h1:ndzgwNDnKIqyCvHTXaCqh9KlOWKvBry6nuXMJmonVsE= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xeipuuv/gojsonschema v1.1.0 h1:ngVtJC9TY/lg0AA/1k48FYhBrhRoFlEmWzsehpNAaZg= github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= -github.com/xenolf/lego v0.0.0-20160613233155-a9d8cec0e656/go.mod h1:fwiGnfsIjG7OHPfOvgK7Y/Qo6+2Ox0iozjNTkZICKbY= -github.com/xenolf/lego v0.3.2-0.20160613233155-a9d8cec0e656 h1:BTvU+npm3/yjuBd53EvgiFLl5+YLikf2WvHsjRQ4KrY= -github.com/xenolf/lego v0.3.2-0.20160613233155-a9d8cec0e656/go.mod h1:fwiGnfsIjG7OHPfOvgK7Y/Qo6+2Ox0iozjNTkZICKbY= 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/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940 h1:p7OofyZ509h8DmPLh8Hn+EIIZm/xYhdZHJ9GnXHdr6U= -github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= -github.com/yvasiyarov/gorelic v0.0.6 h1:qMJQYPNdtJ7UNYHjX38KXZtltKTqimMuoQjNnSVIuJg= -github.com/yvasiyarov/gorelic v0.0.6/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= +github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= +github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= +github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE= +github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -506,27 +479,27 @@ go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 h1:0hQKqeLdqlt5iIwVOBErRisrHJAN57yOiPRQItI20fU= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191028145041-f83a4685e152 h1:ZC1Xn5A1nlpSmQCIva4bZ3ob3lmhYIefc+GU+DLg1Ow= -golang.org/x/crypto v0.0.0-20191028145041-f83a4685e152/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U= +golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/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-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -537,23 +510,21 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/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-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 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-20191028085509-fe3aa8a45271 h1:N66aaryRB3Ax92gH0v3hp1QYZ3zWWCCUR/j8Ifh45Ss= -golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= @@ -561,10 +532,10 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= +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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -578,25 +549,23 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191028164358-195ce5e7f934 h1:u/E0NqCIWRDAo9WCFo6Ko49njPFDLSd3z+X1HgWDMpE= -golang.org/x/sys v0.0.0-20191028164358-195ce5e7f934/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/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.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 h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -607,82 +576,80 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485 h1:OB/uP/Puiu5vS5QMRPrXCDWUPb+kt8f1KW8oQzFejQw= +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= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= +google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190128161407-8ac453e89fca/go.mod h1:L3J43x8/uS+qIUoksaLKe6OS3nUKxOKuIFz1sl2/jx4= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7 h1:ZUjXAXmrAyrmmCPHgCA/vChHcpsX27MZ3yBonD/z1KE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6 h1:UXl+Zk3jqqcbEVV7ace5lrt4YdA4tXiz3f/KbmD29Vo= -google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= 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-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= +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.v1 v1.1.2 h1:/5jmADZB+RiKtZGr4HxsEFOEfbfsjTKsVnqpThUpE30= -gopkg.in/square/go-jose.v1 v1.1.2/go.mod h1:QpYS+a4WhS+DTlyQIi6Ka7MS3SuR9a055rgXNEe6EiA= -gopkg.in/square/go-jose.v2 v2.2.2 h1:orlkJ3myw8CN1nVQHBFfloD+L3egixIa4FvUP6RosSA= 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.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.17.1 h1:i46MidoDOE9tvQ0TTEYggf3ka/pziP1+tHI/GFVeJao= -k8s.io/api v0.17.1/go.mod h1:zxiAc5y8Ngn4fmhWUtSxuUlkfz1ixT7j9wESokELzOg= -k8s.io/apiextensions-apiserver v0.17.1 h1:Gw6zQgmKyyNrFMtVpRBNEKE8p35sDBI7Tq1ImxGS+zU= -k8s.io/apiextensions-apiserver v0.17.1/go.mod h1:DRIFH5x3jalE4rE7JP0MQKby9zdYk9lUJQuMmp+M/L0= -k8s.io/apimachinery v0.17.1 h1:zUjS3szTxoUjTDYNvdFkYt2uMEXLcthcbp+7uZvWhYM= -k8s.io/apimachinery v0.17.1/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= -k8s.io/apiserver v0.17.1/go.mod h1:BQEUObJv8H6ZYO7DeKI5vb50tjk6paRJ4ZhSyJsiSco= -k8s.io/cli-runtime v0.17.1 h1:VoZRWJNRyrxuM5SIRozYhT/EtcZ6jiS+KBCxRw66p1g= -k8s.io/cli-runtime v0.17.1/go.mod h1:e5847Iy85W9uWH3rZofXTG/9nOUyGKGTVnObYF7zSik= -k8s.io/client-go v0.17.1 h1:LbbuZ5tI7OYx4et5DfRFcJuoojvpYO0c7vps2rgJsHY= -k8s.io/client-go v0.17.1/go.mod h1:HZtHJSC/VuSHcETN9QA5QDZky1tXiYrkF/7t7vRpO1A= -k8s.io/code-generator v0.17.1/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= -k8s.io/component-base v0.17.1 h1:lK/lUzZZQK+DlH0XD+gq610OUEmjWOyDuUYOTGetw10= -k8s.io/component-base v0.17.1/go.mod h1:LrBPZkXtlvGjBzDJa0+b7E5Ij4VoAAKrOGudRC5z2eY= +k8s.io/api v0.17.2 h1:NF1UFXcKN7/OOv1uxdRz3qfra8AHsPav5M93hlV9+Dc= +k8s.io/api v0.17.2/go.mod h1:BS9fjjLc4CMuqfSO8vgbHPKMt5+SF0ET6u/RVDihTo4= +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.17.2 h1:hwDQQFbdRlpnnsR64Asdi55GyCaIP/3WQpMmbNBeWr4= +k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= +k8s.io/apiserver v0.17.2/go.mod h1:lBmw/TtQdtxvrTk0e2cgtOxHizXI+d0mmGQURIHQZlo= +k8s.io/cli-runtime v0.17.2 h1:YH4txSplyGudvxjhAJeHEtXc7Tr/16clKGfN076ydGk= +k8s.io/cli-runtime v0.17.2/go.mod h1:aa8t9ziyQdbkuizkNLAw3qe3srSyWh9zlSB7zTqRNPI= +k8s.io/client-go v0.17.2 h1:ndIfkfXEGrNhLIgkr0+qhRguSD3u6DCmonepn1O6NYc= +k8s.io/client-go v0.17.2/go.mod h1:QAzRgsa0C2xl4/eVpeVAZMvikCn8Nm81yqVx3Kk9XYI= +k8s.io/code-generator v0.17.2/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= +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 h1:ZY6yclUKVbZ+SdWnkfY+Je5vrMpKOxmGeKRbsXVmqYM= 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= @@ -690,9 +657,10 @@ 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= -k8s.io/kubectl v0.17.1 h1:+gI5hPZVEXN5wWybrzX3tu3f9af54sUNcALhg86upCY= -k8s.io/kubectl v0.17.1/go.mod h1:ZmbAdEQm+SLA/3s3eWJ3g+liXb5eT6mA85jYj52LMXw= -k8s.io/metrics v0.17.1/go.mod h1:dphDhzjA1KR/nQXtXEQzoQyQXk5ViSJO85Ky8QKwBPM= +k8s.io/kubectl v0.17.2 h1:QZR8Q6lWiVRjwKslekdbN5WPMp53dS/17j5e+oi5XVU= +k8s.io/kubectl v0.17.2/go.mod h1:y4rfLV0n6aPmvbRCqZQjvOp3ezxsFgpqL+zF5jH/lxk= +k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= +k8s.io/metrics v0.17.2/go.mod h1:3TkNHET4ROd+NfzNxkjoVfQ0Ob4iZnaHmSEA4vYpwLw= 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= diff --git a/internal/experimental/registry/client.go b/internal/experimental/registry/client.go index d52d9f3e0..f664c9f38 100644 --- a/internal/experimental/registry/client.go +++ b/internal/experimental/registry/client.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "io/ioutil" + "net/http" "sort" auth "github.com/deislabs/oras/pkg/auth/docker" @@ -69,7 +70,7 @@ func NewClient(opts ...ClientOption) (*Client, error) { } } if client.resolver == nil { - resolver, err := client.authorizer.Resolver(context.Background()) + resolver, err := client.authorizer.Resolver(context.Background(), http.DefaultClient, false) if err != nil { return nil, err } diff --git a/internal/experimental/registry/client_test.go b/internal/experimental/registry/client_test.go index 0861c8984..33799f5fa 100644 --- a/internal/experimental/registry/client_test.go +++ b/internal/experimental/registry/client_test.go @@ -23,6 +23,7 @@ import ( "io" "io/ioutil" "net" + "net/http" "os" "path/filepath" "testing" @@ -66,7 +67,7 @@ func (suite *RegistryClientTestSuite) SetupSuite() { client, err := auth.NewClient(credentialsFile) suite.Nil(err, "no error creating auth client") - resolver, err := client.Resolver(context.Background()) + resolver, err := client.Resolver(context.Background(), http.DefaultClient, false) suite.Nil(err, "no error creating resolver") // create cache diff --git a/pkg/action/action_test.go b/pkg/action/action_test.go index a5baec97d..df6a48e7f 100644 --- a/pkg/action/action_test.go +++ b/pkg/action/action_test.go @@ -19,6 +19,7 @@ import ( "context" "flag" "io/ioutil" + "net/http" "path/filepath" "testing" @@ -45,7 +46,7 @@ func actionConfigFixture(t *testing.T) *Configuration { t.Fatal(err) } - resolver, err := client.Resolver(context.Background()) + resolver, err := client.Resolver(context.Background(), http.DefaultClient, false) if err != nil { t.Fatal(err) }