Merge branch 'main' into 11983

Signed-off-by: BenHesketh21 <55387271+BenHesketh21@users.noreply.github.com>
pull/12300/head
BenHesketh21 2 years ago committed by GitHub
commit cc0d5d1cae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -5,6 +5,16 @@ updates:
directory: "/" directory: "/"
schedule: schedule:
interval: "daily" interval: "daily"
groups:
k8s.io:
patterns:
- "k8s.io/api"
- "k8s.io/apiextensions-apiserver"
- "k8s.io/apimachinery"
- "k8s.io/apiserver"
- "k8s.io/cli-runtime"
- "k8s.io/client-go"
- "k8s.io/kubectl"
- package-ecosystem: "github-actions" - package-ecosystem: "github-actions"
directory: "/" directory: "/"
schedule: schedule:

@ -0,0 +1,18 @@
name: Publish Release Assets to Asset Transparency Log
on:
release:
types: [published, created, edited, released]
jobs:
github_release_asset_transparency_log_publish_job:
runs-on: ubuntu-latest
name: Publish GitHub release asset digests to https://beta-asset.transparencylog.net
steps:
- name: Gather URLs from GitHub release and publish
id: asset-transparency
uses: transparencylog/github-releases-asset-transparency-verify-action@c77874b4514ae4003994ece9582675195fe012e2 # v11
- name: List verified and published URLs
run: echo "Verified URLs ${{ steps.asset-transparency.outputs.verified }}"
- name: List failed URLs
run: echo "Failed URLs ${{ steps.asset-transparency.outputs.failed }}"

@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout source code - name: Checkout source code
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # pin@v3.5.3 uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # pin@v3.6.0
- name: Setup Go - name: Setup Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # pin@4.1.0 uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # pin@4.1.0
with: with:

@ -35,11 +35,11 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # pin@v3.5.3 uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # pin@v3.6.0
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@5b6282e01c62d02e720b81eb8a51204f527c3624 # pinv2.21.3 uses: github/codeql-action/init@6a28655e3dcb49cb0840ea372fd6d17733edd8a4 # pinv2.21.8
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # If you wish to specify custom queries, you can do so here or in a config file.
@ -50,7 +50,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@5b6282e01c62d02e720b81eb8a51204f527c3624 # pinv2.21.3 uses: github/codeql-action/autobuild@6a28655e3dcb49cb0840ea372fd6d17733edd8a4 # pinv2.21.8
# Command-line programs to run using the OS shell. # Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl # 📚 https://git.io/JvXDl
@ -64,4 +64,4 @@ jobs:
# make release # make release
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@5b6282e01c62d02e720b81eb8a51204f527c3624 # pinv2.21.3 uses: github/codeql-action/analyze@6a28655e3dcb49cb0840ea372fd6d17733edd8a4 # pinv2.21.8

@ -18,7 +18,8 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout source code - name: Checkout source code
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # pin@v3.5.3 uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # pin@v3.6.0
fetch-depth: 0
- name: Setup Go - name: Setup Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # pin@4.1.0 uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # pin@4.1.0
@ -32,6 +33,10 @@ jobs:
run: | run: |
make build-cross make build-cross
make dist checksum VERSION="${{ github.ref_name }}" make dist checksum VERSION="${{ github.ref_name }}"
- name: Set latest version
# Push the latest semver tag, excluding prerelease tags
git tag | sort -r --version-sort | grep '^v[0-9]' | grep -v '-' | head -n1 > _dist/helm-latest-version
- name: Upload Binaries - name: Upload Binaries
uses: bacongobbler/azure-blob-storage-upload@50f7d898b7697e864130ea04c303ca38b5751c50 # pin@3.0.0 uses: bacongobbler/azure-blob-storage-upload@50f7d898b7697e864130ea04c303ca38b5751c50 # pin@3.0.0
@ -49,7 +54,7 @@ jobs:
if: github.ref == 'refs/heads/main' if: github.ref == 'refs/heads/main'
steps: steps:
- name: Checkout source code - name: Checkout source code
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # pin@v3.5.3 uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # pin@v3.6.0
- name: Setup Go - name: Setup Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # pin@4.1.0 uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # pin@4.1.0

@ -11,6 +11,7 @@ triage:
- yxxhero - yxxhero
- zonggen - zonggen
- gjenkins8 - gjenkins8
- z4ce
emeritus: emeritus:
- adamreese - adamreese
- bacongobbler - bacongobbler

