From d6580da875962bbe4dada2e11cb02ce7c0fefc05 Mon Sep 17 00:00:00 2001 From: bwplotka Date: Fri, 9 Sep 2022 16:47:56 +0200 Subject: [PATCH 1/7] Moved from io/ioutil. Signed-off-by: bwplotka --- db/prometheus.go | 5 ++--- env.go | 3 +-- env_docker.go | 3 +-- env_docker_ext_test.go | 4 ++-- instrumented.go | 4 ++-- local.go | 7 +++---- monitoring/monitoring.go | 4 ++-- 7 files changed, 13 insertions(+), 17 deletions(-) diff --git a/db/prometheus.go b/db/prometheus.go index d2c053c..3aee788 100644 --- a/db/prometheus.go +++ b/db/prometheus.go @@ -5,7 +5,6 @@ package e2edb import ( "fmt" - "io/ioutil" "os" "path/filepath" "strconv" @@ -43,7 +42,7 @@ scrape_configs: regex: '^.+:80$' action: drop `, name, f.InternalEndpoint("http")) - if err := ioutil.WriteFile(filepath.Join(f.Dir(), "prometheus.yml"), []byte(config), 0600); err != nil { + if err := os.WriteFile(filepath.Join(f.Dir(), "prometheus.yml"), []byte(config), 0600); err != nil { return &Prometheus{InstrumentedRunnable: e2e.NewErrInstrumentedRunnable(name, errors.Wrap(err, "create prometheus config failed"))} } @@ -67,7 +66,7 @@ scrape_configs: } func (p *Prometheus) SetConfig(config string) error { - if err := ioutil.WriteFile(filepath.Join(p.Dir(), "prometheus.yml"), []byte(config), 0600); err != nil { + if err := os.WriteFile(filepath.Join(p.Dir(), "prometheus.yml"), []byte(config), 0600); err != nil { return errors.Wrap(err, "creating prom config failed") } diff --git a/env.go b/env.go index cf19597..8ffda39 100644 --- a/env.go +++ b/env.go @@ -8,7 +8,6 @@ import ( "crypto/tls" "fmt" "io" - "io/ioutil" "net" "net/http" "os/exec" @@ -321,7 +320,7 @@ func (p *HTTPReadinessProbe) Ready(runnable Runnable) (err error) { } defer errcapture.ExhaustClose(&err, res.Body, "response readiness") - body, _ := ioutil.ReadAll(res.Body) + body, _ := io.ReadAll(res.Body) if res.StatusCode < p.expectedStatusRangeStart || res.StatusCode > p.expectedStatusRangeEnd { return errors.Newf("expected code in range: [%v, %v], got status code: %v and body: %v", p.expectedStatusRangeStart, p.expectedStatusRangeEnd, res.StatusCode, string(body)) } diff --git a/env_docker.go b/env_docker.go index e5ddd6d..07794af 100644 --- a/env_docker.go +++ b/env_docker.go @@ -9,7 +9,6 @@ import ( "crypto/sha256" "encoding/json" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -696,7 +695,7 @@ func getTmpDirectory() (string, error) { } } - tmpDir, err := ioutil.TempDir(dir, "e2e_") + tmpDir, err := os.MkdirTemp(dir, "e2e_") if err != nil { return "", err } diff --git a/env_docker_ext_test.go b/env_docker_ext_test.go index 4b12ea5..610720c 100644 --- a/env_docker_ext_test.go +++ b/env_docker_ext_test.go @@ -5,7 +5,7 @@ package e2e_test import ( "bytes" - "io/ioutil" + "io" "net/http" "path/filepath" "testing" @@ -69,7 +69,7 @@ func TestDockerEnvironment(t *testing.T) { testutil.Ok(t, err) defer resp.Body.Close() - b, err := ioutil.ReadAll(resp.Body) + b, err := io.ReadAll(resp.Body) testutil.Ok(t, err) testutil.Equals(t, expectedFlagsOutputProm1, string(b)) testutil.Equals(t, "", p1.Endpoint("not-existing")) diff --git a/instrumented.go b/instrumented.go index cf77a11..5b2ba47 100644 --- a/instrumented.go +++ b/instrumented.go @@ -6,7 +6,7 @@ package e2e import ( "context" "fmt" - "io/ioutil" + "io" "net/http" "strings" "time" @@ -148,7 +148,7 @@ func (r *instrumentedRunnable) Metrics() (_ string, err error) { } defer errcapture.ExhaustClose(&err, res.Body, "metrics response") - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) return string(body), err } diff --git a/local.go b/local.go index 4cc4a95..b5b7b0d 100644 --- a/local.go +++ b/local.go @@ -6,7 +6,6 @@ package e2e import ( "context" "fmt" - "io/ioutil" "os" "path/filepath" "reflect" @@ -61,13 +60,13 @@ func Containerize(e Environment, name string, startFn func(context.Context) erro } // TODO(saswatamcode): Maybe we can do away with goModTmpl, and just run go mod init shim, go mod edit -replace %v=%v and go mod tidy here. - if err := ioutil.WriteFile(filepath.Join(dir, "go.mod"), []byte(fmt.Sprintf(goModTmpl, modulePath, modulePath, absModulePath)), os.ModePerm); err != nil { + if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte(fmt.Sprintf(goModTmpl, modulePath, modulePath, absModulePath)), os.ModePerm); err != nil { return nil, err } - if err := ioutil.WriteFile(filepath.Join(dir, "main.go"), []byte(fmt.Sprintf(mainFileTmpl, pkg, funcName)), os.ModePerm); err != nil { + if err := os.WriteFile(filepath.Join(dir, "main.go"), []byte(fmt.Sprintf(mainFileTmpl, pkg, funcName)), os.ModePerm); err != nil { return nil, err } - if err := ioutil.WriteFile(filepath.Join(dir, "Dockerfile"), []byte(dockerFile), os.ModePerm); err != nil { + if err := os.WriteFile(filepath.Join(dir, "Dockerfile"), []byte(dockerFile), os.ModePerm); err != nil { return nil, err } diff --git a/monitoring/monitoring.go b/monitoring/monitoring.go index 295379b..4f5d3be 100644 --- a/monitoring/monitoring.go +++ b/monitoring/monitoring.go @@ -4,7 +4,7 @@ package e2emonitoring import ( - "io/ioutil" + "io" "net" "net/http" "strings" @@ -235,7 +235,7 @@ func (s *Service) InstantQuery(query string) (string, error) { } defer errcapture.ExhaustClose(&err, res.Body, "metrics response") - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) return string(body), err } From 1b976c07b93a727e9cb8c16e1463f464747d87e5 Mon Sep 17 00:00:00 2001 From: bwplotka Date: Mon, 12 Sep 2022 20:59:19 +0200 Subject: [PATCH 2/7] Cleaned up monitoring/profiling. Signed-off-by: bwplotka --- db/parca.go | 79 +++++++++++++++++++ db/parcaconfig/parca.go | 42 ++++++++++ .../promconfig/discovery/azure/azure.go | 0 .../promconfig/discovery/config/config.go | 24 +++--- .../promconfig/discovery/consul/consul.go | 0 .../promconfig/discovery/dns/dns.go | 0 .../promconfig/discovery/ec2/ec2.go | 0 .../promconfig/discovery/file/file.go | 0 .../promconfig/discovery/gce/gce.go | 0 .../discovery/kubernetes/kubernetes.go | 0 .../promconfig/discovery/marathon/marathon.go | 0 .../discovery/openstack/openstack.go | 0 .../discovery/targetgroup/targetgroup.go | 0 .../promconfig/discovery/triton/triton.go | 0 .../discovery/zookeeper/zookeeper.go | 0 {monitoring => db}/promconfig/prometheus.go | 2 +- db/prometheus.go | 13 ++- monitoring/monitoring.go | 15 +--- 18 files changed, 148 insertions(+), 27 deletions(-) create mode 100644 db/parca.go create mode 100644 db/parcaconfig/parca.go rename {monitoring => db}/promconfig/discovery/azure/azure.go (100%) rename {monitoring => db}/promconfig/discovery/config/config.go (75%) rename {monitoring => db}/promconfig/discovery/consul/consul.go (100%) rename {monitoring => db}/promconfig/discovery/dns/dns.go (100%) rename {monitoring => db}/promconfig/discovery/ec2/ec2.go (100%) rename {monitoring => db}/promconfig/discovery/file/file.go (100%) rename {monitoring => db}/promconfig/discovery/gce/gce.go (100%) rename {monitoring => db}/promconfig/discovery/kubernetes/kubernetes.go (100%) rename {monitoring => db}/promconfig/discovery/marathon/marathon.go (100%) rename {monitoring => db}/promconfig/discovery/openstack/openstack.go (100%) rename {monitoring => db}/promconfig/discovery/targetgroup/targetgroup.go (100%) rename {monitoring => db}/promconfig/discovery/triton/triton.go (100%) rename {monitoring => db}/promconfig/discovery/zookeeper/zookeeper.go (100%) rename {monitoring => db}/promconfig/prometheus.go (99%) diff --git a/db/parca.go b/db/parca.go new file mode 100644 index 0000000..aa9141f --- /dev/null +++ b/db/parca.go @@ -0,0 +1,79 @@ +package e2edb + +import ( + "fmt" + "os" + "path/filepath" + "strconv" + + "github.com/efficientgo/core/errors" + "github.com/efficientgo/e2e" + "github.com/efficientgo/e2e/db/parcaconfig" + "gopkg.in/yaml.v2" +) + +type Parca struct { + e2e.InstrumentedRunnable + + configHeader string +} + +func NewParca(env e2e.Environment, name string, opts ...Option) *Parca { + o := options{image: "ghcr.io/parca-dev/parca:main-4e20a666"} + for _, opt := range opts { + opt(&o) + } + + f := e2e.NewInstrumentedRunnable(env, name).WithPorts(map[string]int{"http": 7070}, "http").Future() + + args := map[string]string{ + "--config-path": filepath.Join(f.InternalDir(), "data", "parca.yml"), + } + if o.flagOverride != nil { + args = e2e.MergeFlagsWithoutRemovingEmpty(args, o.flagOverride) + } + + config := ` +object_storage: + bucket: + type: "FILESYSTEM" + config: + directory: "./data" +scrape_configs: +` + if err := os.WriteFile(filepath.Join(f.Dir(), "data", "parca.yml"), []byte(config), 0600); err != nil { + return &Parca{InstrumentedRunnable: e2e.NewErrInstrumentedRunnable(name, errors.Wrap(err, "create prometheus config failed"))} + } + + return &Parca{ + configHeader: config, + InstrumentedRunnable: f.Init(e2e.StartOptions{ + Image: o.image, + Command: e2e.NewCommand("/parca", e2e.BuildArgs(args)...), + User: strconv.Itoa(os.Getuid()), + Readiness: e2e.NewTCPReadinessProbe("http"), + })} +} + +// SetScrapeConfigs updates Parca with new configuration marsh +func (p *Parca) SetScrapeConfigs(scrapeJobs []parcaconfig.ScrapeConfig) error { + c := p.configHeader + + b, err := yaml.Marshal(struct { + ScrapeConfigs []parcaconfig.ScrapeConfig `yaml:"scrape_configs,omitempty"` + }{ScrapeConfigs: scrapeJobs}) + if err != nil { + return err + } + + config := fmt.Sprintf("%v\n%v", c, b) + if err := os.WriteFile(filepath.Join(p.Dir(), "data", "parca.yml"), []byte(config), 0600); err != nil { + return errors.Wrap(err, "creating parca config failed") + } + + if p.IsRunning() { + // Reload configuration. + return p.Exec(e2e.NewCommand("kill", "-SIGHUP", "1")) + } + return nil +} diff --git a/db/parcaconfig/parca.go b/db/parcaconfig/parca.go new file mode 100644 index 0000000..c29d751 --- /dev/null +++ b/db/parcaconfig/parca.go @@ -0,0 +1,42 @@ +package parcaconfig + +import ( + "net/url" + + "github.com/efficientgo/e2e/db/promconfig" + sdconfig "github.com/efficientgo/e2e/db/promconfig/discovery/config" + config_util "github.com/prometheus/common/config" + "github.com/prometheus/common/model" +) + +// ScrapeConfig configures a scraping unit for conprof. +type ScrapeConfig struct { + // Name of the section in the config + JobName string `yaml:"job_name"` + // A set of query parameters with which the target is scraped. + Params url.Values `yaml:"params,omitempty"` + // How frequently to scrape the targets of this scrape config. + ScrapeInterval model.Duration `yaml:"scrape_interval,omitempty"` + // The timeout for scraping targets of this config. + ScrapeTimeout model.Duration `yaml:"scrape_timeout,omitempty"` + // The URL scheme with which to fetch metrics from targets. + Scheme string `yaml:"scheme,omitempty"` + + ServiceDiscoveryConfig sdconfig.ServiceDiscoveryConfig `yaml:",inline"` + ProfilingConfig *ProfilingConfig `yaml:"profiling_config,omitempty"` + HTTPClientConfig config_util.HTTPClientConfig `yaml:",inline"` + RelabelConfigs []*promconfig.RelabelConfig `yaml:"relabel_configs,omitempty"` +} + +type ProfilingConfig struct { + PprofConfig PprofConfig `yaml:"pprof_config,omitempty"` + PprofPrefix string `yaml:"path_prefix,omitempty"` +} + +type PprofConfig map[string]*PprofProfilingConfig + +type PprofProfilingConfig struct { + Enabled *bool `yaml:"enabled,omitempty"` + Path string `yaml:"path,omitempty"` + Delta bool `yaml:"delta,omitempty"` +} diff --git a/monitoring/promconfig/discovery/azure/azure.go b/db/promconfig/discovery/azure/azure.go similarity index 100% rename from monitoring/promconfig/discovery/azure/azure.go rename to db/promconfig/discovery/azure/azure.go diff --git a/monitoring/promconfig/discovery/config/config.go b/db/promconfig/discovery/config/config.go similarity index 75% rename from monitoring/promconfig/discovery/config/config.go rename to db/promconfig/discovery/config/config.go index 9160494..5dfde26 100644 --- a/monitoring/promconfig/discovery/config/config.go +++ b/db/promconfig/discovery/config/config.go @@ -20,18 +20,18 @@ package sdconfig import ( - "github.com/efficientgo/e2e/monitoring/promconfig/discovery/azure" - "github.com/efficientgo/e2e/monitoring/promconfig/discovery/consul" - "github.com/efficientgo/e2e/monitoring/promconfig/discovery/dns" - "github.com/efficientgo/e2e/monitoring/promconfig/discovery/ec2" - "github.com/efficientgo/e2e/monitoring/promconfig/discovery/file" - "github.com/efficientgo/e2e/monitoring/promconfig/discovery/gce" - "github.com/efficientgo/e2e/monitoring/promconfig/discovery/kubernetes" - "github.com/efficientgo/e2e/monitoring/promconfig/discovery/marathon" - "github.com/efficientgo/e2e/monitoring/promconfig/discovery/openstack" - "github.com/efficientgo/e2e/monitoring/promconfig/discovery/targetgroup" - "github.com/efficientgo/e2e/monitoring/promconfig/discovery/triton" - "github.com/efficientgo/e2e/monitoring/promconfig/discovery/zookeeper" + "github.com/efficientgo/e2e/db/promconfig/discovery/azure" + "github.com/efficientgo/e2e/db/promconfig/discovery/consul" + "github.com/efficientgo/e2e/db/promconfig/discovery/dns" + "github.com/efficientgo/e2e/db/promconfig/discovery/ec2" + "github.com/efficientgo/e2e/db/promconfig/discovery/file" + "github.com/efficientgo/e2e/db/promconfig/discovery/gce" + "github.com/efficientgo/e2e/db/promconfig/discovery/kubernetes" + "github.com/efficientgo/e2e/db/promconfig/discovery/marathon" + "github.com/efficientgo/e2e/db/promconfig/discovery/openstack" + "github.com/efficientgo/e2e/db/promconfig/discovery/targetgroup" + "github.com/efficientgo/e2e/db/promconfig/discovery/triton" + "github.com/efficientgo/e2e/db/promconfig/discovery/zookeeper" ) // ServiceDiscoveryConfig configures lists of different service discovery mechanisms. diff --git a/monitoring/promconfig/discovery/consul/consul.go b/db/promconfig/discovery/consul/consul.go similarity index 100% rename from monitoring/promconfig/discovery/consul/consul.go rename to db/promconfig/discovery/consul/consul.go diff --git a/monitoring/promconfig/discovery/dns/dns.go b/db/promconfig/discovery/dns/dns.go similarity index 100% rename from monitoring/promconfig/discovery/dns/dns.go rename to db/promconfig/discovery/dns/dns.go diff --git a/monitoring/promconfig/discovery/ec2/ec2.go b/db/promconfig/discovery/ec2/ec2.go similarity index 100% rename from monitoring/promconfig/discovery/ec2/ec2.go rename to db/promconfig/discovery/ec2/ec2.go diff --git a/monitoring/promconfig/discovery/file/file.go b/db/promconfig/discovery/file/file.go similarity index 100% rename from monitoring/promconfig/discovery/file/file.go rename to db/promconfig/discovery/file/file.go diff --git a/monitoring/promconfig/discovery/gce/gce.go b/db/promconfig/discovery/gce/gce.go similarity index 100% rename from monitoring/promconfig/discovery/gce/gce.go rename to db/promconfig/discovery/gce/gce.go diff --git a/monitoring/promconfig/discovery/kubernetes/kubernetes.go b/db/promconfig/discovery/kubernetes/kubernetes.go similarity index 100% rename from monitoring/promconfig/discovery/kubernetes/kubernetes.go rename to db/promconfig/discovery/kubernetes/kubernetes.go diff --git a/monitoring/promconfig/discovery/marathon/marathon.go b/db/promconfig/discovery/marathon/marathon.go similarity index 100% rename from monitoring/promconfig/discovery/marathon/marathon.go rename to db/promconfig/discovery/marathon/marathon.go diff --git a/monitoring/promconfig/discovery/openstack/openstack.go b/db/promconfig/discovery/openstack/openstack.go similarity index 100% rename from monitoring/promconfig/discovery/openstack/openstack.go rename to db/promconfig/discovery/openstack/openstack.go diff --git a/monitoring/promconfig/discovery/targetgroup/targetgroup.go b/db/promconfig/discovery/targetgroup/targetgroup.go similarity index 100% rename from monitoring/promconfig/discovery/targetgroup/targetgroup.go rename to db/promconfig/discovery/targetgroup/targetgroup.go diff --git a/monitoring/promconfig/discovery/triton/triton.go b/db/promconfig/discovery/triton/triton.go similarity index 100% rename from monitoring/promconfig/discovery/triton/triton.go rename to db/promconfig/discovery/triton/triton.go diff --git a/monitoring/promconfig/discovery/zookeeper/zookeeper.go b/db/promconfig/discovery/zookeeper/zookeeper.go similarity index 100% rename from monitoring/promconfig/discovery/zookeeper/zookeeper.go rename to db/promconfig/discovery/zookeeper/zookeeper.go diff --git a/monitoring/promconfig/prometheus.go b/db/promconfig/prometheus.go similarity index 99% rename from monitoring/promconfig/prometheus.go rename to db/promconfig/prometheus.go index 1b6de12..94490ee 100644 --- a/monitoring/promconfig/prometheus.go +++ b/db/promconfig/prometheus.go @@ -9,7 +9,7 @@ import ( "strings" "github.com/efficientgo/core/errors" - sdconfig "github.com/efficientgo/e2e/monitoring/promconfig/discovery/config" + sdconfig "github.com/efficientgo/e2e/db/promconfig/discovery/config" config_util "github.com/prometheus/common/config" "github.com/prometheus/common/model" ) diff --git a/db/prometheus.go b/db/prometheus.go index 3aee788..56c6ba3 100644 --- a/db/prometheus.go +++ b/db/prometheus.go @@ -11,6 +11,8 @@ import ( "github.com/efficientgo/core/errors" "github.com/efficientgo/e2e" + "github.com/efficientgo/e2e/db/promconfig" + "gopkg.in/yaml.v2" ) type Prometheus struct { @@ -56,7 +58,6 @@ scrape_configs: if o.flagOverride != nil { args = e2e.MergeFlagsWithoutRemovingEmpty(args, o.flagOverride) } - return &Prometheus{InstrumentedRunnable: f.Init(e2e.StartOptions{ Image: o.image, Command: e2e.NewCommandWithoutEntrypoint("prometheus", e2e.BuildArgs(args)...), @@ -65,12 +66,18 @@ scrape_configs: })} } -func (p *Prometheus) SetConfig(config string) error { - if err := os.WriteFile(filepath.Join(p.Dir(), "prometheus.yml"), []byte(config), 0600); err != nil { +func (p *Prometheus) SetConfig(config promconfig.Config) error { + b, err := yaml.Marshal(config) + if err != nil { + return err + } + + if err := os.WriteFile(filepath.Join(p.Dir(), "prometheus.yml"), b, 0600); err != nil { return errors.Wrap(err, "creating prom config failed") } if p.IsRunning() { + // Reload configuration. return p.Exec(e2e.NewCommand("kill", "-SIGHUP", "1")) } return nil diff --git a/monitoring/monitoring.go b/monitoring/monitoring.go index 4f5d3be..50e60e1 100644 --- a/monitoring/monitoring.go +++ b/monitoring/monitoring.go @@ -15,16 +15,15 @@ import ( "github.com/efficientgo/core/errors" "github.com/efficientgo/e2e" e2edb "github.com/efficientgo/e2e/db" + "github.com/efficientgo/e2e/db/promconfig" + "github.com/efficientgo/e2e/db/promconfig/discovery/config" + "github.com/efficientgo/e2e/db/promconfig/discovery/targetgroup" e2einteractive "github.com/efficientgo/e2e/interactive" - "github.com/efficientgo/e2e/monitoring/promconfig" - sdconfig "github.com/efficientgo/e2e/monitoring/promconfig/discovery/config" - "github.com/efficientgo/e2e/monitoring/promconfig/discovery/targetgroup" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/common/config" "github.com/prometheus/common/model" - "gopkg.in/yaml.v2" ) type Service struct { @@ -39,8 +38,6 @@ type listener struct { } func (l *listener) updateConfig(started map[string]instrumented) error { - // TODO(bwplotka): Scrape our process metrics too? - cfg := promconfig.Config{ GlobalConfig: promconfig.GlobalConfig{ ExternalLabels: map[model.LabelName]model.LabelValue{"prometheus": model.LabelValue(l.p.Name())}, @@ -93,11 +90,7 @@ func (l *listener) updateConfig(started map[string]instrumented) error { add(name, s) } - o, err := yaml.Marshal(cfg) - if err != nil { - return err - } - return l.p.SetConfig(string(o)) + return l.p.SetConfig(cfg) } type instrumented interface { From 37796da406d45a1faa87bcba51a2394e4668a554 Mon Sep 17 00:00:00 2001 From: bwplotka Date: Tue, 13 Sep 2022 09:05:09 +0200 Subject: [PATCH 3/7] Moving things. Signed-off-by: bwplotka --- db/db.go | 66 +++-- db/parca.go | 79 ------ db/prometheus.go | 84 ------ db/thanos.go | 13 +- env.go | 16 +- env_docker.go | 56 ++-- env_docker_ext_test.go | 3 +- examples/exampleapp/exampleapp_test.go | 9 +- examples/thanos/e2etest_test.go | 9 +- examples/thanos/standalone.go | 6 +- go.mod | 2 +- local.go | 2 +- instrumented.go => monitoring/instrumented.go | 150 ++++------ .../instrumented_composite.go | 10 +- .../instrumented_test.go | 106 +++---- {matchers => monitoring/matchers}/matcher.go | 0 {matchers => monitoring/matchers}/regexp.go | 0 metrics.go => monitoring/metrics.go | 4 +- monitoring/monitoring.go | 125 ++++++-- .../promconfig/discovery/azure/azure.go | 0 .../promconfig/discovery/config/config.go | 24 +- .../promconfig/discovery/consul/consul.go | 0 .../promconfig/discovery/dns/dns.go | 0 .../promconfig/discovery/ec2/ec2.go | 0 .../promconfig/discovery/file/file.go | 0 .../promconfig/discovery/gce/gce.go | 0 .../discovery/kubernetes/kubernetes.go | 0 .../promconfig/discovery/marathon/marathon.go | 0 .../discovery/openstack/openstack.go | 0 .../discovery/targetgroup/targetgroup.go | 0 .../promconfig/discovery/triton/triton.go | 0 .../discovery/zookeeper/zookeeper.go | 0 {db => monitoring}/promconfig/prometheus.go | 1 - {db => profiling}/parcaconfig/parca.go | 3 +- profiling/profiled.go | 76 +++++ profiling/profiling.go | 268 ++++++++++++++++++ 36 files changed, 669 insertions(+), 443 deletions(-) delete mode 100644 db/parca.go delete mode 100644 db/prometheus.go rename instrumented.go => monitoring/instrumented.go (55%) rename instrumented_composite.go => monitoring/instrumented_composite.go (88%) rename instrumented_test.go => monitoring/instrumented_test.go (62%) rename {matchers => monitoring/matchers}/matcher.go (100%) rename {matchers => monitoring/matchers}/regexp.go (100%) rename metrics.go => monitoring/metrics.go (98%) rename {db => monitoring}/promconfig/discovery/azure/azure.go (100%) rename {db => monitoring}/promconfig/discovery/config/config.go (75%) rename {db => monitoring}/promconfig/discovery/consul/consul.go (100%) rename {db => monitoring}/promconfig/discovery/dns/dns.go (100%) rename {db => monitoring}/promconfig/discovery/ec2/ec2.go (100%) rename {db => monitoring}/promconfig/discovery/file/file.go (100%) rename {db => monitoring}/promconfig/discovery/gce/gce.go (100%) rename {db => monitoring}/promconfig/discovery/kubernetes/kubernetes.go (100%) rename {db => monitoring}/promconfig/discovery/marathon/marathon.go (100%) rename {db => monitoring}/promconfig/discovery/openstack/openstack.go (100%) rename {db => monitoring}/promconfig/discovery/targetgroup/targetgroup.go (100%) rename {db => monitoring}/promconfig/discovery/triton/triton.go (100%) rename {db => monitoring}/promconfig/discovery/zookeeper/zookeeper.go (100%) rename {db => monitoring}/promconfig/prometheus.go (99%) rename {db => profiling}/parcaconfig/parca.go (92%) create mode 100644 profiling/profiled.go create mode 100644 profiling/profiling.go diff --git a/db/db.go b/db/db.go index 2b39556..fbaedd6 100644 --- a/db/db.go +++ b/db/db.go @@ -13,8 +13,16 @@ import ( "strings" "github.com/efficientgo/e2e" + e2emonitoring "github.com/efficientgo/e2e/monitoring" + e2eprofiling "github.com/efficientgo/e2e/profiling" ) +type Observable struct { + e2e.Runnable + e2emonitoring.Instrumented + e2eprofiling.Profiled +} + const ( MinioAccessKey = "Cheescake" MinioSecretKey = "supersecret" @@ -52,8 +60,26 @@ func WithMinioSSE() Option { const AccessPortName = "http" +func NewPrometheus(env e2e.Environment, name string, opts ...Option) *e2emonitoring.Prometheus { + o := options{} + for _, opt := range opts { + opt(&o) + } + + return e2emonitoring.NewPrometheus(env, name, o.image, o.flagOverride) +} + +func NewParca(env e2e.Environment, name string, opts ...Option) *e2eprofiling.Parca { + o := options{} + for _, opt := range opts { + opt(&o) + } + + return e2eprofiling.NewParca(env, name, o.image, o.flagOverride) +} + // NewMinio returns minio server, used as a local replacement for S3. -func NewMinio(env e2e.Environment, name, bktName string, opts ...Option) e2e.InstrumentedRunnable { +func NewMinio(env e2e.Environment, name, bktName string, opts ...Option) *e2emonitoring.InstrumentedRunnable { o := options{image: "minio/minio:RELEASE.2022-03-14T18-25-24Z"} for _, opt := range opts { opt(&o) @@ -68,7 +94,7 @@ func NewMinio(env e2e.Environment, name, bktName string, opts ...Option) e2e.Ins "ENABLE_HTTPS=" + "0", } - f := e2e.NewInstrumentedRunnable(env, name).WithPorts(ports, AccessPortName).Future() + f := env.Runnable(name).WithPorts(ports).Future() // Hacky: Create user that matches ID with host ID to be able to remove .minio.sys details on the start. // Proper solution would be to contribute/create our own minio image which is non root. @@ -85,7 +111,7 @@ func NewMinio(env e2e.Environment, name, bktName string, opts ...Option) e2e.Ins command += "curl -sSL --tlsv1.3 -O 'https://raw.githubusercontent.com/minio/kes/master/root.key' -O 'https://raw.githubusercontent.com/minio/kes/master/root.cert' && cp root.* /home/me/ && " } - return f.Init( + return e2emonitoring.AsInstrumented(f.Init( e2e.StartOptions{ Image: o.image, // Create the required bucket before starting minio. @@ -95,40 +121,40 @@ func NewMinio(env e2e.Environment, name, bktName string, opts ...Option) e2e.Ins ), Readiness: e2e.NewHTTPReadinessProbe(AccessPortName, "/minio/health/live", 200, 200), }, - ) + ), AccessPortName) } -func NewConsul(env e2e.Environment, name string, opts ...Option) e2e.InstrumentedRunnable { +func NewConsul(env e2e.Environment, name string, opts ...Option) *e2emonitoring.InstrumentedRunnable { o := options{image: "consul:1.8.4"} for _, opt := range opts { opt(&o) } e2e.MergeFlags() - return e2e.NewInstrumentedRunnable(env, name).WithPorts(map[string]int{AccessPortName: 8500}, AccessPortName).Init( + return e2emonitoring.AsInstrumented(env.Runnable(name).WithPorts(map[string]int{AccessPortName: 8500}).Init( e2e.StartOptions{ Image: o.image, // Run consul in "dev" mode so that the initial leader election is immediate. Command: e2e.NewCommand("agent", "-server", "-client=0.0.0.0", "-dev", "-log-level=err"), Readiness: e2e.NewHTTPReadinessProbe(AccessPortName, "/v1/operator/autopilot/health", 200, 200, `"Healthy": true`), }, - ) + ), AccessPortName) } -func NewDynamoDB(env e2e.Environment, name string, opts ...Option) e2e.InstrumentedRunnable { +func NewDynamoDB(env e2e.Environment, name string, opts ...Option) *e2emonitoring.InstrumentedRunnable { o := options{image: "amazon/dynamodb-local:1.11.477"} for _, opt := range opts { opt(&o) } - return e2e.NewInstrumentedRunnable(env, name).WithPorts(map[string]int{AccessPortName: 8000}, AccessPortName).Init( + return e2emonitoring.AsInstrumented(env.Runnable(name).WithPorts(map[string]int{AccessPortName: 8000}).Init( e2e.StartOptions{ Image: o.image, Command: e2e.NewCommand("-jar", "DynamoDBLocal.jar", "-inMemory", "-sharedDb"), // DynamoDB doesn't have a readiness probe, so we check if the / works even if returns 400 Readiness: e2e.NewHTTPReadinessProbe("http", "/", 400, 400), }, - ) + ), AccessPortName) } func NewBigtable(env e2e.Environment, name string, opts ...Option) e2e.Runnable { @@ -137,40 +163,40 @@ func NewBigtable(env e2e.Environment, name string, opts ...Option) e2e.Runnable opt(&o) } - return e2e.NewInstrumentedRunnable(env, name).Init( + return env.Runnable(name).Init( e2e.StartOptions{ Image: o.image, }, ) } -func NewCassandra(env e2e.Environment, name string, opts ...Option) e2e.InstrumentedRunnable { +func NewCassandra(env e2e.Environment, name string, opts ...Option) *e2emonitoring.InstrumentedRunnable { o := options{image: "rinscy/cassandra:3.11.0"} for _, opt := range opts { opt(&o) } - return e2e.NewInstrumentedRunnable(env, name).WithPorts(map[string]int{AccessPortName: 9042}, AccessPortName).Init( + return e2emonitoring.AsInstrumented(env.Runnable(name).WithPorts(map[string]int{AccessPortName: 9042}).Init( e2e.StartOptions{ Image: o.image, // Readiness probe inspired from https://github.com/kubernetes/examples/blob/b86c9d50be45eaf5ce74dee7159ce38b0e149d38/cassandra/image/files/ready-probe.sh Readiness: e2e.NewCmdReadinessProbe(e2e.NewCommand("bash", "-c", "nodetool status | grep UN")), }, - ) + ), AccessPortName) } -func NewSwiftStorage(env e2e.Environment, name string, opts ...Option) e2e.InstrumentedRunnable { +func NewSwiftStorage(env e2e.Environment, name string, opts ...Option) *e2emonitoring.InstrumentedRunnable { o := options{image: "bouncestorage/swift-aio:55ba4331"} for _, opt := range opts { opt(&o) } - return e2e.NewInstrumentedRunnable(env, name).WithPorts(map[string]int{AccessPortName: 8080}, AccessPortName).Init( + return e2emonitoring.AsInstrumented(env.Runnable(name).WithPorts(map[string]int{AccessPortName: 8080}).Init( e2e.StartOptions{ Image: o.image, Readiness: e2e.NewHTTPReadinessProbe(AccessPortName, "/", 404, 404), }, - ) + ), AccessPortName) } func NewMemcached(env e2e.Environment, name string, opts ...Option) e2e.Runnable { @@ -187,17 +213,17 @@ func NewMemcached(env e2e.Environment, name string, opts ...Option) e2e.Runnable ) } -func NewETCD(env e2e.Environment, name string, opts ...Option) e2e.InstrumentedRunnable { +func NewETCD(env e2e.Environment, name string, opts ...Option) *e2emonitoring.InstrumentedRunnable { o := options{image: "gcr.io/etcd-development/etcd:v3.4.7"} for _, opt := range opts { opt(&o) } - return e2e.NewInstrumentedRunnable(env, name).WithPorts(map[string]int{AccessPortName: 2379, "metrics": 9000}, "metrics").Init( + return e2emonitoring.AsInstrumented(env.Runnable(name).WithPorts(map[string]int{AccessPortName: 2379, "metrics": 9000}).Init( e2e.StartOptions{ Image: o.image, Command: e2e.NewCommand("/usr/local/bin/etcd", "--listen-client-urls=http://0.0.0.0:2379", "--advertise-client-urls=http://0.0.0.0:2379", "--listen-metrics-urls=http://0.0.0.0:9000", "--log-level=error"), Readiness: e2e.NewHTTPReadinessProbe("metrics", "/health", 200, 204), }, - ) + ), "metrics") } diff --git a/db/parca.go b/db/parca.go deleted file mode 100644 index aa9141f..0000000 --- a/db/parca.go +++ /dev/null @@ -1,79 +0,0 @@ -package e2edb - -import ( - "fmt" - "os" - "path/filepath" - "strconv" - - "github.com/efficientgo/core/errors" - "github.com/efficientgo/e2e" - "github.com/efficientgo/e2e/db/parcaconfig" - "gopkg.in/yaml.v2" -) - -type Parca struct { - e2e.InstrumentedRunnable - - configHeader string -} - -func NewParca(env e2e.Environment, name string, opts ...Option) *Parca { - o := options{image: "ghcr.io/parca-dev/parca:main-4e20a666"} - for _, opt := range opts { - opt(&o) - } - - f := e2e.NewInstrumentedRunnable(env, name).WithPorts(map[string]int{"http": 7070}, "http").Future() - - args := map[string]string{ - "--config-path": filepath.Join(f.InternalDir(), "data", "parca.yml"), - } - if o.flagOverride != nil { - args = e2e.MergeFlagsWithoutRemovingEmpty(args, o.flagOverride) - } - - config := ` -object_storage: - bucket: - type: "FILESYSTEM" - config: - directory: "./data" -scrape_configs: -` - if err := os.WriteFile(filepath.Join(f.Dir(), "data", "parca.yml"), []byte(config), 0600); err != nil { - return &Parca{InstrumentedRunnable: e2e.NewErrInstrumentedRunnable(name, errors.Wrap(err, "create prometheus config failed"))} - } - - return &Parca{ - configHeader: config, - InstrumentedRunnable: f.Init(e2e.StartOptions{ - Image: o.image, - Command: e2e.NewCommand("/parca", e2e.BuildArgs(args)...), - User: strconv.Itoa(os.Getuid()), - Readiness: e2e.NewTCPReadinessProbe("http"), - })} -} - -// SetScrapeConfigs updates Parca with new configuration marsh -func (p *Parca) SetScrapeConfigs(scrapeJobs []parcaconfig.ScrapeConfig) error { - c := p.configHeader - - b, err := yaml.Marshal(struct { - ScrapeConfigs []parcaconfig.ScrapeConfig `yaml:"scrape_configs,omitempty"` - }{ScrapeConfigs: scrapeJobs}) - if err != nil { - return err - } - - config := fmt.Sprintf("%v\n%v", c, b) - if err := os.WriteFile(filepath.Join(p.Dir(), "data", "parca.yml"), []byte(config), 0600); err != nil { - return errors.Wrap(err, "creating parca config failed") - } - - if p.IsRunning() { - // Reload configuration. - return p.Exec(e2e.NewCommand("kill", "-SIGHUP", "1")) - } - return nil -} diff --git a/db/prometheus.go b/db/prometheus.go deleted file mode 100644 index 56c6ba3..0000000 --- a/db/prometheus.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) The EfficientGo Authors. -// Licensed under the Apache License 2.0. - -package e2edb - -import ( - "fmt" - "os" - "path/filepath" - "strconv" - - "github.com/efficientgo/core/errors" - "github.com/efficientgo/e2e" - "github.com/efficientgo/e2e/db/promconfig" - "gopkg.in/yaml.v2" -) - -type Prometheus struct { - e2e.InstrumentedRunnable -} - -func NewPrometheus(env e2e.Environment, name string, opts ...Option) *Prometheus { - o := options{image: "quay.io/prometheus/prometheus:v2.37.0"} - for _, opt := range opts { - opt(&o) - } - - ports := map[string]int{"http": 9090} - - f := e2e.NewInstrumentedRunnable(env, name).WithPorts(ports, "http").Future() - config := fmt.Sprintf(` -global: - external_labels: - prometheus: %v -scrape_configs: -- job_name: 'myself' - # Quick scrapes for test purposes. - scrape_interval: 1s - scrape_timeout: 1s - static_configs: - - targets: [%s] - relabel_configs: - - source_labels: ['__address__'] - regex: '^.+:80$' - action: drop -`, name, f.InternalEndpoint("http")) - if err := os.WriteFile(filepath.Join(f.Dir(), "prometheus.yml"), []byte(config), 0600); err != nil { - return &Prometheus{InstrumentedRunnable: e2e.NewErrInstrumentedRunnable(name, errors.Wrap(err, "create prometheus config failed"))} - } - - args := map[string]string{ - "--config.file": filepath.Join(f.InternalDir(), "prometheus.yml"), - "--storage.tsdb.path": f.InternalDir(), - "--storage.tsdb.max-block-duration": "2h", // No compaction - mostly not needed for quick test. - "--log.level": "info", - "--web.listen-address": fmt.Sprintf(":%d", ports["http"]), - } - if o.flagOverride != nil { - args = e2e.MergeFlagsWithoutRemovingEmpty(args, o.flagOverride) - } - return &Prometheus{InstrumentedRunnable: f.Init(e2e.StartOptions{ - Image: o.image, - Command: e2e.NewCommandWithoutEntrypoint("prometheus", e2e.BuildArgs(args)...), - Readiness: e2e.NewHTTPReadinessProbe("http", "/-/ready", 200, 200), - User: strconv.Itoa(os.Getuid()), - })} -} - -func (p *Prometheus) SetConfig(config promconfig.Config) error { - b, err := yaml.Marshal(config) - if err != nil { - return err - } - - if err := os.WriteFile(filepath.Join(p.Dir(), "prometheus.yml"), b, 0600); err != nil { - return errors.Wrap(err, "creating prom config failed") - } - - if p.IsRunning() { - // Reload configuration. - return p.Exec(e2e.NewCommand("kill", "-SIGHUP", "1")) - } - return nil -} diff --git a/db/thanos.go b/db/thanos.go index 54aa641..8e2f180 100644 --- a/db/thanos.go +++ b/db/thanos.go @@ -10,9 +10,10 @@ import ( "strings" "github.com/efficientgo/e2e" + e2emonitoring "github.com/efficientgo/e2e/monitoring" ) -func NewThanosQuerier(env e2e.Environment, name string, endpointsAddresses []string, opts ...Option) e2e.InstrumentedRunnable { +func NewThanosQuerier(env e2e.Environment, name string, endpointsAddresses []string, opts ...Option) *e2emonitoring.InstrumentedRunnable { o := options{image: "quay.io/thanos/thanos:v0.27.0"} for _, opt := range opts { opt(&o) @@ -38,7 +39,7 @@ func NewThanosQuerier(env e2e.Environment, name string, endpointsAddresses []str args = e2e.MergeFlagsWithoutRemovingEmpty(args, o.flagOverride) } - return e2e.NewInstrumentedRunnable(env, name).WithPorts(ports, "http").Init(e2e.StartOptions{ + return e2emonitoring.NewInstrumentedRunnable(env, name).WithPorts(ports, "http").Init(e2e.StartOptions{ Image: o.image, Command: e2e.NewCommand("query", e2e.BuildKingpinArgs(args)...), Readiness: e2e.NewHTTPReadinessProbe("http", "/-/ready", 200, 200), @@ -46,7 +47,7 @@ func NewThanosQuerier(env e2e.Environment, name string, endpointsAddresses []str }) } -func NewThanosSidecar(env e2e.Environment, name string, prom e2e.Linkable, opts ...Option) e2e.InstrumentedRunnable { +func NewThanosSidecar(env e2e.Environment, name string, prom e2e.Linkable, opts ...Option) e2emonitoring.InstrumentedRunnable { o := options{image: "quay.io/thanos/thanos:v0.27.0"} for _, opt := range opts { opt(&o) @@ -68,7 +69,7 @@ func NewThanosSidecar(env e2e.Environment, name string, prom e2e.Linkable, opts args = e2e.MergeFlagsWithoutRemovingEmpty(args, o.flagOverride) } - return e2e.NewInstrumentedRunnable(env, name).WithPorts(ports, "http").Init(e2e.StartOptions{ + return e2emonitoring.NewInstrumentedRunnable(env, name).WithPorts(ports, "http").Init(e2e.StartOptions{ Image: o.image, Command: e2e.NewCommand("sidecar", e2e.BuildKingpinArgs(args)...), Readiness: e2e.NewHTTPReadinessProbe("http", "/-/ready", 200, 200), @@ -76,7 +77,7 @@ func NewThanosSidecar(env e2e.Environment, name string, prom e2e.Linkable, opts }) } -func NewThanosStore(env e2e.Environment, name string, bktConfigYaml []byte, opts ...Option) e2e.InstrumentedRunnable { +func NewThanosStore(env e2e.Environment, name string, bktConfigYaml []byte, opts ...Option) e2emonitoring.InstrumentedRunnable { o := options{image: "quay.io/thanos/thanos:v0.27.0"} for _, opt := range opts { opt(&o) @@ -87,7 +88,7 @@ func NewThanosStore(env e2e.Environment, name string, bktConfigYaml []byte, opts "grpc": 9091, } - f := e2e.NewInstrumentedRunnable(env, name).WithPorts(ports, "http").Future() + f := e2emonitoring.NewInstrumentedRunnable(env, name).WithPorts(ports, "http").Future() args := map[string]string{ "--debug.name": name, "--grpc-address": fmt.Sprintf(":%d", ports["grpc"]), diff --git a/env.go b/env.go index 8ffda39..e09e245 100644 --- a/env.go +++ b/env.go @@ -131,24 +131,13 @@ type RunnableBuilder interface { // WithPorts adds ports to runnable, allowing caller to // use `InternalEndpoint` and `Endpoint` methods by referencing port by name. WithPorts(map[string]int) RunnableBuilder - // WithConcreteType allows to use different type for registration in environment, - // so environment listeners listening to `OnRunnableChange` can have different - // concrete type (e.g InstrumentedRunnable). - WithConcreteType(r Runnable) RunnableBuilder - // Future returns future runnable Future() FutureRunnable // Init returns runnable. Init(opts StartOptions) Runnable } -type identificable interface { - id() uintptr -} - type runnable interface { - identificable - // IsRunning returns if runnable was started. IsRunning() bool @@ -177,6 +166,11 @@ type runnable interface { // // If your service is not running, this method returns incorrect `stopped` endpoint. Endpoint(portName string) string + + // SetMetadata allows setting extra metadata describing runnable. + SetMetadata(key, value any) + // GetMetadata retrieves metadata by given key or return false if not found. + GetMetadata(key any) (any, bool) } type ExecOption func(o *ExecOptions) diff --git a/env_docker.go b/env_docker.go index 07794af..d0df75a 100644 --- a/env_docker.go +++ b/env_docker.go @@ -17,7 +17,6 @@ import ( "strconv" "strings" "time" - "unsafe" "github.com/efficientgo/core/backoff" "github.com/efficientgo/core/errors" @@ -183,7 +182,6 @@ func (e *DockerEnvironment) Runnable(name string) RunnableBuilder { ports: map[string]int{}, hostPorts: map[string]int{}, } - d.concreteType = d if err := os.MkdirAll(d.Dir(), 0750); err != nil { return Errorer{name: name, err: err} } @@ -208,22 +206,22 @@ func NewErrorer(name string, err error) Errorer { } } -func (e Errorer) id() uintptr { return 0 } -func (e Errorer) Name() string { return e.name } -func (Errorer) Dir() string { return "" } -func (Errorer) InternalDir() string { return "" } -func (e Errorer) Start() error { return e.err } -func (e Errorer) WaitReady() error { return e.err } -func (e Errorer) Kill() error { return e.err } -func (e Errorer) Stop() error { return e.err } -func (e Errorer) Exec(Command, ...ExecOption) error { return e.err } -func (Errorer) Endpoint(string) string { return "" } -func (Errorer) InternalEndpoint(string) string { return "" } -func (Errorer) IsRunning() bool { return false } -func (e Errorer) Init(StartOptions) Runnable { return e } -func (e Errorer) WithPorts(map[string]int) RunnableBuilder { return e } -func (e Errorer) WithConcreteType(Runnable) RunnableBuilder { return e } -func (e Errorer) Future() FutureRunnable { return e } +func (e Errorer) Name() string { return e.name } +func (Errorer) Dir() string { return "" } +func (Errorer) InternalDir() string { return "" } +func (e Errorer) Start() error { return e.err } +func (e Errorer) WaitReady() error { return e.err } +func (e Errorer) Kill() error { return e.err } +func (e Errorer) Stop() error { return e.err } +func (e Errorer) Exec(Command, ...ExecOption) error { return e.err } +func (Errorer) Endpoint(string) string { return "" } +func (Errorer) InternalEndpoint(string) string { return "" } +func (Errorer) IsRunning() bool { return false } +func (Errorer) SetMetadata(_, _ any) {} +func (Errorer) GetMetadata(any) (any, bool) { return nil, false } +func (e Errorer) Init(StartOptions) Runnable { return e } +func (e Errorer) WithPorts(map[string]int) RunnableBuilder { return e } +func (e Errorer) Future() FutureRunnable { return e } func (e *DockerEnvironment) isRegistered(name string) bool { _, ok := e.registered[name] @@ -339,7 +337,7 @@ type dockerRunnable struct { // hostPorts Maps port name to dynamically binded local ports. hostPorts map[string]int - concreteType Runnable + extensions map[any]any } func (d *dockerRunnable) Name() string { @@ -373,13 +371,13 @@ func (d *dockerRunnable) WithPorts(ports map[string]int) RunnableBuilder { return d } -func (d *dockerRunnable) WithConcreteType(r Runnable) RunnableBuilder { - d.concreteType = r - return d +func (d *dockerRunnable) SetMetadata(key, value any) { + d.extensions[key] = value } -func (d *dockerRunnable) id() uintptr { - return uintptr(unsafe.Pointer(d)) +func (d *dockerRunnable) GetMetadata(key any) (any, bool) { + v, ok := d.extensions[key] + return v, ok } func (d *dockerRunnable) Future() FutureRunnable { @@ -396,14 +394,6 @@ func (d *dockerRunnable) Start() (err error) { return errors.Newf("%v is running. Stop or kill it first to restart.", d.Name()) } - i, ok := d.concreteType.(identificable) - if !ok { - return errors.Newf("concrete type has at least embed runnable or future runnable instance provided by Runnable builder, got %T; not implementing identificable", d.concreteType) - } - if i.id() != d.id() { - return errors.Newf("concrete type has at least embed runnable or future runnable instance provided by Runnable builder, got %T; id %v, expected %v", d.concreteType, i.id(), d.id()) - } - d.logger.Log("Starting", d.Name()) // In case of any error, if the container was already created, we @@ -434,7 +424,7 @@ func (d *dockerRunnable) Start() (err error) { return err } - if err := d.env.registerStarted(d.concreteType); err != nil { + if err := d.env.registerStarted(d); err != nil { return err } diff --git a/env_docker_ext_test.go b/env_docker_ext_test.go index 610720c..047bde8 100644 --- a/env_docker_ext_test.go +++ b/env_docker_ext_test.go @@ -13,6 +13,7 @@ import ( "github.com/efficientgo/core/testutil" "github.com/efficientgo/e2e" e2edb "github.com/efficientgo/e2e/db" + e2e2 "github.com/efficientgo/e2e/monitoring" ) func wgetFlagsCmd(hostPort string) e2e.Command { @@ -48,7 +49,7 @@ func TestDockerEnvironment(t *testing.T) { testutil.Ok(t, p1.WaitReady()) testutil.Ok(t, p1.WaitReady()) - testutil.Ok(t, p1.WaitSumMetrics(e2e.Greater(50), "prometheus_tsdb_head_samples_appended_total")) + testutil.Ok(t, p1.WaitSumMetrics(e2e2.Greater(50), "prometheus_tsdb_head_samples_appended_total")) testutil.Equals(t, "prometheus-1", p1.Name()) testutil.Equals(t, filepath.Join(e.SharedDir(), "data", p1.Name()), p1.Dir()) diff --git a/examples/exampleapp/exampleapp_test.go b/examples/exampleapp/exampleapp_test.go index 3812032..5fafb72 100644 --- a/examples/exampleapp/exampleapp_test.go +++ b/examples/exampleapp/exampleapp_test.go @@ -13,6 +13,7 @@ import ( "github.com/efficientgo/e2e" e2edb "github.com/efficientgo/e2e/db" e2einteractive "github.com/efficientgo/e2e/interactive" + e2e2 "github.com/efficientgo/e2e/monitoring" ) func TestExampleApp(t *testing.T) { @@ -54,7 +55,7 @@ scrape_configs: fmt.Println("=== Ensure that Prometheus already scraped something") // Ensure that Prometheus already scraped something. - testutil.Ok(t, p1.WaitSumMetrics(e2e.Greater(50), "prometheus_tsdb_head_samples_appended_total")) + testutil.Ok(t, p1.WaitSumMetrics(e2e2.Greater(50), "prometheus_tsdb_head_samples_appended_total")) // Open example in browser. exampleAppURL := fmt.Sprintf("http://%s", app.Endpoint("http")) @@ -63,15 +64,15 @@ scrape_configs: fmt.Println("=== I need at least 5 requests!") testutil.Ok(t, app.WaitSumMetricsWithOptions( - e2e.GreaterOrEqual(5), + e2e2.GreaterOrEqual(5), []string{"http_requests_total"}, - e2e.WithWaitBackoff( + e2e2.WithWaitBackoff( &backoff.Config{ Min: 1 * time.Second, Max: 10 * time.Second, MaxRetries: 100, }), - e2e.WaitMissingMetrics()), + e2e2.WaitMissingMetrics()), ) // Now opening Prometheus in browser as well. diff --git a/examples/thanos/e2etest_test.go b/examples/thanos/e2etest_test.go index f0d9dcd..ed9bb1c 100644 --- a/examples/thanos/e2etest_test.go +++ b/examples/thanos/e2etest_test.go @@ -12,6 +12,7 @@ import ( "github.com/efficientgo/core/testutil" "github.com/efficientgo/e2e" e2edb "github.com/efficientgo/e2e/db" + e2e2 "github.com/efficientgo/e2e/monitoring" "github.com/prometheus/client_golang/api" v1 "github.com/prometheus/client_golang/api/prometheus/v1" "github.com/prometheus/common/model" @@ -42,11 +43,11 @@ func TestExample(t *testing.T) { // To ensure query should have access we can check its Prometheus metric using WaitSumMetrics method. Since the metric we are looking for // only appears after init, we add option to wait for it. - testutil.Ok(t, t1.WaitSumMetricsWithOptions(e2e.Equals(2), []string{"thanos_store_nodes_grpc_connections"}, e2e.WaitMissingMetrics())) + testutil.Ok(t, t1.WaitSumMetricsWithOptions(e2e2.Equals(2), []string{"thanos_store_nodes_grpc_connections"}, e2e2.WaitMissingMetrics())) // To ensure Prometheus scraped already something ensure number of scrapes. - testutil.Ok(t, p1.WaitSumMetrics(e2e.Greater(50), "prometheus_tsdb_head_samples_appended_total")) - testutil.Ok(t, p2.WaitSumMetrics(e2e.Greater(50), "prometheus_tsdb_head_samples_appended_total")) + testutil.Ok(t, p1.WaitSumMetrics(e2e2.Greater(50), "prometheus_tsdb_head_samples_appended_total")) + testutil.Ok(t, p2.WaitSumMetrics(e2e2.Greater(50), "prometheus_tsdb_head_samples_appended_total")) // We can now query Thanos Querier directly from here, using it's host address thanks to Endpoint method. a, err := api.NewClient(api.Config{Address: "http://" + t1.Endpoint("http")}) @@ -70,7 +71,7 @@ up{instance="%v", job="myself", prometheus="prometheus-2"} => 1 @[%v]`, p1.Inter testutil.Ok(t, p1.Stop()) // Wait a bit until Thanos drops connection to stopped Prometheus. - testutil.Ok(t, t1.WaitSumMetricsWithOptions(e2e.Equals(1), []string{"thanos_store_nodes_grpc_connections"}, e2e.WaitMissingMetrics())) + testutil.Ok(t, t1.WaitSumMetricsWithOptions(e2e2.Equals(1), []string{"thanos_store_nodes_grpc_connections"}, e2e2.WaitMissingMetrics())) { now := model.Now() diff --git a/examples/thanos/standalone.go b/examples/thanos/standalone.go index f4d77bc..5546578 100644 --- a/examples/thanos/standalone.go +++ b/examples/thanos/standalone.go @@ -69,10 +69,10 @@ config: if err := merrors.New( // To ensure query should have access we can check its Prometheus metric using WaitSumMetrics method. Since the metric we are looking for // only appears after init, we add option to wait for it. - t1.WaitSumMetricsWithOptions(e2e.Equals(2), []string{"thanos_store_nodes_grpc_connections"}, e2e.WaitMissingMetrics()), + t1.WaitSumMetricsWithOptions(e2emonitoring.Equals(2), []string{"thanos_store_nodes_grpc_connections"}, e2emonitoring.WaitMissingMetrics()), // To ensure Prometheus scraped already something ensure number of scrapes. - p1.WaitSumMetrics(e2e.Greater(50), "prometheus_tsdb_head_samples_appended_total"), - p2.WaitSumMetrics(e2e.Greater(50), "prometheus_tsdb_head_samples_appended_total"), + p1.WaitSumMetrics(e2emonitoring.Greater(50), "prometheus_tsdb_head_samples_appended_total"), + p2.WaitSumMetrics(e2emonitoring.Greater(50), "prometheus_tsdb_head_samples_appended_total"), ).Err(); err != nil { return err } diff --git a/go.mod b/go.mod index 56d5995..6993aca 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/efficientgo/e2e -go 1.17 +go 1.18 require ( github.com/efficientgo/core v1.0.0-rc.0 diff --git a/local.go b/local.go index b5b7b0d..f7f1103 100644 --- a/local.go +++ b/local.go @@ -52,7 +52,7 @@ func Containerize(e Environment, name string, startFn func(context.Context) erro return nil, errors.Newf("not a Go module %v", wd) } - f := NewInstrumentedRunnable(e, name).WithPorts(map[string]int{"http": 80}, "http").Future() + f := e.Runnable(name).WithPorts(map[string]int{"http": 80}).Future() dir := filepath.Join(f.Dir(), "shim") if err := os.MkdirAll(dir, os.ModePerm); err != nil { diff --git a/instrumented.go b/monitoring/instrumented.go similarity index 55% rename from instrumented.go rename to monitoring/instrumented.go index 5b2ba47..52c14fe 100644 --- a/instrumented.go +++ b/monitoring/instrumented.go @@ -1,7 +1,7 @@ // Copyright (c) The EfficientGo Authors. // Licensed under the Apache License 2.0. -package e2e +package e2emonitoring import ( "context" @@ -14,22 +14,20 @@ import ( "github.com/efficientgo/core/backoff" "github.com/efficientgo/core/errcapture" "github.com/efficientgo/core/errors" + "github.com/efficientgo/e2e" "github.com/prometheus/common/expfmt" ) var errMissingMetric = errors.New("metric not found") -type MetricTarget struct { +type Target struct { InternalEndpoint string MetricPath string // "/metrics" by default. Scheme string // "http" by default. } -// InstrumentedRunnable represents opinionated microservice with one port marked as HTTP port with metric endpoint. -type InstrumentedRunnable interface { - Runnable - - MetricTargets() []MetricTarget +type Instrumented interface { + MetricTargets() []Target Metrics() (string, error) WaitSumMetrics(expected MetricValueExpectation, metricNames ...string) error WaitSumMetricsWithOptions(expected MetricValueExpectation, metricNames []string, opts ...MetricsOption) error @@ -37,39 +35,9 @@ type InstrumentedRunnable interface { WaitRemovedMetric(metricName string, opts ...MetricsOption) error } -type FutureInstrumentedRunnable interface { - Linkable - - // Init transforms future into runnable. - Init(opts StartOptions) InstrumentedRunnable -} - -// InstrumentedRunnableBuilder represents options that can be build into runnable and if -// you want Future or Initiated InstrumentedRunnableBuilder from it. -type InstrumentedRunnableBuilder interface { - // WithPorts adds ports to runnable, allowing caller to - // use `InternalEndpoint` and `Endpoint` methods by referencing port by name. - WithPorts(ports map[string]int, instrumentedPortName string) InstrumentedRunnableBuilder - // WithMetricPath allows adding customized metric path. "/metrics" by default. - WithMetricPath(path string) InstrumentedRunnableBuilder - // WithMetricScheme allows adding customized scheme. "http" or "https" values allowed. "http" by default. - // If "https" is specified, insecure TLS will be performed. - WithMetricScheme(scheme string) InstrumentedRunnableBuilder - - // Future returns future runnable - Future() FutureInstrumentedRunnable - // Init returns runnable. - Init(opts StartOptions) InstrumentedRunnable -} - -var _ InstrumentedRunnable = &instrumentedRunnable{} +type InstrumentedRunnable struct { + e2e.Runnable -type instrumentedRunnable struct { - runnable - Linkable - builder RunnableBuilder - - name string metricPortName string metricPath string scheme string @@ -77,61 +45,73 @@ type instrumentedRunnable struct { waitBackoff *backoff.Backoff } -func NewInstrumentedRunnable(env Environment, name string) InstrumentedRunnableBuilder { - r := &instrumentedRunnable{name: name, scheme: "http", metricPath: "/metrics", builder: env.Runnable(name)} - r.builder.WithConcreteType(r) - return r +type runnableOpt struct { + metricPath string + scheme string + waitBackoff *backoff.Backoff } -func (r *instrumentedRunnable) WithPorts(ports map[string]int, instrumentedPortName string) InstrumentedRunnableBuilder { - if _, ok := ports[instrumentedPortName]; !ok { - err := NewErrorer(r.name, errors.Newf("metric port name %v does not exists in given ports", instrumentedPortName)) - r.Linkable = err - r.runnable = err - return r +// WithRunnableMetricPath sets a custom path for metrics page. "/metrics" by default. +func WithRunnableMetricPath(metricPath string) RunnableOption { + return func(o *runnableOpt) { + o.metricPath = metricPath } - r.builder.WithPorts(ports) - r.metricPortName = instrumentedPortName - return r } -func (r *instrumentedRunnable) WithMetricPath(path string) InstrumentedRunnableBuilder { - r.metricPath = path - return r +// WithRunnableScheme allows adding customized scheme. "http" or "https" values allowed. "http" by default. +// If "https" is specified, insecure TLS will be performed. +func WithRunnableScheme(scheme string) RunnableOption { + return func(o *runnableOpt) { + o.scheme = scheme + } } -func (r *instrumentedRunnable) WithMetricScheme(scheme string) InstrumentedRunnableBuilder { - r.scheme = scheme - return r +// WithRunnableWaitBackoff allows adding customized scheme. "http" or "https" values allowed. "http" by default. +// If "https" is specified, insecure TLS will be performed. +func WithRunnableWaitBackoff(waitBackoff *backoff.Backoff) RunnableOption { + return func(o *runnableOpt) { + o.waitBackoff = waitBackoff + } } -func (r *instrumentedRunnable) Future() FutureInstrumentedRunnable { - if r.runnable != nil { - // Error. - return r +type RunnableOption func(*runnableOpt) + +// AsInstrumented wraps e2e.Runnable with InstrumentedRunnable that satisfies both Instrumented and e2e.Runnable +// that represents runnable with instrumented Prometheus metric endpoint on a certain port. +// NOTE(bwplotka): Caller is expected to discard passed `r` runnable and use returned InstrumentedRunnable.InstrumentedRunnable instead. +func AsInstrumented(r e2e.Runnable, instrumentedPortName string, opts ...RunnableOption) *InstrumentedRunnable { + opt := runnableOpt{ + metricPath: "/metrics", + scheme: "http", + waitBackoff: backoff.New(context.Background(), backoff.Config{ + Min: 300 * time.Millisecond, + Max: 600 * time.Millisecond, + MaxRetries: 50, // Sometimes the CI is slow ¯\_(ツ)_/¯ + })} + for _, o := range opts { + o(&opt) } - r.Linkable = r.builder.Future() - return r -} - -func (r *instrumentedRunnable) Init(opts StartOptions) InstrumentedRunnable { - if r.runnable != nil { - // Error. - return r + if r.InternalEndpoint(instrumentedPortName) == "" { + return &InstrumentedRunnable{Runnable: e2e.NewErrorer(r.Name(), errors.Newf("metric port name %v does not exists in given runnable ports", instrumentedPortName))} } - inner := r.builder.Init(opts) - r.Linkable = inner - r.runnable = inner - return r + instr := &InstrumentedRunnable{ + Runnable: r, + metricPortName: instrumentedPortName, + metricPath: opt.metricPath, + scheme: opt.scheme, + waitBackoff: opt.waitBackoff, + } + r.SetMetadata(metaKey, Instrumented(instr)) + return instr } -func (r *instrumentedRunnable) MetricTargets() []MetricTarget { - return []MetricTarget{{Scheme: r.scheme, MetricPath: r.metricPath, InternalEndpoint: r.InternalEndpoint(r.metricPortName)}} +func (r *InstrumentedRunnable) MetricTargets() []Target { + return []Target{{Scheme: r.scheme, MetricPath: r.metricPath, InternalEndpoint: r.InternalEndpoint(r.metricPortName)}} } -func (r *instrumentedRunnable) Metrics() (_ string, err error) { +func (r *InstrumentedRunnable) Metrics() (_ string, err error) { if !r.IsRunning() { return "", errors.Newf("%s is not running", r.Name()) } @@ -154,11 +134,11 @@ func (r *instrumentedRunnable) Metrics() (_ string, err error) { // WaitSumMetrics waits for at least one instance of each given metric names to be present and their sums, // returning true when passed to given expected(...). -func (r *instrumentedRunnable) WaitSumMetrics(expected MetricValueExpectation, metricNames ...string) error { +func (r *InstrumentedRunnable) WaitSumMetrics(expected MetricValueExpectation, metricNames ...string) error { return r.WaitSumMetricsWithOptions(expected, metricNames) } -func (r *instrumentedRunnable) WaitSumMetricsWithOptions(expected MetricValueExpectation, metricNames []string, opts ...MetricsOption) error { +func (r *InstrumentedRunnable) WaitSumMetricsWithOptions(expected MetricValueExpectation, metricNames []string, opts ...MetricsOption) error { var ( sums []float64 err error @@ -186,7 +166,7 @@ func (r *instrumentedRunnable) WaitSumMetricsWithOptions(expected MetricValueExp } // SumMetrics returns the sum of the values of each given metric names. -func (r *instrumentedRunnable) SumMetrics(metricNames []string, opts ...MetricsOption) ([]float64, error) { +func (r *InstrumentedRunnable) SumMetrics(metricNames []string, opts ...MetricsOption) ([]float64, error) { options := buildMetricsOptions(opts) sums := make([]float64, len(metricNames)) @@ -231,7 +211,7 @@ func (r *instrumentedRunnable) SumMetrics(metricNames []string, opts ...MetricsO } // WaitRemovedMetric waits until a metric disappear from the list of metrics exported by the service. -func (r *instrumentedRunnable) WaitRemovedMetric(metricName string, opts ...MetricsOption) error { +func (r *InstrumentedRunnable) WaitRemovedMetric(metricName string, opts ...MetricsOption) error { options := buildMetricsOptions(opts) for r.waitBackoff.Reset(); r.waitBackoff.Ongoing(); { @@ -264,11 +244,3 @@ func (r *instrumentedRunnable) WaitRemovedMetric(metricName string, opts ...Metr return errors.Newf("the metric %s is still exported by %s", metricName, r.Name()) } - -func NewErrInstrumentedRunnable(name string, err error) InstrumentedRunnable { - errr := NewErrorer(name, err) - return &instrumentedRunnable{ - runnable: errr, - Linkable: errr, - } -} diff --git a/instrumented_composite.go b/monitoring/instrumented_composite.go similarity index 88% rename from instrumented_composite.go rename to monitoring/instrumented_composite.go index 74df31e..fe3d3c3 100644 --- a/instrumented_composite.go +++ b/monitoring/instrumented_composite.go @@ -1,7 +1,7 @@ // Copyright (c) The EfficientGo Authors. // Licensed under the Apache License 2.0. -package e2e +package e2emonitoring import ( "context" @@ -13,13 +13,13 @@ import ( // CompositeInstrumentedRunnable abstract an higher-level service composed by more than one InstrumentedRunnable. type CompositeInstrumentedRunnable struct { - runnables []InstrumentedRunnable + runnables []*InstrumentedRunnable // Generic retry backoff. backoff *backoff.Backoff } -func NewCompositeInstrumentedRunnable(runnables ...InstrumentedRunnable) *CompositeInstrumentedRunnable { +func NewCompositeInstrumentedRunnable(runnables ...*InstrumentedRunnable) *CompositeInstrumentedRunnable { return &CompositeInstrumentedRunnable{ runnables: runnables, backoff: backoff.New(context.Background(), backoff.Config{ @@ -30,11 +30,11 @@ func NewCompositeInstrumentedRunnable(runnables ...InstrumentedRunnable) *Compos } } -func (r *CompositeInstrumentedRunnable) Instances() []InstrumentedRunnable { +func (r *CompositeInstrumentedRunnable) Instances() []*InstrumentedRunnable { return r.runnables } -func (r *CompositeInstrumentedRunnable) MetricTargets() (ret []MetricTarget) { +func (r *CompositeInstrumentedRunnable) MetricTargets() (ret []Target) { for _, inst := range r.runnables { ret = append(ret, inst.MetricTargets()...) } diff --git a/instrumented_test.go b/monitoring/instrumented_test.go similarity index 62% rename from instrumented_test.go rename to monitoring/instrumented_test.go index 5399bdb..a559a51 100644 --- a/instrumented_test.go +++ b/monitoring/instrumented_test.go @@ -1,21 +1,35 @@ // Copyright (c) The EfficientGo Authors. // Licensed under the Apache License 2.0. -package e2e +package e2emonitoring import ( "context" "math" "net" "net/http" - "strconv" "testing" "time" "github.com/efficientgo/core/backoff" "github.com/efficientgo/core/testutil" + "github.com/efficientgo/e2e" ) +type runnableFake struct { + e2e.Runnable + + endpoints map[string]string +} + +func (r *runnableFake) InternalEndpoint(portName string) string { + return r.endpoints[portName] +} + +func (r *runnableFake) Endpoint(portName string) string { + return r.endpoints[portName] +} + func TestWaitSumMetric(t *testing.T) { // Listen on a random port before starting the HTTP server, to // make sure the port is already open when we'll call WaitSumMetric() @@ -24,13 +38,6 @@ func TestWaitSumMetric(t *testing.T) { testutil.Ok(t, err) defer ln.Close() - // Get the port. - _, addrPort, err := net.SplitHostPort(ln.Addr().String()) - testutil.Ok(t, err) - - port, err := strconv.Atoi(addrPort) - testutil.Ok(t, err) - // Start an HTTP server exposing the metrics. srv := &http.Server{ Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -71,22 +78,16 @@ metric_b_summary_count 1 _ = srv.Serve(ln) }() - r := &dockerRunnable{ - hostPorts: map[string]int{"http": port}, - usedNetworkName: "hack", - } - s := &instrumentedRunnable{ - metricPortName: "http", - runnable: r, - Linkable: r, - } + r := AsInstrumented( + &runnableFake{endpoints: map[string]string{"http": ln.Addr().String()}}, + "http", + WithRunnableWaitBackoff(backoff.New(context.Background(), backoff.Config{ + Min: 300 * time.Millisecond, + Max: 600 * time.Millisecond, + MaxRetries: 50, + }))) - s.waitBackoff = backoff.New(context.Background(), backoff.Config{ - Min: 300 * time.Millisecond, - Max: 600 * time.Millisecond, - MaxRetries: 50, - }) - testutil.Ok(t, s.WaitSumMetrics(Equals(221), "metric_a")) + testutil.Ok(t, r.WaitSumMetrics(Equals(221), "metric_a")) // No retry. noRetryWaitBackoff := backoff.Config{ @@ -94,24 +95,24 @@ metric_b_summary_count 1 Max: 0, MaxRetries: 1, } - testutil.NotOk(t, s.WaitSumMetricsWithOptions(Equals(16), []string{"metric_a"}, WithWaitBackoff(&noRetryWaitBackoff))) - testutil.NotOk(t, s.WaitSumMetricsWithOptions(Equals(16), []string{"unknown_metric"}, WaitMissingMetrics())) + testutil.NotOk(t, r.WaitSumMetricsWithOptions(Equals(16), []string{"metric_a"}, WithWaitBackoff(&noRetryWaitBackoff))) + testutil.NotOk(t, r.WaitSumMetricsWithOptions(Equals(16), []string{"unknown_metric"}, WaitMissingMetrics())) - testutil.Ok(t, s.WaitSumMetricsWithOptions(Equals(1000), []string{"metric_b"}, WithWaitBackoff(&noRetryWaitBackoff))) - testutil.Ok(t, s.WaitSumMetricsWithOptions(Equals(1020), []string{"metric_b_counter"}, WithWaitBackoff(&noRetryWaitBackoff))) - testutil.Ok(t, s.WaitSumMetricsWithOptions(Equals(124), []string{"metric_b_hist"}, WithWaitBackoff(&noRetryWaitBackoff))) - testutil.Ok(t, s.WaitSumMetricsWithOptions(Equals(22), []string{"metric_b_summary"}, WithWaitBackoff(&noRetryWaitBackoff))) + testutil.Ok(t, r.WaitSumMetricsWithOptions(Equals(1000), []string{"metric_b"}, WithWaitBackoff(&noRetryWaitBackoff))) + testutil.Ok(t, r.WaitSumMetricsWithOptions(Equals(1020), []string{"metric_b_counter"}, WithWaitBackoff(&noRetryWaitBackoff))) + testutil.Ok(t, r.WaitSumMetricsWithOptions(Equals(124), []string{"metric_b_hist"}, WithWaitBackoff(&noRetryWaitBackoff))) + testutil.Ok(t, r.WaitSumMetricsWithOptions(Equals(22), []string{"metric_b_summary"}, WithWaitBackoff(&noRetryWaitBackoff))) - testutil.Ok(t, s.WaitSumMetricsWithOptions(EqualsAmongTwo, []string{"metric_a", "metric_a"}, WithWaitBackoff(&noRetryWaitBackoff))) - testutil.NotOk(t, s.WaitSumMetricsWithOptions(EqualsAmongTwo, []string{"metric_a", "metric_b"}, WithWaitBackoff(&noRetryWaitBackoff))) + testutil.Ok(t, r.WaitSumMetricsWithOptions(EqualsAmongTwo, []string{"metric_a", "metric_a"}, WithWaitBackoff(&noRetryWaitBackoff))) + testutil.NotOk(t, r.WaitSumMetricsWithOptions(EqualsAmongTwo, []string{"metric_a", "metric_b"}, WithWaitBackoff(&noRetryWaitBackoff))) - testutil.Ok(t, s.WaitSumMetricsWithOptions(GreaterAmongTwo, []string{"metric_b", "metric_a"}, WithWaitBackoff(&noRetryWaitBackoff))) - testutil.NotOk(t, s.WaitSumMetricsWithOptions(GreaterAmongTwo, []string{"metric_a", "metric_b"}, WithWaitBackoff(&noRetryWaitBackoff))) + testutil.Ok(t, r.WaitSumMetricsWithOptions(GreaterAmongTwo, []string{"metric_b", "metric_a"}, WithWaitBackoff(&noRetryWaitBackoff))) + testutil.NotOk(t, r.WaitSumMetricsWithOptions(GreaterAmongTwo, []string{"metric_a", "metric_b"}, WithWaitBackoff(&noRetryWaitBackoff))) - testutil.Ok(t, s.WaitSumMetricsWithOptions(LessAmongTwo, []string{"metric_a", "metric_b"}, WithWaitBackoff(&noRetryWaitBackoff))) - testutil.NotOk(t, s.WaitSumMetricsWithOptions(LessAmongTwo, []string{"metric_b", "metric_a"}, WithWaitBackoff(&noRetryWaitBackoff))) + testutil.Ok(t, r.WaitSumMetricsWithOptions(LessAmongTwo, []string{"metric_a", "metric_b"}, WithWaitBackoff(&noRetryWaitBackoff))) + testutil.NotOk(t, r.WaitSumMetricsWithOptions(LessAmongTwo, []string{"metric_b", "metric_a"}, WithWaitBackoff(&noRetryWaitBackoff))) - testutil.NotOk(t, s.WaitSumMetricsWithOptions(Equals(0), []string{"non_existing_metric"}, WithWaitBackoff(&noRetryWaitBackoff))) + testutil.NotOk(t, r.WaitSumMetricsWithOptions(Equals(0), []string{"non_existing_metric"}, WithWaitBackoff(&noRetryWaitBackoff))) } func TestWaitSumMetric_Nan(t *testing.T) { @@ -122,13 +123,6 @@ func TestWaitSumMetric_Nan(t *testing.T) { testutil.Ok(t, err) defer ln.Close() - // Get the port. - _, addrPort, err := net.SplitHostPort(ln.Addr().String()) - testutil.Ok(t, err) - - port, err := strconv.Atoi(addrPort) - testutil.Ok(t, err) - // Start an HTTP server exposing the metrics. srv := &http.Server{ Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -157,20 +151,14 @@ metric_b 1000 _ = srv.Serve(ln) }() - r := &dockerRunnable{ - hostPorts: map[string]int{"http": port}, - usedNetworkName: "hack", - } - s := &instrumentedRunnable{ - metricPortName: "http", - runnable: r, - Linkable: r, - } + r := AsInstrumented( + &runnableFake{endpoints: map[string]string{"http": ln.Addr().String()}}, + "http", + WithRunnableWaitBackoff(backoff.New(context.Background(), backoff.Config{ + Min: 300 * time.Millisecond, + Max: 600 * time.Millisecond, + MaxRetries: 50, + }))) - s.waitBackoff = backoff.New(context.Background(), backoff.Config{ - Min: 300 * time.Millisecond, - Max: 600 * time.Millisecond, - MaxRetries: 50, - }) - testutil.Ok(t, s.WaitSumMetrics(Equals(math.NaN()), "metric_a")) + testutil.Ok(t, r.WaitSumMetrics(Equals(math.NaN()), "metric_a")) } diff --git a/matchers/matcher.go b/monitoring/matchers/matcher.go similarity index 100% rename from matchers/matcher.go rename to monitoring/matchers/matcher.go diff --git a/matchers/regexp.go b/monitoring/matchers/regexp.go similarity index 100% rename from matchers/regexp.go rename to monitoring/matchers/regexp.go diff --git a/metrics.go b/monitoring/metrics.go similarity index 98% rename from metrics.go rename to monitoring/metrics.go index b4236a5..cddb159 100644 --- a/metrics.go +++ b/monitoring/metrics.go @@ -1,14 +1,14 @@ // Copyright (c) The EfficientGo Authors. // Licensed under the Apache License 2.0. -package e2e +package e2emonitoring import ( "math" "time" "github.com/efficientgo/core/backoff" - "github.com/efficientgo/e2e/matchers" + "github.com/efficientgo/e2e/monitoring/matchers" io_prometheus_client "github.com/prometheus/client_model/go" ) diff --git a/monitoring/monitoring.go b/monitoring/monitoring.go index 50e60e1..46780dc 100644 --- a/monitoring/monitoring.go +++ b/monitoring/monitoring.go @@ -4,9 +4,13 @@ package e2emonitoring import ( + "fmt" "io" "net" "net/http" + "os" + "path/filepath" + "strconv" "strings" "sync" "time" @@ -15,39 +19,116 @@ import ( "github.com/efficientgo/core/errors" "github.com/efficientgo/e2e" e2edb "github.com/efficientgo/e2e/db" - "github.com/efficientgo/e2e/db/promconfig" "github.com/efficientgo/e2e/db/promconfig/discovery/config" - "github.com/efficientgo/e2e/db/promconfig/discovery/targetgroup" e2einteractive "github.com/efficientgo/e2e/interactive" + "github.com/efficientgo/e2e/monitoring/promconfig" + "github.com/efficientgo/e2e/monitoring/promconfig/discovery/config" + "github.com/efficientgo/e2e/monitoring/promconfig/discovery/targetgroup" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/common/config" "github.com/prometheus/common/model" + "gopkg.in/yaml.v2" ) +var metaKey = struct{}{} + +type Prometheus struct { + e2e.Runnable + Instrumented +} + +func NewPrometheus(env e2e.Environment, name string, image string, flagOverride map[string]string) *Prometheus { + if image == "" { + image = "quay.io/prometheus/prometheus:v2.37.0" + } + ports := map[string]int{"http": 9090} + + f := env.Runnable(name).WithPorts(ports).Future() + config := fmt.Sprintf(` +global: + external_labels: + prometheus: %v +scrape_configs: +- job_name: 'myself' + # Quick scrapes for test purposes. + scrape_interval: 1s + scrape_timeout: 1s + static_configs: + - targets: [%s] + relabel_configs: + - source_labels: ['__address__'] + regex: '^.+:80$' + action: drop +`, name, f.InternalEndpoint("http")) + if err := os.WriteFile(filepath.Join(f.Dir(), "prometheus.yml"), []byte(config), 0600); err != nil { + return &Prometheus{Runnable: e2e.NewErrorer(name, errors.Wrap(err, "create prometheus config failed"))} + } + + args := map[string]string{ + "--config.file": filepath.Join(f.InternalDir(), "prometheus.yml"), + "--storage.tsdb.path": f.InternalDir(), + "--storage.tsdb.max-block-duration": "2h", // No compaction - mostly not needed for quick test. + "--log.level": "info", + "--web.listen-address": fmt.Sprintf(":%d", ports["http"]), + } + if flagOverride != nil { + args = e2e.MergeFlagsWithoutRemovingEmpty(args, flagOverride) + } + + p := AsInstrumented(f.Init(e2e.StartOptions{ + Image: image, + Command: e2e.NewCommandWithoutEntrypoint("prometheus", e2e.BuildArgs(args)...), + Readiness: e2e.NewHTTPReadinessProbe("http", "/-/ready", 200, 200), + User: strconv.Itoa(os.Getuid()), + }), "http") + + return &Prometheus{ + Runnable: p, + Instrumented: p, + } +} + +func (p *Prometheus) SetConfig(config promconfig.Config) error { + b, err := yaml.Marshal(config) + if err != nil { + return err + } + + if err := os.WriteFile(filepath.Join(p.Dir(), "prometheus.yml"), b, 0600); err != nil { + return errors.Wrap(err, "creating prom config failed") + } + + if p.IsRunning() { + // Reload configuration. + return p.Exec(e2e.NewCommand("kill", "-SIGHUP", "1")) + } + return nil +} + type Service struct { - p *e2edb.Prometheus + p *Prometheus } type listener struct { - p *e2edb.Prometheus + p *Prometheus localAddr string scrapeInterval time.Duration } -func (l *listener) updateConfig(started map[string]instrumented) error { +func (l *listener) updateConfig(started map[string]Instrumented) error { cfg := promconfig.Config{ GlobalConfig: promconfig.GlobalConfig{ ExternalLabels: map[model.LabelName]model.LabelValue{"prometheus": model.LabelValue(l.p.Name())}, ScrapeInterval: model.Duration(l.scrapeInterval), }, } - add := func(name string, instr instrumented) { + add := func(name string, instr Instrumented) { scfg := &promconfig.ScrapeConfig{ JobName: name, - ServiceDiscoveryConfig: sdconfig.ServiceDiscoveryConfig{}, + ServiceDiscoveryConfig: sdconfig.sdconfig{}, HTTPClientConfig: config.HTTPClientConfig{ TLSConfig: config.TLSConfig{ // TODO(bwplotka): Allow providing certs? @@ -85,7 +166,7 @@ func (l *listener) updateConfig(started map[string]instrumented) error { } cfg.ScrapeConfigs = append(cfg.ScrapeConfigs, scfg) - add("e2emonitoring-prometheus", l.p) + //add("e2emonitoring-prometheus", l.p) for name, s := range started { add(name, s) } @@ -93,18 +174,14 @@ func (l *listener) updateConfig(started map[string]instrumented) error { return l.p.SetConfig(cfg) } -type instrumented interface { - MetricTargets() []e2e.MetricTarget -} - func (l *listener) OnRunnableChange(started []e2e.Runnable) error { - s := map[string]instrumented{} + s := map[string]Instrumented{} for _, r := range started { - instr, ok := r.(instrumented) + instr, ok := r.GetMetadata(metaKey) if !ok { continue } - s[r.Name()] = instr + s[r.Name()] = instr.(Instrumented) } return l.updateConfig(s) @@ -117,7 +194,7 @@ type opt struct { } // WithScrapeInterval changes how often metrics are scrape by Prometheus. 5s by default. -func WithScrapeInterval(interval time.Duration) func(*opt) { +func WithScrapeInterval(interval time.Duration) Option { return func(o *opt) { o.scrapeInterval = interval } @@ -126,14 +203,14 @@ func WithScrapeInterval(interval time.Duration) func(*opt) { // WithCustomRegistry allows injecting a custom registry to use for this process metrics. // NOTE(bwplotka): Injected registry will be used as is, while the default registry // will have prometheus.NewGoCollector() and prometheus.NewProcessCollector(..) registered. -func WithCustomRegistry(reg *prometheus.Registry) func(*opt) { +func WithCustomRegistry(reg *prometheus.Registry) Option { return func(o *opt) { o.customRegistry = reg } } // WithPrometheusImage allows injecting custom Prometheus docker image to use as scraper and queryable. -func WithPrometheusImage(image string) func(*opt) { +func WithPrometheusImage(image string) Option { return func(o *opt) { o.customPromImage = image } @@ -189,7 +266,7 @@ func Start(env e2e.Environment, opts ...Option) (_ *Service, err error) { return nil, err } l := &listener{p: p, localAddr: net.JoinHostPort(env.HostAddr(), port), scrapeInterval: opt.scrapeInterval} - if err := l.updateConfig(map[string]instrumented{}); err != nil { + if err := l.updateConfig(map[string]Instrumented{}); err != nil { return nil, err } env.AddListener(l) @@ -232,12 +309,8 @@ func (s *Service) InstantQuery(query string) (string, error) { return string(body), err } -func (s *Service) GetMonitoringRunnable() e2e.InstrumentedRunnable { - return s.p.InstrumentedRunnable -} - -func newCadvisor(env e2e.Environment, name string, cgroupPrefixes ...string) e2e.InstrumentedRunnable { - return e2e.NewInstrumentedRunnable(env, name).WithPorts(map[string]int{"http": 8080}, "http").Init(e2e.StartOptions{ +func newCadvisor(env e2e.Environment, name string, cgroupPrefixes ...string) *InstrumentedRunnable { + return AsInstrumented(env.Runnable(name).WithPorts(map[string]int{"http": 8080}).Init(e2e.StartOptions{ // See https://github.com/google/cadvisor/blob/master/docs/runtime_options.md. Command: e2e.NewCommand( // TODO(bwplotka): Add option to scope to dockers only from this network. @@ -254,5 +327,5 @@ func newCadvisor(env e2e.Environment, name string, cgroupPrefixes ...string) e2e }, UserNs: "host", Privileged: true, - }) + }), "http") } diff --git a/db/promconfig/discovery/azure/azure.go b/monitoring/promconfig/discovery/azure/azure.go similarity index 100% rename from db/promconfig/discovery/azure/azure.go rename to monitoring/promconfig/discovery/azure/azure.go diff --git a/db/promconfig/discovery/config/config.go b/monitoring/promconfig/discovery/config/config.go similarity index 75% rename from db/promconfig/discovery/config/config.go rename to monitoring/promconfig/discovery/config/config.go index 5dfde26..9160494 100644 --- a/db/promconfig/discovery/config/config.go +++ b/monitoring/promconfig/discovery/config/config.go @@ -20,18 +20,18 @@ package sdconfig import ( - "github.com/efficientgo/e2e/db/promconfig/discovery/azure" - "github.com/efficientgo/e2e/db/promconfig/discovery/consul" - "github.com/efficientgo/e2e/db/promconfig/discovery/dns" - "github.com/efficientgo/e2e/db/promconfig/discovery/ec2" - "github.com/efficientgo/e2e/db/promconfig/discovery/file" - "github.com/efficientgo/e2e/db/promconfig/discovery/gce" - "github.com/efficientgo/e2e/db/promconfig/discovery/kubernetes" - "github.com/efficientgo/e2e/db/promconfig/discovery/marathon" - "github.com/efficientgo/e2e/db/promconfig/discovery/openstack" - "github.com/efficientgo/e2e/db/promconfig/discovery/targetgroup" - "github.com/efficientgo/e2e/db/promconfig/discovery/triton" - "github.com/efficientgo/e2e/db/promconfig/discovery/zookeeper" + "github.com/efficientgo/e2e/monitoring/promconfig/discovery/azure" + "github.com/efficientgo/e2e/monitoring/promconfig/discovery/consul" + "github.com/efficientgo/e2e/monitoring/promconfig/discovery/dns" + "github.com/efficientgo/e2e/monitoring/promconfig/discovery/ec2" + "github.com/efficientgo/e2e/monitoring/promconfig/discovery/file" + "github.com/efficientgo/e2e/monitoring/promconfig/discovery/gce" + "github.com/efficientgo/e2e/monitoring/promconfig/discovery/kubernetes" + "github.com/efficientgo/e2e/monitoring/promconfig/discovery/marathon" + "github.com/efficientgo/e2e/monitoring/promconfig/discovery/openstack" + "github.com/efficientgo/e2e/monitoring/promconfig/discovery/targetgroup" + "github.com/efficientgo/e2e/monitoring/promconfig/discovery/triton" + "github.com/efficientgo/e2e/monitoring/promconfig/discovery/zookeeper" ) // ServiceDiscoveryConfig configures lists of different service discovery mechanisms. diff --git a/db/promconfig/discovery/consul/consul.go b/monitoring/promconfig/discovery/consul/consul.go similarity index 100% rename from db/promconfig/discovery/consul/consul.go rename to monitoring/promconfig/discovery/consul/consul.go diff --git a/db/promconfig/discovery/dns/dns.go b/monitoring/promconfig/discovery/dns/dns.go similarity index 100% rename from db/promconfig/discovery/dns/dns.go rename to monitoring/promconfig/discovery/dns/dns.go diff --git a/db/promconfig/discovery/ec2/ec2.go b/monitoring/promconfig/discovery/ec2/ec2.go similarity index 100% rename from db/promconfig/discovery/ec2/ec2.go rename to monitoring/promconfig/discovery/ec2/ec2.go diff --git a/db/promconfig/discovery/file/file.go b/monitoring/promconfig/discovery/file/file.go similarity index 100% rename from db/promconfig/discovery/file/file.go rename to monitoring/promconfig/discovery/file/file.go diff --git a/db/promconfig/discovery/gce/gce.go b/monitoring/promconfig/discovery/gce/gce.go similarity index 100% rename from db/promconfig/discovery/gce/gce.go rename to monitoring/promconfig/discovery/gce/gce.go diff --git a/db/promconfig/discovery/kubernetes/kubernetes.go b/monitoring/promconfig/discovery/kubernetes/kubernetes.go similarity index 100% rename from db/promconfig/discovery/kubernetes/kubernetes.go rename to monitoring/promconfig/discovery/kubernetes/kubernetes.go diff --git a/db/promconfig/discovery/marathon/marathon.go b/monitoring/promconfig/discovery/marathon/marathon.go similarity index 100% rename from db/promconfig/discovery/marathon/marathon.go rename to monitoring/promconfig/discovery/marathon/marathon.go diff --git a/db/promconfig/discovery/openstack/openstack.go b/monitoring/promconfig/discovery/openstack/openstack.go similarity index 100% rename from db/promconfig/discovery/openstack/openstack.go rename to monitoring/promconfig/discovery/openstack/openstack.go diff --git a/db/promconfig/discovery/targetgroup/targetgroup.go b/monitoring/promconfig/discovery/targetgroup/targetgroup.go similarity index 100% rename from db/promconfig/discovery/targetgroup/targetgroup.go rename to monitoring/promconfig/discovery/targetgroup/targetgroup.go diff --git a/db/promconfig/discovery/triton/triton.go b/monitoring/promconfig/discovery/triton/triton.go similarity index 100% rename from db/promconfig/discovery/triton/triton.go rename to monitoring/promconfig/discovery/triton/triton.go diff --git a/db/promconfig/discovery/zookeeper/zookeeper.go b/monitoring/promconfig/discovery/zookeeper/zookeeper.go similarity index 100% rename from db/promconfig/discovery/zookeeper/zookeeper.go rename to monitoring/promconfig/discovery/zookeeper/zookeeper.go diff --git a/db/promconfig/prometheus.go b/monitoring/promconfig/prometheus.go similarity index 99% rename from db/promconfig/prometheus.go rename to monitoring/promconfig/prometheus.go index 94490ee..0f762fc 100644 --- a/db/promconfig/prometheus.go +++ b/monitoring/promconfig/prometheus.go @@ -9,7 +9,6 @@ import ( "strings" "github.com/efficientgo/core/errors" - sdconfig "github.com/efficientgo/e2e/db/promconfig/discovery/config" config_util "github.com/prometheus/common/config" "github.com/prometheus/common/model" ) diff --git a/db/parcaconfig/parca.go b/profiling/parcaconfig/parca.go similarity index 92% rename from db/parcaconfig/parca.go rename to profiling/parcaconfig/parca.go index c29d751..184a851 100644 --- a/db/parcaconfig/parca.go +++ b/profiling/parcaconfig/parca.go @@ -3,8 +3,7 @@ package parcaconfig import ( "net/url" - "github.com/efficientgo/e2e/db/promconfig" - sdconfig "github.com/efficientgo/e2e/db/promconfig/discovery/config" + "github.com/efficientgo/e2e/monitoring/promconfig" config_util "github.com/prometheus/common/config" "github.com/prometheus/common/model" ) diff --git a/profiling/profiled.go b/profiling/profiled.go new file mode 100644 index 0000000..27b6630 --- /dev/null +++ b/profiling/profiled.go @@ -0,0 +1,76 @@ +package e2eprofiling + +import ( + "github.com/efficientgo/core/errors" + "github.com/efficientgo/e2e" + "github.com/efficientgo/e2e/profiling/parcaconfig" +) + +type Target struct { + InternalEndpoint string + Scheme string // "http" by default. + Config *parcaconfig.ProfilingConfig +} + +type Profiled interface { + ProfileTargets() []Target +} + +type Runnable struct { + e2e.Runnable + + pprofPort string + scheme string + config *parcaconfig.ProfilingConfig +} + +type runnableOpt struct { + config *parcaconfig.ProfilingConfig + scheme string +} + +// WithRunnableConfig sets a custom parca ProfilingConfig entry about this runnable. Empty by default (Parca defaults apply). +func WithRunnableConfig(config parcaconfig.ProfilingConfig) RunnableOption { + return func(o *runnableOpt) { + o.config = &config + } +} + +// WithRunnableScheme allows adding customized scheme. "http" or "https" values allowed. "http" by default. +// If "https" is specified, insecure TLS will be performed. +func WithRunnableScheme(scheme string) RunnableOption { + return func(o *runnableOpt) { + o.scheme = scheme + } +} + +type RunnableOption func(*runnableOpt) + +// AsProfiled wraps e2e.Runnable with Runnable that satisfies both Profiled and e2e.Runnable +// that represents runnable with pprof HTTP handlers exposed. +// NOTE(bwplotka): Caller is expected to discard passed `r` runnable and use returned Runnable.Runnable instead. +func AsProfiled(r e2e.Runnable, pprofPortName string, opts ...RunnableOption) *Runnable { + opt := runnableOpt{ + scheme: "http", + } + for _, o := range opts { + o(&opt) + } + + if r.InternalEndpoint(pprofPortName) == "" { + return &Runnable{Runnable: e2e.NewErrorer(r.Name(), errors.Newf("pporf port name %v does not exists in given runnable ports", pprofPortName))} + } + + instr := &Runnable{ + Runnable: r, + pprofPort: pprofPortName, + scheme: opt.scheme, + config: opt.config, + } + r.SetMetadata(metaKey, Profiled(instr)) + return instr +} + +func (r *Runnable) ProfileTargets() []Target { + return []Target{{Scheme: r.scheme, Config: r.config, InternalEndpoint: r.InternalEndpoint(r.pprofPort)}} +} diff --git a/profiling/profiling.go b/profiling/profiling.go new file mode 100644 index 0000000..cadc581 --- /dev/null +++ b/profiling/profiling.go @@ -0,0 +1,268 @@ +// Copyright (c) The EfficientGo Authors. +// Licensed under the Apache License 2.0. + +package e2eprofiling + +import ( + "fmt" + "net" + "net/http" + "net/http/pprof" + "os" + "path/filepath" + "strconv" + "strings" + "sync" + "time" + + "github.com/efficientgo/core/errors" + "github.com/efficientgo/e2e" + e2edb "github.com/efficientgo/e2e/db" + "github.com/efficientgo/e2e/db/promconfig/discovery/config" + e2einteractive "github.com/efficientgo/e2e/interactive" + e2emonitoring "github.com/efficientgo/e2e/monitoring" + "github.com/efficientgo/e2e/monitoring/promconfig/discovery/config" + "github.com/efficientgo/e2e/monitoring/promconfig/discovery/targetgroup" + "github.com/efficientgo/e2e/profiling/parcaconfig" + "github.com/prometheus/common/config" + "github.com/prometheus/common/model" + "gopkg.in/yaml.v2" +) + +var metaKey = struct{}{} + +type Parca struct { + e2e.Runnable + e2emonitoring.Instrumented + + configHeader string +} + +func NewParca(env e2e.Environment, name string, image string, flagOverride map[string]string) *Parca { + if image == "" { + image = "ghcr.io/parca-dev/parca:main-4e20a666" + } + + f := env.Runnable(name).WithPorts(map[string]int{"http": 7070}).Future() + + args := map[string]string{ + "--config-path": filepath.Join(f.InternalDir(), "data", "parca.yml"), + } + if flagOverride != nil { + args = e2e.MergeFlagsWithoutRemovingEmpty(args, flagOverride) + } + + config := ` +object_storage: + bucket: + type: "FILESYSTEM" + config: + directory: "./data" +scrape_configs: +` + if err := os.WriteFile(filepath.Join(f.Dir(), "data", "parca.yml"), []byte(config), 0600); err != nil { + return &Parca{Runnable: e2e.NewErrorer(name, errors.Wrap(err, "create prometheus config failed"))} + } + + p := e2emonitoring.AsInstrumented(f.Init(e2e.StartOptions{ + Image: image, + Command: e2e.NewCommand("/parca", e2e.BuildArgs(args)...), + User: strconv.Itoa(os.Getuid()), + Readiness: e2e.NewTCPReadinessProbe("http"), + }), "http") + + return &Parca{ + configHeader: config, + Runnable: p, + Instrumented: p, + } +} + +// SetScrapeConfigs updates Parca with new configuration marsh +func (p *Parca) SetScrapeConfigs(scrapeJobs []parcaconfig.ScrapeConfig) error { + c := p.configHeader + + b, err := yaml.Marshal(struct { + ScrapeConfigs []parcaconfig.ScrapeConfig `yaml:"scrape_configs,omitempty"` + }{ScrapeConfigs: scrapeJobs}) + if err != nil { + return err + } + + config := fmt.Sprintf("%v\n%v", c, b) + if err := os.WriteFile(filepath.Join(p.Dir(), "data", "parca.yml"), []byte(config), 0600); err != nil { + return errors.Wrap(err, "creating parca config failed") + } + + if p.IsRunning() { + // Reload configuration. + return p.Exec(e2e.NewCommand("kill", "-SIGHUP", "1")) + } + return nil +} + +type Service struct { + p Parca +} + +type listener struct { + p Parca + + localAddr string + scrapeInterval time.Duration +} + +func (l *listener) updateConfig(started map[string]instrumented) error { + // - job_name: "labeler" + // scrape_interval: "15s" + // static_configs: + // - targets: [ '` + labeler.InternalEndpoint("http") + `' ] + // profiling_config: + // pprof_config: + // fgprof: + // enabled: true + // path: /debug/fgprof/profile + // delta: true + var scfgs []parcaconfig.ScrapeConfig + add := func(name string, instr instrumented) { + scfg := parcaconfig.ScrapeConfig{ + JobName: name, + ServiceDiscoveryConfig: sdconfig.sdconfig{}, + HTTPClientConfig: config.HTTPClientConfig{ + TLSConfig: config.TLSConfig{ + // TODO(bwplotka): Allow providing certs? + // Allow insecure TLS. We are in benchmark/test that is focused on gathering data on all cost. + InsecureSkipVerify: true, + }, + }, + } + + for _, t := range instr.ProfilingTargets() { + g := &targetgroup.Group{ + Targets: []model.LabelSet{map[model.LabelName]model.LabelValue{ + model.AddressLabel: model.LabelValue(t.InternalEndpoint), + }}, + Labels: map[model.LabelName]model.LabelValue{ + model.SchemeLabel: model.LabelValue(strings.ToLower(t.Scheme)), + }, + } + scfg.ProfilingConfig = t.Config + scfg.ServiceDiscoveryConfig.StaticConfigs = append(scfg.ServiceDiscoveryConfig.StaticConfigs, g) + } + scfgs = append(scfgs, scfg) + } + + // Register local address. + scfg := parcaconfig.ScrapeConfig{ + JobName: "local", + ServiceDiscoveryConfig: sdconfig.ServiceDiscoveryConfig{StaticConfigs: []*targetgroup.Group{{ + Targets: []model.LabelSet{ + map[model.LabelName]model.LabelValue{ + model.AddressLabel: model.LabelValue(l.localAddr), + }, + }, + }}}, + } + scfgs = append(scfgs, scfg) + + for name, s := range started { + add(name, s) + } + + return l.p.SetScrapeConfigs(scfgs) +} + +func (l *listener) OnRunnableChange(started []e2e.Runnable) error { + s := map[string]instrumented{} + for _, r := range started { + instr, ok := r.(instrumented) + if !ok { + continue + } + s[r.Name()] = instr + } + + return l.updateConfig(s) +} + +type opt struct { + scrapeInterval time.Duration + customParcaImage string +} + +// WithScrapeInterval changes how often metrics are scrape by Prometheus. 5s by default. +func WithScrapeInterval(interval time.Duration) func(*opt) { + return func(o *opt) { + o.scrapeInterval = interval + } +} + +// WithParcaImage allows injecting custom Parca docker image to use as scraper and queryable. +func WithParcaImage(image string) func(*opt) { + return func(o *opt) { + o.customParcaImage = image + } +} + +type Option func(*opt) + +// Start deploys monitoring service which deploys Parca that monitors all registered +// InstrumentedServices in environment. +func Start(env e2e.Environment, opts ...Option) (_ *Service, err error) { + opt := opt{scrapeInterval: 5 * time.Second} + for _, o := range opts { + o(&opt) + } + + m := http.NewServeMux() + m.HandleFunc("/debug/pprof/", pprof.Index) + + o := sync.Once{} + scraped := make(chan struct{}) + m.Handle("/debug/pprof/profile", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + o.Do(func() { close(scraped) }) + pprof.Profile(w, req) + })) + + // Listen on all addresses, since we need to connect to it from docker container. + list, err := net.Listen("tcp", "0.0.0.0:0") + if err != nil { + return nil, err + } + s := http.Server{Handler: m} + + go func() { _ = s.Serve(list) }() + env.AddCloser(func() { _ = s.Close() }) + + var dbOpts []e2edb.Option + if opt.customParcaImage != "" { + dbOpts = append(dbOpts, e2edb.WithImage(opt.customParcaImage)) + } + p := e2edb.NewParca(env, "monitoring", dbOpts...) + + _, port, err := net.SplitHostPort(list.Addr().String()) + if err != nil { + return nil, err + } + l := &listener{p: p, localAddr: net.JoinHostPort(env.HostAddr(), port), scrapeInterval: opt.scrapeInterval} + if err := l.updateConfig(map[string]instrumented{}); err != nil { + return nil, err + } + env.AddListener(l) + + if err := e2e.StartAndWaitReady(p); err != nil { + return nil, err + } + + select { + case <-time.After(2 * time.Minute): + return nil, errors.New("Prometheus failed to scrape local endpoint after 2 minutes, check monitoring Prometheus logs") + case <-scraped: + } + + return &Service{p: p}, nil +} + +func (s *Service) OpenUserInterfaceInBrowser(paths ...string) error { + return e2einteractive.OpenInBrowser("http://" + s.p.Endpoint(e2edb.AccessPortName) + strings.Join(paths, "/")) +} From 410782466cf8970554f973c55a406ad45a2e2ca9 Mon Sep 17 00:00:00 2001 From: bwplotka Date: Tue, 13 Sep 2022 10:00:13 +0200 Subject: [PATCH 4/7] Conversion: from return e2emonitoring.NewInstrumentedRunnable(env, name).WithPorts(ports, "http").Init(e2e.StartOptions{ Image: o.image, Command: e2e.NewCommand("sidecar", e2e.BuildKingpinArgs(args)...), Readiness: e2e.NewHTTPReadinessProbe("http", "/-/ready", 200, 200), User: strconv.Itoa(os.Getuid()), }) to return e2emonitoring.AsInstrumented(env.Runnable(name).WithPorts(ports).Init(e2e.StartOptions{ Image: o.image, Command: e2e.NewCommand("sidecar", e2e.BuildKingpinArgs(args)...), Readiness: e2e.NewHTTPReadinessProbe("http", "/-/ready", 200, 200), User: strconv.Itoa(os.Getuid()), }), "http") Signed-off-by: bwplotka --- .bingo/copyright.sum | 125 +++ .bingo/golangci-lint.sum | 1049 ++++++++++++++++++++++++ .bingo/misspell.sum | 2 + .gitignore | 1 + README.md | 124 +-- db/db.go | 52 +- db/thanos.go | 22 +- env.go | 5 + env_docker.go | 61 +- examples/exampleapp/exampleapp_test.go | 19 +- examples/thanos/README.md | 3 - examples/thanos/benchmark_test.go | 12 - examples/thanos/e2etest_test.go | 10 +- examples/thanos/standalone.go | 20 +- monitoring/instrumented.go | 50 +- monitoring/instrumented_composite.go | 4 +- monitoring/instrumented_test.go | 6 +- monitoring/metrics.go | 2 +- monitoring/monitoring.go | 82 +- monitoring/promconfig/prometheus.go | 1 + observable/observable.go | 76 ++ profiling/parcaconfig/parca.go | 1 + profiling/profiled.go | 44 +- profiling/profiling.go | 130 ++- 24 files changed, 1588 insertions(+), 313 deletions(-) create mode 100644 .bingo/copyright.sum create mode 100644 .bingo/golangci-lint.sum create mode 100644 .bingo/misspell.sum delete mode 100644 examples/thanos/README.md delete mode 100644 examples/thanos/benchmark_test.go create mode 100644 observable/observable.go diff --git a/.bingo/copyright.sum b/.bingo/copyright.sum new file mode 100644 index 0000000..11f329b --- /dev/null +++ b/.bingo/copyright.sum @@ -0,0 +1,125 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20201120081800-1786d5ef83d4 h1:EBTWhcAX7rNQ80RLwLCpHZBBrJuzallFHnF+yMXo928= +github.com/alecthomas/units v0.0.0-20201120081800-1786d5ef83d4/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/efficientgo/tools v0.0.0-20201228165755-e2b84817bf79 h1:Pi2rMrMQeQ45UAZr8Ple+eSk9WCyglYpkFh0r22E00c= +github.com/efficientgo/tools v0.0.0-20201228165755-e2b84817bf79/go.mod h1:jQUsxCcf91LHRhOnGqrx/yrleJbosynzf29/UlCbzlk= +github.com/efficientgo/tools/copyright v0.0.0-20210610185804-b6b578a86384 h1:AWXYTZYYsVLisnO9vNxmjvcSEupREgYzZPfETMZkiOs= +github.com/efficientgo/tools/copyright v0.0.0-20210610185804-b6b578a86384/go.mod h1:5J0wuuxLMX06WeEgnpf+SvTCptlR9+RHRNO/WEMAwSw= +github.com/efficientgo/tools/core v0.0.0-20210106193344-1108f4e7d16b h1:yi5z8x/FKDHrqtEFiAsxF5b7Sz2+CJrRwBC2kbyhVcA= +github.com/efficientgo/tools/core v0.0.0-20210106193344-1108f4e7d16b/go.mod h1:RJm2+KCRfMUwgEgRte3obd5uLdVY5YbDZjgSMPY0HSA= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/felixge/fgprof v0.9.1/go.mod h1:7/HK6JFtFaARhIljgP2IV8rJLIoHDoOYoUphsnGvqxE= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.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/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +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.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.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/pprof v0.0.0-20200615235658-03e1cf38a040/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/protoconfig/protoconfig/go v0.0.0-20210106192113-733758adefac h1:PWrv6uwNBua14NbS74ukVgXgdRDQPx/2B+Rf6KXXoQk= +github.com/protoconfig/protoconfig/go v0.0.0-20210106192113-733758adefac/go.mod h1:ig8lL2CeTS14ijDIIRoi6pTap0BHc0Xrnke+SKmn9QM= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/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-20190313153728-d0100b6bd8b3/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-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +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-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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/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-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20201020161133-226fd2f889ca/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +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-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.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +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.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +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= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/.bingo/golangci-lint.sum b/.bingo/golangci-lint.sum new file mode 100644 index 0000000..42ddd8b --- /dev/null +++ b/.bingo/golangci-lint.sum @@ -0,0 +1,1049 @@ +4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a h1:wFEQiK85fRsEVF0CRrPAos5LoAryUsIX1kPW/WrIqFw= +4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= +bitbucket.org/creachadair/shell v0.0.6/go.mod h1:8Qqi/cYk7vPnsOePHroKXDJYmb5x7ENhtiFtfZq8K+M= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +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.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU= +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/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +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/pubsub v1.5.0/go.mod h1:ZEwJccE3z93Z2HWvstpri00jOg7oO4UZDtKhwDwqF0w= +cloud.google.com/go/spanner v1.7.0/go.mod h1:sd3K2gZ9Fd0vMPLXzeCrF6fq4i63Q7aTLW/lBIfBkIk= +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= +contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= +github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= +github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= +github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= +github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= +github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/ashanbrown/forbidigo v1.2.0 h1:RMlEFupPCxQ1IogYOQUnIQwGEUGK8g5vAPMRyJoSxbc= +github.com/ashanbrown/forbidigo v1.2.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI= +github.com/ashanbrown/makezero v0.0.0-20210520155254-b6261585ddde h1:YOsoVXsZQPA9aOTy1g0lAJv5VzZUvwQuZqug8XPeqfM= +github.com/ashanbrown/makezero v0.0.0-20210520155254-b6261585ddde/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU= +github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A= +github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI= +github.com/bombsimon/wsl/v3 v3.3.0 h1:Mka/+kRLoQJq7g2rggtgQsjuI/K5Efd87WX96EWFxjM= +github.com/bombsimon/wsl/v3 v3.3.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/charithe/durationcheck v0.0.8 h1:cnZrThioNW9gSV5JsRIXmkyHUbcDH7Y9hkzFDVc9/j0= +github.com/charithe/durationcheck v0.0.8/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= +github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af h1:spmv8nSH9h5oCQf40jt/ufBCt9j0/58u4G+rkeMqXGI= +github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af/go.mod h1:Qjyv4H3//PWVzTeCezG2b9IRn6myJxJSr4TD/xo6ojU= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/daixiang0/gci v0.2.8 h1:1mrIGMBQsBu0P7j7m1M8Lb+ZeZxsZL+jyGX4YoMJJpg= +github.com/daixiang0/gci v0.2.8/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc= +github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denis-tingajkin/go-header v0.4.2 h1:jEeSF4sdv8/3cT/WY8AgDHUoItNSoEZ7qg9dX7pc218= +github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/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.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/esimonov/ifshort v1.0.2 h1:K5s1W2fGfkoWXsFlxBNqT6J0ZCncPaKrGM5qe0bni68= +github.com/esimonov/ifshort v1.0.2/go.mod h1:yZqNJUrNn20K8Q9n2CrjTKYyVEmX209Hgu+M1LBpeZE= +github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw= +github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= +github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= +github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fullstorydev/grpcurl v1.6.0/go.mod h1:ZQ+ayqbKMJNhzLmbpCiurTVlaK2M/3nqZCxaQ2Ze/sM= +github.com/fzipp/gocyclo v0.3.1 h1:A9UeX3HJSXTBzvHzhqoYVuE0eAhe+aM8XBCCwsPMZOc= +github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-critic/go-critic v0.5.6 h1:siUR1+322iVikWXoV75I1YRfNaC/yaLzhdF9Zwd8Tus= +github.com/go-critic/go-critic v0.5.6/go.mod h1:cVjj0DfqewQVIlIAGexPCaGaZDAqGE29PYDDADIVNEo= +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-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +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/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= +github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= +github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= +github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= +github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= +github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= +github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= +github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= +github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= +github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= +github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= +github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= +github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= +github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= +github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk= +github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= +github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY= +github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +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/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.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/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.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.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.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= +github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw= +github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= +github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= +github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= +github.com/golangci/golangci-lint v1.41.1 h1:KH28pTSqRu6DTXIAANl1sPXNCmqg4VEH21z6G9Wj4SM= +github.com/golangci/golangci-lint v1.41.1/go.mod h1:LPtcY3aAAU8wydHrKpnanx9Og8K/cblZSyGmI5CJZUk= +github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= +github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= +github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo= +github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= +github.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5 h1:c9Mqqrm/Clj5biNaG7rABrmwUq88nHh0uABo2b/WYmc= +github.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5/go.mod h1:LK+zW4MpyytAWQRz0M4xnzEk50lSvqDQKfx304apFkY= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= +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/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= +github.com/google/certificate-transparency-go v1.1.1/go.mod h1:FDKqPvSXawb2ecErVRrD+nfy23RCzyl7eqVCEmlT1Zs= +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.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.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.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/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-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEivX+9mPgw= +github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/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/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= +github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254 h1:Nb2aRlC404yz7gQIfRZxX9/MLvQiqXyiBTJtgAy6yrI= +github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254/go.mod h1:M9mZEtGIsR1oDaZagNPNG9iq9n2HrhZ17dsXk73V3Lw= +github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= +github.com/gostaticanalysis/analysisutil v0.4.1 h1:/7clKqrVfiVwiBQLM0Uke4KvXnO6JcCTS7HwF2D6wG8= +github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0= +github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= +github.com/gostaticanalysis/comment v1.4.1 h1:xHopR5L2lRz6OsjH4R2HG5wRhW9ySl3FsHIvi5pcXwc= +github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= +github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5 h1:rx8127mFPqXXsfPSo8BwnIU97MKFZc89WHAHt8PwDVY= +github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= +github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk= +github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +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-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +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/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= +github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= +github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= +github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4= +github.com/jingyugao/rowserrcheck v1.1.0 h1:u6h4eiNuCLqk73Ic5TXQq9yZS+uEXTdusn7c3w1Mr6A= +github.com/jingyugao/rowserrcheck v1.1.0/go.mod h1:TOQpc2SLx6huPfoFGK3UOnEG+u02D3C1GeosjupAKCA= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +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.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +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/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julz/importas v0.0.0-20210419104244-841f0c0fe66d h1:XeSMXURZPtUffuWAaq90o6kLgZdgu+QA8wk4MPC8ikI= +github.com/julz/importas v0.0.0-20210419104244-841f0c0fe66d/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.6.0 h1:YTDO4pNy7AUN/021p+JGHycQyYNIyMoenM1YDVK6RlY= +github.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +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.2/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/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kulti/thelper v0.4.0 h1:2Nx7XbdbE/BYZeoip2mURKUdtHQRuy6Ug+wR7K9ywNM= +github.com/kulti/thelper v0.4.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U= +github.com/kunwardeep/paralleltest v1.0.2 h1:/jJRv0TiqPoEy/Y8dQxCFJhD56uS/pnvtatgTZBHokU= +github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= +github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= +github.com/ldez/gomoddirectives v0.2.1 h1:9pAcW9KRZW7HQjFwbozNvFMcNVwdCBufU7os5QUwLIY= +github.com/ldez/gomoddirectives v0.2.1/go.mod h1:sGicqkRgBOg//JfpXwkB9Hj0X5RyJ7mlACM5B9f6Me4= +github.com/ldez/tagliatelle v0.2.0 h1:693V8Bf1NdShJ8eu/s84QySA0J2VWBanVBa2WwXD/Wk= +github.com/ldez/tagliatelle v0.2.0/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= +github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/maratori/testpackage v1.0.1 h1:QtJ5ZjqapShm0w5DosRjg0PRlSdAdlx+W6cCKoALdbQ= +github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= +github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= +github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= +github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= +github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 h1:QASJXOGm2RZ5Ardbc86qNFvby9AqkLDibfChMtAg5QM= +github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg= +github.com/mgechev/revive v1.0.7 h1:5kEWTY/W5a0Eiqnkn2BAWsRZpxbs1ft15PsyNC7Rml8= +github.com/mgechev/revive v1.0.7/go.mod h1:vuE5ox/4L/HDd63MCcCk3H6wTLQ6XXezRphJ8cJJOxY= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= +github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= +github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinKo8VaLxe6PWTPEXRXDIHz2QAwiaBaP5/4a8= +github.com/mozilla/tls-observatory v0.0.0-20210209181001-cf43108d6880/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo= +github.com/mwitkow/go-proto-validators v0.2.0/go.mod h1:ZfA1hW+UH/2ZHOWvQ3HnQaU0DtnpXu850MZiy+YUgcc= +github.com/nakabonne/nestif v0.3.0 h1:+yOViDGhg8ygGrmII72nV9B/zGxY188TYpfolntsaPw= +github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= +github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA= +github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nishanths/exhaustive v0.1.0 h1:kVlMw8h2LHPMGUVqUj6230oQjjTMFjwcZrnkhXzFfl8= +github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ= +github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ= +github.com/nishanths/predeclared v0.2.1 h1:1TXtjmy4f3YCFjTxRd8zcFHOmoUir+gp0ESzjFzG2sw= +github.com/nishanths/predeclared v0.2.1/go.mod h1:HvkGJcA3naj4lOwnFXFDkFxVtSqQMB9sbB1usJ+xjQE= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.1/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= +github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/polyfloyd/go-errorlint v0.0.0-20210510181950-ab96adb96fea h1:Sk6Xawg57ZkjXmFYD1xCHSKN6FtYM+km51MM7Lveyyc= +github.com/polyfloyd/go-errorlint v0.0.0-20210510181950-ab96adb96fea/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +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-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/pseudomuto/protoc-gen-doc v1.3.2/go.mod h1:y5+P6n3iGrbKG+9O04V5ld71in3v/bX88wUwgt+U8EA= +github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q= +github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= +github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30= +github.com/quasilyte/go-ruleguard v0.3.4 h1:F6l5p6+7WBcTKS7foNQ4wqA39zjn2+RbdbyzGxIq1B0= +github.com/quasilyte/go-ruleguard v0.3.4/go.mod h1:57FZgMnoo6jqxkYKmVj5Fc8vOt0rVzoE/UNAmFFIPqA= +github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/go-ruleguard/dsl v0.3.2/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc= +github.com/quasilyte/go-ruleguard/rules v0.0.0-20210203162857-b223e0831f88/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= +github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf68pVdQ3bCFZMDmnt9yqcMBro1pC7F+IPYMY= +github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryancurrah/gomodguard v1.2.2 h1:ZJQeYHZ2kaJpojoQBaGqpsn5g7GMcePY36uUGW1umbs= +github.com/ryancurrah/gomodguard v1.2.2/go.mod h1:tpI+C/nzvfUR3bF28b5QHpTn/jM/zlGniI++6ZlIWeE= +github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= +github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3335lYTyxRoA= +github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/securego/gosec/v2 v2.8.0 h1:iHg9cVmHWf5n6/ijUJ4F10h5bKlNtvXmcWzRw0lxiKE= +github.com/securego/gosec/v2 v2.8.0/go.mod h1:hJZ6NT5TqoY+jmOsaxAV4cXoEdrMRLVaNPnSpUCvCZs= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= +github.com/shirou/gopsutil/v3 v3.21.5/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= +github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= +github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ= +github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= +github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/ssgreg/nlreturn/v2 v2.1.0 h1:6/s4Rc49L6Uo6RLjhWZGBpWWjfzk2yrf1nIW8m4wgVA= +github.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.1.4/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.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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b h1:HxLVTlqcHhFAz3nWUcuvpH7WuOMv8LQoCWmruLfFH2U= +github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= +github.com/tetafro/godot v1.4.7 h1:zBaoSY4JRVVz33y/qnODsdaKj2yAaMr91HCbqHCifVc= +github.com/tetafro/godot v1.4.7/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= +github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94 h1:ig99OeTyDwQWhPe2iw9lwfQVF1KB3Q4fpP3X7/2VBG8= +github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= +github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tomarrell/wrapcheck/v2 v2.1.0 h1:LTzwrYlgBUwi9JldazhbJN84fN9nS2UNGrZIo2syqxE= +github.com/tomarrell/wrapcheck/v2 v2.1.0/go.mod h1:crK5eI4RGSUrb9duDTQ5GqcukbKZvi85vX6nbhsBAeI= +github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= +github.com/tommy-muehle/go-mnd/v2 v2.4.0 h1:1t0f8Uiaq+fqKteUR4N9Umr6E99R+lDnLnq7PwX2PPE= +github.com/tommy-muehle/go-mnd/v2 v2.4.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= +github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= +github.com/ultraware/whitespace v0.0.4 h1:If7Va4cM03mpgrNH9k49/VOicWpGoG70XPBFFODYDsg= +github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/uudashr/gocognit v1.0.1 h1:MoG2fZ0b/Eo7NXoIwCVFLG5JED3qgQz5/NEE+rOsjPs= +github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= +github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yeya24/promlinter v0.1.0 h1:goWULN0jH5Yajmu/K+v1xCqIREeB+48OiJ2uu2ssc7U= +github.com/yeya24/promlinter v0.1.0/go.mod h1:rs5vtZzeBHqqMwXqFScncpCF6u06lezhZepno9AB1Oc= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +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.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6yfWfDmlWd35khcWpUa4L0xI/k= +go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403/go.mod h1:jHoPAGnDrCy6kaI2tAze5Prf0Nr0w/oNkROt2lw3n3o= +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.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/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-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-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-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +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/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +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-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-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.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-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-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-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/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-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-20200421231249-e086a090c8fd/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-20200520004742-59133d7f0dd7/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-20200602114024-627f9648deb9/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-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-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +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/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/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-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-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-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-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/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-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/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-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-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-20200420163511-1957bb5e6d1f/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-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/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-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +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.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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/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-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/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-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/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-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-20190910044552-dd2b5c81c578/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-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/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-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-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +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-20200117220505-0cba7a3a9ee9/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-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +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-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201114224030-61ea331ec02b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210104081019-d8d6ddbec6ee/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3 h1:L69ShwSZEyCsLKoAxDKeMvLDZkumEe8gXUZAjab0tX8= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/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.10.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/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/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.2/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/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181107211654-5fc9ac540362/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-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/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-20200423170343-7949de9c1215/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-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +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.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +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.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +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-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.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +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.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/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.6/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.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +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-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-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.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.2.0 h1:ws8AfbgTX3oIczLPNPCu5166oBg9ST2vNs0rcht+mDE= +honnef.co/go/tools v0.2.0/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= +mvdan.cc/gofumpt v0.1.1 h1:bi/1aS/5W00E2ny5q65w9SnKpWEF/UIOqDYBILpo9rA= +mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= +mvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7 h1:HT3e4Krq+IE44tiN36RvVEb6tvqeIdtsVSsxmNPqlFU= +mvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7/go.mod h1:hBpJkZE8H/sb+VRFvw2+rBpHNsTBcvSpk61hr8mzXZE= +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/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/.bingo/misspell.sum b/.bingo/misspell.sum new file mode 100644 index 0000000..ee59480 --- /dev/null +++ b/.bingo/misspell.sum @@ -0,0 +1,2 @@ +github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= diff --git a/.gitignore b/.gitignore index 343c916..27bf87b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ vendor/ .bin/ .idea/ .envrc +e2e_*/ diff --git a/README.md b/README.md index b6dca93..008793a 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ There are three main use cases envisioned for this Go module: * *e2e test use* ([see example](examples/thanos/e2etest_test.go)). Use `e2e` in e2e tests to quickly run complex test scenarios involving many container services. This was the main reason we created this module. You can check usage of it in [Cortex](https://github.com/cortexproject/cortex/tree/master/integration) and [Thanos](https://github.com/thanos-io/thanos/tree/main/test/e2e) projects. * *Standalone use* ([see example](examples/thanos/standalone.go)). Use `e2e` to run setups in interactive mode where you spin up workloads as you want *programmatically* and poke with it on your own using your browser or other tools. No longer need to deploy full Kubernetes or external machines. -* *Benchmark use* ([see example](examples/thanos/benchmark_test.go)). Use `e2e` in local Go benchmarks when your code depends on external services with ease. +* *Benchmark use*. Use `e2e` in local Go benchmarks when your code depends on external services with ease. ### Getting Started @@ -26,18 +26,17 @@ Let's go through an example leveraging the `go test` flow: 1. Get the `e2e` Go module to your `go.mod` using `go get github.com/efficientgo/e2e`. 2. Implement a test. Start by creating an environment. Currently `e2e` supports Docker environment only. Use a unique name for all of your tests. It's recommended to keep it stable so resources are consistently cleaned. - ```go mdox-exec="sed -n '22,26p' examples/thanos/e2etest_test.go" - + ```go mdox-exec="sed -n '24,28p' examples/thanos/e2etest_test.go" // Start isolated environment with given ref. e, err := e2e.New() testutil.Ok(t, err) // Make sure resources (e.g docker containers, network, dir) are cleaned. + t.Cleanup(e.Close) ``` -3. Implement the workload by embedding `e2e.Runnable` or `*e2e.InstrumentedRunnable`. Or you can use existing ones in the [e2edb](db/) package. For example implementing a function that schedules Jaeger with our desired configuration could look like this: +3. Implement the workload by creating `e2e.Runnable`. Or you can use existing runnables in the [e2edb](db/) package. For example implementing a function that schedules Jaeger with our desired configuration could look like this: - ```go mdox-exec="sed -n '35,42p' examples/thanos/standalone.go" - // Setup Jaeger for example purposes, on how easy is to setup tracing pipeline in e2e framework. + ```go mdox-exec="sed -n '42,48p' examples/thanos/standalone.go" j := e.Runnable("tracing"). WithPorts( map[string]int{ @@ -47,10 +46,27 @@ Let's go through an example leveraging the `go test` flow: Init(e2e.StartOptions{Image: "jaegertracing/all-in-one:1.25"}) ``` -4. Program your scenario as you want. You can start, wait for their readiness, stop, check their metrics and use their network endpoints from both unit test (`Endpoint`) as well as within each workload (`InternalEndpoint`). You can also access workload directory. There is a shared directory across all workloads. Check `Dir` and `InternalDir` runnable methods. +4. Use `e2emon.AsInstrumented` if you want to be able to query your service for metrics, which is a great way to assess it's internal state in tests! For example see following Etcd definition: + + ```go mdox-exec="sed -n '216,228p' db/db.go" + return e2emon.AsInstrumented(env.Runnable(name).WithPorts(map[string]int{AccessPortName: 2379, "metrics": 9000}).Init( + e2e.StartOptions{ + Image: o.image, + Command: e2e.NewCommand( + "/usr/local/bin/etcd", + "--listen-client-urls=http://0.0.0.0:2379", + "--advertise-client-urls=http://0.0.0.0:2379", + "--listen-metrics-urls=http://0.0.0.0:9000", + "--log-level=error", + ), + Readiness: e2e.NewHTTPReadinessProbe("metrics", "/health", 200, 204), + }, + ), "metrics") + ``` - ```go mdox-exec="sed -n '28,93p' examples/thanos/e2etest_test.go" +5. Program your scenario as you want. You can start, wait for their readiness, stop, check their metrics and use their network endpoints from both unit test (`Endpoint`) as well as within each workload (`InternalEndpoint`). You can also access workload directory. There is a shared directory across all workloads. Check `Dir` and `InternalDir` runnable methods. + ```go mdox-exec="sed -n '30,53p' examples/thanos/e2etest_test.go" // Create structs for Prometheus containers scraping itself. p1 := e2edb.NewPrometheus(e, "prometheus-1") s1 := e2edb.NewThanosSidecar(e, "sidecar-1", p1) @@ -67,55 +83,14 @@ Let's go through an example leveraging the `go test` flow: // To ensure query should have access we can check its Prometheus metric using WaitSumMetrics method. Since the metric we are looking for // only appears after init, we add option to wait for it. - testutil.Ok(t, t1.WaitSumMetricsWithOptions(e2e.Equals(2), []string{"thanos_store_nodes_grpc_connections"}, e2e.WaitMissingMetrics())) + testutil.Ok(t, t1.WaitSumMetricsWithOptions(e2emon.Equals(2), []string{"thanos_store_nodes_grpc_connections"}, e2emon.WaitMissingMetrics())) // To ensure Prometheus scraped already something ensure number of scrapes. - testutil.Ok(t, p1.WaitSumMetrics(e2e.Greater(50), "prometheus_tsdb_head_samples_appended_total")) - testutil.Ok(t, p2.WaitSumMetrics(e2e.Greater(50), "prometheus_tsdb_head_samples_appended_total")) + testutil.Ok(t, p1.WaitSumMetrics(e2emon.Greater(50), "prometheus_tsdb_head_samples_appended_total")) + testutil.Ok(t, p2.WaitSumMetrics(e2emon.Greater(50), "prometheus_tsdb_head_samples_appended_total")) // We can now query Thanos Querier directly from here, using it's host address thanks to Endpoint method. a, err := api.NewClient(api.Config{Address: "http://" + t1.Endpoint("http")}) - testutil.Ok(t, err) - - { - now := model.Now() - v, w, err := v1.NewAPI(a).Query(context.Background(), "up{}", now.Time()) - testutil.Ok(t, err) - testutil.Equals(t, 0, len(w)) - testutil.Equals( - t, - fmt.Sprintf(`up{instance="%v", job="myself", prometheus="prometheus-1"} => 1 @[%v] - up{instance="%v", job="myself", prometheus="prometheus-2"} => 1 @[%v]`, p1.InternalEndpoint(e2edb.AccessPortName), now, p2.InternalEndpoint(e2edb.AccessPortName), now), - v.String(), - ) - } - - // Stop first Prometheus and sidecar. - testutil.Ok(t, s1.Stop()) - testutil.Ok(t, p1.Stop()) - - // Wait a bit until Thanos drops connection to stopped Prometheus. - testutil.Ok(t, t1.WaitSumMetricsWithOptions(e2e.Equals(1), []string{"thanos_store_nodes_grpc_connections"}, e2e.WaitMissingMetrics())) - - { - now := model.Now() - v, w, err := v1.NewAPI(a).Query(context.Background(), "up{}", now.Time()) - testutil.Ok(t, err) - testutil.Equals(t, 0, len(w)) - testutil.Equals( - t, - fmt.Sprintf(`up{instance="%v", job="myself", prometheus="prometheus-2"} => 1 @[%v]`, p2.InternalEndpoint(e2edb.AccessPortName), now), - v.String(), - ) - } - - // Batch job example. - batch := e.Runnable("batch").Init(e2e.StartOptions{Image: "ubuntu:20.04", Command: e2e.NewCommandRunUntilStop()}) - testutil.Ok(t, batch.Start()) - - var out bytes.Buffer - testutil.Ok(t, batch.Exec(e2e.NewCommand("echo", "it works"), e2e.WithExecOptionStdout(&out))) - testutil.Equals(t, "it works\n", out.String()) ``` ### Interactive @@ -128,22 +103,29 @@ err := e2einteractive.RunUntilEndpointHit() ### Monitoring -Each instrumented workload have programmatic access to the latest metrics with `WaitSumMetricsWithOptions` methods family. Yet, especially for standalone mode it's often useful to query and visualise all metrics provided by your services/runnables using PromQL. In order to do so just start monitoring from `e2emonitoring` package: +Each instrumented workload (runnable wrapped with `e2emon.AsInstrumented`) have programmatic access to the latest metrics with `WaitSumMetricsWithOptions` methods family. Yet, especially for standalone mode it's often useful to query and visualise all metrics provided by your services/runnables using PromQL. In order to do so just start monitoring from [`e2emon`](monitoring) package: ```go -mon, err := e2emonitoring.Start(e) +mon, err := e2emon.Start(e) ``` -This will start Prometheus with automatic discovery for every new and old instrumented runnables being scraped. It also runs cadvisor that monitors docker itself if `env.DockerEnvironment` is started and shows generic performance metrics per container (e.g `container_memory_rss`). Run `OpenUserInterfaceInBrowser()` to open the Prometheus UI in the browser. +This will start Prometheus with automatic discovery for every new and old instrumented runnables. It also runs cadvisor that monitors docker itself if `env.DockerEnvironment` is started and shows generic performance metrics per container (e.g `container_memory_rss`). Run `OpenUserInterfaceInBrowser()` to open the Prometheus UI in the browser: -```go mdox-exec="sed -n '83,86p' examples/thanos/standalone.go" - } +```go mdox-exec="sed -n '90,93p' examples/thanos/standalone.go" // Open monitoring page with all metrics. if err := mon.OpenUserInterfaceInBrowser(); err != nil { return errors.Wrap(err, "open monitoring UI in browser") + } ``` -To see how it works in practice, run our example code in [standalone.go](examples/thanos/standalone.go) by running `make run-example`. At the end, three UIs should show in your browser. Thanos one, monitoring (Prometheus) one and tracing (Jaeger) one. In monitoring UI you can then e.g. query docker container metrics using `container_memory_working_set_bytes{id!="/"}` metric: +To see how it works in practice, run our example code in [standalone.go](examples/thanos/standalone.go) by running `make run-example`. At the end, three UIs should show in your browser: + +* Thanos one, +* Monitoring (Prometheus) +* Profiling (Parca) +* Tracing (Jaeger). + +In the monitoring UI you can then e.g. query docker container metrics using `container_memory_working_set_bytes{id!="/"}` metric: ![mem metric](monitoring.png) @@ -173,6 +155,32 @@ func Run(ctx context.Context) error { This will run your code in a container allowing to use the same monitoring methods thanks to cadvisor. +### Continous Profiling + +Similarly to [Monitoring](#monitoring), you can wrap your runnable (or instrumented runnable) with `e2eprof.AsProfiled` if your service uses HTTP pprof handlers (common in Go). When wrapped, you can start continuous profiler using [`e2eprof`](profiling) package: + +```go +mon, err := e2eprof.Start(e) +``` + +This will start Parca with automatic discovery for every new and old profiled runnables. Run `OpenUserInterfaceInBrowser()` to open the Parca UI in the browser: + +```go mdox-exec="sed -n '94,97p' examples/thanos/standalone.go" + // Open profiling page with all profiles. + if err := prof.OpenUserInterfaceInBrowser(); err != nil { + return errors.Wrap(err, "open profiling UI in browser") + } +``` + +To see how it works in practice, run our example code in [standalone.go](examples/thanos/standalone.go) by running `make run-example`. At the end, four UIs should show in your browser: + +* Thanos one, +* Monitoring (Prometheus) +* Profiling (Parca) +* Tracing (Jaeger). + +> NOTE: For runnables that are both instrumented and profiled you can use [`e2eobs.AsObservable`](observable/observable.go). + ### Troubleshooting #### Can't create docker network diff --git a/db/db.go b/db/db.go index fbaedd6..879ac1c 100644 --- a/db/db.go +++ b/db/db.go @@ -13,16 +13,10 @@ import ( "strings" "github.com/efficientgo/e2e" - e2emonitoring "github.com/efficientgo/e2e/monitoring" - e2eprofiling "github.com/efficientgo/e2e/profiling" + e2emon "github.com/efficientgo/e2e/monitoring" + e2eprof "github.com/efficientgo/e2e/profiling" ) -type Observable struct { - e2e.Runnable - e2emonitoring.Instrumented - e2eprofiling.Profiled -} - const ( MinioAccessKey = "Cheescake" MinioSecretKey = "supersecret" @@ -60,26 +54,26 @@ func WithMinioSSE() Option { const AccessPortName = "http" -func NewPrometheus(env e2e.Environment, name string, opts ...Option) *e2emonitoring.Prometheus { +func NewPrometheus(env e2e.Environment, name string, opts ...Option) *e2emon.Prometheus { o := options{} for _, opt := range opts { opt(&o) } - return e2emonitoring.NewPrometheus(env, name, o.image, o.flagOverride) + return e2emon.NewPrometheus(env, name, o.image, o.flagOverride) } -func NewParca(env e2e.Environment, name string, opts ...Option) *e2eprofiling.Parca { +func NewParca(env e2e.Environment, name string, opts ...Option) *e2eprof.Parca { o := options{} for _, opt := range opts { opt(&o) } - return e2eprofiling.NewParca(env, name, o.image, o.flagOverride) + return e2eprof.NewParca(env, name, o.image, o.flagOverride) } // NewMinio returns minio server, used as a local replacement for S3. -func NewMinio(env e2e.Environment, name, bktName string, opts ...Option) *e2emonitoring.InstrumentedRunnable { +func NewMinio(env e2e.Environment, name, bktName string, opts ...Option) *e2emon.InstrumentedRunnable { o := options{image: "minio/minio:RELEASE.2022-03-14T18-25-24Z"} for _, opt := range opts { opt(&o) @@ -111,7 +105,7 @@ func NewMinio(env e2e.Environment, name, bktName string, opts ...Option) *e2emon command += "curl -sSL --tlsv1.3 -O 'https://raw.githubusercontent.com/minio/kes/master/root.key' -O 'https://raw.githubusercontent.com/minio/kes/master/root.cert' && cp root.* /home/me/ && " } - return e2emonitoring.AsInstrumented(f.Init( + return e2emon.AsInstrumented(f.Init( e2e.StartOptions{ Image: o.image, // Create the required bucket before starting minio. @@ -124,14 +118,14 @@ func NewMinio(env e2e.Environment, name, bktName string, opts ...Option) *e2emon ), AccessPortName) } -func NewConsul(env e2e.Environment, name string, opts ...Option) *e2emonitoring.InstrumentedRunnable { +func NewConsul(env e2e.Environment, name string, opts ...Option) *e2emon.InstrumentedRunnable { o := options{image: "consul:1.8.4"} for _, opt := range opts { opt(&o) } e2e.MergeFlags() - return e2emonitoring.AsInstrumented(env.Runnable(name).WithPorts(map[string]int{AccessPortName: 8500}).Init( + return e2emon.AsInstrumented(env.Runnable(name).WithPorts(map[string]int{AccessPortName: 8500}).Init( e2e.StartOptions{ Image: o.image, // Run consul in "dev" mode so that the initial leader election is immediate. @@ -141,13 +135,13 @@ func NewConsul(env e2e.Environment, name string, opts ...Option) *e2emonitoring. ), AccessPortName) } -func NewDynamoDB(env e2e.Environment, name string, opts ...Option) *e2emonitoring.InstrumentedRunnable { +func NewDynamoDB(env e2e.Environment, name string, opts ...Option) *e2emon.InstrumentedRunnable { o := options{image: "amazon/dynamodb-local:1.11.477"} for _, opt := range opts { opt(&o) } - return e2emonitoring.AsInstrumented(env.Runnable(name).WithPorts(map[string]int{AccessPortName: 8000}).Init( + return e2emon.AsInstrumented(env.Runnable(name).WithPorts(map[string]int{AccessPortName: 8000}).Init( e2e.StartOptions{ Image: o.image, Command: e2e.NewCommand("-jar", "DynamoDBLocal.jar", "-inMemory", "-sharedDb"), @@ -170,13 +164,13 @@ func NewBigtable(env e2e.Environment, name string, opts ...Option) e2e.Runnable ) } -func NewCassandra(env e2e.Environment, name string, opts ...Option) *e2emonitoring.InstrumentedRunnable { +func NewCassandra(env e2e.Environment, name string, opts ...Option) *e2emon.InstrumentedRunnable { o := options{image: "rinscy/cassandra:3.11.0"} for _, opt := range opts { opt(&o) } - return e2emonitoring.AsInstrumented(env.Runnable(name).WithPorts(map[string]int{AccessPortName: 9042}).Init( + return e2emon.AsInstrumented(env.Runnable(name).WithPorts(map[string]int{AccessPortName: 9042}).Init( e2e.StartOptions{ Image: o.image, // Readiness probe inspired from https://github.com/kubernetes/examples/blob/b86c9d50be45eaf5ce74dee7159ce38b0e149d38/cassandra/image/files/ready-probe.sh @@ -185,13 +179,13 @@ func NewCassandra(env e2e.Environment, name string, opts ...Option) *e2emonitori ), AccessPortName) } -func NewSwiftStorage(env e2e.Environment, name string, opts ...Option) *e2emonitoring.InstrumentedRunnable { +func NewSwiftStorage(env e2e.Environment, name string, opts ...Option) *e2emon.InstrumentedRunnable { o := options{image: "bouncestorage/swift-aio:55ba4331"} for _, opt := range opts { opt(&o) } - return e2emonitoring.AsInstrumented(env.Runnable(name).WithPorts(map[string]int{AccessPortName: 8080}).Init( + return e2emon.AsInstrumented(env.Runnable(name).WithPorts(map[string]int{AccessPortName: 8080}).Init( e2e.StartOptions{ Image: o.image, Readiness: e2e.NewHTTPReadinessProbe(AccessPortName, "/", 404, 404), @@ -213,16 +207,22 @@ func NewMemcached(env e2e.Environment, name string, opts ...Option) e2e.Runnable ) } -func NewETCD(env e2e.Environment, name string, opts ...Option) *e2emonitoring.InstrumentedRunnable { +func NewETCD(env e2e.Environment, name string, opts ...Option) *e2emon.InstrumentedRunnable { o := options{image: "gcr.io/etcd-development/etcd:v3.4.7"} for _, opt := range opts { opt(&o) } - return e2emonitoring.AsInstrumented(env.Runnable(name).WithPorts(map[string]int{AccessPortName: 2379, "metrics": 9000}).Init( + return e2emon.AsInstrumented(env.Runnable(name).WithPorts(map[string]int{AccessPortName: 2379, "metrics": 9000}).Init( e2e.StartOptions{ - Image: o.image, - Command: e2e.NewCommand("/usr/local/bin/etcd", "--listen-client-urls=http://0.0.0.0:2379", "--advertise-client-urls=http://0.0.0.0:2379", "--listen-metrics-urls=http://0.0.0.0:9000", "--log-level=error"), + Image: o.image, + Command: e2e.NewCommand( + "/usr/local/bin/etcd", + "--listen-client-urls=http://0.0.0.0:2379", + "--advertise-client-urls=http://0.0.0.0:2379", + "--listen-metrics-urls=http://0.0.0.0:9000", + "--log-level=error", + ), Readiness: e2e.NewHTTPReadinessProbe("metrics", "/health", 200, 204), }, ), "metrics") diff --git a/db/thanos.go b/db/thanos.go index 8e2f180..5182a95 100644 --- a/db/thanos.go +++ b/db/thanos.go @@ -10,10 +10,10 @@ import ( "strings" "github.com/efficientgo/e2e" - e2emonitoring "github.com/efficientgo/e2e/monitoring" + e2eobs "github.com/efficientgo/e2e/observable" ) -func NewThanosQuerier(env e2e.Environment, name string, endpointsAddresses []string, opts ...Option) *e2emonitoring.InstrumentedRunnable { +func NewThanosQuerier(env e2e.Environment, name string, endpointsAddresses []string, opts ...Option) *e2eobs.Observable { o := options{image: "quay.io/thanos/thanos:v0.27.0"} for _, opt := range opts { opt(&o) @@ -39,15 +39,15 @@ func NewThanosQuerier(env e2e.Environment, name string, endpointsAddresses []str args = e2e.MergeFlagsWithoutRemovingEmpty(args, o.flagOverride) } - return e2emonitoring.NewInstrumentedRunnable(env, name).WithPorts(ports, "http").Init(e2e.StartOptions{ + return e2eobs.AsObservable(env.Runnable(name).WithPorts(ports).Init(e2e.StartOptions{ Image: o.image, Command: e2e.NewCommand("query", e2e.BuildKingpinArgs(args)...), Readiness: e2e.NewHTTPReadinessProbe("http", "/-/ready", 200, 200), User: strconv.Itoa(os.Getuid()), - }) + }), "http") } -func NewThanosSidecar(env e2e.Environment, name string, prom e2e.Linkable, opts ...Option) e2emonitoring.InstrumentedRunnable { +func NewThanosSidecar(env e2e.Environment, name string, prom e2e.Linkable, opts ...Option) *e2eobs.Observable { o := options{image: "quay.io/thanos/thanos:v0.27.0"} for _, opt := range opts { opt(&o) @@ -69,15 +69,15 @@ func NewThanosSidecar(env e2e.Environment, name string, prom e2e.Linkable, opts args = e2e.MergeFlagsWithoutRemovingEmpty(args, o.flagOverride) } - return e2emonitoring.NewInstrumentedRunnable(env, name).WithPorts(ports, "http").Init(e2e.StartOptions{ + return e2eobs.AsObservable(env.Runnable(name).WithPorts(ports).Init(e2e.StartOptions{ Image: o.image, Command: e2e.NewCommand("sidecar", e2e.BuildKingpinArgs(args)...), Readiness: e2e.NewHTTPReadinessProbe("http", "/-/ready", 200, 200), User: strconv.Itoa(os.Getuid()), - }) + }), "http") } -func NewThanosStore(env e2e.Environment, name string, bktConfigYaml []byte, opts ...Option) e2emonitoring.InstrumentedRunnable { +func NewThanosStore(env e2e.Environment, name string, bktConfigYaml []byte, opts ...Option) *e2eobs.Observable { o := options{image: "quay.io/thanos/thanos:v0.27.0"} for _, opt := range opts { opt(&o) @@ -88,7 +88,7 @@ func NewThanosStore(env e2e.Environment, name string, bktConfigYaml []byte, opts "grpc": 9091, } - f := e2emonitoring.NewInstrumentedRunnable(env, name).WithPorts(ports, "http").Future() + f := env.Runnable(name).WithPorts(ports).Future() args := map[string]string{ "--debug.name": name, "--grpc-address": fmt.Sprintf(":%d", ports["grpc"]), @@ -105,10 +105,10 @@ func NewThanosStore(env e2e.Environment, name string, bktConfigYaml []byte, opts if o.flagOverride != nil { args = e2e.MergeFlagsWithoutRemovingEmpty(args, o.flagOverride) } - return f.Init(e2e.StartOptions{ + return e2eobs.AsObservable(f.Init(e2e.StartOptions{ Image: o.image, Command: e2e.NewCommand("store", e2e.BuildKingpinArgs(args)...), Readiness: e2e.NewHTTPReadinessProbe("http", "/-/ready", 200, 200), User: strconv.Itoa(os.Getuid()), - }) + }), "http") } diff --git a/env.go b/env.go index e09e245..6136e58 100644 --- a/env.go +++ b/env.go @@ -138,6 +138,11 @@ type RunnableBuilder interface { } type runnable interface { + // BuildErr returns error if runnable failed to build. If error happened during build all methods like + // Start, WaitReady, Kill and Stop will return this error. Rest of the methods will yield empty results, so if you + // want to use those before any of the Start, WaitReady, Kill or Stop, you can use BuildErr to check for error explicitly. + BuildErr() error + // IsRunning returns if runnable was started. IsRunning() bool diff --git a/env_docker.go b/env_docker.go index d0df75a..43bf666 100644 --- a/env_docker.go +++ b/env_docker.go @@ -168,22 +168,23 @@ func (e *DockerEnvironment) AddCloser(f func()) { func (e *DockerEnvironment) Runnable(name string) RunnableBuilder { if e.closed { - return Errorer{name: name, err: errors.New("environment close was invoked already.")} + return errorer{name: name, err: errors.New("environment close was invoked already.")} } if e.isRegistered(name) { - return Errorer{name: name, err: errors.Newf("there is already one runnable created with the same name %v", name)} + return errorer{name: name, err: errors.Newf("there is already one runnable created with the same name %v", name)} } d := &dockerRunnable{ - env: e, - name: name, - logger: e.logger, - ports: map[string]int{}, - hostPorts: map[string]int{}, + env: e, + name: name, + logger: e.logger, + ports: map[string]int{}, + hostPorts: map[string]int{}, + extensions: map[any]any{}, } if err := os.MkdirAll(d.Dir(), 0750); err != nil { - return Errorer{name: name, err: err} + return errorer{name: name, err: err} } e.register(name) return d @@ -194,34 +195,36 @@ func (e *DockerEnvironment) AddListener(listener EnvironmentListener) { e.listeners = append(e.listeners, listener) } -type Errorer struct { +type errorer struct { name string err error } -func NewErrorer(name string, err error) Errorer { - return Errorer{ +// NewFailedRunnable returns runnable that failed in construction. +func NewFailedRunnable(name string, err error) Runnable { + return errorer{ name: name, err: err, } } -func (e Errorer) Name() string { return e.name } -func (Errorer) Dir() string { return "" } -func (Errorer) InternalDir() string { return "" } -func (e Errorer) Start() error { return e.err } -func (e Errorer) WaitReady() error { return e.err } -func (e Errorer) Kill() error { return e.err } -func (e Errorer) Stop() error { return e.err } -func (e Errorer) Exec(Command, ...ExecOption) error { return e.err } -func (Errorer) Endpoint(string) string { return "" } -func (Errorer) InternalEndpoint(string) string { return "" } -func (Errorer) IsRunning() bool { return false } -func (Errorer) SetMetadata(_, _ any) {} -func (Errorer) GetMetadata(any) (any, bool) { return nil, false } -func (e Errorer) Init(StartOptions) Runnable { return e } -func (e Errorer) WithPorts(map[string]int) RunnableBuilder { return e } -func (e Errorer) Future() FutureRunnable { return e } +func (e errorer) BuildErr() error { return e.err } +func (e errorer) Name() string { return e.name } +func (errorer) Dir() string { return "" } +func (errorer) InternalDir() string { return "" } +func (e errorer) Start() error { return e.BuildErr() } +func (e errorer) WaitReady() error { return e.BuildErr() } +func (e errorer) Kill() error { return e.BuildErr() } +func (e errorer) Stop() error { return e.BuildErr() } +func (e errorer) Exec(Command, ...ExecOption) error { return e.BuildErr() } +func (errorer) Endpoint(string) string { return "" } +func (errorer) InternalEndpoint(string) string { return "" } +func (errorer) IsRunning() bool { return false } +func (errorer) SetMetadata(_, _ any) {} +func (errorer) GetMetadata(any) (any, bool) { return nil, false } +func (e errorer) Init(StartOptions) Runnable { return e } +func (e errorer) WithPorts(map[string]int) RunnableBuilder { return e } +func (e errorer) Future() FutureRunnable { return e } func (e *DockerEnvironment) isRegistered(name string) bool { _, ok := e.registered[name] @@ -344,6 +347,10 @@ func (d *dockerRunnable) Name() string { return d.name } +func (d *dockerRunnable) BuildErr() error { + return nil +} + func (d *dockerRunnable) Dir() string { return filepath.Join(d.env.dir, "data", d.Name()) } diff --git a/examples/exampleapp/exampleapp_test.go b/examples/exampleapp/exampleapp_test.go index 5fafb72..144961a 100644 --- a/examples/exampleapp/exampleapp_test.go +++ b/examples/exampleapp/exampleapp_test.go @@ -13,7 +13,7 @@ import ( "github.com/efficientgo/e2e" e2edb "github.com/efficientgo/e2e/db" e2einteractive "github.com/efficientgo/e2e/interactive" - e2e2 "github.com/efficientgo/e2e/monitoring" + e2emon "github.com/efficientgo/e2e/monitoring" ) func TestExampleApp(t *testing.T) { @@ -24,11 +24,12 @@ func TestExampleApp(t *testing.T) { testutil.Ok(t, err) fmt.Println("=== Start example application...") - app := e2e.NewInstrumentedRunnable(e, "example_app"). - WithPorts(map[string]int{"http": 8080}, "http"). + app := e2emon.AsInstrumented(e.Runnable("example_app"). + WithPorts(map[string]int{"http": 8080}). Init(e2e.StartOptions{ Image: "quay.io/brancz/prometheus-example-app:v0.3.0", - }) + }), "http") + testutil.Ok(t, e2e.StartAndWaitReady(app)) config := fmt.Sprintf(` @@ -50,12 +51,12 @@ scrape_configs: fmt.Println("=== Start Prometheus") // Create Prometheus instance and wait for it to be ready. p1 := e2edb.NewPrometheus(e, "prometheus-1") - testutil.Ok(t, p1.SetConfig(config)) + testutil.Ok(t, p1.SetConfigEncoded([]byte(config))) testutil.Ok(t, e2e.StartAndWaitReady(p1)) fmt.Println("=== Ensure that Prometheus already scraped something") // Ensure that Prometheus already scraped something. - testutil.Ok(t, p1.WaitSumMetrics(e2e2.Greater(50), "prometheus_tsdb_head_samples_appended_total")) + testutil.Ok(t, p1.WaitSumMetrics(e2emon.Greater(50), "prometheus_tsdb_head_samples_appended_total")) // Open example in browser. exampleAppURL := fmt.Sprintf("http://%s", app.Endpoint("http")) @@ -64,15 +65,15 @@ scrape_configs: fmt.Println("=== I need at least 5 requests!") testutil.Ok(t, app.WaitSumMetricsWithOptions( - e2e2.GreaterOrEqual(5), + e2emon.GreaterOrEqual(5), []string{"http_requests_total"}, - e2e2.WithWaitBackoff( + e2emon.WithWaitBackoff( &backoff.Config{ Min: 1 * time.Second, Max: 10 * time.Second, MaxRetries: 100, }), - e2e2.WaitMissingMetrics()), + e2emon.WaitMissingMetrics()), ) // Now opening Prometheus in browser as well. diff --git a/examples/thanos/README.md b/examples/thanos/README.md deleted file mode 100644 index 717aa9d..0000000 --- a/examples/thanos/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# e2e Example - -See [Example description](/README.md#how-can-i-use-it) diff --git a/examples/thanos/benchmark_test.go b/examples/thanos/benchmark_test.go deleted file mode 100644 index 05ad16b..0000000 --- a/examples/thanos/benchmark_test.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) The EfficientGo Authors. -// Licensed under the Apache License 2.0. - -package main - -import ( - "testing" -) - -func BenchmarkExample(t *testing.B) { - // TBD. -} diff --git a/examples/thanos/e2etest_test.go b/examples/thanos/e2etest_test.go index ed9bb1c..8cb1695 100644 --- a/examples/thanos/e2etest_test.go +++ b/examples/thanos/e2etest_test.go @@ -12,7 +12,7 @@ import ( "github.com/efficientgo/core/testutil" "github.com/efficientgo/e2e" e2edb "github.com/efficientgo/e2e/db" - e2e2 "github.com/efficientgo/e2e/monitoring" + e2emon "github.com/efficientgo/e2e/monitoring" "github.com/prometheus/client_golang/api" v1 "github.com/prometheus/client_golang/api/prometheus/v1" "github.com/prometheus/common/model" @@ -43,11 +43,11 @@ func TestExample(t *testing.T) { // To ensure query should have access we can check its Prometheus metric using WaitSumMetrics method. Since the metric we are looking for // only appears after init, we add option to wait for it. - testutil.Ok(t, t1.WaitSumMetricsWithOptions(e2e2.Equals(2), []string{"thanos_store_nodes_grpc_connections"}, e2e2.WaitMissingMetrics())) + testutil.Ok(t, t1.WaitSumMetricsWithOptions(e2emon.Equals(2), []string{"thanos_store_nodes_grpc_connections"}, e2emon.WaitMissingMetrics())) // To ensure Prometheus scraped already something ensure number of scrapes. - testutil.Ok(t, p1.WaitSumMetrics(e2e2.Greater(50), "prometheus_tsdb_head_samples_appended_total")) - testutil.Ok(t, p2.WaitSumMetrics(e2e2.Greater(50), "prometheus_tsdb_head_samples_appended_total")) + testutil.Ok(t, p1.WaitSumMetrics(e2emon.Greater(50), "prometheus_tsdb_head_samples_appended_total")) + testutil.Ok(t, p2.WaitSumMetrics(e2emon.Greater(50), "prometheus_tsdb_head_samples_appended_total")) // We can now query Thanos Querier directly from here, using it's host address thanks to Endpoint method. a, err := api.NewClient(api.Config{Address: "http://" + t1.Endpoint("http")}) @@ -71,7 +71,7 @@ up{instance="%v", job="myself", prometheus="prometheus-2"} => 1 @[%v]`, p1.Inter testutil.Ok(t, p1.Stop()) // Wait a bit until Thanos drops connection to stopped Prometheus. - testutil.Ok(t, t1.WaitSumMetricsWithOptions(e2e2.Equals(1), []string{"thanos_store_nodes_grpc_connections"}, e2e2.WaitMissingMetrics())) + testutil.Ok(t, t1.WaitSumMetricsWithOptions(e2emon.Equals(1), []string{"thanos_store_nodes_grpc_connections"}, e2emon.WaitMissingMetrics())) { now := model.Now() diff --git a/examples/thanos/standalone.go b/examples/thanos/standalone.go index 5546578..1c1ac7f 100644 --- a/examples/thanos/standalone.go +++ b/examples/thanos/standalone.go @@ -14,7 +14,8 @@ import ( "github.com/efficientgo/e2e" e2edb "github.com/efficientgo/e2e/db" e2einteractive "github.com/efficientgo/e2e/interactive" - e2emonitoring "github.com/efficientgo/e2e/monitoring" + e2emon "github.com/efficientgo/e2e/monitoring" + e2eprof "github.com/efficientgo/e2e/profiling" "github.com/oklog/run" ) @@ -27,7 +28,12 @@ func deployWithMonitoring(ctx context.Context) error { // Make sure resources (e.g docker containers, network, dir) are cleaned. defer e.Close() - mon, err := e2emonitoring.Start(e) + mon, err := e2emon.Start(e) + if err != nil { + return err + } + + prof, err := e2eprof.Start(e) if err != nil { return err } @@ -69,10 +75,10 @@ config: if err := merrors.New( // To ensure query should have access we can check its Prometheus metric using WaitSumMetrics method. Since the metric we are looking for // only appears after init, we add option to wait for it. - t1.WaitSumMetricsWithOptions(e2emonitoring.Equals(2), []string{"thanos_store_nodes_grpc_connections"}, e2emonitoring.WaitMissingMetrics()), + t1.WaitSumMetricsWithOptions(e2emon.Equals(2), []string{"thanos_store_nodes_grpc_connections"}, e2emon.WaitMissingMetrics()), // To ensure Prometheus scraped already something ensure number of scrapes. - p1.WaitSumMetrics(e2emonitoring.Greater(50), "prometheus_tsdb_head_samples_appended_total"), - p2.WaitSumMetrics(e2emonitoring.Greater(50), "prometheus_tsdb_head_samples_appended_total"), + p1.WaitSumMetrics(e2emon.Greater(50), "prometheus_tsdb_head_samples_appended_total"), + p2.WaitSumMetrics(e2emon.Greater(50), "prometheus_tsdb_head_samples_appended_total"), ).Err(); err != nil { return err } @@ -85,6 +91,10 @@ config: if err := mon.OpenUserInterfaceInBrowser(); err != nil { return errors.Wrap(err, "open monitoring UI in browser") } + // Open profiling page with all profiles. + if err := prof.OpenUserInterfaceInBrowser(); err != nil { + return errors.Wrap(err, "open profiling UI in browser") + } // Open jaeger UI. if err := e2einteractive.OpenInBrowser("http://" + j.Endpoint("http.front")); err != nil { return errors.Wrap(err, "open Jaeger UI in browser") diff --git a/monitoring/instrumented.go b/monitoring/instrumented.go index 52c14fe..6517ffd 100644 --- a/monitoring/instrumented.go +++ b/monitoring/instrumented.go @@ -1,7 +1,7 @@ // Copyright (c) The EfficientGo Authors. // Licensed under the Apache License 2.0. -package e2emonitoring +package e2emon import ( "context" @@ -20,12 +20,14 @@ import ( var errMissingMetric = errors.New("metric not found") +// Target represents scrape target for Prometheus to use. type Target struct { InternalEndpoint string MetricPath string // "/metrics" by default. Scheme string // "http" by default. } +// Instrumented represents methods for instrumented runnable focused on accessing instrumented metrics. type Instrumented interface { MetricTargets() []Target Metrics() (string, error) @@ -35,6 +37,9 @@ type Instrumented interface { WaitRemovedMetric(metricName string, opts ...MetricsOption) error } +var _ Instrumented = &InstrumentedRunnable{} + +// InstrumentedRunnable represents runnable with instrumented Prometheus metric endpoint on a certain port. type InstrumentedRunnable struct { e2e.Runnable @@ -45,42 +50,46 @@ type InstrumentedRunnable struct { waitBackoff *backoff.Backoff } -type runnableOpt struct { +type rOpt struct { metricPath string scheme string waitBackoff *backoff.Backoff } -// WithRunnableMetricPath sets a custom path for metrics page. "/metrics" by default. -func WithRunnableMetricPath(metricPath string) RunnableOption { - return func(o *runnableOpt) { +// WithInstrumentedMetricPath sets a custom path for metrics page. "/metrics" by default. +func WithInstrumentedMetricPath(metricPath string) InstrumentedOption { + return func(o *rOpt) { o.metricPath = metricPath } } -// WithRunnableScheme allows adding customized scheme. "http" or "https" values allowed. "http" by default. +// WithInstrumentedScheme allows adding customized scheme. "http" or "https" values allowed. "http" by default. // If "https" is specified, insecure TLS will be performed. -func WithRunnableScheme(scheme string) RunnableOption { - return func(o *runnableOpt) { +func WithInstrumentedScheme(scheme string) InstrumentedOption { + return func(o *rOpt) { o.scheme = scheme } } -// WithRunnableWaitBackoff allows adding customized scheme. "http" or "https" values allowed. "http" by default. -// If "https" is specified, insecure TLS will be performed. -func WithRunnableWaitBackoff(waitBackoff *backoff.Backoff) RunnableOption { - return func(o *runnableOpt) { +// WithInstrumentedWaitBackoff allows customizing wait backoff when accessing metric endpoint. +func WithInstrumentedWaitBackoff(waitBackoff *backoff.Backoff) InstrumentedOption { + return func(o *rOpt) { o.waitBackoff = waitBackoff } } -type RunnableOption func(*runnableOpt) +// InstrumentedOption is a variadic option for AsInstrumented. +type InstrumentedOption func(*rOpt) -// AsInstrumented wraps e2e.Runnable with InstrumentedRunnable that satisfies both Instrumented and e2e.Runnable -// that represents runnable with instrumented Prometheus metric endpoint on a certain port. -// NOTE(bwplotka): Caller is expected to discard passed `r` runnable and use returned InstrumentedRunnable.InstrumentedRunnable instead. -func AsInstrumented(r e2e.Runnable, instrumentedPortName string, opts ...RunnableOption) *InstrumentedRunnable { - opt := runnableOpt{ +// AsInstrumented wraps e2e.Runnable with InstrumentedRunnable. +// If runnable is running during invocation AsInstrumented panics. +// NOTE(bwplotka): Caller is expected to discard passed `r` runnable and use returned InstrumentedRunnable.Runnable instead. +func AsInstrumented(r e2e.Runnable, instrumentedPortName string, opts ...InstrumentedOption) *InstrumentedRunnable { + if r.IsRunning() { + panic("can't use AsInstrumented with running runnable") + } + + opt := rOpt{ metricPath: "/metrics", scheme: "http", waitBackoff: backoff.New(context.Background(), backoff.Config{ @@ -93,7 +102,10 @@ func AsInstrumented(r e2e.Runnable, instrumentedPortName string, opts ...Runnabl } if r.InternalEndpoint(instrumentedPortName) == "" { - return &InstrumentedRunnable{Runnable: e2e.NewErrorer(r.Name(), errors.Newf("metric port name %v does not exists in given runnable ports", instrumentedPortName))} + return &InstrumentedRunnable{Runnable: e2e.NewFailedRunnable( + r.Name(), + errors.Newf("metric port name %v does not exists in given runnable ports", instrumentedPortName)), + } } instr := &InstrumentedRunnable{ diff --git a/monitoring/instrumented_composite.go b/monitoring/instrumented_composite.go index fe3d3c3..9623add 100644 --- a/monitoring/instrumented_composite.go +++ b/monitoring/instrumented_composite.go @@ -1,7 +1,7 @@ // Copyright (c) The EfficientGo Authors. // Licensed under the Apache License 2.0. -package e2emonitoring +package e2emon import ( "context" @@ -11,7 +11,7 @@ import ( "github.com/efficientgo/core/errors" ) -// CompositeInstrumentedRunnable abstract an higher-level service composed by more than one InstrumentedRunnable. +// CompositeInstrumentedRunnable abstract a higher-level service composed by more than one InstrumentedRunnable. type CompositeInstrumentedRunnable struct { runnables []*InstrumentedRunnable diff --git a/monitoring/instrumented_test.go b/monitoring/instrumented_test.go index a559a51..e186dac 100644 --- a/monitoring/instrumented_test.go +++ b/monitoring/instrumented_test.go @@ -1,7 +1,7 @@ // Copyright (c) The EfficientGo Authors. // Licensed under the Apache License 2.0. -package e2emonitoring +package e2emon import ( "context" @@ -81,7 +81,7 @@ metric_b_summary_count 1 r := AsInstrumented( &runnableFake{endpoints: map[string]string{"http": ln.Addr().String()}}, "http", - WithRunnableWaitBackoff(backoff.New(context.Background(), backoff.Config{ + WithInstrumentedWaitBackoff(backoff.New(context.Background(), backoff.Config{ Min: 300 * time.Millisecond, Max: 600 * time.Millisecond, MaxRetries: 50, @@ -154,7 +154,7 @@ metric_b 1000 r := AsInstrumented( &runnableFake{endpoints: map[string]string{"http": ln.Addr().String()}}, "http", - WithRunnableWaitBackoff(backoff.New(context.Background(), backoff.Config{ + WithInstrumentedWaitBackoff(backoff.New(context.Background(), backoff.Config{ Min: 300 * time.Millisecond, Max: 600 * time.Millisecond, MaxRetries: 50, diff --git a/monitoring/metrics.go b/monitoring/metrics.go index cddb159..ba4b7af 100644 --- a/monitoring/metrics.go +++ b/monitoring/metrics.go @@ -1,7 +1,7 @@ // Copyright (c) The EfficientGo Authors. // Licensed under the Apache License 2.0. -package e2emonitoring +package e2emon import ( "math" diff --git a/monitoring/monitoring.go b/monitoring/monitoring.go index 46780dc..a5cf198 100644 --- a/monitoring/monitoring.go +++ b/monitoring/monitoring.go @@ -1,7 +1,7 @@ // Copyright (c) The EfficientGo Authors. // Licensed under the Apache License 2.0. -package e2emonitoring +package e2emon import ( "fmt" @@ -18,11 +18,9 @@ import ( "github.com/efficientgo/core/errcapture" "github.com/efficientgo/core/errors" "github.com/efficientgo/e2e" - e2edb "github.com/efficientgo/e2e/db" - "github.com/efficientgo/e2e/db/promconfig/discovery/config" e2einteractive "github.com/efficientgo/e2e/interactive" "github.com/efficientgo/e2e/monitoring/promconfig" - "github.com/efficientgo/e2e/monitoring/promconfig/discovery/config" + sdconfig "github.com/efficientgo/e2e/monitoring/promconfig/discovery/config" "github.com/efficientgo/e2e/monitoring/promconfig/discovery/targetgroup" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" @@ -32,7 +30,9 @@ import ( "gopkg.in/yaml.v2" ) -var metaKey = struct{}{} +type metaKeyType struct{} + +var metaKey = metaKeyType{} type Prometheus struct { e2e.Runnable @@ -63,7 +63,7 @@ scrape_configs: action: drop `, name, f.InternalEndpoint("http")) if err := os.WriteFile(filepath.Join(f.Dir(), "prometheus.yml"), []byte(config), 0600); err != nil { - return &Prometheus{Runnable: e2e.NewErrorer(name, errors.Wrap(err, "create prometheus config failed"))} + return &Prometheus{Runnable: e2e.NewFailedRunnable(name, errors.Wrap(err, "create prometheus config failed"))} } args := map[string]string{ @@ -90,13 +90,12 @@ scrape_configs: } } -func (p *Prometheus) SetConfig(config promconfig.Config) error { - b, err := yaml.Marshal(config) - if err != nil { - return err +func (p *Prometheus) SetConfigEncoded(config []byte) error { + if p.BuildErr() != nil { + return p.BuildErr() } - if err := os.WriteFile(filepath.Join(p.Dir(), "prometheus.yml"), b, 0600); err != nil { + if err := os.WriteFile(filepath.Join(p.Dir(), "prometheus.yml"), config, 0600); err != nil { return errors.Wrap(err, "creating prom config failed") } @@ -107,6 +106,15 @@ func (p *Prometheus) SetConfig(config promconfig.Config) error { return nil } +func (p *Prometheus) SetConfig(config promconfig.Config) error { + b, err := yaml.Marshal(config) + if err != nil { + return err + } + + return p.SetConfigEncoded(b) +} + type Service struct { p *Prometheus } @@ -125,10 +133,24 @@ func (l *listener) updateConfig(started map[string]Instrumented) error { ScrapeInterval: model.Duration(l.scrapeInterval), }, } - add := func(name string, instr Instrumented) { + + // Register local address. + scfg := &promconfig.ScrapeConfig{ + JobName: "local", + ServiceDiscoveryConfig: sdconfig.ServiceDiscoveryConfig{StaticConfigs: []*targetgroup.Group{{ + Targets: []model.LabelSet{ + map[model.LabelName]model.LabelValue{ + model.AddressLabel: model.LabelValue(l.localAddr), + }, + }, + }}}, + } + cfg.ScrapeConfigs = append(cfg.ScrapeConfigs, scfg) + + for name, s := range started { scfg := &promconfig.ScrapeConfig{ JobName: name, - ServiceDiscoveryConfig: sdconfig.sdconfig{}, + ServiceDiscoveryConfig: sdconfig.ServiceDiscoveryConfig{}, HTTPClientConfig: config.HTTPClientConfig{ TLSConfig: config.TLSConfig{ // TODO(bwplotka): Allow providing certs? @@ -138,7 +160,7 @@ func (l *listener) updateConfig(started map[string]Instrumented) error { }, } - for _, t := range instr.MetricTargets() { + for _, t := range s.MetricTargets() { g := &targetgroup.Group{ Targets: []model.LabelSet{map[model.LabelName]model.LabelValue{ model.AddressLabel: model.LabelValue(t.InternalEndpoint), @@ -153,24 +175,6 @@ func (l *listener) updateConfig(started map[string]Instrumented) error { cfg.ScrapeConfigs = append(cfg.ScrapeConfigs, scfg) } - // Register local address. - scfg := &promconfig.ScrapeConfig{ - JobName: "local", - ServiceDiscoveryConfig: sdconfig.ServiceDiscoveryConfig{StaticConfigs: []*targetgroup.Group{{ - Targets: []model.LabelSet{ - map[model.LabelName]model.LabelValue{ - model.AddressLabel: model.LabelValue(l.localAddr), - }, - }, - }}}, - } - cfg.ScrapeConfigs = append(cfg.ScrapeConfigs, scfg) - - //add("e2emonitoring-prometheus", l.p) - for name, s := range started { - add(name, s) - } - return l.p.SetConfig(cfg) } @@ -218,8 +222,8 @@ func WithPrometheusImage(image string) Option { type Option func(*opt) -// Start deploys monitoring service which deploys Prometheus that monitors all registered InstrumentedServices -// in environment. +// Start deploys monitoring service which deploys Prometheus that monitors all +// InstrumentedRunnable instances in environment created with AsInstrumented. func Start(env e2e.Environment, opts ...Option) (_ *Service, err error) { opt := opt{scrapeInterval: 5 * time.Second} for _, o := range opts { @@ -255,11 +259,7 @@ func Start(env e2e.Environment, opts ...Option) (_ *Service, err error) { go func() { _ = s.Serve(list) }() env.AddCloser(func() { _ = s.Close() }) - var dbOpts []e2edb.Option - if opt.customPromImage != "" { - dbOpts = append(dbOpts, e2edb.WithImage(opt.customPromImage)) - } - p := e2edb.NewPrometheus(env, "monitoring", dbOpts...) + p := NewPrometheus(env, "monitoring", opt.customPromImage, nil) _, port, err := net.SplitHostPort(list.Addr().String()) if err != nil { @@ -286,7 +286,7 @@ func Start(env e2e.Environment, opts ...Option) (_ *Service, err error) { } func (s *Service) OpenUserInterfaceInBrowser(paths ...string) error { - return e2einteractive.OpenInBrowser("http://" + s.p.Endpoint(e2edb.AccessPortName) + strings.Join(paths, "/")) + return e2einteractive.OpenInBrowser("http://" + s.p.Endpoint("http") + strings.Join(paths, "/")) } // InstantQuery evaluates instant PromQL queries against monitoring service. @@ -295,7 +295,7 @@ func (s *Service) InstantQuery(query string) (string, error) { return "", errors.Newf("%s is not running", s.p.Name()) } - res, err := (&http.Client{}).Get("http://" + s.p.Endpoint(e2edb.AccessPortName) + "/api/v1/query?query=" + query) + res, err := (&http.Client{}).Get("http://" + s.p.Endpoint("http") + "/api/v1/query?query=" + query) if err != nil { return "", err } diff --git a/monitoring/promconfig/prometheus.go b/monitoring/promconfig/prometheus.go index 0f762fc..1b6de12 100644 --- a/monitoring/promconfig/prometheus.go +++ b/monitoring/promconfig/prometheus.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/efficientgo/core/errors" + sdconfig "github.com/efficientgo/e2e/monitoring/promconfig/discovery/config" config_util "github.com/prometheus/common/config" "github.com/prometheus/common/model" ) diff --git a/observable/observable.go b/observable/observable.go new file mode 100644 index 0000000..4bb9cd7 --- /dev/null +++ b/observable/observable.go @@ -0,0 +1,76 @@ +package e2eobs + +import ( + "github.com/efficientgo/core/backoff" + "github.com/efficientgo/e2e" + e2emon "github.com/efficientgo/e2e/monitoring" + e2eprof "github.com/efficientgo/e2e/profiling" + "github.com/efficientgo/e2e/profiling/parcaconfig" +) + +// Observable represents runnable that is both instrumented and profiled. Typically, all well-written Go services +// are observable. +type Observable struct { + e2e.Runnable + e2emon.Instrumented + e2eprof.Profiled +} + +type opt struct { + instrOpts []e2emon.InstrumentedOption + profOpts []e2eprof.ProfiledOption +} + +// WithScheme allows adding customized scheme. "http" or "https" values allowed. "http" by default. +// If "https" is specified, insecure TLS will be performed. +func WithScheme(scheme string) Option { + return func(o *opt) { + o.instrOpts = append(o.instrOpts, e2emon.WithInstrumentedScheme(scheme)) + o.profOpts = append(o.profOpts, e2eprof.WithProfiledScheme(scheme)) + } +} + +// WithMetricPath sets a custom path for metrics page. "/metrics" by default. +func WithMetricPath(metricPath string) Option { + return func(o *opt) { + o.instrOpts = append(o.instrOpts, e2emon.WithInstrumentedMetricPath(metricPath)) + } +} + +// WithProfiledConfig sets a custom parca ProfilingConfig entry about this runnable. Empty by default (Parca defaults apply). +func WithProfiledConfig(config parcaconfig.ProfilingConfig) Option { + return func(o *opt) { + o.profOpts = append(o.profOpts, e2eprof.WithProfiledConfig(config)) + } +} + +// WithInstrumentedWaitBackoff allows customizing wait backoff when accessing metric endpoint. +func WithInstrumentedWaitBackoff(waitBackoff *backoff.Backoff) Option { + return func(o *opt) { + o.instrOpts = append(o.instrOpts, e2emon.WithInstrumentedWaitBackoff(waitBackoff)) + } +} + +type Option func(*opt) + +// AsObservable wraps e2e.Runnable with Observable. +// If runnable is running during invocation AsObservable panics. +// NOTE(bwplotka): Caller is expected to discard passed `r` runnable and use returned Observable.Runnable instead. +func AsObservable(r e2e.Runnable, instrumentedAndProfiledPortName string, opts ...Option) *Observable { + if r.IsRunning() { + panic("can't use AsObservable with running runnable") + } + + opt := opt{} + for _, o := range opts { + o(&opt) + } + + instr := e2emon.AsInstrumented(r, instrumentedAndProfiledPortName, opt.instrOpts...) + prof := e2eprof.AsProfiled(instr, instrumentedAndProfiledPortName, opt.profOpts...) + return &Observable{ + Runnable: prof.Runnable, // Make sure to not use discarded `r` as `As*` API specify. + Instrumented: instr, + Profiled: prof, + } +} diff --git a/profiling/parcaconfig/parca.go b/profiling/parcaconfig/parca.go index 184a851..5c080c7 100644 --- a/profiling/parcaconfig/parca.go +++ b/profiling/parcaconfig/parca.go @@ -4,6 +4,7 @@ import ( "net/url" "github.com/efficientgo/e2e/monitoring/promconfig" + sdconfig "github.com/efficientgo/e2e/monitoring/promconfig/discovery/config" config_util "github.com/prometheus/common/config" "github.com/prometheus/common/model" ) diff --git a/profiling/profiled.go b/profiling/profiled.go index 27b6630..b4c1d3a 100644 --- a/profiling/profiled.go +++ b/profiling/profiled.go @@ -1,4 +1,4 @@ -package e2eprofiling +package e2eprof import ( "github.com/efficientgo/core/errors" @@ -7,6 +7,7 @@ import ( ) type Target struct { + Name string // Represents runnable job and will be used for scrape job name. InternalEndpoint string Scheme string // "http" by default. Config *parcaconfig.ProfilingConfig @@ -16,7 +17,8 @@ type Profiled interface { ProfileTargets() []Target } -type Runnable struct { +// ProfiledRunnable represents runnable with pprof HTTP handlers exposed. +type ProfiledRunnable struct { e2e.Runnable pprofPort string @@ -24,33 +26,37 @@ type Runnable struct { config *parcaconfig.ProfilingConfig } -type runnableOpt struct { +type rOpt struct { config *parcaconfig.ProfilingConfig scheme string } -// WithRunnableConfig sets a custom parca ProfilingConfig entry about this runnable. Empty by default (Parca defaults apply). -func WithRunnableConfig(config parcaconfig.ProfilingConfig) RunnableOption { - return func(o *runnableOpt) { +// WithProfiledConfig sets a custom parca ProfilingConfig entry about this runnable. Empty by default (Parca defaults apply). +func WithProfiledConfig(config parcaconfig.ProfilingConfig) ProfiledOption { + return func(o *rOpt) { o.config = &config } } -// WithRunnableScheme allows adding customized scheme. "http" or "https" values allowed. "http" by default. +// WithProfiledScheme allows adding customized scheme. "http" or "https" values allowed. "http" by default. // If "https" is specified, insecure TLS will be performed. -func WithRunnableScheme(scheme string) RunnableOption { - return func(o *runnableOpt) { +func WithProfiledScheme(scheme string) ProfiledOption { + return func(o *rOpt) { o.scheme = scheme } } -type RunnableOption func(*runnableOpt) +type ProfiledOption func(*rOpt) -// AsProfiled wraps e2e.Runnable with Runnable that satisfies both Profiled and e2e.Runnable -// that represents runnable with pprof HTTP handlers exposed. -// NOTE(bwplotka): Caller is expected to discard passed `r` runnable and use returned Runnable.Runnable instead. -func AsProfiled(r e2e.Runnable, pprofPortName string, opts ...RunnableOption) *Runnable { - opt := runnableOpt{ +// AsProfiled wraps e2e.Runnable with ProfiledRunnable. +// If runnable is running during invocation AsProfiled panics. +// NOTE(bwplotka): Caller is expected to discard passed `r` runnable and use returned ProfiledRunnable.Runnable instead. +func AsProfiled(r e2e.Runnable, pprofPortName string, opts ...ProfiledOption) *ProfiledRunnable { + if r.IsRunning() { + panic("can't use AsProfiled with running runnable") + } + + opt := rOpt{ scheme: "http", } for _, o := range opts { @@ -58,10 +64,10 @@ func AsProfiled(r e2e.Runnable, pprofPortName string, opts ...RunnableOption) *R } if r.InternalEndpoint(pprofPortName) == "" { - return &Runnable{Runnable: e2e.NewErrorer(r.Name(), errors.Newf("pporf port name %v does not exists in given runnable ports", pprofPortName))} + return &ProfiledRunnable{Runnable: e2e.NewFailedRunnable(r.Name(), errors.Newf("pporf port name %v does not exists in given runnable ports", pprofPortName))} } - instr := &Runnable{ + instr := &ProfiledRunnable{ Runnable: r, pprofPort: pprofPortName, scheme: opt.scheme, @@ -71,6 +77,6 @@ func AsProfiled(r e2e.Runnable, pprofPortName string, opts ...RunnableOption) *R return instr } -func (r *Runnable) ProfileTargets() []Target { - return []Target{{Scheme: r.scheme, Config: r.config, InternalEndpoint: r.InternalEndpoint(r.pprofPort)}} +func (r *ProfiledRunnable) ProfileTargets() []Target { + return []Target{{Name: r.Name(), Scheme: r.scheme, Config: r.config, InternalEndpoint: r.InternalEndpoint(r.pprofPort)}} } diff --git a/profiling/profiling.go b/profiling/profiling.go index cadc581..129dd8d 100644 --- a/profiling/profiling.go +++ b/profiling/profiling.go @@ -1,7 +1,7 @@ // Copyright (c) The EfficientGo Authors. // Licensed under the Apache License 2.0. -package e2eprofiling +package e2eprof import ( "fmt" @@ -17,11 +17,9 @@ import ( "github.com/efficientgo/core/errors" "github.com/efficientgo/e2e" - e2edb "github.com/efficientgo/e2e/db" - "github.com/efficientgo/e2e/db/promconfig/discovery/config" e2einteractive "github.com/efficientgo/e2e/interactive" - e2emonitoring "github.com/efficientgo/e2e/monitoring" - "github.com/efficientgo/e2e/monitoring/promconfig/discovery/config" + e2emon "github.com/efficientgo/e2e/monitoring" + sdconfig "github.com/efficientgo/e2e/monitoring/promconfig/discovery/config" "github.com/efficientgo/e2e/monitoring/promconfig/discovery/targetgroup" "github.com/efficientgo/e2e/profiling/parcaconfig" "github.com/prometheus/common/config" @@ -29,11 +27,13 @@ import ( "gopkg.in/yaml.v2" ) -var metaKey = struct{}{} +type metaKeyType struct{} + +var metaKey = metaKeyType{} type Parca struct { e2e.Runnable - e2emonitoring.Instrumented + e2emon.Instrumented configHeader string } @@ -46,7 +46,7 @@ func NewParca(env e2e.Environment, name string, image string, flagOverride map[s f := env.Runnable(name).WithPorts(map[string]int{"http": 7070}).Future() args := map[string]string{ - "--config-path": filepath.Join(f.InternalDir(), "data", "parca.yml"), + "--config-path": filepath.Join(f.InternalDir(), "parca.yml"), } if flagOverride != nil { args = e2e.MergeFlagsWithoutRemovingEmpty(args, flagOverride) @@ -58,13 +58,12 @@ object_storage: type: "FILESYSTEM" config: directory: "./data" -scrape_configs: ` - if err := os.WriteFile(filepath.Join(f.Dir(), "data", "parca.yml"), []byte(config), 0600); err != nil { - return &Parca{Runnable: e2e.NewErrorer(name, errors.Wrap(err, "create prometheus config failed"))} + if err := os.WriteFile(filepath.Join(f.Dir(), "parca.yml"), []byte(config), 0600); err != nil { + return &Parca{Runnable: e2e.NewFailedRunnable(name, errors.Wrap(err, "create Parca config failed"))} } - p := e2emonitoring.AsInstrumented(f.Init(e2e.StartOptions{ + p := e2emon.AsInstrumented(f.Init(e2e.StartOptions{ Image: image, Command: e2e.NewCommand("/parca", e2e.BuildArgs(args)...), User: strconv.Itoa(os.Getuid()), @@ -80,6 +79,10 @@ scrape_configs: // SetScrapeConfigs updates Parca with new configuration marsh func (p *Parca) SetScrapeConfigs(scrapeJobs []parcaconfig.ScrapeConfig) error { + if p.BuildErr() != nil { + return p.BuildErr() + } + c := p.configHeader b, err := yaml.Marshal(struct { @@ -90,8 +93,8 @@ func (p *Parca) SetScrapeConfigs(scrapeJobs []parcaconfig.ScrapeConfig) error { } config := fmt.Sprintf("%v\n%v", c, b) - if err := os.WriteFile(filepath.Join(p.Dir(), "data", "parca.yml"), []byte(config), 0600); err != nil { - return errors.Wrap(err, "creating parca config failed") + if err := os.WriteFile(filepath.Join(p.Dir(), "parca.yml"), []byte(config), 0600); err != nil { + return errors.Wrap(err, "creating Parca config failed") } if p.IsRunning() { @@ -102,59 +105,23 @@ func (p *Parca) SetScrapeConfigs(scrapeJobs []parcaconfig.ScrapeConfig) error { } type Service struct { - p Parca + p *Parca } type listener struct { - p Parca + p *Parca localAddr string scrapeInterval time.Duration } -func (l *listener) updateConfig(started map[string]instrumented) error { - // - job_name: "labeler" - // scrape_interval: "15s" - // static_configs: - // - targets: [ '` + labeler.InternalEndpoint("http") + `' ] - // profiling_config: - // pprof_config: - // fgprof: - // enabled: true - // path: /debug/fgprof/profile - // delta: true +func (l *listener) updateConfig(started map[string]Profiled) error { var scfgs []parcaconfig.ScrapeConfig - add := func(name string, instr instrumented) { - scfg := parcaconfig.ScrapeConfig{ - JobName: name, - ServiceDiscoveryConfig: sdconfig.sdconfig{}, - HTTPClientConfig: config.HTTPClientConfig{ - TLSConfig: config.TLSConfig{ - // TODO(bwplotka): Allow providing certs? - // Allow insecure TLS. We are in benchmark/test that is focused on gathering data on all cost. - InsecureSkipVerify: true, - }, - }, - } - - for _, t := range instr.ProfilingTargets() { - g := &targetgroup.Group{ - Targets: []model.LabelSet{map[model.LabelName]model.LabelValue{ - model.AddressLabel: model.LabelValue(t.InternalEndpoint), - }}, - Labels: map[model.LabelName]model.LabelValue{ - model.SchemeLabel: model.LabelValue(strings.ToLower(t.Scheme)), - }, - } - scfg.ProfilingConfig = t.Config - scfg.ServiceDiscoveryConfig.StaticConfigs = append(scfg.ServiceDiscoveryConfig.StaticConfigs, g) - } - scfgs = append(scfgs, scfg) - } // Register local address. scfg := parcaconfig.ScrapeConfig{ - JobName: "local", + JobName: "local", + ScrapeInterval: model.Duration(l.scrapeInterval), ServiceDiscoveryConfig: sdconfig.ServiceDiscoveryConfig{StaticConfigs: []*targetgroup.Group{{ Targets: []model.LabelSet{ map[model.LabelName]model.LabelValue{ @@ -165,21 +132,44 @@ func (l *listener) updateConfig(started map[string]instrumented) error { } scfgs = append(scfgs, scfg) - for name, s := range started { - add(name, s) + for _, s := range started { + for _, t := range s.ProfileTargets() { + scfg := parcaconfig.ScrapeConfig{ + JobName: t.Name, + ScrapeInterval: model.Duration(l.scrapeInterval), + ServiceDiscoveryConfig: sdconfig.ServiceDiscoveryConfig{ + StaticConfigs: []*targetgroup.Group{{ + Targets: []model.LabelSet{map[model.LabelName]model.LabelValue{ + model.AddressLabel: model.LabelValue(t.InternalEndpoint), + }}, + Labels: map[model.LabelName]model.LabelValue{ + model.SchemeLabel: model.LabelValue(strings.ToLower(t.Scheme)), + }, + }}, + }, + HTTPClientConfig: config.HTTPClientConfig{ + TLSConfig: config.TLSConfig{ + // TODO(bwplotka): Allow providing certs? + // Allow insecure TLS. We are in benchmark/test that is focused on gathering data on all cost. + InsecureSkipVerify: true, + }, + }, + } + scfg.ProfilingConfig = t.Config + scfgs = append(scfgs, scfg) + } } - return l.p.SetScrapeConfigs(scfgs) } func (l *listener) OnRunnableChange(started []e2e.Runnable) error { - s := map[string]instrumented{} + s := map[string]Profiled{} for _, r := range started { - instr, ok := r.(instrumented) + instr, ok := r.GetMetadata(metaKey) if !ok { continue } - s[r.Name()] = instr + s[r.Name()] = instr.(Profiled) } return l.updateConfig(s) @@ -190,7 +180,7 @@ type opt struct { customParcaImage string } -// WithScrapeInterval changes how often metrics are scrape by Prometheus. 5s by default. +// WithScrapeInterval changes how often profiles are collected by Parca. 5s by default. func WithScrapeInterval(interval time.Duration) func(*opt) { return func(o *opt) { o.scrapeInterval = interval @@ -206,8 +196,8 @@ func WithParcaImage(image string) func(*opt) { type Option func(*opt) -// Start deploys monitoring service which deploys Parca that monitors all registered -// InstrumentedServices in environment. +// Start deploys monitoring service which deploys Parca that collects profiles from all +// ProfiledRunnable instances in environment created with AsProfiled. func Start(env e2e.Environment, opts ...Option) (_ *Service, err error) { opt := opt{scrapeInterval: 5 * time.Second} for _, o := range opts { @@ -234,18 +224,14 @@ func Start(env e2e.Environment, opts ...Option) (_ *Service, err error) { go func() { _ = s.Serve(list) }() env.AddCloser(func() { _ = s.Close() }) - var dbOpts []e2edb.Option - if opt.customParcaImage != "" { - dbOpts = append(dbOpts, e2edb.WithImage(opt.customParcaImage)) - } - p := e2edb.NewParca(env, "monitoring", dbOpts...) + p := NewParca(env, "profiling", opt.customParcaImage, nil) _, port, err := net.SplitHostPort(list.Addr().String()) if err != nil { return nil, err } l := &listener{p: p, localAddr: net.JoinHostPort(env.HostAddr(), port), scrapeInterval: opt.scrapeInterval} - if err := l.updateConfig(map[string]instrumented{}); err != nil { + if err := l.updateConfig(map[string]Profiled{}); err != nil { return nil, err } env.AddListener(l) @@ -256,7 +242,7 @@ func Start(env e2e.Environment, opts ...Option) (_ *Service, err error) { select { case <-time.After(2 * time.Minute): - return nil, errors.New("Prometheus failed to scrape local endpoint after 2 minutes, check monitoring Prometheus logs") + return nil, errors.New("Parca failed to collect profiles from local process after 2 minutes, check profiling Parca logs") case <-scraped: } @@ -264,5 +250,5 @@ func Start(env e2e.Environment, opts ...Option) (_ *Service, err error) { } func (s *Service) OpenUserInterfaceInBrowser(paths ...string) error { - return e2einteractive.OpenInBrowser("http://" + s.p.Endpoint(e2edb.AccessPortName) + strings.Join(paths, "/")) + return e2einteractive.OpenInBrowser("http://" + s.p.Endpoint("http") + strings.Join(paths, "/")) } From 00b0959934f98e8e0389565510fde4d692b0c210 Mon Sep 17 00:00:00 2001 From: bwplotka Date: Tue, 13 Sep 2022 11:01:20 +0200 Subject: [PATCH 5/7] Fix Signed-off-by: bwplotka --- .bingo/Variables.mk | 6 +- .bingo/golangci-lint.mod | 4 +- .bingo/golangci-lint.sum | 700 +++++++++++++++++++++++++++++++++ .bingo/variables.env | 2 +- README.md | 6 +- env_docker.go | 7 +- monitoring/monitoring.go | 2 +- observable/observable.go | 3 + profiling.png | Bin 0 -> 133548 bytes profiling/parcaconfig/parca.go | 3 + profiling/profiled.go | 3 + profiling/profiling.go | 11 +- 12 files changed, 728 insertions(+), 19 deletions(-) create mode 100644 profiling.png diff --git a/.bingo/Variables.mk b/.bingo/Variables.mk index 7af4eca..141a697 100644 --- a/.bingo/Variables.mk +++ b/.bingo/Variables.mk @@ -41,11 +41,11 @@ $(GOIMPORTS): $(BINGO_DIR)/goimports.mod @echo "(re)installing $(GOBIN)/goimports-v0.0.0-20200519204825-e64124511800" @cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=goimports.mod -o=$(GOBIN)/goimports-v0.0.0-20200519204825-e64124511800 "golang.org/x/tools/cmd/goimports" -GOLANGCI_LINT := $(GOBIN)/golangci-lint-v1.41.1 +GOLANGCI_LINT := $(GOBIN)/golangci-lint-v1.49.0 $(GOLANGCI_LINT): $(BINGO_DIR)/golangci-lint.mod @# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies. - @echo "(re)installing $(GOBIN)/golangci-lint-v1.41.1" - @cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=golangci-lint.mod -o=$(GOBIN)/golangci-lint-v1.41.1 "github.com/golangci/golangci-lint/cmd/golangci-lint" + @echo "(re)installing $(GOBIN)/golangci-lint-v1.49.0" + @cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=golangci-lint.mod -o=$(GOBIN)/golangci-lint-v1.49.0 "github.com/golangci/golangci-lint/cmd/golangci-lint" MDOX := $(GOBIN)/mdox-v0.2.2-0.20210712170635-f49414cc6b5a $(MDOX): $(BINGO_DIR)/mdox.mod diff --git a/.bingo/golangci-lint.mod b/.bingo/golangci-lint.mod index bcad440..3b240b4 100644 --- a/.bingo/golangci-lint.mod +++ b/.bingo/golangci-lint.mod @@ -1,5 +1,5 @@ module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT -go 1.14 +go 1.16 -require github.com/golangci/golangci-lint v1.41.1 // cmd/golangci-lint +require github.com/golangci/golangci-lint v1.49.0 // cmd/golangci-lint diff --git a/.bingo/golangci-lint.sum b/.bingo/golangci-lint.sum index 42ddd8b..6f7bae0 100644 --- a/.bingo/golangci-lint.sum +++ b/.bingo/golangci-lint.sum @@ -1,11 +1,14 @@ 4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a h1:wFEQiK85fRsEVF0CRrPAos5LoAryUsIX1kPW/WrIqFw= 4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= +4d63.com/gochecknoglobals v0.1.0 h1:zeZSRqj5yCg28tCkIV/z/lWbwvNm5qnKVS15PI8nhD0= +4d63.com/gochecknoglobals v0.1.0/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= bitbucket.org/creachadair/shell v0.0.6/go.mod h1:8Qqi/cYk7vPnsOePHroKXDJYmb5x7ENhtiFtfZq8K+M= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= 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.44.3/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= @@ -15,15 +18,39 @@ cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bP 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.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU= +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 v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= 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/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= 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/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= 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= @@ -34,13 +61,25 @@ cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiy 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= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Antonboom/errname v0.1.7 h1:mBBDKvEYwPl4WFFNwec1CZO096G6vzK9vvDQzAwkako= +github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0SddnIAGavU= +github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q= +github.com/Antonboom/nilnil v0.1.1/go.mod h1:L1jBqoWM7AOeTD+tSquifKSesRHs4ZdaxvZR+xdJEaI= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0= +github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= +github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 h1:+r1rSv4gvYn0wmRjC8X7IAzX8QezqtFV9m0MUHFJgts= +github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0/go.mod h1:b3g59n2Y+T5xmcxJL+UEG2f8cQploZm1mR/v6BW0mU0= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= @@ -50,24 +89,38 @@ github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuN github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= +github.com/OpenPeeDeeP/depguard v1.1.0 h1:pjK9nLPS1FwQYGGpPxoMYpe7qACHOhAWQMQzV71i49o= +github.com/OpenPeeDeeP/depguard v1.1.0/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= +github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= +github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/ashanbrown/forbidigo v1.2.0 h1:RMlEFupPCxQ1IogYOQUnIQwGEUGK8g5vAPMRyJoSxbc= github.com/ashanbrown/forbidigo v1.2.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI= +github.com/ashanbrown/forbidigo v1.3.0 h1:VkYIwb/xxdireGAdJNZoo24O4lmnEWkactplBlWTShc= +github.com/ashanbrown/forbidigo v1.3.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI= github.com/ashanbrown/makezero v0.0.0-20210520155254-b6261585ddde h1:YOsoVXsZQPA9aOTy1g0lAJv5VzZUvwQuZqug8XPeqfM= github.com/ashanbrown/makezero v0.0.0-20210520155254-b6261585ddde/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU= +github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= +github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= @@ -79,22 +132,48 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A= github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI= +github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= +github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= github.com/bombsimon/wsl/v3 v3.3.0 h1:Mka/+kRLoQJq7g2rggtgQsjuI/K5Efd87WX96EWFxjM= github.com/bombsimon/wsl/v3 v3.3.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= +github.com/breml/bidichk v0.2.3 h1:qe6ggxpTfA8E75hdjWPZ581sY3a2lnl0IRxLQFelECI= +github.com/breml/bidichk v0.2.3/go.mod h1:8u2C6DnAy0g2cEq+k/A2+tr9O1s+vHGxWn0LTc70T2A= +github.com/breml/errchkjson v0.3.0 h1:YdDqhfqMT+I1vIxPSas44P+9Z9HzJwCeAzjB8PxP1xw= +github.com/breml/errchkjson v0.3.0/go.mod h1:9Cogkyv9gcT8HREpzi3TiqBxCqDzo8awa92zSDFcofU= +github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY= +github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charithe/durationcheck v0.0.8 h1:cnZrThioNW9gSV5JsRIXmkyHUbcDH7Y9hkzFDVc9/j0= github.com/charithe/durationcheck v0.0.8/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= +github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy6EEutYk= +github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af h1:spmv8nSH9h5oCQf40jt/ufBCt9j0/58u4G+rkeMqXGI= github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af/go.mod h1:Qjyv4H3//PWVzTeCezG2b9IRn6myJxJSr4TD/xo6ojU= +github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 h1:E7LT642ysztPWE0dfz43cWOvMiF42DyTRC+eZIaO4yI= +github.com/chavacava/garif v0.0.0-20220630083739-93517212f375/go.mod h1:4m1Rv7xfuwWPNKXlThldNuJvutYM6J95wNuuVmn55To= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= 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/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -105,19 +184,29 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cristalhq/acmd v0.7.0/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ= +github.com/curioswitch/go-reassign v0.1.2 h1:ekM07+z+VFT560Exz4mTv0/s1yU9gem6CJc/tlYpkmI= +github.com/curioswitch/go-reassign v0.1.2/go.mod h1:bFJIHgtTM3hRm2sKXSPkbwNjSFyGURQXyn4IXD2qwfQ= github.com/daixiang0/gci v0.2.8 h1:1mrIGMBQsBu0P7j7m1M8Lb+ZeZxsZL+jyGX4YoMJJpg= github.com/daixiang0/gci v0.2.8/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc= +github.com/daixiang0/gci v0.6.3 h1:wUAqXChk8HbwXn8AfxD9DYSCp9Bpz1L3e6Q4Roe+q9E= +github.com/daixiang0/gci v0.6.3/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= +github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= github.com/denis-tingajkin/go-header v0.4.2 h1:jEeSF4sdv8/3cT/WY8AgDHUoItNSoEZ7qg9dX7pc218= github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -127,10 +216,20 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn 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.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= github.com/esimonov/ifshort v1.0.2 h1:K5s1W2fGfkoWXsFlxBNqT6J0ZCncPaKrGM5qe0bni68= github.com/esimonov/ifshort v1.0.2/go.mod h1:yZqNJUrNn20K8Q9n2CrjTKYyVEmX209Hgu+M1LBpeZE= +github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStBA= +github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0= github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw= github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -138,25 +237,41 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= +github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= +github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= +github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fullstorydev/grpcurl v1.6.0/go.mod h1:ZQ+ayqbKMJNhzLmbpCiurTVlaK2M/3nqZCxaQ2Ze/sM= github.com/fzipp/gocyclo v0.3.1 h1:A9UeX3HJSXTBzvHzhqoYVuE0eAhe+aM8XBCCwsPMZOc= github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E= +github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= +github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-critic/go-critic v0.5.6 h1:siUR1+322iVikWXoV75I1YRfNaC/yaLzhdF9Zwd8Tus= github.com/go-critic/go-critic v0.5.6/go.mod h1:cVjj0DfqewQVIlIAGexPCaGaZDAqGE29PYDDADIVNEo= +github.com/go-critic/go-critic v0.6.4 h1:tucuG1pvOyYgpBIrVxw0R6gwO42lNa92Aq3VaDoIs+E= +github.com/go-critic/go-critic v0.6.4/go.mod h1:qL5SOlk7NtY6sJPoVCTKDIgzNOxHkkkOCVDyi9wJe1U= 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-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-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.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= @@ -166,14 +281,20 @@ github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= +github.com/go-toolsmith/astcopy v1.0.1 h1:l09oBhAPyV74kLJ3ZO31iBU8htZGTwr9LTjuMCyL8go= +github.com/go-toolsmith/astcopy v1.0.1/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y= github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= +github.com/go-toolsmith/astequal v1.0.1/go.mod h1:4oGA3EZXTVItV/ipGiOx7NWkY5veFfcsOJVS2YxltLw= +github.com/go-toolsmith/astequal v1.0.2 h1:+XvaV8zNxua+9+Oa4AHmgmpo4RYAbwr/qjNppLfX2yM= +github.com/go-toolsmith/astequal v1.0.2/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= +github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5/go.mod h1:3NAwwmD4uY/yggRxoEjk/S00MIV3A+H7rrE3i87eYxM= github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= @@ -183,18 +304,23 @@ github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4 github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY= github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +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/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 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/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -202,6 +328,8 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt 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/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.1.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= @@ -218,16 +346,25 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= 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.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw= github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= +github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6J5HIP8ZtyMdiDscjMLfRBSPuzVVeo= +github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= github.com/golangci/golangci-lint v1.41.1 h1:KH28pTSqRu6DTXIAANl1sPXNCmqg4VEH21z6G9Wj4SM= github.com/golangci/golangci-lint v1.41.1/go.mod h1:LPtcY3aAAU8wydHrKpnanx9Og8K/cblZSyGmI5CJZUk= +github.com/golangci/golangci-lint v1.49.0 h1:I8WHOavragDttlLHtSraHn/h39C+R60bEQ5NoGcHQr8= +github.com/golangci/golangci-lint v1.49.0/go.mod h1:+V/7lLv449R6w9mQ3WdV0EKh7Je/jTylMeSwBZcLeWE= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= @@ -236,6 +373,8 @@ github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTeh github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= github.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5 h1:c9Mqqrm/Clj5biNaG7rABrmwUq88nHh0uABo2b/WYmc= github.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5/go.mod h1:LK+zW4MpyytAWQRz0M4xnzEk50lSvqDQKfx304apFkY= +github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 h1:DIPQnGy2Gv2FSA4B/hh8Q7xx3B7AIDk3DAMeHclH1vQ= +github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6/go.mod h1:0AKcRCkMoKvUvlf89F6O7H2LYdhr1zBh736mBItOdRs= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -246,13 +385,23 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a 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.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.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= 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.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= 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= @@ -260,18 +409,39 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf 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-20200507031123-427632fa3b1c/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-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEivX+9mPgw= github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/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/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= +github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254 h1:Nb2aRlC404yz7gQIfRZxX9/MLvQiqXyiBTJtgAy6yrI= github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254/go.mod h1:M9mZEtGIsR1oDaZagNPNG9iq9n2HrhZ17dsXk73V3Lw= +github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 h1:PVRE9d4AQKmbelZ7emNig1+NT27DUmKZn5qXxfio54U= +github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -282,13 +452,21 @@ github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7 github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= github.com/gostaticanalysis/analysisutil v0.4.1 h1:/7clKqrVfiVwiBQLM0Uke4KvXnO6JcCTS7HwF2D6wG8= github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0= +github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= +github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= github.com/gostaticanalysis/comment v1.4.1 h1:xHopR5L2lRz6OsjH4R2HG5wRhW9ySl3FsHIvi5pcXwc= github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= +github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q= +github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5 h1:rx8127mFPqXXsfPSo8BwnIU97MKFZc89WHAHt8PwDVY= github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= +github.com/gostaticanalysis/forcetypeassert v0.1.0 h1:6eUflI3DiGusXGK6X7cCcIgVCpZ2CiZ1Q7jl6ZxNV70= +github.com/gostaticanalysis/forcetypeassert v0.1.0/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk= github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= +github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= +github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -297,21 +475,37 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= +github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= 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-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= 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= @@ -320,12 +514,23 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= +github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -334,6 +539,8 @@ github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7H github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4= github.com/jingyugao/rowserrcheck v1.1.0 h1:u6h4eiNuCLqk73Ic5TXQq9yZS+uEXTdusn7c3w1Mr6A= github.com/jingyugao/rowserrcheck v1.1.0/go.mod h1:TOQpc2SLx6huPfoFGK3UOnEG+u02D3C1GeosjupAKCA= +github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= +github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -342,60 +549,103 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfC github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/josharian/txtarfs v0.0.0-20210218200122-0702f000015a/go.mod h1:izVPOvVRsHiKkeGCT6tYBNWyDVuzj9wAaBb5R9qamfw= +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.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/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/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/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= 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/julz/importas v0.0.0-20210419104244-841f0c0fe66d h1:XeSMXURZPtUffuWAaq90o6kLgZdgu+QA8wk4MPC8ikI= github.com/julz/importas v0.0.0-20210419104244-841f0c0fe66d/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= +github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= +github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.6.0 h1:YTDO4pNy7AUN/021p+JGHycQyYNIyMoenM1YDVK6RlY= github.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7c= +github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= 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.2/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/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= 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.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kulti/thelper v0.4.0 h1:2Nx7XbdbE/BYZeoip2mURKUdtHQRuy6Ug+wR7K9ywNM= github.com/kulti/thelper v0.4.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U= +github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= +github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= github.com/kunwardeep/paralleltest v1.0.2 h1:/jJRv0TiqPoEy/Y8dQxCFJhD56uS/pnvtatgTZBHokU= github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30= +github.com/kunwardeep/paralleltest v1.0.6 h1:FCKYMF1OF2+RveWlABsdnmsvJrei5aoyZoaGS+Ugg8g= +github.com/kunwardeep/paralleltest v1.0.6/go.mod h1:Y0Y0XISdZM5IKm3TREQMZ6iteqn1YuwCsJO/0kL9Zes= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= github.com/ldez/gomoddirectives v0.2.1 h1:9pAcW9KRZW7HQjFwbozNvFMcNVwdCBufU7os5QUwLIY= github.com/ldez/gomoddirectives v0.2.1/go.mod h1:sGicqkRgBOg//JfpXwkB9Hj0X5RyJ7mlACM5B9f6Me4= +github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUcJwlhA= +github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= github.com/ldez/tagliatelle v0.2.0 h1:693V8Bf1NdShJ8eu/s84QySA0J2VWBanVBa2WwXD/Wk= github.com/ldez/tagliatelle v0.2.0/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= +github.com/ldez/tagliatelle v0.3.1 h1:3BqVVlReVUZwafJUwQ+oxbx2BEX2vUG4Yu/NOfMiKiM= +github.com/ldez/tagliatelle v0.3.1/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= +github.com/leonklingele/grouper v1.1.0 h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRrf0SAg= +github.com/leonklingele/grouper v1.1.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= +github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= +github.com/magefile/mage v1.13.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= +github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/maratori/testpackage v1.0.1 h1:QtJ5ZjqapShm0w5DosRjg0PRlSdAdlx+W6cCKoALdbQ= github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= +github.com/maratori/testpackage v1.1.0 h1:GJY4wlzQhuBusMF1oahQCBtUV/AQ/k69IZ68vxaac2Q= +github.com/maratori/testpackage v1.1.0/go.mod h1:PeAhzU8qkCwdGEMTEupsHJNlQu2gZopMC6RjbhmHeDc= github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -403,6 +653,9 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -416,13 +669,19 @@ github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwg github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 h1:QASJXOGm2RZ5Ardbc86qNFvby9AqkLDibfChMtAg5QM= github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg= +github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg= github.com/mgechev/revive v1.0.7 h1:5kEWTY/W5a0Eiqnkn2BAWsRZpxbs1ft15PsyNC7Rml8= github.com/mgechev/revive v1.0.7/go.mod h1:vuE5ox/4L/HDd63MCcCk3H6wTLQ6XXezRphJ8cJJOxY= +github.com/mgechev/revive v1.2.3 h1:NzIEEa9+WimQ6q2Ov7OcNeySS/IOcwtkQ8RAh0R5UJ4= +github.com/mgechev/revive v1.2.3/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -434,30 +693,42 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinKo8VaLxe6PWTPEXRXDIHz2QAwiaBaP5/4a8= github.com/mozilla/tls-observatory v0.0.0-20210209181001-cf43108d6880/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s= +github.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s= 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/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo= github.com/mwitkow/go-proto-validators v0.2.0/go.mod h1:ZfA1hW+UH/2ZHOWvQ3HnQaU0DtnpXu850MZiy+YUgcc= github.com/nakabonne/nestif v0.3.0 h1:+yOViDGhg8ygGrmII72nV9B/zGxY188TYpfolntsaPw= github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= +github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= +github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA= github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nishanths/exhaustive v0.1.0 h1:kVlMw8h2LHPMGUVqUj6230oQjjTMFjwcZrnkhXzFfl8= github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ= +github.com/nishanths/exhaustive v0.8.1 h1:0QKNascWv9qIHY7zRoZSxeRr6kuk5aAT3YXLTiDmjTo= +github.com/nishanths/exhaustive v0.8.1/go.mod h1:qj+zJJUgJ76tR92+25+03oYUhzF4R7/2Wk7fGTfCHmg= github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ= github.com/nishanths/predeclared v0.2.1 h1:1TXtjmy4f3YCFjTxRd8zcFHOmoUir+gp0ESzjFzG2sw= github.com/nishanths/predeclared v0.2.1/go.mod h1:HvkGJcA3naj4lOwnFXFDkFxVtSqQMB9sbB1usJ+xjQE= +github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= +github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= @@ -470,32 +741,62 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.1/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= +github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= +github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw= +github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polyfloyd/go-errorlint v0.0.0-20210510181950-ab96adb96fea h1:Sk6Xawg57ZkjXmFYD1xCHSKN6FtYM+km51MM7Lveyyc= github.com/polyfloyd/go-errorlint v0.0.0-20210510181950-ab96adb96fea/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= +github.com/polyfloyd/go-errorlint v1.0.2 h1:kp1yvHflYhTmw5m3MmBy8SCyQkKPjwDthVuMH0ug6Yk= +github.com/polyfloyd/go-errorlint v1.0.2/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= 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-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -504,13 +805,21 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/pseudomuto/protoc-gen-doc v1.3.2/go.mod h1:y5+P6n3iGrbKG+9O04V5ld71in3v/bX88wUwgt+U8EA= github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q= @@ -518,33 +827,58 @@ github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1: github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30= github.com/quasilyte/go-ruleguard v0.3.4 h1:F6l5p6+7WBcTKS7foNQ4wqA39zjn2+RbdbyzGxIq1B0= github.com/quasilyte/go-ruleguard v0.3.4/go.mod h1:57FZgMnoo6jqxkYKmVj5Fc8vOt0rVzoE/UNAmFFIPqA= +github.com/quasilyte/go-ruleguard v0.3.17 h1:cDdoaSbQg11LXPDQqiCK54QmQXsEQQCTIgdcpeULGSI= +github.com/quasilyte/go-ruleguard v0.3.17/go.mod h1:sST5PvaR7yb/Az5ksX8oc88usJ4EGjmJv7cK7y3jyig= github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= github.com/quasilyte/go-ruleguard/dsl v0.3.2/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/go-ruleguard/dsl v0.3.21/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc= github.com/quasilyte/go-ruleguard/rules v0.0.0-20210203162857-b223e0831f88/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= +github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= +github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 h1:PDWGei+Rf2bBiuZIbZmM20J2ftEy9IeUCHA8HbQqed8= +github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5/go.mod h1:wSEyW6O61xRV6zb6My3HxrQ5/8ke7NE2OayqCHa3xRM= github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf68pVdQ3bCFZMDmnt9yqcMBro1pC7F+IPYMY= github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= +github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= +github.com/remyoudompheng/go-dbus v0.0.0-20121104212943-b7232d34b1d5/go.mod h1:+u151txRmLpwxBmpYn9z3d1sdJdjRPQpsXuYeY9jNls= +github.com/remyoudompheng/go-liblzma v0.0.0-20190506200333-81bf2d431b96/go.mod h1:90HvCY7+oHHUKkbeMCiHt1WuFR2/hPJ9QrljDG+v6ls= +github.com/remyoudompheng/go-misc v0.0.0-20190427085024-2d6ac652a50e/go.mod h1:80FQABjoFzZ2M5uEa6FUaJYEmqU2UOKojlFVak1UAwI= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryancurrah/gomodguard v1.2.2 h1:ZJQeYHZ2kaJpojoQBaGqpsn5g7GMcePY36uUGW1umbs= github.com/ryancurrah/gomodguard v1.2.2/go.mod h1:tpI+C/nzvfUR3bF28b5QHpTn/jM/zlGniI++6ZlIWeE= +github.com/ryancurrah/gomodguard v1.2.4 h1:CpMSDKan0LtNGGhPrvupAoLeObRFjND8/tU1rEOtBp4= +github.com/ryancurrah/gomodguard v1.2.4/go.mod h1:+Kem4VjWwvFpUJRJSwa16s1tBJe+vbv02+naTow2f6M= github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= +github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8= github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3335lYTyxRoA= github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= +github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= +github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= +github.com/sashamelentyev/usestdlibvars v1.13.0 h1:uObNudVEEHf6JbOJy5bgKJloA1bWjxR9fwgNFpPzKnI= +github.com/sashamelentyev/usestdlibvars v1.13.0/go.mod h1:D2Wb7niIYmTB+gB8z7kh8tyP5ccof1dQ+SFk+WW5NtY= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/securego/gosec/v2 v2.8.0 h1:iHg9cVmHWf5n6/ijUJ4F10h5bKlNtvXmcWzRw0lxiKE= github.com/securego/gosec/v2 v2.8.0/go.mod h1:hJZ6NT5TqoY+jmOsaxAV4cXoEdrMRLVaNPnSpUCvCZs= +github.com/securego/gosec/v2 v2.13.1 h1:7mU32qn2dyC81MH9L2kefnQyRMUarfDER3iQyMHcjYM= +github.com/securego/gosec/v2 v2.13.1/go.mod h1:EO1sImBMBWFjOTFzMWfTRrZW6M15gm60ljzrmy/wtHo= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= github.com/shirou/gopsutil/v3 v3.21.5/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= +github.com/shirou/gopsutil/v3 v3.22.7/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -554,6 +888,14 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sivchari/containedctx v1.0.2 h1:0hLQKpgC53OVF1VT7CeoFHk9YKstur1XOgfYIc1yrHI= +github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw= +github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt95do8= +github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY= +github.com/sivchari/tenv v1.7.0 h1:d4laZMBK6jpe5PWepxlV9S+LC0yXqvYHiq8E6ceoVVE= +github.com/sivchari/tenv v1.7.0/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -564,14 +906,26 @@ github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag07 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= +github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= +github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= +github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -580,11 +934,20 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= +github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= +github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= github.com/ssgreg/nlreturn/v2 v2.1.0 h1:6/s4Rc49L6Uo6RLjhWZGBpWWjfzk2yrf1nIW8m4wgVA= github.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= +github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0= +github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= +github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc= +github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -594,43 +957,80 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 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.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= +github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs= +github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= +github.com/sylvia7788/contextcheck v1.0.6 h1:o2EZgVPyMKE/Mtoqym61DInKEjwEbsmyoxg3VrmjNO4= +github.com/sylvia7788/contextcheck v1.0.6/go.mod h1:9XDxwvxyuKD+8N+a7Gs7bfWLityh5t70g/GjdEt2N2M= github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b h1:HxLVTlqcHhFAz3nWUcuvpH7WuOMv8LQoCWmruLfFH2U= github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= +github.com/tdakkota/asciicheck v0.1.1 h1:PKzG7JUTUmVspQTDqtkX9eSiLGossXTybutHwTXuO0A= +github.com/tdakkota/asciicheck v0.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= +github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= +github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= github.com/tetafro/godot v1.4.7 h1:zBaoSY4JRVVz33y/qnODsdaKj2yAaMr91HCbqHCifVc= github.com/tetafro/godot v1.4.7/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= +github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw= +github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94 h1:ig99OeTyDwQWhPe2iw9lwfQVF1KB3Q4fpP3X7/2VBG8= github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro= +github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/timonwong/logrlint v0.1.0 h1:phZCcypL/vtx6cGxObJgWZ5wexZF5SXFPLOM+ru0e/M= +github.com/timonwong/logrlint v0.1.0/go.mod h1:Zleg4Gw+kRxNej+Ra7o+tEaW5k1qthTaYKU7rSD39LU= github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= +github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= +github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tomarrell/wrapcheck/v2 v2.1.0 h1:LTzwrYlgBUwi9JldazhbJN84fN9nS2UNGrZIo2syqxE= github.com/tomarrell/wrapcheck/v2 v2.1.0/go.mod h1:crK5eI4RGSUrb9duDTQ5GqcukbKZvi85vX6nbhsBAeI= +github.com/tomarrell/wrapcheck/v2 v2.6.2 h1:3dI6YNcrJTQ/CJQ6M/DUkc0gnqYSIk6o0rChn9E/D0M= +github.com/tomarrell/wrapcheck/v2 v2.6.2/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= github.com/tommy-muehle/go-mnd/v2 v2.4.0 h1:1t0f8Uiaq+fqKteUR4N9Umr6E99R+lDnLnq7PwX2PPE= github.com/tommy-muehle/go-mnd/v2 v2.4.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= +github.com/tommy-muehle/go-mnd/v2 v2.5.0 h1:iAj0a8e6+dXSL7Liq0aXPox36FiN1dBbjA6lt9fl65s= +github.com/tommy-muehle/go-mnd/v2 v2.5.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= github.com/ultraware/whitespace v0.0.4 h1:If7Va4cM03mpgrNH9k49/VOicWpGoG70XPBFFODYDsg= github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= +github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI= +github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/uudashr/gocognit v1.0.1 h1:MoG2fZ0b/Eo7NXoIwCVFLG5JED3qgQz5/NEE+rOsjPs= github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= +github.com/uudashr/gocognit v1.0.6 h1:2Cgi6MweCsdB6kpcVQp7EW4U23iBFQWfTXiWlyp842Y= +github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= +github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY= +github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= +github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= github.com/yeya24/promlinter v0.1.0 h1:goWULN0jH5Yajmu/K+v1xCqIREeB+48OiJ2uu2ssc7U= github.com/yeya24/promlinter v0.1.0/go.mod h1:rs5vtZzeBHqqMwXqFScncpCF6u06lezhZepno9AB1Oc= +github.com/yeya24/promlinter v0.2.0 h1:xFKDQ82orCU5jQujdaD8stOHiv8UN68BSdn2a8u8Y3o= +github.com/yeya24/promlinter v0.2.0/go.mod h1:u54lkmBOZrpEbQQ6gox2zWKKLKu2SGe+2KOiextY+IA= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= @@ -639,25 +1039,47 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de 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.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +gitlab.com/bosi/decorder v0.2.3 h1:gX4/RgK16ijY8V+BRQHAySfQAb354T7/xQpDB2n10P0= +gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6yfWfDmlWd35khcWpUa4L0xI/k= +go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= +go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= +go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU= +go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403/go.mod h1:jHoPAGnDrCy6kaI2tAze5Prf0Nr0w/oNkROt2lw3n3o= 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.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -665,9 +1087,18 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf 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-20190820162420-60c769a6c586/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-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-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 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= @@ -679,6 +1110,12 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 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/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic= +golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= 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= @@ -691,6 +1128,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl 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/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/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= @@ -703,6 +1142,11 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -719,6 +1163,7 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-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-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -738,17 +1183,54 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/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-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/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-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 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-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/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.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -759,7 +1241,11 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ 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-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/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= @@ -780,6 +1266,8 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/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-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -792,6 +1280,7 @@ golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7w 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-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/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= @@ -805,23 +1294,83 @@ golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/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-20200905004654-be1d3432aa8f/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-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/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-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/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-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220702020025-31831981b65f/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-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 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/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.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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -834,6 +1383,7 @@ golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190228203856-589c23e65e65/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -849,6 +1399,7 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw 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-20190910044552-dd2b5c81c578/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-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -886,6 +1437,7 @@ golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roY 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-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -894,30 +1446,56 @@ golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +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-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201114224030-61ea331ec02b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210104081019-d8d6ddbec6ee/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= +golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3 h1:L69ShwSZEyCsLKoAxDKeMvLDZkumEe8gXUZAjab0tX8= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.11-0.20220513221640-090b14e8501f/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= +golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= +golang.org/x/tools v0.1.12-0.20220628192153-7743d1d949f1/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= 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= @@ -934,6 +1512,31 @@ google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/ 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/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.81.0/go.mod h1:FA6Mb/bZxj706H2j+j2d6mHEEaHBmbbWnkfvmorOCko= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -941,6 +1544,7 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww google.golang.org/appengine v1.6.2/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/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181107211654-5fc9ac540362/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -968,10 +1572,65 @@ google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/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-20200513103714-09dca8ec2884/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-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +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-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -986,6 +1645,28 @@ google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= 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.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= 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-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -997,6 +1678,11 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= 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/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1009,6 +1695,10 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= +gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= @@ -1026,6 +1716,9 @@ 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-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1035,15 +1728,22 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.2.0 h1:ws8AfbgTX3oIczLPNPCu5166oBg9ST2vNs0rcht+mDE= honnef.co/go/tools v0.2.0/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= +honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA= +honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= mvdan.cc/gofumpt v0.1.1 h1:bi/1aS/5W00E2ny5q65w9SnKpWEF/UIOqDYBILpo9rA= mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48= +mvdan.cc/gofumpt v0.3.1 h1:avhhrOmv0IuvQVK7fvwV91oFSGAk5/6Po8GXTzICeu8= +mvdan.cc/gofumpt v0.3.1/go.mod h1:w3ymliuxvzVx8DAutBnVyDqYb1Niy/yCJt/lk821YCE= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7 h1:HT3e4Krq+IE44tiN36RvVEb6tvqeIdtsVSsxmNPqlFU= mvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7/go.mod h1:hBpJkZE8H/sb+VRFvw2+rBpHNsTBcvSpk61hr8mzXZE= +mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 h1:seuXWbRB1qPrS3NQnHmFKLJLtskWyueeIzmLXghMGgk= +mvdan.cc/unparam v0.0.0-20220706161116-678bad134442/go.mod h1:F/Cxw/6mVrNKqrR2YjFf5CaW0Bw4RL8RfbEf4GRggJk= 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/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/.bingo/variables.env b/.bingo/variables.env index 4f191fd..700b853 100644 --- a/.bingo/variables.env +++ b/.bingo/variables.env @@ -16,7 +16,7 @@ FAILLINT="${GOBIN}/faillint-v1.11.0" GOIMPORTS="${GOBIN}/goimports-v0.0.0-20200519204825-e64124511800" -GOLANGCI_LINT="${GOBIN}/golangci-lint-v1.41.1" +GOLANGCI_LINT="${GOBIN}/golangci-lint-v1.49.0" MDOX="${GOBIN}/mdox-v0.2.2-0.20210712170635-f49414cc6b5a" diff --git a/README.md b/README.md index 008793a..b724a5a 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,7 @@ func Run(ctx context.Context) error { This will run your code in a container allowing to use the same monitoring methods thanks to cadvisor. -### Continous Profiling +### Continuous Profiling Similarly to [Monitoring](#monitoring), you can wrap your runnable (or instrumented runnable) with `e2eprof.AsProfiled` if your service uses HTTP pprof handlers (common in Go). When wrapped, you can start continuous profiler using [`e2eprof`](profiling) package: @@ -179,6 +179,10 @@ To see how it works in practice, run our example code in [standalone.go](example * Profiling (Parca) * Tracing (Jaeger). +In the profiling UI choose a profile type, filter by instances (autocompleted) and select the profile: + +![img.png](profiling.png) + > NOTE: For runnables that are both instrumented and profiled you can use [`e2eobs.AsObservable`](observable/observable.go). ### Troubleshooting diff --git a/env_docker.go b/env_docker.go index 43bf666..98a7a41 100644 --- a/env_docker.go +++ b/env_docker.go @@ -413,7 +413,7 @@ func (d *dockerRunnable) Start() (err error) { }() // Make sure the image is available locally; if not wait for it to download. - if err = d.prePullImage(context.TODO()); err != nil { + if err := d.prePullImage(context.TODO()); err != nil { return err } @@ -421,13 +421,13 @@ func (d *dockerRunnable) Start() (err error) { l := &LinePrefixLogger{prefix: d.Name() + ": ", logger: d.logger} cmd.Stdout = l cmd.Stderr = l - if err = cmd.Start(); err != nil { + if err := cmd.Start(); err != nil { return err } d.usedNetworkName = d.env.networkName // Wait until the container has been started. - if err = d.waitForRunning(); err != nil { + if err := d.waitForRunning(); err != nil { return err } @@ -452,6 +452,7 @@ func (d *dockerRunnable) Start() (err error) { return errors.Wrapf(err, "unable to get mapping for port %d; service: %s", containerPort, d.Name()) } } + d.logger.Log("Ports for container", d.containerName(), ">> Local ports:", d.ports, "Ports available from host:", d.hostPorts) return nil } diff --git a/monitoring/monitoring.go b/monitoring/monitoring.go index a5cf198..19d5f81 100644 --- a/monitoring/monitoring.go +++ b/monitoring/monitoring.go @@ -273,7 +273,7 @@ func Start(env e2e.Environment, opts ...Option) (_ *Service, err error) { c := newCadvisor(env, "cadvisor") if err := e2e.StartAndWaitReady(c, p); err != nil { - return nil, err + return nil, errors.Wrap(err, "starting cadvisor and monitoring and waiting until ready") } select { diff --git a/observable/observable.go b/observable/observable.go index 4bb9cd7..8ebd85a 100644 --- a/observable/observable.go +++ b/observable/observable.go @@ -1,3 +1,6 @@ +// Copyright (c) The EfficientGo Authors. +// Licensed under the Apache License 2.0. + package e2eobs import ( diff --git a/profiling.png b/profiling.png new file mode 100644 index 0000000000000000000000000000000000000000..97e32e14c57b17588705a339665f049bc58d3421 GIT binary patch literal 133548 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 s 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≤3I2d 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%0AxnV{o7^B@aoG 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 Date: Wed, 14 Sep 2022 16:17:26 +0200 Subject: [PATCH 6/7] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jéssica Lins --- README.md | 4 ++-- monitoring/monitoring.go | 2 +- observable/observable.go | 4 ++-- profiling/profiled.go | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b724a5a..d7948a6 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ This will start Prometheus with automatic discovery for every new and old instru } ``` -To see how it works in practice, run our example code in [standalone.go](examples/thanos/standalone.go) by running `make run-example`. At the end, three UIs should show in your browser: +To see how it works in practice, run our example code in [standalone.go](examples/thanos/standalone.go) by running `make run-example`. At the end, four UIs should show in your browser: * Thanos one, * Monitoring (Prometheus) @@ -160,7 +160,7 @@ This will run your code in a container allowing to use the same monitoring metho Similarly to [Monitoring](#monitoring), you can wrap your runnable (or instrumented runnable) with `e2eprof.AsProfiled` if your service uses HTTP pprof handlers (common in Go). When wrapped, you can start continuous profiler using [`e2eprof`](profiling) package: ```go -mon, err := e2eprof.Start(e) +prof, err := e2eprof.Start(e) ``` This will start Parca with automatic discovery for every new and old profiled runnables. Run `OpenUserInterfaceInBrowser()` to open the Parca UI in the browser: diff --git a/monitoring/monitoring.go b/monitoring/monitoring.go index 19d5f81..abe9a27 100644 --- a/monitoring/monitoring.go +++ b/monitoring/monitoring.go @@ -223,7 +223,7 @@ func WithPrometheusImage(image string) Option { type Option func(*opt) // Start deploys monitoring service which deploys Prometheus that monitors all -// InstrumentedRunnable instances in environment created with AsInstrumented. +// InstrumentedRunnable instances in an environment created with AsInstrumented. func Start(env e2e.Environment, opts ...Option) (_ *Service, err error) { opt := opt{scrapeInterval: 5 * time.Second} for _, o := range opts { diff --git a/observable/observable.go b/observable/observable.go index 8ebd85a..c49e3db 100644 --- a/observable/observable.go +++ b/observable/observable.go @@ -11,7 +11,7 @@ import ( "github.com/efficientgo/e2e/profiling/parcaconfig" ) -// Observable represents runnable that is both instrumented and profiled. Typically, all well-written Go services +// Observable represents a runnable that is both instrumented and profiled. Typically, all well-written Go services // are observable. type Observable struct { e2e.Runnable @@ -24,7 +24,7 @@ type opt struct { profOpts []e2eprof.ProfiledOption } -// WithScheme allows adding customized scheme. "http" or "https" values allowed. "http" by default. +// WithScheme allows adding a customized scheme. "http" or "https" values are allowed. "http" by default. // If "https" is specified, insecure TLS will be performed. func WithScheme(scheme string) Option { return func(o *opt) { diff --git a/profiling/profiled.go b/profiling/profiled.go index 166cefa..b140046 100644 --- a/profiling/profiled.go +++ b/profiling/profiled.go @@ -67,7 +67,7 @@ func AsProfiled(r e2e.Runnable, pprofPortName string, opts ...ProfiledOption) *P } if r.InternalEndpoint(pprofPortName) == "" { - return &ProfiledRunnable{Runnable: e2e.NewFailedRunnable(r.Name(), errors.Newf("pporf port name %v does not exists in given runnable ports", pprofPortName))} + return &ProfiledRunnable{Runnable: e2e.NewFailedRunnable(r.Name(), errors.Newf("pprof port name %v does not exist in given runnable ports", pprofPortName))} } instr := &ProfiledRunnable{ From 5d93ac76dc94795eed440a89fc4a7872627b1eaa Mon Sep 17 00:00:00 2001 From: bwplotka Date: Wed, 14 Sep 2022 17:11:55 +0200 Subject: [PATCH 7/7] Addressed comments. Signed-off-by: bwplotka --- README.md | 4 +++- env_docker_ext_test.go | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d7948a6..8f2ef59 100644 --- a/README.md +++ b/README.md @@ -183,7 +183,9 @@ In the profiling UI choose a profile type, filter by instances (autocompleted) a ![img.png](profiling.png) -> NOTE: For runnables that are both instrumented and profiled you can use [`e2eobs.AsObservable`](observable/observable.go). +### Monitoring + Profiling + +For runnables that are both instrumented and profiled you can use [`e2eobs.AsObservable`](observable/observable.go). ### Troubleshooting diff --git a/env_docker_ext_test.go b/env_docker_ext_test.go index 047bde8..c3e869c 100644 --- a/env_docker_ext_test.go +++ b/env_docker_ext_test.go @@ -13,7 +13,7 @@ import ( "github.com/efficientgo/core/testutil" "github.com/efficientgo/e2e" e2edb "github.com/efficientgo/e2e/db" - e2e2 "github.com/efficientgo/e2e/monitoring" + e2emon "github.com/efficientgo/e2e/monitoring" ) func wgetFlagsCmd(hostPort string) e2e.Command { @@ -49,7 +49,7 @@ func TestDockerEnvironment(t *testing.T) { testutil.Ok(t, p1.WaitReady()) testutil.Ok(t, p1.WaitReady()) - testutil.Ok(t, p1.WaitSumMetrics(e2e2.Greater(50), "prometheus_tsdb_head_samples_appended_total")) + testutil.Ok(t, p1.WaitSumMetrics(e2emon.Greater(50), "prometheus_tsdb_head_samples_appended_total")) testutil.Equals(t, "prometheus-1", p1.Name()) testutil.Equals(t, filepath.Join(e.SharedDir(), "data", p1.Name()), p1.Dir())