@ -39,7 +39,6 @@ If you want to use a package manager:
- [Homebrew](https://brew.sh/) users can use `brew install helm`. - [Homebrew](https://brew.sh/) users can use `brew install helm`.
- [Chocolatey](https://chocolatey.org/) users can use `choco install kubernetes-helm`. - [Chocolatey](https://chocolatey.org/) users can use `choco install kubernetes-helm`.
- [Scoop](https://scoop.sh/) users can use `scoop install helm`. - [Scoop](https://scoop.sh/) users can use `scoop install helm`.
- [GoFish](https://gofi.sh/) users can use `gofish install helm`.
- [Snapcraft](https://snapcraft.io/) users can use `snap install helm --classic` - [Snapcraft](https://snapcraft.io/) users can use `snap install helm --classic`
To rapidly get Helm up and running, start with the [Quick Start Guide](https://helm.sh/docs/intro/quickstart/). To rapidly get Helm up and running, start with the [Quick Start Guide](https://helm.sh/docs/intro/quickstart/).

@ -30,9 +30,9 @@ import (
) )
func TestCreateCmd(t *testing.T) { func TestCreateCmd(t *testing.T) {
defer ensure.HelmHome(t)() ensure.HelmHome(t)
cname := "testchart" cname := "testchart"
dir := ensure.TempDir(t) dir := t.TempDir()
defer testChdir(t, dir)() defer testChdir(t, dir)()
// Run a create // Run a create
@ -61,7 +61,7 @@ func TestCreateCmd(t *testing.T) {
} }
func TestCreateStarterCmd(t *testing.T) { func TestCreateStarterCmd(t *testing.T) {
defer ensure.HelmHome(t)() ensure.HelmHome(t)
cname := "testchart" cname := "testchart"
defer resetEnv()() defer resetEnv()()
os.MkdirAll(helmpath.CachePath(), 0755) os.MkdirAll(helmpath.CachePath(), 0755)
@ -127,7 +127,7 @@ func TestCreateStarterCmd(t *testing.T) {
func TestCreateStarterAbsoluteCmd(t *testing.T) { func TestCreateStarterAbsoluteCmd(t *testing.T) {
defer resetEnv()() defer resetEnv()()
defer ensure.HelmHome(t)() ensure.HelmHome(t)
cname := "testchart" cname := "testchart"
// Create a starter. // Create a starter.

@ -149,7 +149,7 @@ func TestDependencyUpdateCmd(t *testing.T) {
func TestDependencyUpdateCmd_DoNotDeleteOldChartsOnError(t *testing.T) { func TestDependencyUpdateCmd_DoNotDeleteOldChartsOnError(t *testing.T) {
defer resetEnv()() defer resetEnv()()
defer ensure.HelmHome(t)() ensure.HelmHome(t)
srv, err := repotest.NewTempServerWithCleanup(t, "testdata/testcharts/*.tgz") srv, err := repotest.NewTempServerWithCleanup(t, "testdata/testcharts/*.tgz")
if err != nil { if err != nil {
@ -206,6 +206,61 @@ func TestDependencyUpdateCmd_DoNotDeleteOldChartsOnError(t *testing.T) {
} }
} }
func TestDependencyUpdateCmd_WithRepoThatWasNotAdded(t *testing.T) {
srv := setupMockRepoServer(t)
srvForUnmanagedRepo := setupMockRepoServer(t)
defer srv.Stop()
defer srvForUnmanagedRepo.Stop()
dir := func(p ...string) string {
return filepath.Join(append([]string{srv.Root()}, p...)...)
}
chartname := "depup"
ch := createTestingMetadata(chartname, srv.URL())
chartDependency := &chart.Dependency{
Name: "signtest",
Version: "0.1.0",
Repository: srvForUnmanagedRepo.URL(),
}
ch.Metadata.Dependencies = append(ch.Metadata.Dependencies, chartDependency)
if err := chartutil.SaveDir(ch, dir()); err != nil {
t.Fatal(err)
}
_, out, err := executeActionCommand(
fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s", dir(chartname),
dir("repositories.yaml"), dir()),
)
if err != nil {
t.Logf("Output: %s", out)
t.Fatal(err)
}
// This is written directly to stdout, so we have to capture as is
if !strings.Contains(out, `Getting updates for unmanaged Helm repositories...`) {
t.Errorf("No unmanaged Helm repo used in test chartdependency or it doesnt cause the creation "+
"of an ad hoc repo index cache file\n%s", out)
}
}
func setupMockRepoServer(t *testing.T) *repotest.Server {
srv, err := repotest.NewTempServerWithCleanup(t, "testdata/testcharts/*.tgz")
if err != nil {
t.Fatal(err)
}
t.Logf("Listening on directory %s", srv.Root())
if err := srv.LinkIndices(); err != nil {
t.Fatal(err)
}
return srv
}
// createTestingMetadata creates a basic chart that depends on reqtest-0.1.0 // createTestingMetadata creates a basic chart that depends on reqtest-0.1.0
// //
// The baseURL can be used to point to a particular repository server. // The baseURL can be used to point to a particular repository server.

@ -33,6 +33,7 @@ get extended information about the release, including:
- The generated manifest file - The generated manifest file
- The notes provided by the chart of the release - The notes provided by the chart of the release
- The hooks associated with the release - The hooks associated with the release
- The metadata of the release
` `
func newGetCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { func newGetCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
@ -48,6 +49,7 @@ func newGetCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
cmd.AddCommand(newGetManifestCmd(cfg, out)) cmd.AddCommand(newGetManifestCmd(cfg, out))
cmd.AddCommand(newGetHooksCmd(cfg, out)) cmd.AddCommand(newGetHooksCmd(cfg, out))
cmd.AddCommand(newGetNotesCmd(cfg, out)) cmd.AddCommand(newGetNotesCmd(cfg, out))
cmd.AddCommand(newGetMetadataCmd(cfg, out))
return cmd return cmd
} }

@ -59,7 +59,7 @@ func newGetAllCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
return tpl(template, data, out) return tpl(template, data, out)
} }
return output.Table.Write(out, &statusPrinter{res, true, false, false}) return output.Table.Write(out, &statusPrinter{res, true, false, false, true})
}, },
} }

@ -0,0 +1,94 @@
/*
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"
"io"
"log"
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cli/output"
)
type metadataWriter struct {
metadata *action.Metadata
}
func newGetMetadataCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
var outfmt output.Format
client := action.NewGetMetadata(cfg)
cmd := &cobra.Command{
Use: "metadata RELEASE_NAME",
Short: "This command fetches metadata for a given release",
Args: require.ExactArgs(1),
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) != 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
}
return compListReleases(toComplete, args, cfg)
},
RunE: func(cmd *cobra.Command, args []string) error {
releaseMetadata, err := client.Run(args[0])
if err != nil {
return err
}
return outfmt.Write(out, &metadataWriter{releaseMetadata})
},
}
f := cmd.Flags()
f.IntVar(&client.Version, "revision", 0, "specify release revision")
err := cmd.RegisterFlagCompletionFunc("revision", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) == 1 {
return compListRevisions(toComplete, cfg, args[0])
}
return nil, cobra.ShellCompDirectiveNoFileComp
})
if err != nil {
log.Fatal(err)
}
bindOutputFlag(cmd, &outfmt)
return cmd
}
func (w metadataWriter) WriteTable(out io.Writer) error {
_, _ = fmt.Fprintf(out, "NAME: %v\n", w.metadata.Name)
_, _ = fmt.Fprintf(out, "CHART: %v\n", w.metadata.Chart)
_, _ = fmt.Fprintf(out, "VERSION: %v\n", w.metadata.Version)
_, _ = fmt.Fprintf(out, "APP_VERSION: %v\n", w.metadata.AppVersion)
_, _ = fmt.Fprintf(out, "NAMESPACE: %v\n", w.metadata.Namespace)
_, _ = fmt.Fprintf(out, "REVISION: %v\n", w.metadata.Revision)
_, _ = fmt.Fprintf(out, "STATUS: %v\n", w.metadata.Status)
_, _ = fmt.Fprintf(out, "DEPLOYED_AT: %v\n", w.metadata.DeployedAt)
return nil
}
func (w metadataWriter) WriteJSON(out io.Writer) error {
return output.EncodeJSON(out, w.metadata)
}
func (w metadataWriter) WriteYAML(out io.Writer) error {
return output.EncodeYAML(out, w.metadata)
}

@ -0,0 +1,66 @@
/*
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"
"helm.sh/helm/v3/pkg/release"
)
func TestGetMetadataCmd(t *testing.T) {
tests := []cmdTestCase{{
name: "get metadata with a release",
cmd: "get metadata thomas-guide",
golden: "output/get-metadata.txt",
rels: []*release.Release{release.Mock(&release.MockReleaseOptions{Name: "thomas-guide"})},
}, {
name: "get metadata requires release name arg",
cmd: "get metadata",
golden: "output/get-metadata-args.txt",
rels: []*release.Release{release.Mock(&release.MockReleaseOptions{Name: "thomas-guide"})},
wantError: true,
}, {
name: "get metadata to json",
cmd: "get metadata thomas-guide --output json",
golden: "output/get-metadata.json",
rels: []*release.Release{release.Mock(&release.MockReleaseOptions{Name: "thomas-guide"})},
}, {
name: "get metadata to yaml",
cmd: "get metadata thomas-guide --output yaml",
golden: "output/get-metadata.yaml",
rels: []*release.Release{release.Mock(&release.MockReleaseOptions{Name: "thomas-guide"})},
}}
runTestCmd(t, tests)
}
func TestGetMetadataCompletion(t *testing.T) {
checkReleaseCompletion(t, "get metadata", false)
}
func TestGetMetadataRevisionCompletion(t *testing.T) {
revisionFlagCompletionTest(t, "get metadata")
}
func TestGetMetadataOutputCompletion(t *testing.T) {
outputFlagCompletionTest(t, "get metadata")
}
func TestGetMetadataFileCompletion(t *testing.T) {
checkFileCompletion(t, "get metadata", false)
checkFileCompletion(t, "get metadata myrelease", false)
}

@ -154,7 +154,7 @@ func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
return errors.Wrap(err, "INSTALLATION FAILED") return errors.Wrap(err, "INSTALLATION FAILED")
} }
return outfmt.Write(out, &statusPrinter{rel, settings.Debug, false, false}) return outfmt.Write(out, &statusPrinter{rel, settings.Debug, false, false, false})
}, },
} }
@ -190,6 +190,7 @@ func addInstallFlags(cmd *cobra.Command, f *pflag.FlagSet, client *action.Instal
f.BoolVar(&client.Atomic, "atomic", false, "if set, the installation process deletes the installation on failure. The --wait flag will be set automatically if --atomic is used") f.BoolVar(&client.Atomic, "atomic", false, "if set, the installation process deletes the installation on failure. 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.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") f.BoolVar(&client.SubNotes, "render-subchart-notes", false, "if set, render subchart notes along with the parent")
f.StringToStringVarP(&client.Labels, "labels", "l", nil, "Labels that would be added to release metadata. Should be divided by comma.")
f.BoolVar(&client.EnableDNS, "enable-dns", false, "enable DNS lookups when rendering templates") f.BoolVar(&client.EnableDNS, "enable-dns", false, "enable DNS lookups when rendering templates")
addValueOptionsFlags(f, valueOpts) addValueOptionsFlags(f, valueOpts)
addChartPathOptionsFlags(f, &client.ChartPathOptions) addChartPathOptionsFlags(f, &client.ChartPathOptions)

@ -128,7 +128,8 @@ func callPluginExecutable(pluginName string, main string, argv []string, out io.
env = append(env, fmt.Sprintf("%s=%s", k, v)) env = append(env, fmt.Sprintf("%s=%s", k, v))
} }
prog := exec.Command(main, argv...) mainCmdExp := os.ExpandEnv(main)
prog := exec.Command(mainCmdExp, argv...)
prog.Env = env prog.Env = env
prog.Stdin = os.Stdin prog.Stdin = os.Stdin
prog.Stdout = out prog.Stdout = out

@ -23,7 +23,6 @@ import (
"strings" "strings"
"testing" "testing"
"helm.sh/helm/v3/internal/test/ensure"
"helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader" "helm.sh/helm/v3/pkg/chart/loader"
) )
@ -111,7 +110,7 @@ func TestPackage(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
cachePath := ensure.TempDir(t) cachePath := t.TempDir()
defer testChdir(t, cachePath)() defer testChdir(t, cachePath)()
if err := os.MkdirAll("toot", 0777); err != nil { if err := os.MkdirAll("toot", 0777); err != nil {
@ -170,7 +169,7 @@ func TestSetAppVersion(t *testing.T) {
var ch *chart.Chart var ch *chart.Chart
expectedAppVersion := "app-version-foo" expectedAppVersion := "app-version-foo"
chartToPackage := "testdata/testcharts/alpine" chartToPackage := "testdata/testcharts/alpine"
dir := ensure.TempDir(t) dir := t.TempDir()
cmd := fmt.Sprintf("package %s --destination=%s --app-version=%s", chartToPackage, dir, expectedAppVersion) cmd := fmt.Sprintf("package %s --destination=%s --app-version=%s", chartToPackage, dir, expectedAppVersion)
_, output, err := executeActionCommand(cmd) _, output, err := executeActionCommand(cmd)
if err != nil { if err != nil {

@ -161,6 +161,81 @@ func TestLoadPlugins(t *testing.T) {
} }
} }
func TestLoadPluginsWithSpace(t *testing.T) {
settings.PluginsDirectory = "testdata/helm home with space/helm/plugins"
settings.RepositoryConfig = "testdata/helm home with space/helm/repositories.yaml"
settings.RepositoryCache = "testdata/helm home with space/helm/repository"
var (
out bytes.Buffer
cmd cobra.Command
)
loadPlugins(&cmd, &out)
envs := strings.Join([]string{
"fullenv",
"testdata/helm home with space/helm/plugins/fullenv",
"testdata/helm home with space/helm/plugins",
"testdata/helm home with space/helm/repositories.yaml",
"testdata/helm home with space/helm/repository",
os.Args[0],
}, "\n")
// Test that the YAML file was correctly converted to a command.
tests := []struct {
use string
short string
long string
expect string
args []string
code int
}{
{"fullenv", "show env vars", "show all env vars", envs + "\n", []string{}, 0},
}
plugins := cmd.Commands()
if len(plugins) != len(tests) {
t.Fatalf("Expected %d plugins, got %d", len(tests), len(plugins))
}
for i := 0; i < len(plugins); i++ {
out.Reset()
tt := tests[i]
pp := plugins[i]
if pp.Use != tt.use {
t.Errorf("%d: Expected Use=%q, got %q", i, tt.use, pp.Use)
}
if pp.Short != tt.short {
t.Errorf("%d: Expected Use=%q, got %q", i, tt.short, pp.Short)
}
if pp.Long != tt.long {
t.Errorf("%d: Expected Use=%q, got %q", i, tt.long, pp.Long)
}
// Currently, plugins assume a Linux subsystem. Skip the execution
// tests until this is fixed
if runtime.GOOS != "windows" {
if err := pp.RunE(pp, tt.args); err != nil {
if tt.code > 0 {
perr, ok := err.(pluginError)
if !ok {
t.Errorf("Expected %s to return pluginError: got %v(%T)", tt.use, err, err)
}
if perr.code != tt.code {
t.Errorf("Expected %s to return %d: got %d", tt.use, tt.code, perr.code)
}
} else {
t.Errorf("Error running %s: %+v", tt.use, err)
}
}
if out.String() != tt.expect {
t.Errorf("Expected %s to output:\n%s\ngot\n%s", tt.use, tt.expect, out.String())
}
}
}
}
type staticCompletionDetails struct { type staticCompletionDetails struct {
use string use string
validArgs []string validArgs []string

@ -72,7 +72,7 @@ func newReleaseTestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command
return runErr return runErr
} }
if err := outfmt.Write(out, &statusPrinter{rel, settings.Debug, false, false}); err != nil { if err := outfmt.Write(out, &statusPrinter{rel, settings.Debug, false, false, false}); err != nil {
return err return err
} }

@ -27,7 +27,6 @@ import (
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
"helm.sh/helm/v3/internal/test/ensure"
"helm.sh/helm/v3/pkg/helmpath" "helm.sh/helm/v3/pkg/helmpath"
"helm.sh/helm/v3/pkg/helmpath/xdg" "helm.sh/helm/v3/pkg/helmpath/xdg"
"helm.sh/helm/v3/pkg/repo" "helm.sh/helm/v3/pkg/repo"
@ -48,7 +47,7 @@ func TestRepoAddCmd(t *testing.T) {
} }
defer srv2.Stop() defer srv2.Stop()
tmpdir := filepath.Join(ensure.TempDir(t), "path-component.yaml/data") tmpdir := filepath.Join(t.TempDir(), "path-component.yaml/data")
err = os.MkdirAll(tmpdir, 0777) err = os.MkdirAll(tmpdir, 0777)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -88,7 +87,7 @@ func TestRepoAdd(t *testing.T) {
} }
defer ts.Stop() defer ts.Stop()
rootDir := ensure.TempDir(t) rootDir := t.TempDir()
repoFile := filepath.Join(rootDir, "repositories.yaml") repoFile := filepath.Join(rootDir, "repositories.yaml")
const testRepoName = "test-name" const testRepoName = "test-name"
@ -145,8 +144,8 @@ func TestRepoAddCheckLegalName(t *testing.T) {
const testRepoName = "test-hub/test-name" const testRepoName = "test-hub/test-name"
rootDir := ensure.TempDir(t) rootDir := t.TempDir()
repoFile := filepath.Join(ensure.TempDir(t), "repositories.yaml") repoFile := filepath.Join(t.TempDir(), "repositories.yaml")
o := &repoAddOptions{ o := &repoAddOptions{
name: testRepoName, name: testRepoName,
@ -170,25 +169,25 @@ func TestRepoAddCheckLegalName(t *testing.T) {
func TestRepoAddConcurrentGoRoutines(t *testing.T) { func TestRepoAddConcurrentGoRoutines(t *testing.T) {
const testName = "test-name" const testName = "test-name"
repoFile := filepath.Join(ensure.TempDir(t), "repositories.yaml") repoFile := filepath.Join(t.TempDir(), "repositories.yaml")
repoAddConcurrent(t, testName, repoFile) repoAddConcurrent(t, testName, repoFile)
} }
func TestRepoAddConcurrentDirNotExist(t *testing.T) { func TestRepoAddConcurrentDirNotExist(t *testing.T) {
const testName = "test-name-2" const testName = "test-name-2"
repoFile := filepath.Join(ensure.TempDir(t), "foo", "repositories.yaml") repoFile := filepath.Join(t.TempDir(), "foo", "repositories.yaml")
repoAddConcurrent(t, testName, repoFile) repoAddConcurrent(t, testName, repoFile)
} }
func TestRepoAddConcurrentNoFileExtension(t *testing.T) { func TestRepoAddConcurrentNoFileExtension(t *testing.T) {
const testName = "test-name-3" const testName = "test-name-3"
repoFile := filepath.Join(ensure.TempDir(t), "repositories") repoFile := filepath.Join(t.TempDir(), "repositories")
repoAddConcurrent(t, testName, repoFile) repoAddConcurrent(t, testName, repoFile)
} }
func TestRepoAddConcurrentHiddenFile(t *testing.T) { func TestRepoAddConcurrentHiddenFile(t *testing.T) {
const testName = "test-name-4" const testName = "test-name-4"
repoFile := filepath.Join(ensure.TempDir(t), ".repositories") repoFile := filepath.Join(t.TempDir(), ".repositories")
repoAddConcurrent(t, testName, repoFile) repoAddConcurrent(t, testName, repoFile)
} }
@ -254,7 +253,7 @@ func TestRepoAddWithPasswordFromStdin(t *testing.T) {
t.Errorf("unexpected error, got '%v'", err) t.Errorf("unexpected error, got '%v'", err)
} }
tmpdir := ensure.TempDir(t) tmpdir := t.TempDir()
repoFile := filepath.Join(tmpdir, "repositories.yaml") repoFile := filepath.Join(tmpdir, "repositories.yaml")
store := storageFixture() store := storageFixture()

@ -43,6 +43,7 @@ type repoIndexOptions struct {
dir string dir string
url string url string
merge string merge string
json bool
} }
func newRepoIndexCmd(out io.Writer) *cobra.Command { func newRepoIndexCmd(out io.Writer) *cobra.Command {
@ -70,6 +71,7 @@ func newRepoIndexCmd(out io.Writer) *cobra.Command {
f := cmd.Flags() f := cmd.Flags()
f.StringVar(&o.url, "url", "", "url of chart repository") f.StringVar(&o.url, "url", "", "url of chart repository")
f.StringVar(&o.merge, "merge", "", "merge the generated index into the given index") f.StringVar(&o.merge, "merge", "", "merge the generated index into the given index")
f.BoolVar(&o.json, "json", false, "output in JSON format")
return cmd return cmd
} }
@ -80,10 +82,10 @@ func (i *repoIndexOptions) run(out io.Writer) error {
return err return err
} }
return index(path, i.url, i.merge) return index(path, i.url, i.merge, i.json)
} }
func index(dir, url, mergeTo string) error { func index(dir, url, mergeTo string, json bool) error {
out := filepath.Join(dir, "index.yaml") out := filepath.Join(dir, "index.yaml")
i, err := repo.IndexDirectory(dir, url) i, err := repo.IndexDirectory(dir, url)
@ -95,7 +97,7 @@ func index(dir, url, mergeTo string) error {
var i2 *repo.IndexFile var i2 *repo.IndexFile
if _, err := os.Stat(mergeTo); os.IsNotExist(err) { if _, err := os.Stat(mergeTo); os.IsNotExist(err) {
i2 = repo.NewIndexFile() i2 = repo.NewIndexFile()
i2.WriteFile(mergeTo, 0644) writeIndexFile(i2, mergeTo, json)
} else { } else {
i2, err = repo.LoadIndexFile(mergeTo) i2, err = repo.LoadIndexFile(mergeTo)
if err != nil { if err != nil {
@ -105,5 +107,12 @@ func index(dir, url, mergeTo string) error {
i.Merge(i2) i.Merge(i2)
} }
i.SortEntries() i.SortEntries()
return writeIndexFile(i, out, json)
}
func writeIndexFile(i *repo.IndexFile, out string, json bool) error {
if json {
return i.WriteJSONFile(out, 0644)
}
return i.WriteFile(out, 0644) return i.WriteFile(out, 0644)
} }

@ -18,18 +18,18 @@ package main
import ( import (
"bytes" "bytes"
"encoding/json"
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
"helm.sh/helm/v3/internal/test/ensure"
"helm.sh/helm/v3/pkg/repo" "helm.sh/helm/v3/pkg/repo"
) )
func TestRepoIndexCmd(t *testing.T) { func TestRepoIndexCmd(t *testing.T) {
dir := ensure.TempDir(t) dir := t.TempDir()
comp := filepath.Join(dir, "compressedchart-0.1.0.tgz") comp := filepath.Join(dir, "compressedchart-0.1.0.tgz")
if err := linkOrCopy("testdata/testcharts/compressedchart-0.1.0.tgz", comp); err != nil { if err := linkOrCopy("testdata/testcharts/compressedchart-0.1.0.tgz", comp); err != nil {
@ -68,6 +68,28 @@ func TestRepoIndexCmd(t *testing.T) {
t.Errorf("expected %q, got %q", expectedVersion, vs[0].Version) t.Errorf("expected %q, got %q", expectedVersion, vs[0].Version)
} }
b, err := os.ReadFile(destIndex)
if err != nil {
t.Fatal(err)
}
if json.Valid(b) {
t.Error("did not expect index file to be valid json")
}
// Test with `--json`
c.ParseFlags([]string{"--json", "true"})
if err := c.RunE(c, []string{dir}); err != nil {
t.Error(err)
}
if b, err = os.ReadFile(destIndex); err != nil {
t.Fatal(err)
}
if !json.Valid(b) {
t.Error("index file is not valid json")
}
// Test with `--merge` // Test with `--merge`
// Remove first two charts. // Remove first two charts.

@ -24,7 +24,6 @@ import (
"strings" "strings"
"testing" "testing"
"helm.sh/helm/v3/internal/test/ensure"
"helm.sh/helm/v3/pkg/helmpath" "helm.sh/helm/v3/pkg/helmpath"
"helm.sh/helm/v3/pkg/repo" "helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v3/pkg/repo/repotest" "helm.sh/helm/v3/pkg/repo/repotest"
@ -37,7 +36,7 @@ func TestRepoRemove(t *testing.T) {
} }
defer ts.Stop() defer ts.Stop()
rootDir := ensure.TempDir(t) rootDir := t.TempDir()
repoFile := filepath.Join(rootDir, "repositories.yaml") repoFile := filepath.Join(rootDir, "repositories.yaml")
const testRepoName = "test-name" const testRepoName = "test-name"
@ -169,7 +168,7 @@ func TestRepoRemoveCompletion(t *testing.T) {
} }
defer ts.Stop() defer ts.Stop()
rootDir := ensure.TempDir(t) rootDir := t.TempDir()
repoFile := filepath.Join(rootDir, "repositories.yaml") repoFile := filepath.Join(rootDir, "repositories.yaml")
repoCache := filepath.Join(rootDir, "cache/") repoCache := filepath.Join(rootDir, "cache/")

@ -102,10 +102,9 @@ func TestUpdateCmdInvalid(t *testing.T) {
} }
func TestUpdateCustomCacheCmd(t *testing.T) { func TestUpdateCustomCacheCmd(t *testing.T) {
rootDir := ensure.TempDir(t) rootDir := t.TempDir()
cachePath := filepath.Join(rootDir, "updcustomcache") cachePath := filepath.Join(rootDir, "updcustomcache")
os.Mkdir(cachePath, os.ModePerm) os.Mkdir(cachePath, os.ModePerm)
defer os.RemoveAll(cachePath)
ts, err := repotest.NewTempServerWithCleanup(t, "testdata/testserver/*.*") ts, err := repotest.NewTempServerWithCleanup(t, "testdata/testserver/*.*")
if err != nil { if err != nil {
@ -129,7 +128,7 @@ func TestUpdateCustomCacheCmd(t *testing.T) {
func TestUpdateCharts(t *testing.T) { func TestUpdateCharts(t *testing.T) {
defer resetEnv()() defer resetEnv()()
defer ensure.HelmHome(t)() ensure.HelmHome(t)
ts, err := repotest.NewTempServerWithCleanup(t, "testdata/testserver/*.*") ts, err := repotest.NewTempServerWithCleanup(t, "testdata/testserver/*.*")
if err != nil { if err != nil {
@ -164,7 +163,7 @@ func TestRepoUpdateFileCompletion(t *testing.T) {
func TestUpdateChartsFail(t *testing.T) { func TestUpdateChartsFail(t *testing.T) {
defer resetEnv()() defer resetEnv()()
defer ensure.HelmHome(t)() ensure.HelmHome(t)
ts, err := repotest.NewTempServerWithCleanup(t, "testdata/testserver/*.*") ts, err := repotest.NewTempServerWithCleanup(t, "testdata/testserver/*.*")
if err != nil { if err != nil {
@ -197,7 +196,7 @@ func TestUpdateChartsFail(t *testing.T) {
func TestUpdateChartsFailWithError(t *testing.T) { func TestUpdateChartsFailWithError(t *testing.T) {
defer resetEnv()() defer resetEnv()()
defer ensure.HelmHome(t)() ensure.HelmHome(t)
ts, err := repotest.NewTempServerWithCleanup(t, "testdata/testserver/*.*") ts, err := repotest.NewTempServerWithCleanup(t, "testdata/testserver/*.*")
if err != nil { if err != nil {

@ -32,8 +32,8 @@ const rollbackDesc = `
This command rolls back a release to a previous revision. This command rolls back a release to a previous revision.
The first argument of the rollback command is the name of a release, and the The first argument of the rollback command is the name of a release, and the
second is a revision (version) number. If this argument is omitted, it will second is a revision (version) number. If this argument is omitted or set to
roll back to the previous release. 0, it will roll back to the previous release.
To see revision numbers, run 'helm history RELEASE'. To see revision numbers, run 'helm history RELEASE'.
` `

@ -64,6 +64,12 @@ func TestRollbackCmd(t *testing.T) {
cmd: "rollback funny-honey", cmd: "rollback funny-honey",
golden: "output/rollback-no-revision.txt", golden: "output/rollback-no-revision.txt",
rels: rels, rels: rels,
}, {
name: "rollback a release with non-existent version",
cmd: "rollback funny-honey 3",
golden: "output/rollback-non-existent-version.txt",
rels: rels,
wantError: true,
}, { }, {
name: "rollback a release without release name", name: "rollback a release without release name",
cmd: "rollback", cmd: "rollback",

@ -77,7 +77,7 @@ func TestRootCmd(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
defer ensure.HelmHome(t)() ensure.HelmHome(t)
for k, v := range tt.envvars { for k, v := range tt.envvars {
os.Setenv(k, v) os.Setenv(k, v)

@ -54,6 +54,7 @@ type searchHubOptions struct {
maxColWidth uint maxColWidth uint
outputFormat output.Format outputFormat output.Format
listRepoURL bool listRepoURL bool
failOnNoResult bool
} }
func newSearchHubCmd(out io.Writer) *cobra.Command { func newSearchHubCmd(out io.Writer) *cobra.Command {
@ -72,6 +73,7 @@ func newSearchHubCmd(out io.Writer) *cobra.Command {
f.StringVar(&o.searchEndpoint, "endpoint", "https://hub.helm.sh", "Hub instance to query for charts") f.StringVar(&o.searchEndpoint, "endpoint", "https://hub.helm.sh", "Hub instance to query for charts")
f.UintVar(&o.maxColWidth, "max-col-width", 50, "maximum column width for output table") f.UintVar(&o.maxColWidth, "max-col-width", 50, "maximum column width for output table")
f.BoolVar(&o.listRepoURL, "list-repo-url", false, "print charts repository URL") f.BoolVar(&o.listRepoURL, "list-repo-url", false, "print charts repository URL")
f.BoolVar(&o.failOnNoResult, "fail-on-no-result", false, "search fails if no results are found")
bindOutputFlag(cmd, &o.outputFormat) bindOutputFlag(cmd, &o.outputFormat)
@ -91,7 +93,7 @@ func (o *searchHubOptions) run(out io.Writer, args []string) error {
return fmt.Errorf("unable to perform search against %q", o.searchEndpoint) return fmt.Errorf("unable to perform search against %q", o.searchEndpoint)
} }
return o.outputFormat.Write(out, newHubSearchWriter(results, o.searchEndpoint, o.maxColWidth, o.listRepoURL)) return o.outputFormat.Write(out, newHubSearchWriter(results, o.searchEndpoint, o.maxColWidth, o.listRepoURL, o.failOnNoResult))
} }
type hubChartRepo struct { type hubChartRepo struct {
@ -108,12 +110,13 @@ type hubChartElement struct {
} }
type hubSearchWriter struct { type hubSearchWriter struct {
elements []hubChartElement elements []hubChartElement
columnWidth uint columnWidth uint
listRepoURL bool listRepoURL bool
failOnNoResult bool
} }
func newHubSearchWriter(results []monocular.SearchResult, endpoint string, columnWidth uint, listRepoURL bool) *hubSearchWriter { func newHubSearchWriter(results []monocular.SearchResult, endpoint string, columnWidth uint, listRepoURL, failOnNoResult bool) *hubSearchWriter {
var elements []hubChartElement var elements []hubChartElement
for _, r := range results { for _, r := range results {
// Backwards compatibility for Monocular // Backwards compatibility for Monocular
@ -126,11 +129,16 @@ func newHubSearchWriter(results []monocular.SearchResult, endpoint string, colum
elements = append(elements, hubChartElement{url, r.Relationships.LatestChartVersion.Data.Version, r.Relationships.LatestChartVersion.Data.AppVersion, r.Attributes.Description, hubChartRepo{URL: r.Attributes.Repo.URL, Name: r.Attributes.Repo.Name}}) elements = append(elements, hubChartElement{url, r.Relationships.LatestChartVersion.Data.Version, r.Relationships.LatestChartVersion.Data.AppVersion, r.Attributes.Description, hubChartRepo{URL: r.Attributes.Repo.URL, Name: r.Attributes.Repo.Name}})
} }
return &hubSearchWriter{elements, columnWidth, listRepoURL} return &hubSearchWriter{elements, columnWidth, listRepoURL, failOnNoResult}
} }
func (h *hubSearchWriter) WriteTable(out io.Writer) error { func (h *hubSearchWriter) WriteTable(out io.Writer) error {
if len(h.elements) == 0 { if len(h.elements) == 0 {
// Fail if no results found and --fail-on-no-result is enabled
if h.failOnNoResult {
return fmt.Errorf("no results found")
}
_, err := out.Write([]byte("No results found\n")) _, err := out.Write([]byte("No results found\n"))
if err != nil { if err != nil {
return fmt.Errorf("unable to write results: %s", err) return fmt.Errorf("unable to write results: %s", err)
@ -165,6 +173,11 @@ func (h *hubSearchWriter) WriteYAML(out io.Writer) error {
} }
func (h *hubSearchWriter) encodeByFormat(out io.Writer, format output.Format) error { func (h *hubSearchWriter) encodeByFormat(out io.Writer, format output.Format) error {
// Fail if no results found and --fail-on-no-result is enabled
if len(h.elements) == 0 && h.failOnNoResult {
return fmt.Errorf("no results found")
}
// Initialize the array so no results returns an empty array instead of null // Initialize the array so no results returns an empty array instead of null
chartList := make([]hubChartElement, 0, len(h.elements)) chartList := make([]hubChartElement, 0, len(h.elements))

@ -90,3 +90,98 @@ func TestSearchHubOutputCompletion(t *testing.T) {
func TestSearchHubFileCompletion(t *testing.T) { func TestSearchHubFileCompletion(t *testing.T) {
checkFileCompletion(t, "search hub", true) // File completion may be useful when inputting a keyword checkFileCompletion(t, "search hub", true) // File completion may be useful when inputting a keyword
} }
func TestSearchHubCmd_FailOnNoResponseTests(t *testing.T) {
var (
searchResult = `{"data":[]}`
noResultFoundErr = "Error: no results found\n"
noResultFoundWarn = "No results found\n"
noResultFoundWarnInList = "[]\n"
)
type testCase struct {
name string
cmd string
response string
expected string
wantErr bool
}
var tests = []testCase{
{
name: "Search hub with no results in response",
cmd: `search hub maria`,
response: searchResult,
expected: noResultFoundWarn,
wantErr: false,
},
{
name: "Search hub with no results in response and output JSON",
cmd: `search hub maria --output json`,
response: searchResult,
expected: noResultFoundWarnInList,
wantErr: false,
},
{
name: "Search hub with no results in response and output YAML",
cmd: `search hub maria --output yaml`,
response: searchResult,
expected: noResultFoundWarnInList,
wantErr: false,
},
{
name: "Search hub with no results in response and --fail-on-no-result enabled, expected failure",
cmd: `search hub maria --fail-on-no-result`,
response: searchResult,
expected: noResultFoundErr,
wantErr: true,
},
{
name: "Search hub with no results in response, output JSON and --fail-on-no-result enabled, expected failure",
cmd: `search hub maria --fail-on-no-result --output json`,
response: searchResult,
expected: noResultFoundErr,
wantErr: true,
},
{
name: "Search hub with no results in response, output YAML and --fail-on-no-result enabled, expected failure",
cmd: `search hub maria --fail-on-no-result --output yaml`,
response: searchResult,
expected: noResultFoundErr,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Setup a mock search service
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, tt.response)
}))
defer ts.Close()
// Add mock server URL to command
tt.cmd += " --endpoint " + ts.URL
storage := storageFixture()
_, out, err := executeActionCommandC(storage, tt.cmd)
if tt.wantErr {
if err == nil {
t.Errorf("expected error due to no record in response, got nil")
}
} else {
if err != nil {
t.Errorf("unexpected error, got %q", err)
}
}
if out != tt.expected {
t.Errorf("expected and actual output did not match\n"+
"expected: %q\n"+
"actual : %q",
tt.expected, out)
}
})
}
}

@ -63,14 +63,15 @@ Repositories are managed with 'helm repo' commands.
const searchMaxScore = 25 const searchMaxScore = 25
type searchRepoOptions struct { type searchRepoOptions struct {
versions bool versions bool
regexp bool regexp bool
devel bool devel bool
version string version string
maxColWidth uint maxColWidth uint
repoFile string repoFile string
repoCacheDir string repoCacheDir string
outputFormat output.Format outputFormat output.Format
failOnNoResult bool
} }
func newSearchRepoCmd(out io.Writer) *cobra.Command { func newSearchRepoCmd(out io.Writer) *cobra.Command {
@ -93,6 +94,8 @@ func newSearchRepoCmd(out io.Writer) *cobra.Command {
f.BoolVar(&o.devel, "devel", false, "use development versions (alpha, beta, and release candidate releases), too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored") f.BoolVar(&o.devel, "devel", false, "use development versions (alpha, beta, and release candidate releases), too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored")
f.StringVar(&o.version, "version", "", "search using semantic versioning constraints on repositories you have added") f.StringVar(&o.version, "version", "", "search using semantic versioning constraints on repositories you have added")
f.UintVar(&o.maxColWidth, "max-col-width", 50, "maximum column width for output table") f.UintVar(&o.maxColWidth, "max-col-width", 50, "maximum column width for output table")
f.BoolVar(&o.failOnNoResult, "fail-on-no-result", false, "search fails if no results are found")
bindOutputFlag(cmd, &o.outputFormat) bindOutputFlag(cmd, &o.outputFormat)
return cmd return cmd
@ -123,7 +126,7 @@ func (o *searchRepoOptions) run(out io.Writer, args []string) error {
return err return err
} }
return o.outputFormat.Write(out, &repoSearchWriter{data, o.maxColWidth}) return o.outputFormat.Write(out, &repoSearchWriter{data, o.maxColWidth, o.failOnNoResult})
} }
func (o *searchRepoOptions) setupSearchedVersion() { func (o *searchRepoOptions) setupSearchedVersion() {
@ -204,12 +207,18 @@ type repoChartElement struct {
} }
type repoSearchWriter struct { type repoSearchWriter struct {
results []*search.Result results []*search.Result
columnWidth uint columnWidth uint
failOnNoResult bool
} }
func (r *repoSearchWriter) WriteTable(out io.Writer) error { func (r *repoSearchWriter) WriteTable(out io.Writer) error {
if len(r.results) == 0 { if len(r.results) == 0 {
// Fail if no results found and --fail-on-no-result is enabled
if r.failOnNoResult {
return fmt.Errorf("no results found")
}
_, err := out.Write([]byte("No results found\n")) _, err := out.Write([]byte("No results found\n"))
if err != nil { if err != nil {
return fmt.Errorf("unable to write results: %s", err) return fmt.Errorf("unable to write results: %s", err)
@ -234,6 +243,11 @@ func (r *repoSearchWriter) WriteYAML(out io.Writer) error {
} }
func (r *repoSearchWriter) encodeByFormat(out io.Writer, format output.Format) error { func (r *repoSearchWriter) encodeByFormat(out io.Writer, format output.Format) error {
// Fail if no results found and --fail-on-no-result is enabled
if len(r.results) == 0 && r.failOnNoResult {
return fmt.Errorf("no results found")
}
// Initialize the array so no results returns an empty array instead of null // Initialize the array so no results returns an empty array instead of null
chartList := make([]repoChartElement, 0, len(r.results)) chartList := make([]repoChartElement, 0, len(r.results))

@ -56,6 +56,20 @@ func TestSearchRepositoriesCmd(t *testing.T) {
name: "search for 'syzygy', expect no matches", name: "search for 'syzygy', expect no matches",
cmd: "search repo syzygy", cmd: "search repo syzygy",
golden: "output/search-not-found.txt", golden: "output/search-not-found.txt",
}, {
name: "search for 'syzygy' with --fail-on-no-result, expect failure for no results",
cmd: "search repo syzygy --fail-on-no-result",
golden: "output/search-not-found-error.txt",
wantError: true,
}, {name: "search for 'syzygy' with json output and --fail-on-no-result, expect failure for no results",
cmd: "search repo syzygy --output json --fail-on-no-result",
golden: "output/search-not-found-error.txt",
wantError: true,
}, {
name: "search for 'syzygy' with yaml output --fail-on-no-result, expect failure for no results",
cmd: "search repo syzygy --output yaml --fail-on-no-result",
golden: "output/search-not-found-error.txt",
wantError: true,
}, { }, {
name: "search for 'alp[a-z]+', expect two matches", name: "search for 'alp[a-z]+', expect two matches",
cmd: "search repo alp[a-z]+ --regexp", cmd: "search repo alp[a-z]+ --regexp",

@ -80,7 +80,7 @@ func newStatusCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
// strip chart metadata from the output // strip chart metadata from the output
rel.Chart = nil rel.Chart = nil
return outfmt.Write(out, &statusPrinter{rel, false, client.ShowDescription, client.ShowResources}) return outfmt.Write(out, &statusPrinter{rel, false, client.ShowDescription, client.ShowResources, false})
}, },
} }
@ -112,6 +112,7 @@ type statusPrinter struct {
debug bool debug bool
showDescription bool showDescription bool
showResources bool showResources bool
showMetadata bool
} }
func (s statusPrinter) WriteJSON(out io.Writer) error { func (s statusPrinter) WriteJSON(out io.Writer) error {
@ -126,15 +127,20 @@ func (s statusPrinter) WriteTable(out io.Writer) error {
if s.release == nil { if s.release == nil {
return nil return nil
} }
fmt.Fprintf(out, "NAME: %s\n", s.release.Name) _, _ = fmt.Fprintf(out, "NAME: %s\n", s.release.Name)
if !s.release.Info.LastDeployed.IsZero() { if !s.release.Info.LastDeployed.IsZero() {
fmt.Fprintf(out, "LAST DEPLOYED: %s\n", s.release.Info.LastDeployed.Format(time.ANSIC)) _, _ = fmt.Fprintf(out, "LAST DEPLOYED: %s\n", s.release.Info.LastDeployed.Format(time.ANSIC))
}
_, _ = fmt.Fprintf(out, "NAMESPACE: %s\n", s.release.Namespace)
_, _ = fmt.Fprintf(out, "STATUS: %s\n", s.release.Info.Status.String())
_, _ = fmt.Fprintf(out, "REVISION: %d\n", s.release.Version)
if s.showMetadata {
_, _ = fmt.Fprintf(out, "CHART: %s\n", s.release.Chart.Metadata.Name)
_, _ = fmt.Fprintf(out, "VERSION: %s\n", s.release.Chart.Metadata.Version)
_, _ = fmt.Fprintf(out, "APP_VERSION: %s\n", s.release.Chart.Metadata.AppVersion)
} }
fmt.Fprintf(out, "NAMESPACE: %s\n", s.release.Namespace)
fmt.Fprintf(out, "STATUS: %s\n", s.release.Info.Status.String())
fmt.Fprintf(out, "REVISION: %d\n", s.release.Version)
if s.showDescription { if s.showDescription {
fmt.Fprintf(out, "DESCRIPTION: %s\n", s.release.Info.Description) _, _ = fmt.Fprintf(out, "DESCRIPTION: %s\n", s.release.Info.Description)
} }
if s.showResources && s.release.Info.Resources != nil && len(s.release.Info.Resources) > 0 { if s.showResources && s.release.Info.Resources != nil && len(s.release.Info.Resources) > 0 {
@ -149,31 +155,31 @@ func (s statusPrinter) WriteTable(out io.Writer) error {
} }
for _, t := range keys { for _, t := range keys {
fmt.Fprintf(buf, "==> %s\n", t) _, _ = fmt.Fprintf(buf, "==> %s\n", t)
vk := s.release.Info.Resources[t] vk := s.release.Info.Resources[t]
for _, resource := range vk { for _, resource := range vk {
if err := printer.PrintObj(resource, buf); err != nil { if err := printer.PrintObj(resource, buf); err != nil {
fmt.Fprintf(buf, "failed to print object type %s: %v\n", t, err) _, _ = fmt.Fprintf(buf, "failed to print object type %s: %v\n", t, err)
} }
} }
buf.WriteString("\n") buf.WriteString("\n")
} }
fmt.Fprintf(out, "RESOURCES:\n%s\n", buf.String()) _, _ = fmt.Fprintf(out, "RESOURCES:\n%s\n", buf.String())
} }
executions := executionsByHookEvent(s.release) executions := executionsByHookEvent(s.release)
if tests, ok := executions[release.HookTest]; !ok || len(tests) == 0 { if tests, ok := executions[release.HookTest]; !ok || len(tests) == 0 {
fmt.Fprintln(out, "TEST SUITE: None") _, _ = fmt.Fprintln(out, "TEST SUITE: None")
} else { } else {
for _, h := range tests { for _, h := range tests {
// Don't print anything if hook has not been initiated // Don't print anything if hook has not been initiated
if h.LastRun.StartedAt.IsZero() { if h.LastRun.StartedAt.IsZero() {
continue continue
} }
fmt.Fprintf(out, "TEST SUITE: %s\n%s\n%s\n%s\n", _, _ = fmt.Fprintf(out, "TEST SUITE: %s\n%s\n%s\n%s\n",
h.Name, h.Name,
fmt.Sprintf("Last Started: %s", h.LastRun.StartedAt.Format(time.ANSIC)), fmt.Sprintf("Last Started: %s", h.LastRun.StartedAt.Format(time.ANSIC)),
fmt.Sprintf("Last Completed: %s", h.LastRun.CompletedAt.Format(time.ANSIC)), fmt.Sprintf("Last Completed: %s", h.LastRun.CompletedAt.Format(time.ANSIC)),
@ -183,38 +189,38 @@ func (s statusPrinter) WriteTable(out io.Writer) error {
} }
if s.debug { if s.debug {
fmt.Fprintln(out, "USER-SUPPLIED VALUES:") _, _ = fmt.Fprintln(out, "USER-SUPPLIED VALUES:")
err := output.EncodeYAML(out, s.release.Config) err := output.EncodeYAML(out, s.release.Config)
if err != nil { if err != nil {
return err return err
} }
// Print an extra newline // Print an extra newline
fmt.Fprintln(out) _, _ = fmt.Fprintln(out)
cfg, err := chartutil.CoalesceValues(s.release.Chart, s.release.Config) cfg, err := chartutil.CoalesceValues(s.release.Chart, s.release.Config)
if err != nil { if err != nil {
return err return err
} }
fmt.Fprintln(out, "COMPUTED VALUES:") _, _ = fmt.Fprintln(out, "COMPUTED VALUES:")
err = output.EncodeYAML(out, cfg.AsMap()) err = output.EncodeYAML(out, cfg.AsMap())
if err != nil { if err != nil {
return err return err
} }
// Print an extra newline // Print an extra newline
fmt.Fprintln(out) _, _ = fmt.Fprintln(out)
} }
if strings.EqualFold(s.release.Info.Description, "Dry run complete") || s.debug { if strings.EqualFold(s.release.Info.Description, "Dry run complete") || s.debug {
fmt.Fprintln(out, "HOOKS:") _, _ = fmt.Fprintln(out, "HOOKS:")
for _, h := range s.release.Hooks { for _, h := range s.release.Hooks {
fmt.Fprintf(out, "---\n# Source: %s\n%s\n", h.Path, h.Manifest) _, _ = fmt.Fprintf(out, "---\n# Source: %s\n%s\n", h.Path, h.Manifest)
} }
fmt.Fprintf(out, "MANIFEST:\n%s\n", s.release.Manifest) _, _ = fmt.Fprintf(out, "MANIFEST:\n%s\n", s.release.Manifest)
} }
if len(s.release.Info.Notes) > 0 { if len(s.release.Info.Notes) > 0 {
fmt.Fprintf(out, "NOTES:\n%s\n", strings.TrimSpace(s.release.Info.Notes)) _, _ = fmt.Fprintf(out, "NOTES:\n%s\n", strings.TrimSpace(s.release.Info.Notes))
} }
return nil return nil
} }

@ -32,7 +32,7 @@ func TestStatusCmd(t *testing.T) {
Name: "flummoxed-chickadee", Name: "flummoxed-chickadee",
Namespace: "default", Namespace: "default",
Info: info, Info: info,
Chart: &chart.Chart{}, Chart: &chart.Chart{Metadata: &chart.Metadata{Name: "name", Version: "1.2.3", AppVersion: "3.2.1"}},
Hooks: hooks, Hooks: hooks,
}} }}
} }

@ -0,0 +1,19 @@
name: wrongname
commands:
- name: empty
- name: full
commands:
- name: more
validArgs:
- one
- two
flags:
- b
- ball
- name: less
flags:
- a
- all
flags:
- z
- q

@ -0,0 +1,7 @@
#!/bin/sh
echo $HELM_PLUGIN_NAME
echo $HELM_PLUGIN_DIR
echo $HELM_PLUGINS
echo $HELM_REPOSITORY_CONFIG
echo $HELM_REPOSITORY_CACHE
echo $HELM_BIN

@ -0,0 +1,4 @@
name: fullenv
usage: "show env vars"
description: "show all env vars"
command: "$HELM_PLUGIN_DIR/fullenv.sh"

@ -0,0 +1,6 @@
apiVersion: v1
generated: 2016-10-03T16:03:10.640376913-06:00
repositories:
- cache: testing-index.yaml
name: testing
url: http://example.com/charts

@ -0,0 +1,3 @@
apiVersion: v1
entries: {}
generated: "2020-09-09T19:50:50.198347916-04:00"

@ -0,0 +1,66 @@
apiVersion: v1
entries:
alpine:
- name: alpine
url: https://charts.helm.sh/stable/alpine-0.1.0.tgz
checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d
created: "2018-06-27T10:00:18.230700509Z"
deprecated: true
home: https://helm.sh/helm
sources:
- https://github.com/helm/helm
version: 0.1.0
appVersion: 1.2.3
description: Deploy a basic Alpine Linux pod
keywords: []
maintainers: []
icon: ""
apiVersion: v2
- name: alpine
url: https://charts.helm.sh/stable/alpine-0.2.0.tgz
checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d
created: "2018-07-09T11:34:37.797864902Z"
home: https://helm.sh/helm
sources:
- https://github.com/helm/helm
version: 0.2.0
appVersion: 2.3.4
description: Deploy a basic Alpine Linux pod
keywords: []
maintainers: []
icon: ""
apiVersion: v2
- name: alpine
url: https://charts.helm.sh/stable/alpine-0.3.0-rc.1.tgz
checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d
created: "2020-11-12T08:44:58.872726222Z"
home: https://helm.sh/helm
sources:
- https://github.com/helm/helm
version: 0.3.0-rc.1
appVersion: 3.0.0
description: Deploy a basic Alpine Linux pod
keywords: []
maintainers: []
icon: ""
apiVersion: v2
mariadb:
- name: mariadb
url: https://charts.helm.sh/stable/mariadb-0.3.0.tgz
checksum: 65229f6de44a2be9f215d11dbff311673fc8ba56
created: "2018-04-23T08:20:27.160959131Z"
home: https://mariadb.org
sources:
- https://github.com/bitnami/bitnami-docker-mariadb
version: 0.3.0
description: Chart for MariaDB
keywords:
- mariadb
- mysql
- database
- sql
maintainers:
- name: Bitnami
email: containers@bitnami.com
icon: ""
apiVersion: v2

@ -0,0 +1,3 @@
Error: "helm get metadata" requires 1 argument
Usage: helm get metadata RELEASE_NAME [flags]

@ -0,0 +1 @@
{"name":"thomas-guide","chart":"foo","version":"0.1.0-beta.1","appVersion":"1.0","namespace":"default","revision":1,"status":"deployed","deployedAt":"1977-09-02T22:04:05Z"}

@ -0,0 +1,8 @@
NAME: thomas-guide
CHART: foo
VERSION: 0.1.0-beta.1
APP_VERSION: 1.0
NAMESPACE: default
REVISION: 1
STATUS: deployed
DEPLOYED_AT: 1977-09-02T22:04:05Z

@ -0,0 +1,8 @@
appVersion: "1.0"
chart: foo
deployedAt: "1977-09-02T22:04:05Z"
name: thomas-guide
namespace: default
revision: 1
status: deployed
version: 0.1.0-beta.1

@ -3,6 +3,9 @@ LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default NAMESPACE: default
STATUS: deployed STATUS: deployed
REVISION: 1 REVISION: 1
CHART: foo
VERSION: 0.1.0-beta.1
APP_VERSION: 1.0
TEST SUITE: None TEST SUITE: None
USER-SUPPLIED VALUES: USER-SUPPLIED VALUES:
name: value name: value

@ -0,0 +1 @@
Error: release has no 3 version

@ -0,0 +1 @@
Error: no results found

@ -1 +1 @@
version.BuildInfo{Version:"v3.12", GitCommit:"", GitTreeState:"", GoVersion:""} version.BuildInfo{Version:"v3.13", GitCommit:"", GitTreeState:"", GoVersion:""}

@ -1 +1 @@
version.BuildInfo{Version:"v3.12", GitCommit:"", GitTreeState:"", GoVersion:""} version.BuildInfo{Version:"v3.13", GitCommit:"", GitTreeState:"", GoVersion:""}

@ -1 +1 @@
Version: v3.12 Version: v3.13

@ -1 +1 @@
version.BuildInfo{Version:"v3.12", GitCommit:"", GitTreeState:"", GoVersion:""} version.BuildInfo{Version:"v3.13", GitCommit:"", GitTreeState:"", GoVersion:""}

@ -140,13 +140,14 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
instClient.SubNotes = client.SubNotes instClient.SubNotes = client.SubNotes
instClient.Description = client.Description instClient.Description = client.Description
instClient.DependencyUpdate = client.DependencyUpdate instClient.DependencyUpdate = client.DependencyUpdate
instClient.Labels = client.Labels
instClient.EnableDNS = client.EnableDNS instClient.EnableDNS = client.EnableDNS
rel, err := runInstall(args, instClient, valueOpts, out) rel, err := runInstall(args, instClient, valueOpts, out)
if err != nil { if err != nil {
return err return err
} }
return outfmt.Write(out, &statusPrinter{rel, settings.Debug, false, false}) return outfmt.Write(out, &statusPrinter{rel, settings.Debug, false, false, false})
} else if err != nil { } else if err != nil {
return err return err
} }
@ -232,7 +233,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
fmt.Fprintf(out, "Release %q has been upgraded. Happy Helming!\n", args[0]) fmt.Fprintf(out, "Release %q has been upgraded. Happy Helming!\n", args[0])
} }
return outfmt.Write(out, &statusPrinter{rel, settings.Debug, false, false}) return outfmt.Write(out, &statusPrinter{rel, settings.Debug, false, false, false})
}, },
} }
@ -258,6 +259,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
f.IntVar(&client.MaxHistory, "history-max", settings.MaxHistory, "limit the maximum number of revisions saved per release. Use 0 for no limit") f.IntVar(&client.MaxHistory, "history-max", settings.MaxHistory, "limit the maximum number of revisions saved per release. Use 0 for no limit")
f.BoolVar(&client.CleanupOnFail, "cleanup-on-fail", false, "allow deletion of new resources created in this upgrade when upgrade fails") f.BoolVar(&client.CleanupOnFail, "cleanup-on-fail", false, "allow deletion of new resources created in this upgrade when upgrade fails")
f.BoolVar(&client.SubNotes, "render-subchart-notes", false, "if set, render subchart notes along with the parent") f.BoolVar(&client.SubNotes, "render-subchart-notes", false, "if set, render subchart notes along with the parent")
f.StringToStringVarP(&client.Labels, "labels", "l", nil, "Labels that would be added to release metadata. Should be separated by comma. Original release labels will be merged with upgrade labels. You can unset label using null.")
f.StringVar(&client.Description, "description", "", "add a custom description") f.StringVar(&client.Description, "description", "", "add a custom description")
f.BoolVar(&client.DependencyUpdate, "dependency-update", false, "update dependencies if they are missing before installing the chart") f.BoolVar(&client.DependencyUpdate, "dependency-update", false, "update dependencies if they are missing before installing the chart")
f.BoolVar(&client.EnableDNS, "enable-dns", false, "enable DNS lookups when rendering templates") f.BoolVar(&client.EnableDNS, "enable-dns", false, "enable DNS lookups when rendering templates")

@ -20,10 +20,10 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"reflect"
"strings" "strings"
"testing" "testing"
"helm.sh/helm/v3/internal/test/ensure"
"helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader" "helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/chartutil" "helm.sh/helm/v3/pkg/chartutil"
@ -32,7 +32,7 @@ import (
func TestUpgradeCmd(t *testing.T) { func TestUpgradeCmd(t *testing.T) {
tmpChart := ensure.TempDir(t) tmpChart := t.TempDir()
cfile := &chart.Chart{ cfile := &chart.Chart{
Metadata: &chart.Metadata{ Metadata: &chart.Metadata{
APIVersion: chart.APIVersionV1, APIVersion: chart.APIVersionV1,
@ -357,7 +357,7 @@ func TestUpgradeInstallWithValuesFromStdin(t *testing.T) {
} }
func prepareMockRelease(releaseName string, t *testing.T) (func(n string, v int, ch *chart.Chart) *release.Release, *chart.Chart, string) { func prepareMockRelease(releaseName string, t *testing.T) (func(n string, v int, ch *chart.Chart) *release.Release, *chart.Chart, string) {
tmpChart := ensure.TempDir(t) tmpChart := t.TempDir()
configmapData, err := os.ReadFile("testdata/testcharts/upgradetest/templates/configmap.yaml") configmapData, err := os.ReadFile("testdata/testcharts/upgradetest/templates/configmap.yaml")
if err != nil { if err != nil {
t.Fatalf("Error loading template yaml %v", err) t.Fatalf("Error loading template yaml %v", err)
@ -430,3 +430,31 @@ func TestUpgradeFileCompletion(t *testing.T) {
checkFileCompletion(t, "upgrade myrelease", true) checkFileCompletion(t, "upgrade myrelease", true)
checkFileCompletion(t, "upgrade myrelease repo/chart", false) checkFileCompletion(t, "upgrade myrelease repo/chart", false)
} }
func TestUpgradeInstallWithLabels(t *testing.T) {
releaseName := "funny-bunny-labels"
_, _, chartPath := prepareMockRelease(releaseName, t)
defer resetEnv()()
store := storageFixture()
expectedLabels := map[string]string{
"key1": "val1",
"key2": "val2",
}
cmd := fmt.Sprintf("upgrade %s --install --labels key1=val1,key2=val2 '%s'", releaseName, chartPath)
_, _, err := executeActionCommandC(store, cmd)
if err != nil {
t.Errorf("unexpected error, got '%v'", err)
}
updatedRel, err := store.Get(releaseName, 1)
if err != nil {
t.Errorf("unexpected error, got '%v'", err)
}
if !reflect.DeepEqual(updatedRel.Labels, expectedLabels) {
t.Errorf("Expected {%v}, got {%v}", expectedLabels, updatedRel.Labels)
}
}

@ -10,8 +10,8 @@ require (
github.com/Masterminds/squirrel v1.5.4 github.com/Masterminds/squirrel v1.5.4
github.com/Masterminds/vcs v1.13.3 github.com/Masterminds/vcs v1.13.3
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535
github.com/containerd/containerd v1.7.0 github.com/containerd/containerd v1.7.6
github.com/cyphar/filepath-securejoin v0.2.3 github.com/cyphar/filepath-securejoin v0.2.4
github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2
github.com/evanphx/json-patch v5.6.0+incompatible github.com/evanphx/json-patch v5.6.0+incompatible
github.com/foxcpp/go-mockdns v1.0.0 github.com/foxcpp/go-mockdns v1.0.0
@ -23,36 +23,37 @@ require (
github.com/lib/pq v1.10.9 github.com/lib/pq v1.10.9
github.com/mattn/go-shellwords v1.0.12 github.com/mattn/go-shellwords v1.0.12
github.com/mitchellh/copystructure v1.2.0 github.com/mitchellh/copystructure v1.2.0
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 github.com/moby/term v0.5.0
github.com/opencontainers/image-spec v1.1.0-rc4 github.com/opencontainers/image-spec v1.1.0-rc4
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/rubenv/sql-migrate v1.5.1 github.com/rubenv/sql-migrate v1.5.2
github.com/sirupsen/logrus v1.9.3 github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.7.0 github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
github.com/xeipuuv/gojsonschema v1.2.0 github.com/xeipuuv/gojsonschema v1.2.0
golang.org/x/crypto v0.11.0 golang.org/x/crypto v0.11.0
golang.org/x/term v0.10.0 golang.org/x/term v0.11.0
golang.org/x/text v0.11.0 golang.org/x/text v0.13.0
k8s.io/api v0.27.3 k8s.io/api v0.28.2
k8s.io/apiextensions-apiserver v0.27.3 k8s.io/apiextensions-apiserver v0.28.2
k8s.io/apimachinery v0.27.3 k8s.io/apimachinery v0.28.2
k8s.io/apiserver v0.27.3 k8s.io/apiserver v0.28.2
k8s.io/cli-runtime v0.27.3 k8s.io/cli-runtime v0.28.2
k8s.io/client-go v0.27.3 k8s.io/client-go v0.28.2
k8s.io/klog/v2 v2.100.1 k8s.io/klog/v2 v2.100.1
k8s.io/kubectl v0.27.3 k8s.io/kubectl v0.28.2
oras.land/oras-go v1.2.3 oras.land/oras-go v1.2.3
sigs.k8s.io/yaml v1.3.0 sigs.k8s.io/yaml v1.3.0
) )
require ( require (
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Microsoft/hcsshim v0.11.0 // indirect
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d // indirect github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/bshuster-repo/logrus-logstash-hook v1.0.0 // indirect github.com/bshuster-repo/logrus-logstash-hook v1.0.0 // indirect
@ -63,7 +64,7 @@ require (
github.com/chai2010/gettext-go v1.0.2 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/cli v23.0.1+incompatible // indirect github.com/docker/cli v23.0.3+incompatible // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker v23.0.3+incompatible // indirect github.com/docker/docker v23.0.3+incompatible // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect
@ -76,19 +77,19 @@ require (
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/fatih/color v1.13.0 // indirect github.com/fatih/color v1.13.0 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fvbommel/sortorder v1.0.1 // indirect github.com/fvbommel/sortorder v1.1.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect github.com/go-errors/errors v1.4.2 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.1 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.3 // indirect github.com/go-openapi/swag v0.22.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/gomodule/redigo v1.8.2 // indirect github.com/gomodule/redigo v1.8.2 // indirect
github.com/google/btree v1.0.1 // indirect github.com/google/btree v1.0.1 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-cmp v0.5.9 // indirect
github.com/google/gofuzz v1.2.0 // indirect github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
@ -113,7 +114,7 @@ require (
github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/miekg/dns v1.1.25 // indirect github.com/miekg/dns v1.1.25 // indirect
github.com/mitchellh/go-wordwrap v1.0.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/locker v1.0.1 // indirect github.com/moby/locker v1.0.1 // indirect
github.com/moby/spdystream v0.2.0 // indirect github.com/moby/spdystream v0.2.0 // indirect
@ -125,39 +126,39 @@ require (
github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_golang v1.16.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect github.com/shopspring/decimal v1.3.1 // indirect
github.com/spf13/cast v1.5.0 // indirect github.com/spf13/cast v1.5.0 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xlab/treeprint v1.1.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 // indirect github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 // indirect
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 // indirect github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 // indirect
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f // indirect github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f // indirect
go.opentelemetry.io/otel v1.14.0 // indirect go.opentelemetry.io/otel v1.14.0 // indirect
go.opentelemetry.io/otel/trace v1.14.0 // indirect go.opentelemetry.io/otel/trace v1.14.0 // indirect
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
golang.org/x/net v0.10.0 // indirect golang.org/x/net v0.13.0 // indirect
golang.org/x/oauth2 v0.4.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect
golang.org/x/sync v0.1.0 // indirect golang.org/x/sync v0.2.0 // indirect
golang.org/x/sys v0.10.0 // indirect golang.org/x/sys v0.11.0 // indirect
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect golang.org/x/time v0.3.0 // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
google.golang.org/grpc v1.53.0 // indirect google.golang.org/grpc v1.54.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/component-base v0.27.3 // indirect k8s.io/component-base v0.28.2 // indirect
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect
k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 // indirect k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/kustomize/api v0.13.2 // indirect sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect
sigs.k8s.io/kustomize/kyaml v0.14.1 // indirect sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
) )

491
go.sum

@ -1,44 +1,11 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
@ -54,15 +21,13 @@ github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8
github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
github.com/Masterminds/vcs v1.13.3 h1:IIA2aBdXvfbIM+yl/eTnL4hb1XwdpvuQLglAix1gweE= github.com/Masterminds/vcs v1.13.3 h1:IIA2aBdXvfbIM+yl/eTnL4hb1XwdpvuQLglAix1gweE=
github.com/Masterminds/vcs v1.13.3/go.mod h1:TiE7xuEjl1N4j016moRd6vezp6e6Lz23gypeXfzXeW8= github.com/Masterminds/vcs v1.13.3/go.mod h1:TiE7xuEjl1N4j016moRd6vezp6e6Lz23gypeXfzXeW8=
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/hcsshim v0.10.0-rc.7 h1:HBytQPxcv8Oy4244zbQbe6hnOnx544eL5QPUqhJldz8= github.com/Microsoft/hcsshim v0.11.0 h1:7EFNIY4igHEXUdj1zXgAyU3fLc7QfOKHbkldRVTBdiM=
github.com/Microsoft/hcsshim v0.11.0/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM=
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= 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/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 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-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY=
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
@ -80,8 +45,6 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0Bsq
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= 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/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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk=
@ -90,24 +53,23 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/containerd v1.7.0 h1:G/ZQr3gMZs6ZT0qPUZ15znx5QSdQdASW11nXTLTM2Pg= github.com/containerd/containerd v1.7.6 h1:oNAVsnhPoy4BTPQivLgTzI9Oleml9l/+eYIDYXRCYo8=
github.com/containerd/containerd v1.7.0/go.mod h1:QfR7Efgb/6X2BDpTPJRvPTYDE9rsF0FsXX9J8sIs/sc= github.com/containerd/containerd v1.7.6/go.mod h1:SY6lrkkuJT40BVNO37tlYTSnKJnP5AXBc0fhx0q+TJ4=
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc= github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc=
github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI= github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI=
github.com/docker/cli v23.0.1+incompatible h1:LRyWITpGzl2C9e9uGxzisptnxAn1zfZKXy13Ul2Q5oM= github.com/docker/cli v23.0.3+incompatible h1:Zcse1DuDqBdgI7OQDV8Go7b83xLgfhW1eza4HfEdxpY=
github.com/docker/cli v23.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v23.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v23.0.3+incompatible h1:9GhVsShNWz1hO//9BNg/dpMnZW25KydO4wtVxWAIbho= github.com/docker/docker v23.0.3+incompatible h1:9GhVsShNWz1hO//9BNg/dpMnZW25KydO4wtVxWAIbho=
@ -124,12 +86,9 @@ github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= 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/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ=
github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
@ -143,39 +102,31 @@ github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw
github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI= github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI=
github.com/foxcpp/go-mockdns v1.0.0/go.mod h1:lgRN6+KxQBawyIghpnl5CezHFGS9VLzvtVlwxvzXTQ4= github.com/foxcpp/go-mockdns v1.0.0/go.mod h1:lgRN6+KxQBawyIghpnl5CezHFGS9VLzvtVlwxvzXTQ4=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE= github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw=
github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs= github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw= github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 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-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 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-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/gobuffalo/logger v1.0.6 h1:nnZNpxYo0zx+Aj9RfMPBm+x9zAU2OayFh/xrAWi34HU= github.com/gobuffalo/logger v1.0.6 h1:nnZNpxYo0zx+Aj9RfMPBm+x9zAU2OayFh/xrAWi34HU=
github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0= github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0=
github.com/gobuffalo/packr/v2 v2.8.3 h1:xE1yzvnO56cUC0sTpKR3DIbxZgB54AftTFMhB2XEWlY= github.com/gobuffalo/packr/v2 v2.8.3 h1:xE1yzvnO56cUC0sTpKR3DIbxZgB54AftTFMhB2XEWlY=
@ -187,75 +138,44 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k=
github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/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/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
@ -270,14 +190,11 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
@ -287,27 +204,18 @@ github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw= github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4=
github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@ -350,8 +258,8 @@ github.com/miekg/dns v1.1.25/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKju
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f h1:2+myh5ml7lgEU/51gbeLHfKGNfgEQQIWrlbdaOsidbQ= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f h1:2+myh5ml7lgEU/51gbeLHfKGNfgEQQIWrlbdaOsidbQ=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
@ -361,8 +269,8 @@ github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQ
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -377,9 +285,8 @@ github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7P
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE=
github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0=
@ -389,7 +296,6 @@ github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@ -398,36 +304,25 @@ github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rubenv/sql-migrate v1.5.1 h1:WsZo4jPQfjmddDTh/suANP2aKPA7/ekN0LzuuajgQEo= github.com/rubenv/sql-migrate v1.5.2 h1:bMDqOnrJVV/6JQgQ/MxOpU+AdO8uzYYA/TxFUBzFtS0=
github.com/rubenv/sql-migrate v1.5.1/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is= github.com/rubenv/sql-migrate v1.5.2/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
@ -435,8 +330,6 @@ github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFR
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
@ -446,7 +339,6 @@ github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
@ -454,7 +346,6 @@ github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@ -469,11 +360,9 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI=
@ -482,22 +371,15 @@ github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMzt
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= 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 h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY=
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM=
go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY=
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -506,366 +388,169 @@ golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-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-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/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-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-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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M=
golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-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-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA=
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU=
k8s.io/api v0.27.3 h1:yR6oQXXnUEBWEWcvPWS0jQL575KoAboQPfJAuKNrw5Y= k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg=
k8s.io/api v0.27.3/go.mod h1:C4BNvZnQOF7JA/0Xed2S+aUyJSfTGkGFxLXz9MnpIpg= k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ=
k8s.io/apiextensions-apiserver v0.27.3 h1:xAwC1iYabi+TDfpRhxh4Eapl14Hs2OftM2DN5MpgKX4= k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU=
k8s.io/apiextensions-apiserver v0.27.3/go.mod h1:BH3wJ5NsB9XE1w+R6SSVpKmYNyIiyIz9xAmBl8Mb+84= k8s.io/apiserver v0.28.2 h1:rBeYkLvF94Nku9XfXyUIirsVzCzJBs6jMn3NWeHieyI=
k8s.io/apimachinery v0.27.3 h1:Ubye8oBufD04l9QnNtW05idcOe9Z3GQN8+7PqmuVcUM= k8s.io/apiserver v0.28.2/go.mod h1:f7D5e8wH8MWcKD7azq6Csw9UN+CjdtXIVQUyUhrtb+E=
k8s.io/apimachinery v0.27.3/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= k8s.io/cli-runtime v0.28.2 h1:64meB2fDj10/ThIMEJLO29a1oujSm0GQmKzh1RtA/uk=
k8s.io/apiserver v0.27.3 h1:AxLvq9JYtveYWK+D/Dz/uoPCfz8JC9asR5z7+I/bbQ4= k8s.io/cli-runtime v0.28.2/go.mod h1:bTpGOvpdsPtDKoyfG4EG041WIyFZLV9qq4rPlkyYfDA=
k8s.io/apiserver v0.27.3/go.mod h1:Y61+EaBMVWUBJtxD5//cZ48cHZbQD+yIyV/4iEBhhNA= k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY=
k8s.io/cli-runtime v0.27.3 h1:h592I+2eJfXj/4jVYM+tu9Rv8FEc/dyCoD80UJlMW2Y= k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY=
k8s.io/cli-runtime v0.27.3/go.mod h1:LzXud3vFFuDFXn2LIrWnscPgUiEj7gQQcYZE2UPn9Kw= k8s.io/component-base v0.28.2 h1:Yc1yU+6AQSlpJZyvehm/NkJBII72rzlEsd6MkBQ+G0E=
k8s.io/client-go v0.27.3 h1:7dnEGHZEJld3lYwxvLl7WoehK6lAq7GvgjxpA3nv1E8= k8s.io/component-base v0.28.2/go.mod h1:4IuQPQviQCg3du4si8GpMrhAIegxpsgPngPRR/zWpzc=
k8s.io/client-go v0.27.3/go.mod h1:2MBEKuTo6V1lbKy3z1euEGnhPfGZLKTS9tiJ2xodM48=
k8s.io/component-base v0.27.3 h1:g078YmdcdTfrCE4fFobt7qmVXwS8J/3cI1XxRi/2+6k=
k8s.io/component-base v0.27.3/go.mod h1:JNiKYcGImpQ44iwSYs6dysxzR9SxIIgQalk4HaCNVUY=
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ=
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM=
k8s.io/kubectl v0.27.3 h1:HyC4o+8rCYheGDWrkcOQHGwDmyLKR5bxXFgpvF82BOw= k8s.io/kubectl v0.28.2 h1:fOWOtU6S0smdNjG1PB9WFbqEIMlkzU5ahyHkc7ESHgM=
k8s.io/kubectl v0.27.3/go.mod h1:g9OQNCC2zxT+LT3FS09ZYqnDhlvsKAfFq76oyarBcq4= k8s.io/kubectl v0.28.2/go.mod h1:6EQWTPySF1fn7yKoQZHYf9TPwIl2AygHEcJoxFekr64=
k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk= k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk=
k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
oras.land/oras-go v1.2.3 h1:v8PJl+gEAntI1pJ/LCrDgsuk+1PKVavVEPsYIHFE5uY= oras.land/oras-go v1.2.3 h1:v8PJl+gEAntI1pJ/LCrDgsuk+1PKVavVEPsYIHFE5uY=
oras.land/oras-go v1.2.3/go.mod h1:M/uaPdYklze0Vf3AakfarnpoEckvw0ESbRdN8Z1vdJg= oras.land/oras-go v1.2.3/go.mod h1:M/uaPdYklze0Vf3AakfarnpoEckvw0ESbRdN8Z1vdJg=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/kustomize/api v0.13.2 h1:kejWfLeJhUsTGioDoFNJET5LQe/ajzXhJGYoU+pJsiA= sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0=
sigs.k8s.io/kustomize/api v0.13.2/go.mod h1:DUp325VVMFVcQSq+ZxyDisA8wtldwHxLZbr1g94UHsw= sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY=
sigs.k8s.io/kustomize/kyaml v0.14.1 h1:c8iibius7l24G2wVAGZn/Va2wNys03GXLjYVIcFVxKA= sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U=
sigs.k8s.io/kustomize/kyaml v0.14.1/go.mod h1:AN1/IpawKilWD7V+YvQwRGUvuUOOWpjsHu6uHwonSF4= sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=

@ -26,41 +26,27 @@ import (
) )
// HelmHome sets up a Helm Home in a temp dir. // HelmHome sets up a Helm Home in a temp dir.
func HelmHome(t *testing.T) func() { func HelmHome(t *testing.T) {
t.Helper() t.Helper()
base := TempDir(t) base := t.TempDir()
os.Setenv(xdg.CacheHomeEnvVar, base) os.Setenv(xdg.CacheHomeEnvVar, base)
os.Setenv(xdg.ConfigHomeEnvVar, base) os.Setenv(xdg.ConfigHomeEnvVar, base)
os.Setenv(xdg.DataHomeEnvVar, base) os.Setenv(xdg.DataHomeEnvVar, base)
os.Setenv(helmpath.CacheHomeEnvVar, "") os.Setenv(helmpath.CacheHomeEnvVar, "")
os.Setenv(helmpath.ConfigHomeEnvVar, "") os.Setenv(helmpath.ConfigHomeEnvVar, "")
os.Setenv(helmpath.DataHomeEnvVar, "") os.Setenv(helmpath.DataHomeEnvVar, "")
return func() {
os.RemoveAll(base)
}
}
// TempDir ensures a scratch test directory for unit testing purposes.
func TempDir(t *testing.T) string {
t.Helper()
d, err := os.MkdirTemp("", "helm")
if err != nil {
t.Fatal(err)
}
return d
} }
// TempFile ensures a temp file for unit testing purposes. // TempFile ensures a temp file for unit testing purposes.
// //
// It returns the path to the directory (to which you will still need to join the filename) // It returns the path to the directory (to which you will still need to join the filename)
// //
// You must clean up the directory that is returned. // The returned directory is automatically removed when the test and all its subtests complete.
// //
// tempdir := TempFile(t, "foo", []byte("bar")) // tempdir := TempFile(t, "foo", []byte("bar"))
// defer os.RemoveAll(tempdir)
// filename := filepath.Join(tempdir, "foo") // filename := filepath.Join(tempdir, "foo")
func TempFile(t *testing.T, name string, data []byte) string { func TempFile(t *testing.T, name string, data []byte) string {
path := TempDir(t) path := t.TempDir()
filename := filepath.Join(path, name) filename := filepath.Join(path, name)
if err := os.WriteFile(filename, data, 0755); err != nil { if err := os.WriteFile(filename, data, 0755); err != nil {
t.Fatal(err) t.Fatal(err)

@ -29,7 +29,7 @@ var (
// //
// Increment major number for new feature additions and behavioral changes. // Increment major number for new feature additions and behavioral changes.
// Increment minor number for bug fixes and performance enhancements. // Increment minor number for bug fixes and performance enhancements.
version = "v3.12" version = "v3.13"
// metadata is extra build time data // metadata is extra build time data
metadata = "" metadata = ""

@ -0,0 +1,69 @@
/*
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 action
import "time"
// GetMetadata is the action for checking a given release's metadata.
//
// It provides the implementation of 'helm get metadata'.
type GetMetadata struct {
cfg *Configuration
Version int
}
type Metadata struct {
Name string `json:"name" yaml:"name"`
Chart string `json:"chart" yaml:"chart"`
Version string `json:"version" yaml:"version"`
AppVersion string `json:"appVersion" yaml:"appVersion"`
Namespace string `json:"namespace" yaml:"namespace"`
Revision int `json:"revision" yaml:"revision"`
Status string `json:"status" yaml:"status"`
DeployedAt string `json:"deployedAt" yaml:"deployedAt"`
}
// NewGetMetadata creates a new GetMetadata object with the given configuration.
func NewGetMetadata(cfg *Configuration) *GetMetadata {
return &GetMetadata{
cfg: cfg,
}
}
// Run executes 'helm get metadata' against the given release.
func (g *GetMetadata) Run(name string) (*Metadata, error) {
if err := g.cfg.KubeClient.IsReachable(); err != nil {
return nil, err
}
rel, err := g.cfg.releaseContent(name, g.Version)
if err != nil {
return nil, err
}
return &Metadata{
Name: rel.Name,
Chart: rel.Chart.Metadata.Name,
Version: rel.Chart.Metadata.Version,
AppVersion: rel.Chart.Metadata.AppVersion,
Namespace: rel.Namespace,
Revision: rel.Version,
Status: rel.Info.Status.String(),
DeployedAt: rel.Info.LastDeployed.Format(time.RFC3339),
}, nil
}

@ -93,6 +93,7 @@ type Install struct {
SubNotes bool SubNotes bool
DisableOpenAPIValidation bool DisableOpenAPIValidation bool
IncludeCRDs bool IncludeCRDs bool
Labels map[string]string
// KubeVersion allows specifying a custom kubernetes version to use and // KubeVersion allows specifying a custom kubernetes version to use and
// APIVersions allows a manual set of supported API Versions to be passed // APIVersions allows a manual set of supported API Versions to be passed
// (for things like templating). These are ignored if ClientOnly is false // (for things like templating). These are ignored if ClientOnly is false
@ -219,6 +220,9 @@ func (i *Install) Run(chrt *chart.Chart, vals map[string]interface{}) (*release.
} }
// Run executes the installation with Context // Run executes the installation with Context
//
// When the task is cancelled through ctx, the function returns and the install
// proceeds in the background.
func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals map[string]interface{}) (*release.Release, error) { func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals map[string]interface{}) (*release.Release, error) {
// Check reachability of cluster unless in client-only mode (e.g. `helm template` without `--validate`) // Check reachability of cluster unless in client-only mode (e.g. `helm template` without `--validate`)
if !i.ClientOnly { if !i.ClientOnly {
@ -291,7 +295,11 @@ func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals ma
return nil, err return nil, err
} }
rel := i.createRelease(chrt, vals) if driver.ContainsSystemLabels(i.Labels) {
return nil, fmt.Errorf("user suplied labels contains system reserved label name. System labels: %+v", driver.GetSystemLabels())
}
rel := i.createRelease(chrt, vals, i.Labels)
var manifestDoc *bytes.Buffer var manifestDoc *bytes.Buffer
rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.SubNotes, i.UseReleaseName, i.IncludeCRDs, i.PostRenderer, interactWithRemote, i.EnableDNS) rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.SubNotes, i.UseReleaseName, i.IncludeCRDs, i.PostRenderer, interactWithRemote, i.EnableDNS)
@ -381,17 +389,31 @@ func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals ma
// not working. // not working.
return rel, err return rel, err
} }
rChan := make(chan resultMessage)
ctxChan := make(chan resultMessage) rel, err = i.performInstallCtx(ctx, rel, toBeAdopted, resources)
doneChan := make(chan struct{}) if err != nil {
defer close(doneChan) rel, err = i.failRelease(rel, err)
go i.performInstall(rChan, rel, toBeAdopted, resources) }
go i.handleContext(ctx, ctxChan, doneChan, rel) return rel, err
}
func (i *Install) performInstallCtx(ctx context.Context, rel *release.Release, toBeAdopted kube.ResourceList, resources kube.ResourceList) (*release.Release, error) {
type Msg struct {
r *release.Release
e error
}
resultChan := make(chan Msg, 1)
go func() {
rel, err := i.performInstall(rel, toBeAdopted, resources)
resultChan <- Msg{rel, err}
}()
select { select {
case result := <-rChan: case <-ctx.Done():
return result.r, result.e err := ctx.Err()
case result := <-ctxChan: return rel, err
return result.r, result.e case msg := <-resultChan:
return msg.r, msg.e
} }
} }
@ -403,18 +425,18 @@ func (i *Install) isDryRun() bool {
return false return false
} }
func (i *Install) performInstall(c chan<- resultMessage, rel *release.Release, toBeAdopted kube.ResourceList, resources kube.ResourceList) { func (i *Install) performInstall(rel *release.Release, toBeAdopted kube.ResourceList, resources kube.ResourceList) (*release.Release, error) {
// using HookTimeout if set otherwise using Timeout // using HookTimeout if set otherwise using Timeout
if i.HookTimeout == 0*time.Second { if i.HookTimeout == 0*time.Second {
i.HookTimeout = i.Timeout i.HookTimeout = i.Timeout
} }
var err error
// pre-install hooks // pre-install hooks
if !i.DisableHooks { if !i.DisableHooks {
if err := i.cfg.execHook(rel, release.HookPreInstall, i.HookTimeout); err != nil { if err := i.cfg.execHook(rel, release.HookPreInstall, i.HookTimeout); err != nil {
i.reportToRun(c, rel, fmt.Errorf("failed pre-install: %s", err)) return rel, fmt.Errorf("failed pre-install: %s", err)
return
} }
} }
@ -422,35 +444,28 @@ func (i *Install) performInstall(c chan<- resultMessage, rel *release.Release, t
// do an update, but it's not clear whether we WANT to do an update if the re-use is set // do an update, but it's not clear whether we WANT to do an update if the re-use is set
// to true, since that is basically an upgrade operation. // to true, since that is basically an upgrade operation.
if len(toBeAdopted) == 0 && len(resources) > 0 { if len(toBeAdopted) == 0 && len(resources) > 0 {
if _, err := i.cfg.KubeClient.Create(resources); err != nil { _, err = i.cfg.KubeClient.Create(resources)
i.reportToRun(c, rel, err)
return
}
} else if len(resources) > 0 { } else if len(resources) > 0 {
if _, err := i.cfg.KubeClient.Update(toBeAdopted, resources, i.Force); err != nil { _, err = i.cfg.KubeClient.Update(toBeAdopted, resources, i.Force)
i.reportToRun(c, rel, err) }
return if err != nil {
} return rel, err
} }
if i.Wait { if i.Wait {
if i.WaitForJobs { if i.WaitForJobs {
if err := i.cfg.KubeClient.WaitWithJobs(resources, i.Timeout); err != nil { err = i.cfg.KubeClient.WaitWithJobs(resources, i.Timeout)
i.reportToRun(c, rel, err)
return
}
} else { } else {
if err := i.cfg.KubeClient.Wait(resources, i.Timeout); err != nil { err = i.cfg.KubeClient.Wait(resources, i.Timeout)
i.reportToRun(c, rel, err) }
return if err != nil {
} return rel, err
} }
} }
if !i.DisableHooks { if !i.DisableHooks {
if err := i.cfg.execHook(rel, release.HookPostInstall, i.HookTimeout); err != nil { if err := i.cfg.execHook(rel, release.HookPostInstall, i.HookTimeout); err != nil {
i.reportToRun(c, rel, fmt.Errorf("failed post-install: %s", err)) return rel, fmt.Errorf("failed post-install: %s", err)
return
} }
} }
@ -471,25 +486,9 @@ func (i *Install) performInstall(c chan<- resultMessage, rel *release.Release, t
i.cfg.Log("failed to record the release: %s", err) i.cfg.Log("failed to record the release: %s", err)
} }
i.reportToRun(c, rel, nil) return rel, nil
}
func (i *Install) handleContext(ctx context.Context, c chan<- resultMessage, done chan struct{}, rel *release.Release) {
select {
case <-ctx.Done():
err := ctx.Err()
i.reportToRun(c, rel, err)
case <-done:
return
}
}
func (i *Install) reportToRun(c chan<- resultMessage, rel *release.Release, err error) {
i.Lock.Lock()
if err != nil {
rel, err = i.failRelease(rel, err)
}
c <- resultMessage{r: rel, e: err}
i.Lock.Unlock()
} }
func (i *Install) failRelease(rel *release.Release, err error) (*release.Release, error) { func (i *Install) failRelease(rel *release.Release, err error) (*release.Release, error) {
rel.SetStatus(release.StatusFailed, fmt.Sprintf("Release %q failed: %s", i.ReleaseName, err.Error())) rel.SetStatus(release.StatusFailed, fmt.Sprintf("Release %q failed: %s", i.ReleaseName, err.Error()))
if i.Atomic { if i.Atomic {
@ -540,7 +539,7 @@ func (i *Install) availableName() error {
} }
// createRelease creates a new release object // createRelease creates a new release object
func (i *Install) createRelease(chrt *chart.Chart, rawVals map[string]interface{}) *release.Release { func (i *Install) createRelease(chrt *chart.Chart, rawVals map[string]interface{}, labels map[string]string) *release.Release {
ts := i.cfg.Now() ts := i.cfg.Now()
return &release.Release{ return &release.Release{
Name: i.ReleaseName, Name: i.ReleaseName,
@ -553,6 +552,7 @@ func (i *Install) createRelease(chrt *chart.Chart, rawVals map[string]interface{
Status: release.StatusUnknown, Status: release.StatusUnknown,
}, },
Version: 1, Version: 1,
Labels: labels,
} }
} }

@ -23,6 +23,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
"runtime"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -369,10 +370,14 @@ func TestInstallRelease_Wait(t *testing.T) {
instAction.Wait = true instAction.Wait = true
vals := map[string]interface{}{} vals := map[string]interface{}{}
goroutines := runtime.NumGoroutine()
res, err := instAction.Run(buildChart(), vals) res, err := instAction.Run(buildChart(), vals)
is.Error(err) is.Error(err)
is.Contains(res.Info.Description, "I timed out") is.Contains(res.Info.Description, "I timed out")
is.Equal(res.Info.Status, release.StatusFailed) is.Equal(res.Info.Status, release.StatusFailed)
is.Equal(goroutines, runtime.NumGoroutine())
} }
func TestInstallRelease_Wait_Interrupted(t *testing.T) { func TestInstallRelease_Wait_Interrupted(t *testing.T) {
is := assert.New(t) is := assert.New(t)
@ -388,10 +393,16 @@ func TestInstallRelease_Wait_Interrupted(t *testing.T) {
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
time.AfterFunc(time.Second, cancel) time.AfterFunc(time.Second, cancel)
goroutines := runtime.NumGoroutine()
res, err := instAction.RunWithContext(ctx, buildChart(), vals) res, err := instAction.RunWithContext(ctx, buildChart(), vals)
is.Error(err) is.Error(err)
is.Contains(res.Info.Description, "Release \"interrupted-release\" failed: context canceled") is.Contains(res.Info.Description, "Release \"interrupted-release\" failed: context canceled")
is.Equal(res.Info.Status, release.StatusFailed) is.Equal(res.Info.Status, release.StatusFailed)
is.Equal(goroutines+1, runtime.NumGoroutine()) // installation goroutine still is in background
time.Sleep(10 * time.Second) // wait for goroutine to finish
is.Equal(goroutines, runtime.NumGoroutine())
} }
func TestInstallRelease_WaitForJobs(t *testing.T) { func TestInstallRelease_WaitForJobs(t *testing.T) {
is := assert.New(t) is := assert.New(t)
@ -717,3 +728,33 @@ func TestNameAndChartGenerateName(t *testing.T) {
}) })
} }
} }
func TestInstallWithLabels(t *testing.T) {
is := assert.New(t)
instAction := installAction(t)
instAction.Labels = map[string]string{
"key1": "val1",
"key2": "val2",
}
res, err := instAction.Run(buildChart(), nil)
if err != nil {
t.Fatalf("Failed install: %s", err)
}
is.Equal(instAction.Labels, res.Labels)
}
func TestInstallWithSystemLabels(t *testing.T) {
is := assert.New(t)
instAction := installAction(t)
instAction.Labels = map[string]string{
"owner": "val1",
"key2": "val2",
}
_, err := instAction.Run(buildChart(), nil)
if err == nil {
t.Fatal("expected an error")
}
is.Equal(fmt.Errorf("user suplied labels contains system reserved label name. System labels: %+v", driver.GetSystemLabels()), err)
}

@ -29,7 +29,6 @@ import (
func TestPassphraseFileFetcher(t *testing.T) { func TestPassphraseFileFetcher(t *testing.T) {
secret := "secret" secret := "secret"
directory := ensure.TempFile(t, "passphrase-file", []byte(secret)) directory := ensure.TempFile(t, "passphrase-file", []byte(secret))
defer os.RemoveAll(directory)
fetcher, err := passphraseFileFetcher(path.Join(directory, "passphrase-file"), nil) fetcher, err := passphraseFileFetcher(path.Join(directory, "passphrase-file"), nil)
if err != nil { if err != nil {
@ -49,7 +48,6 @@ func TestPassphraseFileFetcher(t *testing.T) {
func TestPassphraseFileFetcher_WithLineBreak(t *testing.T) { func TestPassphraseFileFetcher_WithLineBreak(t *testing.T) {
secret := "secret" secret := "secret"
directory := ensure.TempFile(t, "passphrase-file", []byte(secret+"\n\n.")) directory := ensure.TempFile(t, "passphrase-file", []byte(secret+"\n\n."))
defer os.RemoveAll(directory)
fetcher, err := passphraseFileFetcher(path.Join(directory, "passphrase-file"), nil) fetcher, err := passphraseFileFetcher(path.Join(directory, "passphrase-file"), nil)
if err != nil { if err != nil {
@ -67,8 +65,7 @@ func TestPassphraseFileFetcher_WithLineBreak(t *testing.T) {
} }
func TestPassphraseFileFetcher_WithInvalidStdin(t *testing.T) { func TestPassphraseFileFetcher_WithInvalidStdin(t *testing.T) {
directory := ensure.TempDir(t) directory := t.TempDir()
defer os.RemoveAll(directory)
stdin, err := os.CreateTemp(directory, "non-existing") stdin, err := os.CreateTemp(directory, "non-existing")
if err != nil { if err != nil {

@ -20,6 +20,7 @@ import (
"context" "context"
"fmt" "fmt"
"io" "io"
"sort"
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -118,7 +119,9 @@ func (r *ReleaseTesting) GetPodLogs(out io.Writer, rel *release.Release) error {
return errors.Wrap(err, "unable to get kubernetes client to fetch pod logs") return errors.Wrap(err, "unable to get kubernetes client to fetch pod logs")
} }
for _, h := range rel.Hooks { hooksByWight := append([]*release.Hook{}, rel.Hooks...)
sort.Stable(hookByWeight(hooksByWight))
for _, h := range hooksByWight {
for _, e := range h.Events { for _, e := range h.Events {
if e == release.HookTest { if e == release.HookTest {
if contains(r.Filters[ExcludeNameFilter], h.Name) { if contains(r.Filters[ExcludeNameFilter], h.Name) {

@ -111,6 +111,24 @@ func (r *Rollback) prepareRollback(name string) (*release.Release, *release.Rele
previousVersion = currentRelease.Version - 1 previousVersion = currentRelease.Version - 1
} }
historyReleases, err := r.cfg.Releases.History(name)
if err != nil {
return nil, nil, err
}
// Check if the history version to be rolled back exists
previousVersionExist := false
for _, historyRelease := range historyReleases {
version := historyRelease.Version
if previousVersion == version {
previousVersionExist = true
break
}
}
if !previousVersionExist {
return nil, nil, errors.Errorf("release has no %d version", previousVersion)
}
r.cfg.Log("rolling back %s (current: v%d, target: v%d)", name, currentRelease.Version, previousVersion) r.cfg.Log("rolling back %s (current: v%d, target: v%d)", name, currentRelease.Version, previousVersion)
previousRelease, err := r.cfg.Releases.Get(name, previousVersion) previousRelease, err := r.cfg.Releases.Get(name, previousVersion)

@ -96,6 +96,7 @@ type Upgrade struct {
SubNotes bool SubNotes bool
// Description is the description of this operation // Description is the description of this operation
Description string Description string
Labels map[string]string
// PostRender is an optional post-renderer // PostRender is an optional post-renderer
// //
// If this is non-nil, then after templates are rendered, they will be sent to the // If this is non-nil, then after templates are rendered, they will be sent to the
@ -263,6 +264,11 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[strin
return nil, nil, err return nil, nil, err
} }
fmt.Println(driver.ContainsSystemLabels(u.Labels))
if driver.ContainsSystemLabels(u.Labels) {
return nil, nil, fmt.Errorf("user suplied labels contains system reserved label name. System labels: %+v", driver.GetSystemLabels())
}
// Store an upgraded release. // Store an upgraded release.
upgradedRelease := &release.Release{ upgradedRelease := &release.Release{
Name: name, Name: name,
@ -278,6 +284,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[strin
Version: revision, Version: revision,
Manifest: manifestDoc.String(), Manifest: manifestDoc.String(),
Hooks: hooks, Hooks: hooks,
Labels: mergeCustomLabels(lastRelease.Labels, u.Labels),
} }
if len(notesTxt) > 0 { if len(notesTxt) > 0 {
@ -603,3 +610,13 @@ func objectKey(r *resource.Info) string {
gvk := r.Object.GetObjectKind().GroupVersionKind() gvk := r.Object.GetObjectKind().GroupVersionKind()
return fmt.Sprintf("%s/%s/%s/%s", gvk.GroupVersion().String(), gvk.Kind, r.Namespace, r.Name) return fmt.Sprintf("%s/%s/%s/%s", gvk.GroupVersion().String(), gvk.Kind, r.Namespace, r.Name)
} }
func mergeCustomLabels(current, desired map[string]string) map[string]string {
labels := mergeStrStrMaps(current, desired)
for k, v := range labels {
if v == "null" {
delete(labels, k)
}
}
return labels
}

@ -19,10 +19,12 @@ package action
import ( import (
"context" "context"
"fmt" "fmt"
"reflect"
"testing" "testing"
"time" "time"
"helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/storage/driver"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -386,5 +388,97 @@ func TestUpgradeRelease_Interrupted_Atomic(t *testing.T) {
is.NoError(err) is.NoError(err)
// Should have rolled back to the previous // Should have rolled back to the previous
is.Equal(updatedRes.Info.Status, release.StatusDeployed) is.Equal(updatedRes.Info.Status, release.StatusDeployed)
}
func TestMergeCustomLabels(t *testing.T) {
var tests = [][3]map[string]string{
{nil, nil, map[string]string{}},
{map[string]string{}, map[string]string{}, map[string]string{}},
{map[string]string{"k1": "v1", "k2": "v2"}, nil, map[string]string{"k1": "v1", "k2": "v2"}},
{nil, map[string]string{"k1": "v1", "k2": "v2"}, map[string]string{"k1": "v1", "k2": "v2"}},
{map[string]string{"k1": "v1", "k2": "v2"}, map[string]string{"k1": "null", "k2": "v3"}, map[string]string{"k2": "v3"}},
}
for _, test := range tests {
if output := mergeCustomLabels(test[0], test[1]); !reflect.DeepEqual(test[2], output) {
t.Errorf("Expected {%v}, got {%v}", test[2], output)
}
}
}
func TestUpgradeRelease_Labels(t *testing.T) {
is := assert.New(t)
upAction := upgradeAction(t)
rel := releaseStub()
rel.Name = "labels"
// It's needed to check that suppressed release would keep original labels
rel.Labels = map[string]string{
"key1": "val1",
"key2": "val2.1",
}
rel.Info.Status = release.StatusDeployed
err := upAction.cfg.Releases.Create(rel)
is.NoError(err)
upAction.Labels = map[string]string{
"key1": "null",
"key2": "val2.2",
"key3": "val3",
}
// setting newValues and upgrading
res, err := upAction.Run(rel.Name, buildChart(), nil)
is.NoError(err)
// Now make sure it is actually upgraded and labels were merged
updatedRes, err := upAction.cfg.Releases.Get(res.Name, 2)
is.NoError(err)
if updatedRes == nil {
is.Fail("Updated Release is nil")
return
}
is.Equal(release.StatusDeployed, updatedRes.Info.Status)
is.Equal(mergeCustomLabels(rel.Labels, upAction.Labels), updatedRes.Labels)
// Now make sure it is suppressed release still contains original labels
initialRes, err := upAction.cfg.Releases.Get(res.Name, 1)
is.NoError(err)
if initialRes == nil {
is.Fail("Updated Release is nil")
return
}
is.Equal(initialRes.Info.Status, release.StatusSuperseded)
is.Equal(initialRes.Labels, rel.Labels)
}
func TestUpgradeRelease_SystemLabels(t *testing.T) {
is := assert.New(t)
upAction := upgradeAction(t)
rel := releaseStub()
rel.Name = "labels"
// It's needed to check that suppressed release would keep original labels
rel.Labels = map[string]string{
"key1": "val1",
"key2": "val2.1",
}
rel.Info.Status = release.StatusDeployed
err := upAction.cfg.Releases.Create(rel)
is.NoError(err)
upAction.Labels = map[string]string{
"key1": "null",
"key2": "val2.2",
"owner": "val3",
}
// setting newValues and upgrading
_, err = upAction.Run(rel.Name, buildChart(), nil)
if err == nil {
t.Fatal("expected an error")
}
is.Equal(fmt.Errorf("user suplied labels contains system reserved label name. System labels: %+v", driver.GetSystemLabels()), err)
} }

@ -85,7 +85,10 @@ func ensureArchive(name string, raw *os.File) error {
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
return fmt.Errorf("file '%s' cannot be read: %s", name, err) return fmt.Errorf("file '%s' cannot be read: %s", name, err)
} }
if contentType := http.DetectContentType(buffer); contentType != "application/x-gzip" {
// Helm may identify achieve of the application/x-gzip as application/vnd.ms-fontobject.
// Fix for: https://github.com/helm/helm/issues/12261
if contentType := http.DetectContentType(buffer); contentType != "application/x-gzip" && !isGZipApplication(buffer) {
// TODO: Is there a way to reliably test if a file content is YAML? ghodss/yaml accepts a wide // TODO: Is there a way to reliably test if a file content is YAML? ghodss/yaml accepts a wide
// variety of content (Makefile, .zshrc) as valid YAML without errors. // variety of content (Makefile, .zshrc) as valid YAML without errors.
@ -98,6 +101,12 @@ func ensureArchive(name string, raw *os.File) error {
return nil return nil
} }
// isGZipApplication checks whether the achieve is of the application/x-gzip type.
func isGZipApplication(data []byte) bool {
sig := []byte("\x1F\x8B\x08")
return bytes.HasPrefix(data, sig)
}
// LoadArchiveFiles reads in files out of an archive into memory. This function // LoadArchiveFiles reads in files out of an archive into memory. This function
// performs important path security checks and should always be used before // performs important path security checks and should always be used before
// expanding a tarball // expanding a tarball

@ -62,8 +62,8 @@ func TestDefaultCapabilities(t *testing.T) {
func TestDefaultCapabilitiesHelmVersion(t *testing.T) { func TestDefaultCapabilitiesHelmVersion(t *testing.T) {
hv := DefaultCapabilities.HelmVersion hv := DefaultCapabilities.HelmVersion
if hv.Version != "v3.12" { if hv.Version != "v3.13" {
t.Errorf("Expected default HelmVersion to be v3.12, got %q", hv.Version) t.Errorf("Expected default HelmVersion to be v3.13, got %q", hv.Version)
} }
} }

@ -310,7 +310,7 @@ spec:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
labels: labels:
{{- include "<CHARTNAME>.selectorLabels" . | nindent 8 }} {{- include "<CHARTNAME>.labels" . | nindent 8 }}
{{- with .Values.podLabels }} {{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}

@ -29,14 +29,12 @@ import (
"testing" "testing"
"time" "time"
"helm.sh/helm/v3/internal/test/ensure"
"helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader" "helm.sh/helm/v3/pkg/chart/loader"
) )
func TestSave(t *testing.T) { func TestSave(t *testing.T) {
tmp := ensure.TempDir(t) tmp := t.TempDir()
defer os.RemoveAll(tmp)
for _, dest := range []string{tmp, filepath.Join(tmp, "newdir")} { for _, dest := range []string{tmp, filepath.Join(tmp, "newdir")} {
t.Run("outDir="+dest, func(t *testing.T) { t.Run("outDir="+dest, func(t *testing.T) {

@ -269,10 +269,9 @@ func TestDownloadTo_TLS(t *testing.T) {
} }
func TestDownloadTo_VerifyLater(t *testing.T) { func TestDownloadTo_VerifyLater(t *testing.T) {
defer ensure.HelmHome(t)() ensure.HelmHome(t)
dest := ensure.TempDir(t) dest := t.TempDir()
defer os.RemoveAll(dest)
// Set up a fake repo // Set up a fake repo
srv, err := repotest.NewTempServerWithCleanup(t, "testdata/*.tgz*") srv, err := repotest.NewTempServerWithCleanup(t, "testdata/*.tgz*")

@ -667,6 +667,7 @@ func (m *Manager) parallelRepoUpdate(repos []*repo.Entry) error {
if err != nil { if err != nil {
return err return err
} }
r.CachePath = m.RepositoryCache
wg.Add(1) wg.Add(1)
go func(r *repo.ChartRepository) { go func(r *repo.ChartRepository) {
if _, err := r.DownloadIndexFile(); err != nil { if _, err := r.DownloadIndexFile(); err != nil {

@ -179,9 +179,21 @@ func (p Providers) ByScheme(scheme string) (Getter, error) {
return nil, errors.Errorf("scheme %q not supported", scheme) return nil, errors.Errorf("scheme %q not supported", scheme)
} }
const (
// The cost timeout references curl's default connection timeout.
// https://github.com/curl/curl/blob/master/lib/connect.h#L40C21-L40C21
// The helm commands are usually executed manually. Considering the acceptable waiting time, we reduced the entire request time to 120s.
DefaultHTTPTimeout = 120
)
var defaultOptions = []Option{WithTimeout(time.Second * DefaultHTTPTimeout)}
var httpProvider = Provider{ var httpProvider = Provider{
Schemes: []string{"http", "https"}, Schemes: []string{"http", "https"},
New: NewHTTPGetter, New: func(options ...Option) (Getter, error) {
options = append(options, defaultOptions...)
return NewHTTPGetter(options...)
},
} }
var ociProvider = Provider{ var ociProvider = Provider{

@ -69,6 +69,14 @@ var ManagedFieldsManager string
// Client represents a client capable of communicating with the Kubernetes API. // Client represents a client capable of communicating with the Kubernetes API.
type Client struct { type Client struct {
// Factory provides a minimal version of the kubectl Factory interface. If
// you need the full Factory you can type switch to the full interface.
// Since Kubernetes Go API does not provide backwards compatibility across
// minor versions, this API does not follow Helm backwards compatibility.
// Helm is exposing Kubernetes in this property and cannot guarantee this
// will not change. The minimal interface only has the functions that Helm
// needs. The smaller surface area of the interface means there is a lower
// chance of it changing.
Factory Factory Factory Factory
Log func(string, ...interface{}) Log func(string, ...interface{})
// Namespace allows to bypass the kubeconfig file for the choice of the namespace // Namespace allows to bypass the kubeconfig file for the choice of the namespace

@ -26,6 +26,12 @@ import (
// Factory provides abstractions that allow the Kubectl command to be extended across multiple types // Factory provides abstractions that allow the Kubectl command to be extended across multiple types
// of resources and different API sets. // of resources and different API sets.
// This interface is a minimal copy of the kubectl Factory interface containing only the functions
// needed by Helm. Since Kubernetes Go APIs, including interfaces, can change in any minor release
// this interface is not covered by the Helm backwards compatibility guarantee. The reasons for the
// minimal copy is that it does not include the full interface. Changes or additions to functions
// Helm does not need are not impacted or exposed. This minimizes the impact of Kubernetes changes
// being exposed.
type Factory interface { type Factory interface {
// ToRawKubeConfigLoader return kubeconfig loader as-is // ToRawKubeConfigLoader return kubeconfig loader as-is
ToRawKubeConfigLoader() clientcmd.ClientConfig ToRawKubeConfigLoader() clientcmd.ClientConfig

@ -16,11 +16,9 @@ limitations under the License.
package rules package rules
import ( import (
"os"
"path/filepath" "path/filepath"
"testing" "testing"
"helm.sh/helm/v3/internal/test/ensure"
"helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chartutil" "helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/lint/support" "helm.sh/helm/v3/pkg/lint/support"
@ -79,8 +77,7 @@ func TestValidateDependencyInMetadata(t *testing.T) {
} }
func TestDependencies(t *testing.T) { func TestDependencies(t *testing.T) {
tmp := ensure.TempDir(t) tmp := t.TempDir()
defer os.RemoveAll(tmp)
c := chartWithBadDependencies() c := chartWithBadDependencies()
err := chartutil.SaveDir(&c, tmp) err := chartutil.SaveDir(&c, tmp)

@ -23,7 +23,6 @@ import (
"strings" "strings"
"testing" "testing"
"helm.sh/helm/v3/internal/test/ensure"
"helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chartutil" "helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/lint/support" "helm.sh/helm/v3/pkg/lint/support"
@ -221,8 +220,7 @@ func TestDeprecatedAPIFails(t *testing.T) {
}, },
}, },
} }
tmpdir := ensure.TempDir(t) tmpdir := t.TempDir()
defer os.RemoveAll(tmpdir)
if err := chartutil.SaveDir(&mychart, tmpdir); err != nil { if err := chartutil.SaveDir(&mychart, tmpdir); err != nil {
t.Fatal(err) t.Fatal(err)
@ -278,8 +276,7 @@ func TestStrictTemplateParsingMapError(t *testing.T) {
}, },
}, },
} }
dir := ensure.TempDir(t) dir := t.TempDir()
defer os.RemoveAll(dir)
if err := chartutil.SaveDir(&ch, dir); err != nil { if err := chartutil.SaveDir(&ch, dir); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -408,8 +405,7 @@ func TestEmptyWithCommentsManifests(t *testing.T) {
}, },
}, },
} }
tmpdir := ensure.TempDir(t) tmpdir := t.TempDir()
defer os.RemoveAll(tmpdir)
if err := chartutil.SaveDir(&mychart, tmpdir); err != nil { if err := chartutil.SaveDir(&mychart, tmpdir); err != nil {
t.Fatal(err) t.Fatal(err)

@ -66,7 +66,6 @@ func TestValidateValuesFileWellFormed(t *testing.T) {
not:well[]{}formed not:well[]{}formed
` `
tmpdir := ensure.TempFile(t, "values.yaml", []byte(badYaml)) tmpdir := ensure.TempFile(t, "values.yaml", []byte(badYaml))
defer os.RemoveAll(tmpdir)
valfile := filepath.Join(tmpdir, "values.yaml") valfile := filepath.Join(tmpdir, "values.yaml")
if err := validateValuesFile(valfile, map[string]interface{}{}); err == nil { if err := validateValuesFile(valfile, map[string]interface{}{}); err == nil {
t.Fatal("expected values file to fail parsing") t.Fatal("expected values file to fail parsing")
@ -76,7 +75,6 @@ func TestValidateValuesFileWellFormed(t *testing.T) {
func TestValidateValuesFileSchema(t *testing.T) { func TestValidateValuesFileSchema(t *testing.T) {
yaml := "username: admin\npassword: swordfish" yaml := "username: admin\npassword: swordfish"
tmpdir := ensure.TempFile(t, "values.yaml", []byte(yaml)) tmpdir := ensure.TempFile(t, "values.yaml", []byte(yaml))
defer os.RemoveAll(tmpdir)
createTestingSchema(t, tmpdir) createTestingSchema(t, tmpdir)
valfile := filepath.Join(tmpdir, "values.yaml") valfile := filepath.Join(tmpdir, "values.yaml")
@ -89,7 +87,6 @@ func TestValidateValuesFileSchemaFailure(t *testing.T) {
// 1234 is an int, not a string. This should fail. // 1234 is an int, not a string. This should fail.
yaml := "username: 1234\npassword: swordfish" yaml := "username: 1234\npassword: swordfish"
tmpdir := ensure.TempFile(t, "values.yaml", []byte(yaml)) tmpdir := ensure.TempFile(t, "values.yaml", []byte(yaml))
defer os.RemoveAll(tmpdir)
createTestingSchema(t, tmpdir) createTestingSchema(t, tmpdir)
valfile := filepath.Join(tmpdir, "values.yaml") valfile := filepath.Join(tmpdir, "values.yaml")
@ -108,7 +105,6 @@ func TestValidateValuesFileSchemaOverrides(t *testing.T) {
"password": "swordfish", "password": "swordfish",
} }
tmpdir := ensure.TempFile(t, "values.yaml", []byte(yaml)) tmpdir := ensure.TempFile(t, "values.yaml", []byte(yaml))
defer os.RemoveAll(tmpdir)
createTestingSchema(t, tmpdir) createTestingSchema(t, tmpdir)
valfile := filepath.Join(tmpdir, "values.yaml") valfile := filepath.Join(tmpdir, "values.yaml")
@ -145,7 +141,6 @@ func TestValidateValuesFile(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
tmpdir := ensure.TempFile(t, "values.yaml", []byte(tt.yaml)) tmpdir := ensure.TempFile(t, "values.yaml", []byte(tt.yaml))
defer os.RemoveAll(tmpdir)
createTestingSchema(t, tmpdir) createTestingSchema(t, tmpdir)
valfile := filepath.Join(tmpdir, "values.yaml") valfile := filepath.Join(tmpdir, "values.yaml")

@ -79,7 +79,7 @@ func mockArchiveServer() *httptest.Server {
} }
func TestHTTPInstaller(t *testing.T) { func TestHTTPInstaller(t *testing.T) {
defer ensure.HelmHome(t)() ensure.HelmHome(t)
srv := mockArchiveServer() srv := mockArchiveServer()
defer srv.Close() defer srv.Close()
@ -128,7 +128,7 @@ func TestHTTPInstaller(t *testing.T) {
} }
func TestHTTPInstallerNonExistentVersion(t *testing.T) { func TestHTTPInstallerNonExistentVersion(t *testing.T) {
defer ensure.HelmHome(t)() ensure.HelmHome(t)
srv := mockArchiveServer() srv := mockArchiveServer()
defer srv.Close() defer srv.Close()
source := srv.URL + "/plugins/fake-plugin-0.0.1.tar.gz" source := srv.URL + "/plugins/fake-plugin-0.0.1.tar.gz"
@ -164,7 +164,7 @@ func TestHTTPInstallerUpdate(t *testing.T) {
srv := mockArchiveServer() srv := mockArchiveServer()
defer srv.Close() defer srv.Close()
source := srv.URL + "/plugins/fake-plugin-0.0.1.tar.gz" source := srv.URL + "/plugins/fake-plugin-0.0.1.tar.gz"
defer ensure.HelmHome(t)() ensure.HelmHome(t)
if err := os.MkdirAll(helmpath.DataPath("plugins"), 0755); err != nil { if err := os.MkdirAll(helmpath.DataPath("plugins"), 0755); err != nil {
t.Fatalf("Could not create %s: %s", helmpath.DataPath("plugins"), err) t.Fatalf("Could not create %s: %s", helmpath.DataPath("plugins"), err)

@ -49,7 +49,7 @@ func (r *testRepo) UpdateVersion(version string) error {
} }
func TestVCSInstaller(t *testing.T) { func TestVCSInstaller(t *testing.T) {
defer ensure.HelmHome(t)() ensure.HelmHome(t)
if err := os.MkdirAll(helmpath.DataPath("plugins"), 0755); err != nil { if err := os.MkdirAll(helmpath.DataPath("plugins"), 0755); err != nil {
t.Fatalf("Could not create %s: %s", helmpath.DataPath("plugins"), err) t.Fatalf("Could not create %s: %s", helmpath.DataPath("plugins"), err)
@ -102,7 +102,7 @@ func TestVCSInstaller(t *testing.T) {
} }
func TestVCSInstallerNonExistentVersion(t *testing.T) { func TestVCSInstallerNonExistentVersion(t *testing.T) {
defer ensure.HelmHome(t)() ensure.HelmHome(t)
source := "https://github.com/adamreese/helm-env" source := "https://github.com/adamreese/helm-env"
version := "0.2.0" version := "0.2.0"
@ -124,7 +124,7 @@ func TestVCSInstallerNonExistentVersion(t *testing.T) {
} }
} }
func TestVCSInstallerUpdate(t *testing.T) { func TestVCSInstallerUpdate(t *testing.T) {
defer ensure.HelmHome(t)() ensure.HelmHome(t)
source := "https://github.com/adamreese/helm-env" source := "https://github.com/adamreese/helm-env"

@ -121,10 +121,10 @@ func getPlatformCommand(cmds []PlatformCommand) []string {
eq := strings.EqualFold eq := strings.EqualFold
for _, c := range cmds { for _, c := range cmds {
if eq(c.OperatingSystem, runtime.GOOS) { if eq(c.OperatingSystem, runtime.GOOS) {
command = strings.Split(os.ExpandEnv(c.Command), " ") command = strings.Split(c.Command, " ")
} }
if eq(c.OperatingSystem, runtime.GOOS) && eq(c.Architecture, runtime.GOARCH) { if eq(c.OperatingSystem, runtime.GOOS) && eq(c.Architecture, runtime.GOARCH) {
return strings.Split(os.ExpandEnv(c.Command), " ") return strings.Split(c.Command, " ")
} }
} }
return command return command
@ -148,16 +148,19 @@ func (p *Plugin) PrepareCommand(extraArgs []string) (string, []string, error) {
parts = getPlatformCommand(p.Metadata.PlatformCommand) parts = getPlatformCommand(p.Metadata.PlatformCommand)
} }
if platCmdLen == 0 || parts == nil { if platCmdLen == 0 || parts == nil {
parts = strings.Split(os.ExpandEnv(p.Metadata.Command), " ") parts = strings.Split(p.Metadata.Command, " ")
} }
if len(parts) == 0 || parts[0] == "" { if len(parts) == 0 || parts[0] == "" {
return "", nil, fmt.Errorf("no plugin command is applicable") return "", nil, fmt.Errorf("no plugin command is applicable")
} }
main := parts[0] main := os.ExpandEnv(parts[0])
baseArgs := []string{} baseArgs := []string{}
if len(parts) > 1 { if len(parts) > 1 {
baseArgs = parts[1:] for _, cmdpart := range parts[1:] {
cmdexp := os.ExpandEnv(cmdpart)
baseArgs = append(baseArgs, cmdexp)
}
} }
if !p.Metadata.IgnoreFlags { if !p.Metadata.IgnoreFlags {
baseArgs = append(baseArgs, extraArgs...) baseArgs = append(baseArgs, extraArgs...)

@ -329,6 +329,26 @@ func TestSetupEnv(t *testing.T) {
} }
} }
func TestSetupEnvWithSpace(t *testing.T) {
name := "sureshdsk"
base := filepath.Join("testdata/helm home/helm/plugins", name)
s := cli.New()
s.PluginsDirectory = "testdata/helm home/helm/plugins"
SetupPluginEnv(s, name, base)
for _, tt := range []struct {
name, expect string
}{
{"HELM_PLUGIN_NAME", name},
{"HELM_PLUGIN_DIR", base},
} {
if got := os.Getenv(tt.name); got != tt.expect {
t.Errorf("Expected $%s=%q, got %q", tt.name, tt.expect, got)
}
}
}
func TestValidatePluginData(t *testing.T) { func TestValidatePluginData(t *testing.T) {
for i, item := range []struct { for i, item := range []struct {
pass bool pass bool

@ -25,8 +25,6 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"helm.sh/helm/v3/internal/test/ensure"
) )
const testingScript = `#!/bin/sh const testingScript = `#!/bin/sh
@ -40,8 +38,7 @@ fi
func TestGetFullPath(t *testing.T) { func TestGetFullPath(t *testing.T) {
is := assert.New(t) is := assert.New(t)
t.Run("full path resolves correctly", func(t *testing.T) { t.Run("full path resolves correctly", func(t *testing.T) {
testpath, cleanup := setupTestingScript(t) testpath := setupTestingScript(t)
defer cleanup()
fullPath, err := getFullPath(testpath) fullPath, err := getFullPath(testpath)
is.NoError(err) is.NoError(err)
@ -49,8 +46,7 @@ func TestGetFullPath(t *testing.T) {
}) })
t.Run("relative path resolves correctly", func(t *testing.T) { t.Run("relative path resolves correctly", func(t *testing.T) {
testpath, cleanup := setupTestingScript(t) testpath := setupTestingScript(t)
defer cleanup()
currentDir, err := os.Getwd() currentDir, err := os.Getwd()
require.NoError(t, err) require.NoError(t, err)
@ -62,8 +58,7 @@ func TestGetFullPath(t *testing.T) {
}) })
t.Run("binary in PATH resolves correctly", func(t *testing.T) { t.Run("binary in PATH resolves correctly", func(t *testing.T) {
testpath, cleanup := setupTestingScript(t) testpath := setupTestingScript(t)
defer cleanup()
realPath := os.Getenv("PATH") realPath := os.Getenv("PATH")
os.Setenv("PATH", filepath.Dir(testpath)) os.Setenv("PATH", filepath.Dir(testpath))
@ -116,8 +111,7 @@ func TestExecRun(t *testing.T) {
t.Skip("skipping on windows") t.Skip("skipping on windows")
} }
is := assert.New(t) is := assert.New(t)
testpath, cleanup := setupTestingScript(t) testpath := setupTestingScript(t)
defer cleanup()
renderer, err := NewExec(testpath) renderer, err := NewExec(testpath)
require.NoError(t, err) require.NoError(t, err)
@ -133,8 +127,7 @@ func TestNewExecWithOneArgsRun(t *testing.T) {
t.Skip("skipping on windows") t.Skip("skipping on windows")
} }
is := assert.New(t) is := assert.New(t)
testpath, cleanup := setupTestingScript(t) testpath := setupTestingScript(t)
defer cleanup()
renderer, err := NewExec(testpath, "ARG1") renderer, err := NewExec(testpath, "ARG1")
require.NoError(t, err) require.NoError(t, err)
@ -150,8 +143,7 @@ func TestNewExecWithTwoArgsRun(t *testing.T) {
t.Skip("skipping on windows") t.Skip("skipping on windows")
} }
is := assert.New(t) is := assert.New(t)
testpath, cleanup := setupTestingScript(t) testpath := setupTestingScript(t)
defer cleanup()
renderer, err := NewExec(testpath, "ARG1", "ARG2") renderer, err := NewExec(testpath, "ARG1", "ARG2")
require.NoError(t, err) require.NoError(t, err)
@ -161,10 +153,10 @@ func TestNewExecWithTwoArgsRun(t *testing.T) {
is.Contains(output.String(), "ARG1 ARG2") is.Contains(output.String(), "ARG1 ARG2")
} }
func setupTestingScript(t *testing.T) (filepath string, cleanup func()) { func setupTestingScript(t *testing.T) (filepath string) {
t.Helper() t.Helper()
tempdir := ensure.TempDir(t) tempdir := t.TempDir()
f, err := os.CreateTemp(tempdir, "post-render-test.sh") f, err := os.CreateTemp(tempdir, "post-render-test.sh")
if err != nil { if err != nil {
@ -186,7 +178,5 @@ func setupTestingScript(t *testing.T) (filepath string, cleanup func()) {
t.Fatalf("unable to close tempfile after writing: %s", err) t.Fatalf("unable to close tempfile after writing: %s", err)
} }
return f.Name(), func() { return f.Name()
os.RemoveAll(tempdir)
}
} }

@ -30,7 +30,6 @@ import (
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
"helm.sh/helm/v3/internal/test/ensure"
"helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/cli" "helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/getter" "helm.sh/helm/v3/pkg/getter"
@ -147,8 +146,7 @@ func TestIndexCustomSchemeDownload(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Problem loading chart repository from %s: %v", repoURL, err) t.Fatalf("Problem loading chart repository from %s: %v", repoURL, err)
} }
repo.CachePath = ensure.TempDir(t) repo.CachePath = t.TempDir()
defer os.RemoveAll(repo.CachePath)
tempIndexFile, err := os.CreateTemp("", "test-repo") tempIndexFile, err := os.CreateTemp("", "test-repo")
if err != nil { if err != nil {
@ -349,7 +347,7 @@ func TestFindChartInRepoURL(t *testing.T) {
func TestErrorFindChartInRepoURL(t *testing.T) { func TestErrorFindChartInRepoURL(t *testing.T) {
g := getter.All(&cli.EnvSettings{ g := getter.All(&cli.EnvSettings{
RepositoryCache: ensure.TempDir(t), RepositoryCache: t.TempDir(),
}) })
if _, err := FindChartInRepoURL("http://someserver/something", "nginx", "", "", "", "", g); err == nil { if _, err := FindChartInRepoURL("http://someserver/something", "nginx", "", "", "", "", g); err == nil {

@ -18,6 +18,7 @@ package repo
import ( import (
"bytes" "bytes"
"encoding/json"
"log" "log"
"os" "os"
"path" "path"
@ -232,6 +233,18 @@ func (i IndexFile) WriteFile(dest string, mode os.FileMode) error {
return fileutil.AtomicWriteFile(dest, bytes.NewReader(b), mode) return fileutil.AtomicWriteFile(dest, bytes.NewReader(b), mode)
} }
// WriteJSONFile writes an index file in JSON format to the given destination
// path.
//
// The mode on the file is set to 'mode'.
func (i IndexFile) WriteJSONFile(dest string, mode os.FileMode) error {
b, err := json.MarshalIndent(i, "", " ")
if err != nil {
return err
}
return fileutil.AtomicWriteFile(dest, bytes.NewReader(b), mode)
}
// Merge merges the given index file into this index. // Merge merges the given index file into this index.
// //
// This merges by name and version. // This merges by name and version.
@ -336,7 +349,7 @@ func loadIndex(data []byte, source string) (*IndexFile, error) {
return i, ErrEmptyIndexYaml return i, ErrEmptyIndexYaml
} }
if err := yaml.UnmarshalStrict(data, i); err != nil { if err := jsonOrYamlUnmarshal(data, i); err != nil {
return i, err return i, err
} }
@ -361,3 +374,17 @@ func loadIndex(data []byte, source string) (*IndexFile, error) {
} }
return i, nil return i, nil
} }
// jsonOrYamlUnmarshal unmarshals the given byte slice containing JSON or YAML
// into the provided interface.
//
// It automatically detects whether the data is in JSON or YAML format by
// checking its validity as JSON. If the data is valid JSON, it will use the
// `encoding/json` package to unmarshal it. Otherwise, it will use the
// `sigs.k8s.io/yaml` package to unmarshal the YAML data.
func jsonOrYamlUnmarshal(b []byte, i interface{}) error {
if json.Valid(b) {
return json.Unmarshal(b, i)
}
return yaml.UnmarshalStrict(b, i)
}

@ -19,6 +19,7 @@ package repo
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"encoding/json"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
@ -37,6 +38,7 @@ const (
annotationstestfile = "testdata/local-index-annotations.yaml" annotationstestfile = "testdata/local-index-annotations.yaml"
chartmuseumtestfile = "testdata/chartmuseum-index.yaml" chartmuseumtestfile = "testdata/chartmuseum-index.yaml"
unorderedTestfile = "testdata/local-index-unordered.yaml" unorderedTestfile = "testdata/local-index-unordered.yaml"
jsonTestfile = "testdata/local-index.json"
testRepo = "test-repo" testRepo = "test-repo"
indexWithDuplicates = ` indexWithDuplicates = `
apiVersion: v1 apiVersion: v1
@ -145,6 +147,10 @@ func TestLoadIndex(t *testing.T) {
Name: "chartmuseum index file", Name: "chartmuseum index file",
Filename: chartmuseumtestfile, Filename: chartmuseumtestfile,
}, },
{
Name: "JSON index file",
Filename: jsonTestfile,
},
} }
for _, tc := range tests { for _, tc := range tests {
@ -548,6 +554,27 @@ func TestIndexWrite(t *testing.T) {
} }
} }
func TestIndexJSONWrite(t *testing.T) {
i := NewIndexFile()
if err := i.MustAdd(&chart.Metadata{APIVersion: "v2", Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890"); err != nil {
t.Fatalf("unexpected error: %s", err)
}
dir := t.TempDir()
testpath := filepath.Join(dir, "test")
i.WriteJSONFile(testpath, 0600)
got, err := os.ReadFile(testpath)
if err != nil {
t.Fatal(err)
}
if !json.Valid(got) {
t.Fatal("Index files doesn't contain valid JSON")
}
if !strings.Contains(string(got), "clipper-0.1.0.tgz") {
t.Fatal("Index files doesn't contain expected content")
}
}
func TestAddFileIndexEntriesNil(t *testing.T) { func TestAddFileIndexEntriesNil(t *testing.T) {
i := NewIndexFile() i := NewIndexFile()
i.APIVersion = chart.APIVersionV1 i.APIVersion = chart.APIVersionV1

@ -18,7 +18,6 @@ package repotest
import ( import (
"io" "io"
"net/http" "net/http"
"os"
"path/filepath" "path/filepath"
"testing" "testing"
@ -31,10 +30,9 @@ import (
// Young'n, in these here parts, we test our tests. // Young'n, in these here parts, we test our tests.
func TestServer(t *testing.T) { func TestServer(t *testing.T) {
defer ensure.HelmHome(t)() ensure.HelmHome(t)
rootDir := ensure.TempDir(t) rootDir := t.TempDir()
defer os.RemoveAll(rootDir)
srv := NewServer(rootDir) srv := NewServer(rootDir)
defer srv.Stop() defer srv.Stop()
@ -99,7 +97,7 @@ func TestServer(t *testing.T) {
} }
func TestNewTempServer(t *testing.T) { func TestNewTempServer(t *testing.T) {
defer ensure.HelmHome(t)() ensure.HelmHome(t)
srv, err := NewTempServerWithCleanup(t, "testdata/examplechart-0.1.0.tgz") srv, err := NewTempServerWithCleanup(t, "testdata/examplechart-0.1.0.tgz")
if err != nil { if err != nil {

@ -0,0 +1,53 @@
{
"apiVersion": "v1",
"entries": {
"nginx": [
{
"urls": ["https://charts.helm.sh/stable/nginx-0.2.0.tgz"],
"name": "nginx",
"description": "string",
"version": "0.2.0",
"home": "https://github.com/something/else",
"digest": "sha256:1234567890abcdef",
"keywords": ["popular", "web server", "proxy"],
"apiVersion": "v2"
},
{
"urls": ["https://charts.helm.sh/stable/nginx-0.1.0.tgz"],
"name": "nginx",
"description": "string",
"version": "0.1.0",
"home": "https://github.com/something",
"digest": "sha256:1234567890abcdef",
"keywords": ["popular", "web server", "proxy"],
"apiVersion": "v2"
}
],
"alpine": [
{
"urls": [
"https://charts.helm.sh/stable/alpine-1.0.0.tgz",
"http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz"
],
"name": "alpine",
"description": "string",
"version": "1.0.0",
"home": "https://github.com/something",
"keywords": ["linux", "alpine", "small", "sumtin"],
"digest": "sha256:1234567890abcdef",
"apiVersion": "v2"
}
],
"chartWithNoURL": [
{
"name": "chartWithNoURL",
"description": "string",
"version": "1.0.0",
"home": "https://github.com/something",
"keywords": ["small", "sumtin"],
"digest": "sha256:1234567890abcdef",
"apiVersion": "v2"
}
]
}
}

@ -78,6 +78,7 @@ func (cfgmaps *ConfigMaps) Get(key string) (*rspb.Release, error) {
cfgmaps.Log("get: failed to decode data %q: %s", key, err) cfgmaps.Log("get: failed to decode data %q: %s", key, err)
return nil, err return nil, err
} }
r.Labels = filterSystemLabels(obj.ObjectMeta.Labels)
// return the release object // return the release object
return r, nil return r, nil
} }
@ -106,7 +107,7 @@ func (cfgmaps *ConfigMaps) List(filter func(*rspb.Release) bool) ([]*rspb.Releas
continue continue
} }
rls.Labels = item.ObjectMeta.Labels rls.Labels = filterSystemLabels(item.ObjectMeta.Labels)
if filter(rls) { if filter(rls) {
results = append(results, rls) results = append(results, rls)
@ -145,6 +146,7 @@ func (cfgmaps *ConfigMaps) Query(labels map[string]string) ([]*rspb.Release, err
cfgmaps.Log("query: failed to decode release: %s", err) cfgmaps.Log("query: failed to decode release: %s", err)
continue continue
} }
rls.Labels = filterSystemLabels(item.ObjectMeta.Labels)
results = append(results, rls) results = append(results, rls)
} }
return results, nil return results, nil
@ -157,6 +159,7 @@ func (cfgmaps *ConfigMaps) Create(key string, rls *rspb.Release) error {
var lbs labels var lbs labels
lbs.init() lbs.init()
lbs.fromMap(rls.Labels)
lbs.set("createdAt", strconv.Itoa(int(time.Now().Unix()))) lbs.set("createdAt", strconv.Itoa(int(time.Now().Unix())))
// create a new configmap to hold the release // create a new configmap to hold the release
@ -184,6 +187,7 @@ func (cfgmaps *ConfigMaps) Update(key string, rls *rspb.Release) error {
var lbs labels var lbs labels
lbs.init() lbs.init()
lbs.fromMap(rls.Labels)
lbs.set("modifiedAt", strconv.Itoa(int(time.Now().Unix()))) lbs.set("modifiedAt", strconv.Itoa(int(time.Now().Unix())))
// create a new configmap object to hold the release // create a new configmap object to hold the release
@ -239,6 +243,9 @@ func newConfigMapsObject(key string, rls *rspb.Release, lbs labels) (*v1.ConfigM
lbs.init() lbs.init()
} }
// apply custom labels
lbs.fromMap(rls.Labels)
// apply labels // apply labels
lbs.set("name", rls.Name) lbs.set("name", rls.Name)
lbs.set("owner", owner) lbs.set("owner", owner)

@ -40,6 +40,10 @@ func releaseStub(name string, vers int, namespace string, status rspb.Status) *r
Version: vers, Version: vers,
Namespace: namespace, Namespace: namespace,
Info: &rspb.Info{Status: status}, Info: &rspb.Info{Status: status},
Labels: map[string]string{
"key1": "val1",
"key2": "val2",
},
} }
} }

@ -72,6 +72,7 @@ func (secrets *Secrets) Get(key string) (*rspb.Release, error) {
} }
// found the secret, decode the base64 data string // found the secret, decode the base64 data string
r, err := decodeRelease(string(obj.Data["release"])) r, err := decodeRelease(string(obj.Data["release"]))
r.Labels = filterSystemLabels(obj.ObjectMeta.Labels)
return r, errors.Wrapf(err, "get: failed to decode data %q", key) return r, errors.Wrapf(err, "get: failed to decode data %q", key)
} }
@ -98,7 +99,7 @@ func (secrets *Secrets) List(filter func(*rspb.Release) bool) ([]*rspb.Release,
continue continue
} }
rls.Labels = item.ObjectMeta.Labels rls.Labels = filterSystemLabels(item.ObjectMeta.Labels)
if filter(rls) { if filter(rls) {
results = append(results, rls) results = append(results, rls)
@ -136,6 +137,7 @@ func (secrets *Secrets) Query(labels map[string]string) ([]*rspb.Release, error)
secrets.Log("query: failed to decode release: %s", err) secrets.Log("query: failed to decode release: %s", err)
continue continue
} }
rls.Labels = filterSystemLabels(item.ObjectMeta.Labels)
results = append(results, rls) results = append(results, rls)
} }
return results, nil return results, nil
@ -148,6 +150,7 @@ func (secrets *Secrets) Create(key string, rls *rspb.Release) error {
var lbs labels var lbs labels
lbs.init() lbs.init()
lbs.fromMap(rls.Labels)
lbs.set("createdAt", strconv.Itoa(int(time.Now().Unix()))) lbs.set("createdAt", strconv.Itoa(int(time.Now().Unix())))
// create a new secret to hold the release // create a new secret to hold the release
@ -173,6 +176,7 @@ func (secrets *Secrets) Update(key string, rls *rspb.Release) error {
var lbs labels var lbs labels
lbs.init() lbs.init()
lbs.fromMap(rls.Labels)
lbs.set("modifiedAt", strconv.Itoa(int(time.Now().Unix()))) lbs.set("modifiedAt", strconv.Itoa(int(time.Now().Unix())))
// create a new secret object to hold the release // create a new secret object to hold the release
@ -221,6 +225,9 @@ func newSecretsObject(key string, rls *rspb.Release, lbs labels) (*v1.Secret, er
lbs.init() lbs.init()
} }
// apply custom labels
lbs.fromMap(rls.Labels)
// apply labels // apply labels
lbs.set("name", rls.Name) lbs.set("name", rls.Name)
lbs.set("owner", owner) lbs.set("owner", owner)

@ -49,6 +49,7 @@ const postgreSQLDialect = "postgres"
const SQLDriverName = "SQL" const SQLDriverName = "SQL"
const sqlReleaseTableName = "releases_v1" const sqlReleaseTableName = "releases_v1"
const sqlCustomLabelsTableName = "custom_labels_v1"
const ( const (
sqlReleaseTableKeyColumn = "key" sqlReleaseTableKeyColumn = "key"
@ -61,6 +62,17 @@ const (
sqlReleaseTableOwnerColumn = "owner" sqlReleaseTableOwnerColumn = "owner"
sqlReleaseTableCreatedAtColumn = "createdAt" sqlReleaseTableCreatedAtColumn = "createdAt"
sqlReleaseTableModifiedAtColumn = "modifiedAt" sqlReleaseTableModifiedAtColumn = "modifiedAt"
sqlCustomLabelsTableReleaseKeyColumn = "releaseKey"
sqlCustomLabelsTableReleaseNamespaceColumn = "releaseNamespace"
sqlCustomLabelsTableKeyColumn = "key"
sqlCustomLabelsTableValueColumn = "value"
)
// Following limits based on k8s labels limits - https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set
const (
sqlCustomLabelsTableKeyMaxLenght = 253 + 1 + 63
sqlCustomLabelsTableValueMaxLenght = 63
) )
const ( const (
@ -82,8 +94,42 @@ func (s *SQL) Name() string {
return SQLDriverName return SQLDriverName
} }
// Check if all migrations al
func (s *SQL) checkAlreadyApplied(migrations []*migrate.Migration) bool {
// make map (set) of ids for fast search
migrationsIds := make(map[string]struct{})
for _, migration := range migrations {
migrationsIds[migration.Id] = struct{}{}
}
// get list of applied migrations
migrate.SetDisableCreateTable(true)
records, err := migrate.GetMigrationRecords(s.db.DB, postgreSQLDialect)
migrate.SetDisableCreateTable(false)
if err != nil {
s.Log("checkAlreadyApplied: failed to get migration records: %v", err)
return false
}
for _, record := range records {
if _, ok := migrationsIds[record.Id]; ok {
s.Log("checkAlreadyApplied: found previous migration (Id: %v) applied at %v", record.Id, record.AppliedAt)
delete(migrationsIds, record.Id)
}
}
// check if all migrations appliyed
if len(migrationsIds) != 0 {
for id := range migrationsIds {
s.Log("checkAlreadyApplied: find unapplied migration (id: %v)", id)
}
return false
}
return true
}
func (s *SQL) ensureDBSetup() error { func (s *SQL) ensureDBSetup() error {
// Populate the database with the relations we need if they don't exist yet
migrations := &migrate.MemoryMigrationSource{ migrations := &migrate.MemoryMigrationSource{
Migrations: []*migrate.Migration{ Migrations: []*migrate.Migration{
{ {
@ -91,7 +137,7 @@ func (s *SQL) ensureDBSetup() error {
Up: []string{ Up: []string{
fmt.Sprintf(` fmt.Sprintf(`
CREATE TABLE %s ( CREATE TABLE %s (
%s VARCHAR(67), %s VARCHAR(90),
%s VARCHAR(64) NOT NULL, %s VARCHAR(64) NOT NULL,
%s TEXT NOT NULL, %s TEXT NOT NULL,
%s VARCHAR(64) NOT NULL, %s VARCHAR(64) NOT NULL,
@ -109,9 +155,9 @@ func (s *SQL) ensureDBSetup() error {
CREATE INDEX ON %s (%s); CREATE INDEX ON %s (%s);
CREATE INDEX ON %s (%s); CREATE INDEX ON %s (%s);
CREATE INDEX ON %s (%s); CREATE INDEX ON %s (%s);
GRANT ALL ON %s TO PUBLIC; GRANT ALL ON %s TO PUBLIC;
ALTER TABLE %s ENABLE ROW LEVEL SECURITY; ALTER TABLE %s ENABLE ROW LEVEL SECURITY;
`, `,
sqlReleaseTableName, sqlReleaseTableName,
@ -150,9 +196,50 @@ func (s *SQL) ensureDBSetup() error {
`, sqlReleaseTableName), `, sqlReleaseTableName),
}, },
}, },
{
Id: "custom_labels",
Up: []string{
fmt.Sprintf(`
CREATE TABLE %s (
%s VARCHAR(64),
%s VARCHAR(67),
%s VARCHAR(%d),
%s VARCHAR(%d)
);
CREATE INDEX ON %s (%s, %s);
GRANT ALL ON %s TO PUBLIC;
ALTER TABLE %s ENABLE ROW LEVEL SECURITY;
`,
sqlCustomLabelsTableName,
sqlCustomLabelsTableReleaseKeyColumn,
sqlCustomLabelsTableReleaseNamespaceColumn,
sqlCustomLabelsTableKeyColumn,
sqlCustomLabelsTableKeyMaxLenght,
sqlCustomLabelsTableValueColumn,
sqlCustomLabelsTableValueMaxLenght,
sqlCustomLabelsTableName,
sqlCustomLabelsTableReleaseKeyColumn,
sqlCustomLabelsTableReleaseNamespaceColumn,
sqlCustomLabelsTableName,
sqlCustomLabelsTableName,
),
},
Down: []string{
fmt.Sprintf(`
DELETE TABLE %s;
`, sqlCustomLabelsTableName),
},
},
}, },
} }
// Check that init migration already applied
if s.checkAlreadyApplied(migrations.Migrations) {
return nil
}
// Populate the database with the relations we need if they don't exist yet
_, err := migrate.Exec(s.db.DB, postgreSQLDialect, migrations, migrate.Up) _, err := migrate.Exec(s.db.DB, postgreSQLDialect, migrations, migrate.Up)
return err return err
} }
@ -180,6 +267,13 @@ type SQLReleaseWrapper struct {
ModifiedAt int `db:"modifiedAt"` ModifiedAt int `db:"modifiedAt"`
} }
type SQLReleaseCustomLabelWrapper struct {
ReleaseKey string `db:"release_key"`
ReleaseNamespace string `db:"release_namespace"`
Key string `db:"key"`
Value string `db:"value"`
}
// NewSQL initializes a new sql driver. // NewSQL initializes a new sql driver.
func NewSQL(connectionString string, logger func(string, ...interface{}), namespace string) (*SQL, error) { func NewSQL(connectionString string, logger func(string, ...interface{}), namespace string) (*SQL, error) {
db, err := sqlx.Connect(postgreSQLDialect, connectionString) db, err := sqlx.Connect(postgreSQLDialect, connectionString)
@ -230,13 +324,18 @@ func (s *SQL) Get(key string) (*rspb.Release, error) {
return nil, err return nil, err
} }
if release.Labels, err = s.getReleaseCustomLabels(key, s.namespace); err != nil {
s.Log("failed to get release %s/%s custom labels: %v", s.namespace, key, err)
return nil, err
}
return release, nil return release, nil
} }
// List returns the list of all releases such that filter(release) == true // List returns the list of all releases such that filter(release) == true
func (s *SQL) List(filter func(*rspb.Release) bool) ([]*rspb.Release, error) { func (s *SQL) List(filter func(*rspb.Release) bool) ([]*rspb.Release, error) {
sb := s.statementBuilder. sb := s.statementBuilder.
Select(sqlReleaseTableBodyColumn). Select(sqlReleaseTableKeyColumn, sqlReleaseTableNamespaceColumn, sqlReleaseTableBodyColumn).
From(sqlReleaseTableName). From(sqlReleaseTableName).
Where(sq.Eq{sqlReleaseTableOwnerColumn: sqlReleaseDefaultOwner}) Where(sq.Eq{sqlReleaseTableOwnerColumn: sqlReleaseDefaultOwner})
@ -264,6 +363,12 @@ func (s *SQL) List(filter func(*rspb.Release) bool) ([]*rspb.Release, error) {
s.Log("list: failed to decode release: %v: %v", record, err) s.Log("list: failed to decode release: %v: %v", record, err)
continue continue
} }
if release.Labels, err = s.getReleaseCustomLabels(record.Key, record.Namespace); err != nil {
s.Log("failed to get release %s/%s custom labels: %v", record.Namespace, record.Key, err)
return nil, err
}
if filter(release) { if filter(release) {
releases = append(releases, release) releases = append(releases, release)
} }
@ -275,7 +380,7 @@ func (s *SQL) List(filter func(*rspb.Release) bool) ([]*rspb.Release, error) {
// Query returns the set of releases that match the provided set of labels. // Query returns the set of releases that match the provided set of labels.
func (s *SQL) Query(labels map[string]string) ([]*rspb.Release, error) { func (s *SQL) Query(labels map[string]string) ([]*rspb.Release, error) {
sb := s.statementBuilder. sb := s.statementBuilder.
Select(sqlReleaseTableBodyColumn). Select(sqlReleaseTableKeyColumn, sqlReleaseTableNamespaceColumn, sqlReleaseTableBodyColumn).
From(sqlReleaseTableName) From(sqlReleaseTableName)
keys := make([]string, 0, len(labels)) keys := make([]string, 0, len(labels))
@ -321,6 +426,12 @@ func (s *SQL) Query(labels map[string]string) ([]*rspb.Release, error) {
s.Log("list: failed to decode release: %v: %v", record, err) s.Log("list: failed to decode release: %v: %v", record, err)
continue continue
} }
if release.Labels, err = s.getReleaseCustomLabels(record.Key, record.Namespace); err != nil {
s.Log("failed to get release %s/%s custom labels: %v", record.Namespace, record.Key, err)
return nil, err
}
releases = append(releases, release) releases = append(releases, release)
} }
@ -403,6 +514,36 @@ func (s *SQL) Create(key string, rls *rspb.Release) error {
s.Log("failed to store release %s in SQL database: %v", key, err) s.Log("failed to store release %s in SQL database: %v", key, err)
return err return err
} }
// Filtering labels before insert cause in SQL storage driver system releases are stored in separate columns of release table
for k, v := range filterSystemLabels(rls.Labels) {
insertLabelsQuery, args, err := s.statementBuilder.
Insert(sqlCustomLabelsTableName).
Columns(
sqlCustomLabelsTableReleaseKeyColumn,
sqlCustomLabelsTableReleaseNamespaceColumn,
sqlCustomLabelsTableKeyColumn,
sqlCustomLabelsTableValueColumn,
).
Values(
key,
namespace,
k,
v,
).ToSql()
if err != nil {
defer transaction.Rollback()
s.Log("failed to build insert query: %v", err)
return err
}
if _, err := transaction.Exec(insertLabelsQuery, args...); err != nil {
defer transaction.Rollback()
s.Log("failed to write Labels: %v", err)
return err
}
}
defer transaction.Commit() defer transaction.Commit()
return nil return nil
@ -487,10 +628,56 @@ func (s *SQL) Delete(key string) (*rspb.Release, error) {
Where(sq.Eq{sqlReleaseTableNamespaceColumn: s.namespace}). Where(sq.Eq{sqlReleaseTableNamespaceColumn: s.namespace}).
ToSql() ToSql()
if err != nil { if err != nil {
s.Log("failed to build select query: %v", err) s.Log("failed to build delete query: %v", err)
return nil, err return nil, err
} }
_, err = transaction.Exec(deleteQuery, args...) _, err = transaction.Exec(deleteQuery, args...)
if err != nil {
s.Log("failed perform delete query: %v", err)
return release, err
}
if release.Labels, err = s.getReleaseCustomLabels(key, s.namespace); err != nil {
s.Log("failed to get release %s/%s custom labels: %v", s.namespace, key, err)
return nil, err
}
deleteCustomLabelsQuery, args, err := s.statementBuilder.
Delete(sqlCustomLabelsTableName).
Where(sq.Eq{sqlCustomLabelsTableReleaseKeyColumn: key}).
Where(sq.Eq{sqlCustomLabelsTableReleaseNamespaceColumn: s.namespace}).
ToSql()
if err != nil {
s.Log("failed to build delete Labels query: %v", err)
return nil, err
}
_, err = transaction.Exec(deleteCustomLabelsQuery, args...)
return release, err return release, err
} }
// Get release custom labels from database
func (s *SQL) getReleaseCustomLabels(key string, namespace string) (map[string]string, error) {
query, args, err := s.statementBuilder.
Select(sqlCustomLabelsTableKeyColumn, sqlCustomLabelsTableValueColumn).
From(sqlCustomLabelsTableName).
Where(sq.Eq{sqlCustomLabelsTableReleaseKeyColumn: key,
sqlCustomLabelsTableReleaseNamespaceColumn: s.namespace}).
ToSql()
if err != nil {
return nil, err
}
var labelsList = []SQLReleaseCustomLabelWrapper{}
if err := s.db.Select(&labelsList, query, args...); err != nil {
return nil, err
}
labelsMap := make(map[string]string)
for _, i := range labelsList {
labelsMap[i.Key] = i.Value
}
return filterSystemLabels(labelsMap), nil
}

@ -21,6 +21,7 @@ import (
"time" "time"
sqlmock "github.com/DATA-DOG/go-sqlmock" sqlmock "github.com/DATA-DOG/go-sqlmock"
migrate "github.com/rubenv/sql-migrate"
rspb "helm.sh/helm/v3/pkg/release" rspb "helm.sh/helm/v3/pkg/release"
) )
@ -62,6 +63,8 @@ func TestSQLGet(t *testing.T) {
), ),
).RowsWillBeClosed() ).RowsWillBeClosed()
mockGetReleaseCustomLabels(mock, key, namespace, rel.Labels)
got, err := sqlDriver.Get(key) got, err := sqlDriver.Get(key)
if err != nil { if err != nil {
t.Fatalf("Failed to get release: %v", err) t.Fatalf("Failed to get release: %v", err)
@ -77,38 +80,42 @@ func TestSQLGet(t *testing.T) {
} }
func TestSQLList(t *testing.T) { func TestSQLList(t *testing.T) {
body1, _ := encodeRelease(releaseStub("key-1", 1, "default", rspb.StatusUninstalled)) releases := []*rspb.Release{}
body2, _ := encodeRelease(releaseStub("key-2", 1, "default", rspb.StatusUninstalled)) releases = append(releases, releaseStub("key-1", 1, "default", rspb.StatusUninstalled))
body3, _ := encodeRelease(releaseStub("key-3", 1, "default", rspb.StatusDeployed)) releases = append(releases, releaseStub("key-2", 1, "default", rspb.StatusUninstalled))
body4, _ := encodeRelease(releaseStub("key-4", 1, "default", rspb.StatusDeployed)) releases = append(releases, releaseStub("key-3", 1, "default", rspb.StatusDeployed))
body5, _ := encodeRelease(releaseStub("key-5", 1, "default", rspb.StatusSuperseded)) releases = append(releases, releaseStub("key-4", 1, "default", rspb.StatusDeployed))
body6, _ := encodeRelease(releaseStub("key-6", 1, "default", rspb.StatusSuperseded)) releases = append(releases, releaseStub("key-5", 1, "default", rspb.StatusSuperseded))
releases = append(releases, releaseStub("key-6", 1, "default", rspb.StatusSuperseded))
sqlDriver, mock := newTestFixtureSQL(t) sqlDriver, mock := newTestFixtureSQL(t)
for i := 0; i < 3; i++ { for i := 0; i < 3; i++ {
query := fmt.Sprintf( query := fmt.Sprintf(
"SELECT %s FROM %s WHERE %s = $1 AND %s = $2", "SELECT %s, %s, %s FROM %s WHERE %s = $1 AND %s = $2",
sqlReleaseTableKeyColumn,
sqlReleaseTableNamespaceColumn,
sqlReleaseTableBodyColumn, sqlReleaseTableBodyColumn,
sqlReleaseTableName, sqlReleaseTableName,
sqlReleaseTableOwnerColumn, sqlReleaseTableOwnerColumn,
sqlReleaseTableNamespaceColumn, sqlReleaseTableNamespaceColumn,
) )
rows := mock.NewRows([]string{
sqlReleaseTableBodyColumn,
})
for _, r := range releases {
body, _ := encodeRelease(r)
rows.AddRow(body)
}
mock. mock.
ExpectQuery(regexp.QuoteMeta(query)). ExpectQuery(regexp.QuoteMeta(query)).
WithArgs(sqlReleaseDefaultOwner, sqlDriver.namespace). WithArgs(sqlReleaseDefaultOwner, sqlDriver.namespace).
WillReturnRows( WillReturnRows(rows).RowsWillBeClosed()
mock.NewRows([]string{
sqlReleaseTableBodyColumn, for _, r := range releases {
}). mockGetReleaseCustomLabels(mock, "", r.Namespace, r.Labels)
AddRow(body1). }
AddRow(body2).
AddRow(body3).
AddRow(body4).
AddRow(body5).
AddRow(body6),
).RowsWillBeClosed()
} }
// list all deleted releases // list all deleted releases
@ -181,6 +188,23 @@ func TestSqlCreate(t *testing.T) {
ExpectExec(regexp.QuoteMeta(query)). ExpectExec(regexp.QuoteMeta(query)).
WithArgs(key, sqlReleaseDefaultType, body, rel.Name, rel.Namespace, int(rel.Version), rel.Info.Status.String(), sqlReleaseDefaultOwner, int(time.Now().Unix())). WithArgs(key, sqlReleaseDefaultType, body, rel.Name, rel.Namespace, int(rel.Version), rel.Info.Status.String(), sqlReleaseDefaultOwner, int(time.Now().Unix())).
WillReturnResult(sqlmock.NewResult(1, 1)) WillReturnResult(sqlmock.NewResult(1, 1))
labelsQuery := fmt.Sprintf(
"INSERT INTO %s (%s,%s,%s,%s) VALUES ($1,$2,$3,$4)",
sqlCustomLabelsTableName,
sqlCustomLabelsTableReleaseKeyColumn,
sqlCustomLabelsTableReleaseNamespaceColumn,
sqlCustomLabelsTableKeyColumn,
sqlCustomLabelsTableValueColumn,
)
mock.MatchExpectationsInOrder(false)
for k, v := range filterSystemLabels(rel.Labels) {
mock.
ExpectExec(regexp.QuoteMeta(labelsQuery)).
WithArgs(key, rel.Namespace, k, v).
WillReturnResult(sqlmock.NewResult(1, 1))
}
mock.ExpectCommit() mock.ExpectCommit()
if err := sqlDriver.Create(key, rel); err != nil { if err := sqlDriver.Create(key, rel); err != nil {
@ -316,7 +340,9 @@ func TestSqlQuery(t *testing.T) {
sqlDriver, mock := newTestFixtureSQL(t) sqlDriver, mock := newTestFixtureSQL(t)
query := fmt.Sprintf( query := fmt.Sprintf(
"SELECT %s FROM %s WHERE %s = $1 AND %s = $2 AND %s = $3 AND %s = $4", "SELECT %s, %s, %s FROM %s WHERE %s = $1 AND %s = $2 AND %s = $3 AND %s = $4",
sqlReleaseTableKeyColumn,
sqlReleaseTableNamespaceColumn,
sqlReleaseTableBodyColumn, sqlReleaseTableBodyColumn,
sqlReleaseTableName, sqlReleaseTableName,
sqlReleaseTableNameColumn, sqlReleaseTableNameColumn,
@ -345,8 +371,12 @@ func TestSqlQuery(t *testing.T) {
), ),
).RowsWillBeClosed() ).RowsWillBeClosed()
mockGetReleaseCustomLabels(mock, "", deployedRelease.Namespace, deployedRelease.Labels)
query = fmt.Sprintf( query = fmt.Sprintf(
"SELECT %s FROM %s WHERE %s = $1 AND %s = $2 AND %s = $3", "SELECT %s, %s, %s FROM %s WHERE %s = $1 AND %s = $2 AND %s = $3",
sqlReleaseTableKeyColumn,
sqlReleaseTableNamespaceColumn,
sqlReleaseTableBodyColumn, sqlReleaseTableBodyColumn,
sqlReleaseTableName, sqlReleaseTableName,
sqlReleaseTableNameColumn, sqlReleaseTableNameColumn,
@ -367,6 +397,9 @@ func TestSqlQuery(t *testing.T) {
), ),
).RowsWillBeClosed() ).RowsWillBeClosed()
mockGetReleaseCustomLabels(mock, "", supersededRelease.Namespace, supersededRelease.Labels)
mockGetReleaseCustomLabels(mock, "", deployedRelease.Namespace, deployedRelease.Labels)
_, err := sqlDriver.Query(labelSetUnknown) _, err := sqlDriver.Query(labelSetUnknown)
if err == nil { if err == nil {
t.Errorf("Expected error {%v}, got nil", ErrReleaseNotFound) t.Errorf("Expected error {%v}, got nil", ErrReleaseNotFound)
@ -447,6 +480,20 @@ func TestSqlDelete(t *testing.T) {
ExpectExec(regexp.QuoteMeta(deleteQuery)). ExpectExec(regexp.QuoteMeta(deleteQuery)).
WithArgs(key, namespace). WithArgs(key, namespace).
WillReturnResult(sqlmock.NewResult(0, 1)) WillReturnResult(sqlmock.NewResult(0, 1))
mockGetReleaseCustomLabels(mock, key, namespace, rel.Labels)
deleteLabelsQuery := fmt.Sprintf(
"DELETE FROM %s WHERE %s = $1 AND %s = $2",
sqlCustomLabelsTableName,
sqlCustomLabelsTableReleaseKeyColumn,
sqlCustomLabelsTableReleaseNamespaceColumn,
)
mock.
ExpectExec(regexp.QuoteMeta(deleteLabelsQuery)).
WithArgs(key, namespace).
WillReturnResult(sqlmock.NewResult(0, 1))
mock.ExpectCommit() mock.ExpectCommit()
deletedRelease, err := sqlDriver.Delete(key) deletedRelease, err := sqlDriver.Delete(key)
@ -461,3 +508,74 @@ func TestSqlDelete(t *testing.T) {
t.Errorf("Expected release {%v}, got {%v}", rel, deletedRelease) t.Errorf("Expected release {%v}, got {%v}", rel, deletedRelease)
} }
} }
func mockGetReleaseCustomLabels(mock sqlmock.Sqlmock, key string, namespace string, labels map[string]string) {
query := fmt.Sprintf(
regexp.QuoteMeta("SELECT %s, %s FROM %s WHERE %s = $1 AND %s = $2"),
sqlCustomLabelsTableKeyColumn,
sqlCustomLabelsTableValueColumn,
sqlCustomLabelsTableName,
sqlCustomLabelsTableReleaseKeyColumn,
sqlCustomLabelsTableReleaseNamespaceColumn,
)
eq := mock.ExpectQuery(query).
WithArgs(key, namespace)
returnRows := mock.NewRows([]string{
sqlCustomLabelsTableKeyColumn,
sqlCustomLabelsTableValueColumn,
})
for k, v := range labels {
returnRows.AddRow(k, v)
}
eq.WillReturnRows(returnRows).RowsWillBeClosed()
}
func TestSqlChechkAppliedMigrations(t *testing.T) {
cases := []struct {
migrationsToApply []*migrate.Migration
appliedMigrationsIds []string
expectedResult bool
errorExplanation string
}{
{
migrationsToApply: []*migrate.Migration{{Id: "init1"}, {Id: "init2"}, {Id: "init3"}},
appliedMigrationsIds: []string{"1", "2", "init1", "3", "init2", "4", "5"},
expectedResult: false,
errorExplanation: "Has found one migration id \"init3\" as applied, that was not applied",
},
{
migrationsToApply: []*migrate.Migration{{Id: "init1"}, {Id: "init2"}, {Id: "init3"}},
appliedMigrationsIds: []string{"1", "2", "init1", "3", "init2", "4", "init3", "5"},
expectedResult: true,
errorExplanation: "Has not found one or more migration ids, that was applied",
},
{
migrationsToApply: []*migrate.Migration{{Id: "init"}},
appliedMigrationsIds: []string{"1", "2", "3", "inits", "4", "tinit", "5"},
expectedResult: false,
errorExplanation: "Has found single \"init\", that was not applied",
},
{
migrationsToApply: []*migrate.Migration{{Id: "init"}},
appliedMigrationsIds: []string{"1", "2", "init", "3", "init2", "4", "init3", "5"},
expectedResult: true,
errorExplanation: "Has not found single migration id \"init\", that was applied",
},
}
for i, c := range cases {
sqlDriver, mock := newTestFixtureSQL(t)
rows := sqlmock.NewRows([]string{"id", "applied_at"})
for _, id := range c.appliedMigrationsIds {
rows.AddRow(id, time.Time{})
}
mock.
ExpectQuery("").
WillReturnRows(rows)
mock.ExpectCommit()
if sqlDriver.checkAlreadyApplied(c.migrationsToApply) != c.expectedResult {
t.Errorf("Test case: %v, Expected: %v, Have: %v, Explanation: %v", i, c.expectedResult, !c.expectedResult, c.errorExplanation)
}
}
}

@ -30,6 +30,8 @@ var b64 = base64.StdEncoding
var magicGzip = []byte{0x1f, 0x8b, 0x08} var magicGzip = []byte{0x1f, 0x8b, 0x08}
var systemLabels = []string{"name", "owner", "status", "version", "createdAt", "modifiedAt"}
// encodeRelease encodes a release returning a base64 encoded // encodeRelease encodes a release returning a base64 encoded
// gzipped string representation, or error. // gzipped string representation, or error.
func encodeRelease(rls *rspb.Release) (string, error) { func encodeRelease(rls *rspb.Release) (string, error) {
@ -83,3 +85,38 @@ func decodeRelease(data string) (*rspb.Release, error) {
} }
return &rls, nil return &rls, nil
} }
// Checks if label is system
func isSystemLabel(key string) bool {
for _, v := range GetSystemLabels() {
if key == v {
return true
}
}
return false
}
// Removes system labels from labels map
func filterSystemLabels(lbs map[string]string) map[string]string {
result := make(map[string]string)
for k, v := range lbs {
if !isSystemLabel(k) {
result[k] = v
}
}
return result
}
// Checks if labels array contains system labels
func ContainsSystemLabels(lbs map[string]string) bool {
for k := range lbs {
if isSystemLabel(k) {
return true
}
}
return false
}
func GetSystemLabels() []string {
return systemLabels
}

@ -0,0 +1,108 @@
/*
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 driver
import (
"reflect"
"testing"
)
func TestGetSystemLabel(t *testing.T) {
if output := GetSystemLabels(); !reflect.DeepEqual(systemLabels, output) {
t.Errorf("Expected {%v}, got {%v}", systemLabels, output)
}
}
func TestIsSystemLabel(t *testing.T) {
tests := map[string]bool{
"name": true,
"owner": true,
"test": false,
"NaMe": false,
}
for label, result := range tests {
if output := isSystemLabel(label); output != result {
t.Errorf("Output %t not equal to expected %t", output, result)
}
}
}
func TestFilterSystemLabels(t *testing.T) {
var tests = [][2]map[string]string{
{nil, map[string]string{}},
{map[string]string{}, map[string]string{}},
{map[string]string{
"name": "name",
"owner": "owner",
"status": "status",
"version": "version",
"createdAt": "createdAt",
"modifiedAt": "modifiedAt",
}, map[string]string{}},
{map[string]string{
"StaTus": "status",
"name": "name",
"owner": "owner",
"key": "value",
}, map[string]string{
"StaTus": "status",
"key": "value",
}},
{map[string]string{
"key1": "value1",
"key2": "value2",
}, map[string]string{
"key1": "value1",
"key2": "value2",
}},
}
for _, test := range tests {
if output := filterSystemLabels(test[0]); !reflect.DeepEqual(test[1], output) {
t.Errorf("Expected {%v}, got {%v}", test[1], output)
}
}
}
func TestContainsSystemLabels(t *testing.T) {
var tests = []struct {
input map[string]string
output bool
}{
{nil, false},
{map[string]string{}, false},
{map[string]string{
"name": "name",
"owner": "owner",
"status": "status",
"version": "version",
"createdAt": "createdAt",
"modifiedAt": "modifiedAt",
}, true},
{map[string]string{
"StaTus": "status",
"name": "name",
"owner": "owner",
"key": "value",
}, true},
{map[string]string{
"key1": "value1",
"key2": "value2",
}, false},
}
for _, test := range tests {
if output := ContainsSystemLabels(test.input); !reflect.DeepEqual(test.output, output) {
t.Errorf("Expected {%v}, got {%v}", test.output, output)
}
}
}

@ -207,6 +207,10 @@ while [[ $# -gt 0 ]]; do
shift shift
if [[ $# -ne 0 ]]; then if [[ $# -ne 0 ]]; then
export DESIRED_VERSION="${1}" export DESIRED_VERSION="${1}"
if [[ "$1" != "v"* ]]; then
echo "Expected version arg ('${DESIRED_VERSION}') to begin with 'v', fixing..."
export DESIRED_VERSION="v${1}"
fi
else else
echo -e "Please provide the desired version. e.g. --version v2.4.0 or -v latest" echo -e "Please provide the desired version. e.g. --version v2.4.0 or -v latest"
exit 0 exit 0

@ -108,11 +108,17 @@ verifySupported() {
checkDesiredVersion() { checkDesiredVersion() {
if [ "x$DESIRED_VERSION" == "x" ]; then if [ "x$DESIRED_VERSION" == "x" ]; then
# Get tag from release URL # Get tag from release URL
local latest_release_url="https://github.com/helm/helm/releases" local latest_release_url="https://api.github.com/repos/helm/helm/releases/latest"
local latest_release_response=""
if [ "${HAS_CURL}" == "true" ]; then if [ "${HAS_CURL}" == "true" ]; then
TAG=$(curl -Ls $latest_release_url | grep 'href="/helm/helm/releases/tag/v3.[0-9]*.[0-9]*\"' | sed -E 's/.*\/helm\/helm\/releases\/tag\/(v[0-9\.]+)".*/\1/g' | head -1) latest_release_response=$( curl -L --silent --show-error --fail "$latest_release_url" 2>&1 || true )
elif [ "${HAS_WGET}" == "true" ]; then elif [ "${HAS_WGET}" == "true" ]; then
TAG=$(wget $latest_release_url -O - 2>&1 | grep 'href="/helm/helm/releases/tag/v3.[0-9]*.[0-9]*\"' | sed -E 's/.*\/helm\/helm\/releases\/tag\/(v[0-9\.]+)".*/\1/g' | head -1) latest_release_response=$( wget "$latest_release_url" -O - 2>&1 || true )
fi
TAG=$( echo "$latest_release_response" | grep '"tag_name"' | sed -E 's/.*"(v[0-9\.]+)".*/\1/g' )
if [ "x$TAG" == "x" ]; then
printf "Could not retrieve the latest release tag information from %s: %s\n" "${latest_release_url}" "${latest_release_response}"
exit 1
fi fi
else else
TAG=$DESIRED_VERSION TAG=$DESIRED_VERSION
@ -299,6 +305,10 @@ while [[ $# -gt 0 ]]; do
shift shift
if [[ $# -ne 0 ]]; then if [[ $# -ne 0 ]]; then
export DESIRED_VERSION="${1}" export DESIRED_VERSION="${1}"
if [[ "$1" != "v"* ]]; then
echo "Expected version arg ('${DESIRED_VERSION}') to begin with 'v', fixing..."
export DESIRED_VERSION="v${1}"
fi
else else
echo -e "Please provide the desired version. e.g. --version v3.0.0 or -v canary" echo -e "Please provide the desired version. e.g. --version v3.0.0 or -v canary"
exit 0 exit 0

Loading…
Cancel
Save