1
0
Fork 0
mirror of https://github.com/drone/drone-cli.git synced 2024-03-29 02:10:06 +01:00

(drone-372) use the modern docker runner for exec, upgrade deps

This commit is contained in:
TP Honey 2022-07-05 13:53:47 +01:00
parent c992a25102
commit 960e23233e
13 changed files with 705 additions and 694 deletions

View File

@ -4,12 +4,12 @@ name: default
steps:
- name: test
image: golang:1.16
image: golang:1.18
commands:
- go test ./...
- name: build
image: golang:1.16
image: golang:1.18
commands:
- sh .drone.sh

View File

@ -63,15 +63,3 @@ func prefixedEnviron(environ []string) map[string]string {
}
return envs
}
// helper function combines one or more maps of environment
// variables into a single map.
func combineEnviron(env ...map[string]string) map[string]string {
c := map[string]string{}
for _, e := range env {
for k, v := range e {
c[k] = v
}
}
return c
}

View File

@ -2,35 +2,37 @@ package exec
import (
"context"
"errors"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/url"
"os"
"strconv"
"strings"
"time"
"github.com/drone/envsubst"
"github.com/drone-runners/drone-runner-docker/engine"
"github.com/drone-runners/drone-runner-docker/engine/compiler"
"github.com/drone-runners/drone-runner-docker/engine/linter"
"github.com/drone-runners/drone-runner-docker/engine/resource"
"github.com/drone/drone-runtime/engine"
"github.com/drone/drone-runtime/engine/docker"
"github.com/drone/drone-runtime/runtime"
"github.com/drone/drone-runtime/runtime/term"
"github.com/drone/drone-yaml/yaml"
"github.com/drone/drone-yaml/yaml/compiler"
"github.com/drone/drone-yaml/yaml/compiler/transform"
"github.com/drone/drone-yaml/yaml/converter"
"github.com/drone/drone-yaml/yaml/linter"
"github.com/drone/drone-go/drone"
"github.com/drone/envsubst"
"github.com/drone/runner-go/environ"
"github.com/drone/runner-go/environ/provider"
"github.com/drone/runner-go/logger"
"github.com/drone/runner-go/manifest"
"github.com/drone/runner-go/pipeline"
"github.com/drone/runner-go/pipeline/runtime"
"github.com/drone/runner-go/pipeline/streamer/console"
"github.com/drone/runner-go/registry"
"github.com/drone/runner-go/secret"
"github.com/drone/signal"
"github.com/joho/godotenv"
"github.com/mattn/go-colorable"
"github.com/mattn/go-isatty"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
var tty = isatty.IsTerminal(os.Stdout.Fd())
var nocontext = context.Background()
// Command exports the exec command.
var Command = cli.Command{
@ -80,9 +82,9 @@ var Command = cli.Command{
Name: "network",
Usage: "external networks",
},
cli.StringSliceFlag{
cli.StringFlag{
Name: "registry",
Usage: "registry",
Usage: "registry file",
},
cli.StringFlag{
Name: "secret-file",
@ -103,10 +105,7 @@ var Command = cli.Command{
"plugins/heroku",
},
},
//
// netrc parameters
//
cli.StringFlag{
Name: "netrc-username",
},
@ -116,11 +115,7 @@ var Command = cli.Command{
cli.StringFlag{
Name: "netrc-machine",
},
//
// trigger parameters
//
cli.StringFlag{
Name: "branch",
Usage: "branch name",
@ -133,14 +128,14 @@ var Command = cli.Command{
Name: "instance",
Usage: "instance hostname (e.g. drone.company.com)",
},
cli.StringFlag{
Name: "ref",
Usage: "git reference",
},
cli.StringFlag{
Name: "sha",
Usage: "git sha",
},
// cli.StringFlag{
// Name: "ref",
// Usage: "git reference",
// }, NOT NEEDED
// cli.StringFlag{
// Name: "sha",
// Usage: "git sha",
// },
cli.StringFlag{
Name: "repo",
Usage: "git repository name (e.g. octocat/hello-world)",
@ -152,215 +147,220 @@ var Command = cli.Command{
},
}
func exec(c *cli.Context) error {
file := c.Args().First()
if file == "" {
file = ".drone.yml"
func exec(cliContext *cli.Context) error {
// lets do our mapping from CLI flags to an execCommand struct
commy := mapOldToExecCommand(cliContext)
rawsource, err := ioutil.ReadFile(commy.Source)
if err != nil {
return err
}
envs := environ.Combine(
getEnv(cliContext),
environ.System(commy.System),
environ.Repo(commy.Repo),
environ.Build(commy.Build),
environ.Stage(commy.Stage),
environ.Link(commy.Repo, commy.Build, commy.System),
commy.Build.Params,
)
// string substitution function ensures that string
// replacement variables are escaped and quoted if they
// contain newlines.
subf := func(k string) string {
v := envs[k]
if strings.Contains(v, "\n") {
v = fmt.Sprintf("%q", v)
}
return v
}
data, err := ioutil.ReadFile(file)
// evaluates string replacement expressions and returns an
// update configuration.
config, err := envsubst.Eval(string(rawsource), subf)
if err != nil {
return err
}
environ := getEnv(c)
dataS, err := envsubst.Eval(string(data), func(name string) string {
return environ[name]
})
// parse and lint the configuration.
manifest, err := manifest.ParseString(config)
if err != nil {
return err
}
// this code is temporarily in place to detect and convert
// the legacy yaml configuration file to the new format.
dataS, err = converter.ConvertString(dataS, converter.Metadata{
Filename: file,
Ref: c.String("ref"),
})
// a configuration can contain multiple pipelines.
// get a specific pipeline resource for execution.
if commy.Stage.Name == "" {
fmt.Println("No stage specified, assuming 'default'")
}
res, err := resource.Lookup(commy.Stage.Name, manifest)
if err != nil {
return fmt.Errorf("Stage '%s' not found in build file : %s", commy.Stage.Name, err)
}
// lint the pipeline and return an error if any
// linting rules are broken
lint := linter.New()
err = lint.Lint(res, commy.Repo)
if err != nil {
return err
}
manifest, err := yaml.ParseString(dataS)
if err != nil {
return err
// compile the pipeline to an intermediate representation.
comp := &compiler.Compiler{
Environ: provider.Static(commy.Environ),
Labels: commy.Labels,
Resources: commy.Resources,
Tmate: commy.Tmate,
Privileged: append(commy.Privileged, compiler.Privileged...),
Networks: commy.Networks,
Volumes: commy.Volumes,
Secret: secret.StaticVars(commy.Secrets),
Registry: registry.Combine(
registry.File(commy.Config),
),
}
var pipeline *yaml.Pipeline
filter := c.String("pipeline")
for _, resource := range manifest.Resources {
v, ok := resource.(*yaml.Pipeline)
if !ok {
// when running a build locally cloning is always
// disabled in favor of mounting the source code
// from the current working directory.
if !commy.Clone {
comp.Mount, _ = os.Getwd()
}
args := runtime.CompilerArgs{
Pipeline: res,
Manifest: manifest,
Build: commy.Build,
Netrc: commy.Netrc,
Repo: commy.Repo,
Stage: commy.Stage,
System: commy.System,
}
spec := comp.Compile(nocontext, args).(*engine.Spec)
// include only steps that are in the include list,
// if the list in non-empty.
if len(commy.Include) > 0 {
I:
for _, step := range spec.Steps {
if step.Name == "clone" {
continue
}
for _, name := range commy.Include {
if step.Name == name {
continue I
}
}
step.RunPolicy = runtime.RunNever
}
}
// exclude steps that are in the exclude list, if the list in non-empty.
if len(commy.Exclude) > 0 {
E:
for _, step := range spec.Steps {
if step.Name == "clone" {
continue
}
for _, name := range commy.Exclude {
if step.Name == name {
step.RunPolicy = runtime.RunNever
continue E
}
}
}
}
// resume at a specific step
if cliContext.String("resume-at") != "" {
for _, step := range spec.Steps {
if step.Name == cliContext.String("resume-at") {
break
}
if step.Name == "clone" {
continue
}
for _, name := range commy.Exclude {
if step.Name == name {
step.RunPolicy = runtime.RunNever
continue
}
}
}
}
// create a step object for each pipeline step.
for _, step := range spec.Steps {
if step.RunPolicy == runtime.RunNever {
continue
}
if v.Type != "" && v.Type != "docker" {
return fmt.Errorf("pipeline type (%s) is not supported with 'drone exec'", v.Type)
}
if filter == "" || filter == v.Name {
pipeline = v
break
}
}
if pipeline == nil {
return errors.New("cannot find pipeline")
}
trusted := c.Bool("trusted")
err = linter.Lint(pipeline, trusted)
if err != nil {
return err
}
// the user has the option to disable the git clone
// if the pipeline is being executed on the local
// codebase.
if c.Bool("clone") == false {
pipeline.Clone.Disable = true
}
comp := new(compiler.Compiler)
comp.PrivilegedFunc = compiler.DindFunc(
c.StringSlice("privileged"),
)
comp.SkipFunc = compiler.SkipFunc(
compiler.SkipData{
Branch: environ["DRONE_BRANCH"],
Event: environ["DRONE_EVENT"],
Instance: environ["DRONE_SYSTEM_HOST"],
Ref: environ["DRONE_COMMIT_REF"],
Repo: environ["DRONE_REPO"],
Target: environ["DRONE_DEPLOY_TO"],
},
)
transforms := []func(*engine.Spec){
transform.Include(
c.StringSlice("include"),
),
transform.Exclude(
c.StringSlice("exclude"),
),
transform.ResumeAt(
c.String("resume-at"),
),
transform.WithAuths(
toRegistry(
c.StringSlice("registry"),
),
),
transform.WithEnviron(
readParams(
c.String("env-file"),
),
),
transform.WithEnviron(environ),
transform.WithLables(nil),
transform.WithLimits(0, 0),
transform.WithNetrc(
c.String("netrc-machine"),
c.String("netrc-username"),
c.String("netrc-password"),
),
transform.WithNetworks(
c.StringSlice("network"),
),
transform.WithProxy(),
transform.WithSecrets(
readParams(
c.String("secret-file"),
),
),
transform.WithVolumeSlice(
c.StringSlice("volume"),
),
}
if c.Bool("clone") == false {
pwd, _ := os.Getwd()
comp.WorkspaceMountFunc = compiler.MountHostWorkspace
comp.WorkspaceFunc = compiler.CreateHostWorkspace(pwd)
}
comp.TransformFunc = transform.Combine(transforms...)
ir := comp.Compile(pipeline)
ctx, cancel := context.WithTimeout(
context.Background(),
c.Duration("timeout"),
)
ctx = signal.WithContext(ctx)
defer cancel()
// creates a docker-based engine. eventually we will
// include the kubernetes and vmware fusion engines.
engine, err := docker.NewEnv()
if err != nil {
return err
}
// creates a hook to print the step output to stdout,
// with per-step color coding if a tty.
hooks := &runtime.Hook{}
hooks.BeforeEach = func(s *runtime.State) error {
s.Step.Envs["CI_BUILD_STATUS"] = "success"
s.Step.Envs["CI_BUILD_STARTED"] = strconv.FormatInt(s.Runtime.Time, 10)
s.Step.Envs["CI_BUILD_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10)
s.Step.Envs["DRONE_BUILD_STATUS"] = "success"
s.Step.Envs["DRONE_BUILD_STARTED"] = strconv.FormatInt(s.Runtime.Time, 10)
s.Step.Envs["DRONE_BUILD_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10)
s.Step.Envs["CI_JOB_STATUS"] = "success"
s.Step.Envs["CI_JOB_STARTED"] = strconv.FormatInt(s.Runtime.Time, 10)
s.Step.Envs["CI_JOB_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10)
s.Step.Envs["DRONE_JOB_STATUS"] = "success"
s.Step.Envs["DRONE_JOB_STARTED"] = strconv.FormatInt(s.Runtime.Time, 10)
s.Step.Envs["DRONE_JOB_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10)
if s.Runtime.Error != nil {
s.Step.Envs["CI_BUILD_STATUS"] = "failure"
s.Step.Envs["CI_JOB_STATUS"] = "failure"
s.Step.Envs["DRONE_BUILD_STATUS"] = "failure"
s.Step.Envs["DRONE_JOB_STATUS"] = "failure"
}
return nil
}
hooks.GotLine = term.WriteLine(os.Stdout)
if tty {
hooks.GotLine = term.WriteLinePretty(
colorable.NewColorableStdout(),
)
}
return runtime.New(
runtime.WithEngine(engine),
runtime.WithConfig(ir),
runtime.WithHooks(hooks),
).Run(ctx)
}
// helper function converts a slice of urls to a slice
// of docker registry credentials.
func toRegistry(items []string) []*engine.DockerAuth {
auths := []*engine.DockerAuth{}
for _, item := range items {
uri, err := url.Parse(item)
if err != nil {
continue // skip invalid
}
user := uri.User.Username()
pass, _ := uri.User.Password()
uri.User = nil
auths = append(auths, &engine.DockerAuth{
Address: uri.String(),
Username: user,
Password: pass,
commy.Stage.Steps = append(commy.Stage.Steps, &drone.Step{
StageID: commy.Stage.ID,
Number: len(commy.Stage.Steps) + 1,
Name: step.Name,
Status: drone.StatusPending,
ErrIgnore: step.ErrPolicy == runtime.ErrIgnore,
})
}
return auths
// configures the pipeline timeout.
timeout := time.Duration(commy.Repo.Timeout) * time.Minute
ctx, cancel := context.WithTimeout(nocontext, timeout)
defer cancel()
// listen for operating system signals and cancel execution when received.
ctx = signal.WithContextFunc(ctx, func() {
println("received signal, terminating process")
cancel()
})
state := &pipeline.State{
Build: commy.Build,
Stage: commy.Stage,
Repo: commy.Repo,
System: commy.System,
}
// enable debug logging
logrus.SetLevel(logrus.WarnLevel)
if commy.Debug {
logrus.SetLevel(logrus.DebugLevel)
}
if commy.Trace {
logrus.SetLevel(logrus.TraceLevel)
}
logger.Default = logger.Logrus(
logrus.NewEntry(
logrus.StandardLogger(),
),
)
engine, err := engine.NewEnv(engine.Opts{})
if err != nil {
return err
}
err = runtime.NewExecer(
pipeline.NopReporter(),
console.New(commy.Pretty),
pipeline.NopUploader(),
engine,
commy.Procs,
).Exec(ctx, spec, state)
if err != nil {
dump(state)
return err
}
switch state.Stage.Status {
case drone.StatusError, drone.StatusFailing, drone.StatusKilled:
os.Exit(1)
}
return nil
}
// helper function reads secrets from a key-value file.
func readParams(path string) map[string]string {
data, _ := godotenv.Read(path)
return data
func dump(v interface{}) {
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
_ = enc.Encode(v)
}

View File

@ -5,8 +5,11 @@
package exec
import (
"strings"
"github.com/drone-runners/drone-runner-docker/engine/compiler"
"github.com/drone/drone-go/drone"
"github.com/joho/godotenv"
"github.com/urfave/cli"
)
@ -51,10 +54,11 @@ func mapOldToExecCommand(input *cli.Context) (returnVal *execCommand) {
Event: input.String("event"),
Ref: input.String("ref"),
Deploy: input.String("deploy-to"),
Target: input.String("branch"),
},
Repo: &drone.Repo{
Trusted: input.Bool("trusted"),
Timeout: int64(input.Int("timeout")),
Timeout: int64(input.Duration("timeout").Seconds()),
Branch: input.String("branch"),
Name: input.String("name"),
},
@ -75,8 +79,33 @@ func mapOldToExecCommand(input *cli.Context) (returnVal *execCommand) {
Exclude: input.StringSlice("exclude"),
Clone: input.Bool("clone"),
Networks: input.StringSlice("network"),
Environ: readParams(input.String("env-file")),
Volumes: withVolumeSlice(input.StringSlice("volume")),
Secrets: readParams(input.String("secrets")),
Config: input.String("registry"),
Privileged: input.StringSlice("privileged"),
}
return returnVal
}
// WithVolumeSlice is a transform function that adds a set of global volumes to the container that are defined in --volume=host:container format.
func withVolumeSlice(volumes []string) (to map[string]string) {
to = map[string]string{}
for _, s := range volumes {
parts := strings.Split(s, ":")
if len(parts) != 2 {
continue
}
key := parts[0]
val := parts[1]
to[key] = val
}
return to
}
// helper function reads secrets from a key-value file.
func readParams(path string) map[string]string {
data, _ := godotenv.Read(path)
return data
}

View File

@ -1,366 +0,0 @@
package exec2
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"strings"
"time"
"github.com/drone-runners/drone-runner-docker/engine"
"github.com/drone-runners/drone-runner-docker/engine/compiler"
"github.com/drone-runners/drone-runner-docker/engine/linter"
"github.com/drone-runners/drone-runner-docker/engine/resource"
"github.com/drone/drone-go/drone"
"github.com/drone/envsubst"
"github.com/drone/runner-go/environ"
"github.com/drone/runner-go/environ/provider"
"github.com/drone/runner-go/logger"
"github.com/drone/runner-go/manifest"
"github.com/drone/runner-go/pipeline"
"github.com/drone/runner-go/pipeline/runtime"
"github.com/drone/runner-go/pipeline/streamer/console"
"github.com/drone/runner-go/registry"
"github.com/drone/runner-go/secret"
"github.com/drone/signal"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
var nocontext = context.Background()
// Command exports the exec command.
var Command = cli.Command{
Name: "exec2",
Usage: "execute a local build",
ArgsUsage: "[path/to/.drone.yml]",
Action: func(c *cli.Context) {
if err := exec(c); err != nil {
log.Fatalln(err)
}
},
Flags: []cli.Flag{
cli.StringFlag{
Name: "pipeline",
Usage: "Name of the pipeline to execute",
},
cli.StringSliceFlag{
Name: "include",
Usage: "Name of steps to include",
},
cli.StringSliceFlag{
Name: "exclude",
Usage: "Name of steps to exclude",
},
cli.StringFlag{
Name: "resume-at",
Usage: "Name of start to resume at",
},
cli.BoolFlag{
Name: "clone",
Usage: "enable the clone step",
},
cli.BoolFlag{
Name: "trusted",
Usage: "build is trusted",
},
cli.DurationFlag{
Name: "timeout",
Usage: "build timeout",
Value: time.Hour,
},
cli.StringSliceFlag{
Name: "volume",
Usage: "build volumes",
},
cli.StringSliceFlag{
Name: "network",
Usage: "external networks",
},
cli.StringFlag{
Name: "registry",
Usage: "registry file",
},
cli.StringFlag{
Name: "secret-file",
Usage: "secret file, define values that can be used with from_secret",
},
cli.StringFlag{
Name: "env-file",
Usage: "env file",
},
cli.StringSliceFlag{
Name: "privileged",
Usage: "privileged plugins",
Value: &cli.StringSlice{
"plugins/docker",
"plugins/acr",
"plugins/ecr",
"plugins/gcr",
"plugins/heroku",
},
},
// netrc parameters
cli.StringFlag{
Name: "netrc-username",
},
cli.StringFlag{
Name: "netrc-password",
},
cli.StringFlag{
Name: "netrc-machine",
},
// trigger parameters
cli.StringFlag{
Name: "branch",
Usage: "branch name",
},
cli.StringFlag{
Name: "event",
Usage: "build event name (push, pull_request, etc)",
},
cli.StringFlag{
Name: "instance",
Usage: "instance hostname (e.g. drone.company.com)",
},
// cli.StringFlag{
// Name: "ref",
// Usage: "git reference",
// }, NOT NEEDED
// cli.StringFlag{
// Name: "sha",
// Usage: "git sha",
// },
cli.StringFlag{
Name: "repo",
Usage: "git repository name (e.g. octocat/hello-world)",
},
cli.StringFlag{
Name: "deploy-to",
Usage: "deployment target (e.g. production)",
},
},
}
func exec(cliContext *cli.Context) error {
// lets do our mapping from CLI flags to an execCommand struct
commy := mapOldToExecCommand(cliContext)
rawsource, err := ioutil.ReadFile(commy.Source)
if err != nil {
return err
}
envs := environ.Combine(
getEnv(cliContext),
environ.System(commy.System),
environ.Repo(commy.Repo),
environ.Build(commy.Build),
environ.Stage(commy.Stage),
environ.Link(commy.Repo, commy.Build, commy.System),
commy.Build.Params,
)
// string substitution function ensures that string
// replacement variables are escaped and quoted if they
// contain newlines.
subf := func(k string) string {
v := envs[k]
if strings.Contains(v, "\n") {
v = fmt.Sprintf("%q", v)
}
return v
}
// evaluates string replacement expressions and returns an
// update configuration.
config, err := envsubst.Eval(string(rawsource), subf)
if err != nil {
return err
}
// parse and lint the configuration.
manifest, err := manifest.ParseString(config)
if err != nil {
return err
}
// a configuration can contain multiple pipelines.
// get a specific pipeline resource for execution.
if commy.Stage.Name == "" {
fmt.Println("No stage specified, assuming 'default'")
}
res, err := resource.Lookup(commy.Stage.Name, manifest)
if err != nil {
return fmt.Errorf("Stage '%s' not found in build file : %s", commy.Stage.Name, err)
}
// lint the pipeline and return an error if any
// linting rules are broken
lint := linter.New()
err = lint.Lint(res, commy.Repo)
if err != nil {
return err
}
// compile the pipeline to an intermediate representation.
comp := &compiler.Compiler{
Environ: provider.Static(commy.Environ),
Labels: commy.Labels,
Resources: commy.Resources,
Tmate: commy.Tmate,
Privileged: append(commy.Privileged, compiler.Privileged...),
Networks: commy.Networks,
Volumes: commy.Volumes,
Secret: secret.StaticVars(commy.Secrets),
Registry: registry.Combine(
registry.File(commy.Config),
),
}
// when running a build locally cloning is always
// disabled in favor of mounting the source code
// from the current working directory.
if !commy.Clone {
comp.Mount, _ = os.Getwd()
}
args := runtime.CompilerArgs{
Pipeline: res,
Manifest: manifest,
Build: commy.Build,
Netrc: commy.Netrc,
Repo: commy.Repo,
Stage: commy.Stage,
System: commy.System,
}
spec := comp.Compile(nocontext, args).(*engine.Spec)
// include only steps that are in the include list,
// if the list in non-empty.
if len(commy.Include) > 0 {
I:
for _, step := range spec.Steps {
if step.Name == "clone" {
continue
}
for _, name := range commy.Include {
if step.Name == name {
continue I
}
}
step.RunPolicy = runtime.RunNever
}
}
// exclude steps that are in the exclude list, if the list in non-empty.
if len(commy.Exclude) > 0 {
E:
for _, step := range spec.Steps {
if step.Name == "clone" {
continue
}
for _, name := range commy.Exclude {
if step.Name == name {
step.RunPolicy = runtime.RunNever
continue E
}
}
}
}
// resume at a specific step
if cliContext.String("resume-at") != "" {
for _, step := range spec.Steps {
if step.Name == cliContext.String("resume-at") {
break
}
if step.Name == "clone" {
continue
}
for _, name := range commy.Exclude {
if step.Name == name {
step.RunPolicy = runtime.RunNever
continue
}
}
}
}
// create a step object for each pipeline step.
for _, step := range spec.Steps {
if step.RunPolicy == runtime.RunNever {
continue
}
commy.Stage.Steps = append(commy.Stage.Steps, &drone.Step{
StageID: commy.Stage.ID,
Number: len(commy.Stage.Steps) + 1,
Name: step.Name,
Status: drone.StatusPending,
ErrIgnore: step.ErrPolicy == runtime.ErrIgnore,
})
}
// configures the pipeline timeout.
timeout := time.Duration(commy.Repo.Timeout) * time.Minute
ctx, cancel := context.WithTimeout(nocontext, timeout)
defer cancel()
// listen for operating system signals and cancel execution when received.
ctx = signal.WithContextFunc(ctx, func() {
println("received signal, terminating process")
cancel()
})
state := &pipeline.State{
Build: commy.Build,
Stage: commy.Stage,
Repo: commy.Repo,
System: commy.System,
}
// enable debug logging
logrus.SetLevel(logrus.WarnLevel)
if commy.Debug {
logrus.SetLevel(logrus.DebugLevel)
}
if commy.Trace {
logrus.SetLevel(logrus.TraceLevel)
}
logger.Default = logger.Logrus(
logrus.NewEntry(
logrus.StandardLogger(),
),
)
engine, err := engine.NewEnv(engine.Opts{})
if err != nil {
return err
}
err = runtime.NewExecer(
pipeline.NopReporter(),
console.New(commy.Pretty),
pipeline.NopUploader(),
engine,
commy.Procs,
).Exec(ctx, spec, state)
if err != nil {
dump(state)
return err
}
switch state.Stage.Status {
case drone.StatusError, drone.StatusFailing, drone.StatusKilled:
os.Exit(1)
}
return nil
}
func dump(v interface{}) {
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
_ = enc.Encode(v)
}

View File

@ -1,4 +1,4 @@
package exec2
package execold
import (
"os"
@ -63,3 +63,15 @@ func prefixedEnviron(environ []string) map[string]string {
}
return envs
}
// helper function combines one or more maps of environment
// variables into a single map.
func combineEnviron(env ...map[string]string) map[string]string {
c := map[string]string{}
for _, e := range env {
for k, v := range e {
c[k] = v
}
}
return c
}

367
drone/execold/exec.go Normal file
View File

@ -0,0 +1,367 @@
package execold
import (
"context"
"errors"
"fmt"
"io/ioutil"
"log"
"net/url"
"os"
"strconv"
"time"
"github.com/drone/envsubst"
"github.com/drone/drone-runtime/engine"
"github.com/drone/drone-runtime/engine/docker"
"github.com/drone/drone-runtime/runtime"
"github.com/drone/drone-runtime/runtime/term"
"github.com/drone/drone-yaml/yaml"
"github.com/drone/drone-yaml/yaml/compiler"
"github.com/drone/drone-yaml/yaml/compiler/transform"
"github.com/drone/drone-yaml/yaml/converter"
"github.com/drone/drone-yaml/yaml/linter"
"github.com/drone/signal"
"github.com/joho/godotenv"
"github.com/mattn/go-colorable"
"github.com/mattn/go-isatty"
"github.com/urfave/cli"
)
var tty = isatty.IsTerminal(os.Stdout.Fd())
// Command exports the exec command.
var Command = cli.Command{
Name: "exec_old",
Usage: "(deprecated) execute a local build",
Hidden: true,
ArgsUsage: "[path/to/.drone.yml]",
Action: func(c *cli.Context) {
if err := exec(c); err != nil {
log.Fatalln(err)
}
},
Flags: []cli.Flag{
cli.StringFlag{
Name: "pipeline",
Usage: "Name of the pipeline to execute",
},
cli.StringSliceFlag{
Name: "include",
Usage: "Name of steps to include",
},
cli.StringSliceFlag{
Name: "exclude",
Usage: "Name of steps to exclude",
},
cli.StringFlag{
Name: "resume-at",
Usage: "Name of start to resume at",
},
cli.BoolFlag{
Name: "clone",
Usage: "enable the clone step",
},
cli.BoolFlag{
Name: "trusted",
Usage: "build is trusted",
},
cli.DurationFlag{
Name: "timeout",
Usage: "build timeout",
Value: time.Hour,
},
cli.StringSliceFlag{
Name: "volume",
Usage: "build volumes",
},
cli.StringSliceFlag{
Name: "network",
Usage: "external networks",
},
cli.StringSliceFlag{
Name: "registry",
Usage: "registry",
},
cli.StringFlag{
Name: "secret-file",
Usage: "secret file, define values that can be used with from_secret",
},
cli.StringFlag{
Name: "env-file",
Usage: "env file",
},
cli.StringSliceFlag{
Name: "privileged",
Usage: "privileged plugins",
Value: &cli.StringSlice{
"plugins/docker",
"plugins/acr",
"plugins/ecr",
"plugins/gcr",
"plugins/heroku",
},
},
//
// netrc parameters
//
cli.StringFlag{
Name: "netrc-username",
},
cli.StringFlag{
Name: "netrc-password",
},
cli.StringFlag{
Name: "netrc-machine",
},
//
// trigger parameters
//
cli.StringFlag{
Name: "branch",
Usage: "branch name",
},
cli.StringFlag{
Name: "event",
Usage: "build event name (push, pull_request, etc)",
},
cli.StringFlag{
Name: "instance",
Usage: "instance hostname (e.g. drone.company.com)",
},
cli.StringFlag{
Name: "ref",
Usage: "git reference",
},
cli.StringFlag{
Name: "sha",
Usage: "git sha",
},
cli.StringFlag{
Name: "repo",
Usage: "git repository name (e.g. octocat/hello-world)",
},
cli.StringFlag{
Name: "deploy-to",
Usage: "deployment target (e.g. production)",
},
},
}
func exec(c *cli.Context) error {
file := c.Args().First()
if file == "" {
file = ".drone.yml"
}
data, err := ioutil.ReadFile(file)
if err != nil {
return err
}
environ := getEnv(c)
dataS, err := envsubst.Eval(string(data), func(name string) string {
return environ[name]
})
if err != nil {
return err
}
// this code is temporarily in place to detect and convert
// the legacy yaml configuration file to the new format.
dataS, err = converter.ConvertString(dataS, converter.Metadata{
Filename: file,
Ref: c.String("ref"),
})
if err != nil {
return err
}
manifest, err := yaml.ParseString(dataS)
if err != nil {
return err
}
var pipeline *yaml.Pipeline
filter := c.String("pipeline")
for _, resource := range manifest.Resources {
v, ok := resource.(*yaml.Pipeline)
if !ok {
continue
}
if v.Type != "" && v.Type != "docker" {
return fmt.Errorf("pipeline type (%s) is not supported with 'drone exec'", v.Type)
}
if filter == "" || filter == v.Name {
pipeline = v
break
}
}
if pipeline == nil {
return errors.New("cannot find pipeline")
}
trusted := c.Bool("trusted")
err = linter.Lint(pipeline, trusted)
if err != nil {
return err
}
// the user has the option to disable the git clone
// if the pipeline is being executed on the local
// codebase.
if c.Bool("clone") == false {
pipeline.Clone.Disable = true
}
comp := new(compiler.Compiler)
comp.PrivilegedFunc = compiler.DindFunc(
c.StringSlice("privileged"),
)
comp.SkipFunc = compiler.SkipFunc(
compiler.SkipData{
Branch: environ["DRONE_BRANCH"],
Event: environ["DRONE_EVENT"],
Instance: environ["DRONE_SYSTEM_HOST"],
Ref: environ["DRONE_COMMIT_REF"],
Repo: environ["DRONE_REPO"],
Target: environ["DRONE_DEPLOY_TO"],
},
)
transforms := []func(*engine.Spec){
transform.Include(
c.StringSlice("include"),
),
transform.Exclude(
c.StringSlice("exclude"),
),
transform.ResumeAt(
c.String("resume-at"),
),
transform.WithAuths(
toRegistry(
c.StringSlice("registry"),
),
),
transform.WithEnviron(
readParams(
c.String("env-file"),
),
),
transform.WithEnviron(environ),
transform.WithLables(nil),
transform.WithLimits(0, 0),
transform.WithNetrc(
c.String("netrc-machine"),
c.String("netrc-username"),
c.String("netrc-password"),
),
transform.WithNetworks(
c.StringSlice("network"),
),
transform.WithProxy(),
transform.WithSecrets(
readParams(
c.String("secret-file"),
),
),
transform.WithVolumeSlice(
c.StringSlice("volume"),
),
}
if c.Bool("clone") == false {
pwd, _ := os.Getwd()
comp.WorkspaceMountFunc = compiler.MountHostWorkspace
comp.WorkspaceFunc = compiler.CreateHostWorkspace(pwd)
}
comp.TransformFunc = transform.Combine(transforms...)
ir := comp.Compile(pipeline)
ctx, cancel := context.WithTimeout(
context.Background(),
c.Duration("timeout"),
)
ctx = signal.WithContext(ctx)
defer cancel()
// creates a docker-based engine. eventually we will
// include the kubernetes and vmware fusion engines.
engine, err := docker.NewEnv()
if err != nil {
return err
}
// creates a hook to print the step output to stdout,
// with per-step color coding if a tty.
hooks := &runtime.Hook{}
hooks.BeforeEach = func(s *runtime.State) error {
s.Step.Envs["CI_BUILD_STATUS"] = "success"
s.Step.Envs["CI_BUILD_STARTED"] = strconv.FormatInt(s.Runtime.Time, 10)
s.Step.Envs["CI_BUILD_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10)
s.Step.Envs["DRONE_BUILD_STATUS"] = "success"
s.Step.Envs["DRONE_BUILD_STARTED"] = strconv.FormatInt(s.Runtime.Time, 10)
s.Step.Envs["DRONE_BUILD_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10)
s.Step.Envs["CI_JOB_STATUS"] = "success"
s.Step.Envs["CI_JOB_STARTED"] = strconv.FormatInt(s.Runtime.Time, 10)
s.Step.Envs["CI_JOB_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10)
s.Step.Envs["DRONE_JOB_STATUS"] = "success"
s.Step.Envs["DRONE_JOB_STARTED"] = strconv.FormatInt(s.Runtime.Time, 10)
s.Step.Envs["DRONE_JOB_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10)
if s.Runtime.Error != nil {
s.Step.Envs["CI_BUILD_STATUS"] = "failure"
s.Step.Envs["CI_JOB_STATUS"] = "failure"
s.Step.Envs["DRONE_BUILD_STATUS"] = "failure"
s.Step.Envs["DRONE_JOB_STATUS"] = "failure"
}
return nil
}
hooks.GotLine = term.WriteLine(os.Stdout)
if tty {
hooks.GotLine = term.WriteLinePretty(
colorable.NewColorableStdout(),
)
}
return runtime.New(
runtime.WithEngine(engine),
runtime.WithConfig(ir),
runtime.WithHooks(hooks),
).Run(ctx)
}
// helper function converts a slice of urls to a slice
// of docker registry credentials.
func toRegistry(items []string) []*engine.DockerAuth {
auths := []*engine.DockerAuth{}
for _, item := range items {
uri, err := url.Parse(item)
if err != nil {
continue // skip invalid
}
user := uri.User.Username()
pass, _ := uri.User.Password()
uri.User = nil
auths = append(auths, &engine.DockerAuth{
Address: uri.String(),
Username: user,
Password: pass,
})
}
return auths
}
// helper function reads secrets from a key-value file.
func readParams(path string) map[string]string {
data, _ := godotenv.Read(path)
return data
}

View File

@ -2,14 +2,11 @@
// Use of this source code is governed by the Polyform License
// that can be found in the LICENSE file.
package exec2
package execold
import (
"strings"
"github.com/drone-runners/drone-runner-docker/engine/compiler"
"github.com/drone/drone-go/drone"
"github.com/joho/godotenv"
"github.com/urfave/cli"
)
@ -54,11 +51,10 @@ func mapOldToExecCommand(input *cli.Context) (returnVal *execCommand) {
Event: input.String("event"),
Ref: input.String("ref"),
Deploy: input.String("deploy-to"),
Target: input.String("branch"),
},
Repo: &drone.Repo{
Trusted: input.Bool("trusted"),
Timeout: int64(input.Duration("timeout").Seconds()),
Timeout: int64(input.Int("timeout")),
Branch: input.String("branch"),
Name: input.String("name"),
},
@ -79,33 +75,8 @@ func mapOldToExecCommand(input *cli.Context) (returnVal *execCommand) {
Exclude: input.StringSlice("exclude"),
Clone: input.Bool("clone"),
Networks: input.StringSlice("network"),
Environ: readParams(input.String("env-file")),
Volumes: withVolumeSlice(input.StringSlice("volume")),
Secrets: readParams(input.String("secrets")),
Config: input.String("registry"),
Privileged: input.StringSlice("privileged"),
}
return returnVal
}
// WithVolumeSlice is a transform function that adds a set of global volumes to the container that are defined in --volume=host:container format.
func withVolumeSlice(volumes []string) (to map[string]string) {
to = map[string]string{}
for _, s := range volumes {
parts := strings.Split(s, ":")
if len(parts) != 2 {
continue
}
key := parts[0]
val := parts[1]
to[key] = val
}
return to
}
// helper function reads secrets from a key-value file.
func readParams(path string) map[string]string {
data, _ := godotenv.Read(path)
return data
}

View File

@ -10,7 +10,7 @@ import (
"github.com/drone/drone-cli/drone/cron"
"github.com/drone/drone-cli/drone/encrypt"
"github.com/drone/drone-cli/drone/exec"
"github.com/drone/drone-cli/drone/exec2"
"github.com/drone/drone-cli/drone/execold"
"github.com/drone/drone-cli/drone/format"
"github.com/drone/drone-cli/drone/info"
"github.com/drone/drone-cli/drone/jsonnet"
@ -82,7 +82,7 @@ func main() {
log.Command,
encrypt.Command,
exec.Command,
exec2.Command,
execold.Command,
info.Command,
repo.Command,
user.Command,

38
go.mod
View File

@ -1,41 +1,40 @@
module github.com/drone/drone-cli
go 1.17
go 1.18
replace github.com/docker/docker => github.com/docker/engine v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible
require (
github.com/buildkite/yaml v2.1.0+incompatible
github.com/docker/go-units v0.4.0
github.com/drone-runners/drone-runner-docker v1.8.0
github.com/drone-runners/drone-runner-docker v1.8.2
github.com/drone/drone-go v1.7.1
github.com/drone/drone-runtime v1.1.0
github.com/drone/drone-yaml v1.2.3
github.com/drone/envsubst v1.0.3
github.com/drone/funcmap v0.0.0-20190918184546-d4ef6e88376d
github.com/drone/funcmap v0.0.0-20211123105308-29742f68a7d1
github.com/drone/runner-go v1.12.0
github.com/drone/signal v1.0.0
github.com/fatih/color v1.9.0
github.com/fatih/color v1.13.0
github.com/ghodss/yaml v1.0.0
github.com/google/go-jsonnet v0.17.0
github.com/google/go-jsonnet v0.18.0
github.com/jackspirou/syscerts v0.0.0-20160531025014-b68f5469dff1
github.com/joho/godotenv v1.3.0
github.com/mattn/go-colorable v0.1.4
github.com/mattn/go-isatty v0.0.11
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4
github.com/joho/godotenv v1.4.0
github.com/mattn/go-colorable v0.1.12
github.com/mattn/go-isatty v0.0.14
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.7.0
github.com/urfave/cli v1.22.2
go.starlark.net v0.0.0-20201118183435-e55f603d8c79
golang.org/x/net v0.0.0-20211209124913-491a49abca63
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
github.com/stretchr/testify v1.8.0
github.com/urfave/cli v1.22.9
go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd
golang.org/x/net v0.0.0-20220630215102-69896b714898
golang.org/x/oauth2 v0.0.0-20220630143837-2104d58473e0
)
require (
github.com/gorilla/mux v1.8.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
)
@ -65,11 +64,12 @@ require (
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
github.com/vinzenz/yaml v0.0.0-20170920082545-91409cdd725d // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e // indirect
google.golang.org/appengine v1.6.6 // indirect
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a // indirect
google.golang.org/grpc v1.33.2 // indirect
google.golang.org/protobuf v1.27.1 // indirect
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
)

84
go.sum
View File

@ -250,8 +250,8 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/drone-runners/drone-runner-docker v1.8.0 h1:cNjEAxAR/crqfcRyqoumPaHdulfUdj5x2aB2oArvBno=
github.com/drone-runners/drone-runner-docker v1.8.0/go.mod h1:Jdm+apC9XcDGlgdXH+wHjegwqW2oMH9+RR6TfAOu9D8=
github.com/drone-runners/drone-runner-docker v1.8.2 h1:F7+39FSyzEUqLXYMvTdTGBhCS79ODDIhw3DQeF5GYT8=
github.com/drone-runners/drone-runner-docker v1.8.2/go.mod h1:JR3pZeVZKKpkbTajiq0YtAx9WutkODdVKZGNR83kEwE=
github.com/drone/drone-go v1.7.1 h1:ZX+3Rs8YHUSUQ5mkuMLmm1zr1ttiiE2YGNxF3AnyDKw=
github.com/drone/drone-go v1.7.1/go.mod h1:fxCf9jAnXDZV1yDr0ckTuWd1intvcQwfJmTRpTZ1mXg=
github.com/drone/drone-runtime v1.0.7-0.20190729202838-87c84080f4a1/go.mod h1:+osgwGADc/nyl40J0fdsf8Z09bgcBZXvXXnLOY48zYs=
@ -262,9 +262,8 @@ github.com/drone/drone-yaml v1.2.3/go.mod h1:QsqliFK8nG04AHFN9tTn9XJomRBQHD4wcej
github.com/drone/envsubst v1.0.2/go.mod h1:bkZbnc/2vh1M12Ecn7EYScpI4YGYU0etwLJICOWi8Z0=
github.com/drone/envsubst v1.0.3 h1:PCIBwNDYjs50AsLZPYdfhSATKaRg/FJmDc2D6+C2x8g=
github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9bFiJ2g=
github.com/drone/funcmap v0.0.0-20190918184546-d4ef6e88376d h1:/IO7UVVu191Jc0DajV4cDVoO+91cuppvgxg2MZl+AXI=
github.com/drone/funcmap v0.0.0-20190918184546-d4ef6e88376d/go.mod h1:Hph0/pT6ZxbujnE1Z6/08p5I0XXuOsppqF6NQlGOK0E=
github.com/drone/runner-go v1.11.0/go.mod h1:vu4pPPYDoeN6vdYQAY01GGGsAIW4aLganJNaa8Fx8zE=
github.com/drone/funcmap v0.0.0-20211123105308-29742f68a7d1 h1:E8hjIYiEyI+1S2XZSLpMkqT9V8+YMljFNBWrFpuVM3A=
github.com/drone/funcmap v0.0.0-20211123105308-29742f68a7d1/go.mod h1:Hph0/pT6ZxbujnE1Z6/08p5I0XXuOsppqF6NQlGOK0E=
github.com/drone/runner-go v1.12.0 h1:zUjDj9ylsJ4n4Mvy4znddq/Z4EBzcUXzTltpzokKtgs=
github.com/drone/runner-go v1.12.0/go.mod h1:vu4pPPYDoeN6vdYQAY01GGGsAIW4aLganJNaa8Fx8zE=
github.com/drone/signal v1.0.0 h1:NrnM2M/4yAuU/tXs6RP1a1ZfxnaHwYkd0kJurA1p6uI=
@ -280,8 +279,9 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
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.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@ -362,10 +362,10 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
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/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-jsonnet v0.17.0 h1:/9NIEfhK1NQRKl3sP2536b2+x5HnZMdql7x3yK/l8JY=
github.com/google/go-jsonnet v0.17.0/go.mod h1:sOcuej3UW1vpPTZOr8L7RQimqai1a57bt5j22LzGZCw=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-jsonnet v0.18.0 h1:/6pTy6g+Jh1a1I2UMoAODkqELFiVIdOxbNwv0DDzoOg=
github.com/google/go-jsonnet v0.18.0/go.mod h1:C3fTzyVJDslXdiTqw/bTFk7vSGyCtH3MGRbDfvEwGd0=
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@ -423,8 +423,9 @@ github.com/jackspirou/syscerts v0.0.0-20160531025014-b68f5469dff1 h1:9Xm8CKtMZIX
github.com/jackspirou/syscerts v0.0.0-20160531025014-b68f5469dff1/go.mod h1:zuHl3Hh+e9P6gmBPvcqR1HjkaWHC/csgyskg6IaFKFo=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
@ -459,12 +460,15 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
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 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
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.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@ -540,8 +544,8 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/petar/GoLLRB v0.0.0-20130427215148-53be0d36a84c/go.mod h1:HUpKUBZnpzkdx0kD/+Yfuft+uD3zHGtXF/XJB14TUr4=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -622,13 +626,15 @@ github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/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.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.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
@ -639,8 +645,9 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.9 h1:cv3/KhXGBGjEXLC4bH0sLuJ9BewaAbpk5oyMOveu4pw=
github.com/urfave/cli v1.22.9/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vinzenz/yaml v0.0.0-20170920082545-91409cdd725d h1:3wDi6J5APMqaHBVPuVd7RmHD2gRTfqbdcVSpCNoUWtk=
github.com/vinzenz/yaml v0.0.0-20170920082545-91409cdd725d/go.mod h1:mb5taDqMnJiZNRQ3+02W2IFG+oEz1+dTuCXkp4jpkfo=
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
@ -670,8 +677,8 @@ 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.starlark.net v0.0.0-20201118183435-e55f603d8c79 h1:JPjLPz44y2N9mkzh2N344kTk1Y4/V4yJAjTrXGmzv8I=
go.starlark.net v0.0.0-20201118183435-e55f603d8c79/go.mod h1:5YFcFnRptTN+41758c2bMPiqpGg4zBfYji1IQz8wNFk=
go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd h1:Uo/x0Ir5vQJ+683GXB9Ug+4fcjsbp7z7Ul8UaZbhsRM=
go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd/go.mod h1:t3mmBBPzAVvK0L0n1drDmrQsJ8FoIx4INCqVMTr/Zo0=
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/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
@ -756,15 +763,16 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY=
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220630215102-69896b714898 h1:K7wO6V1IrczY9QOQ2WkVpw4JQSwCd52UsxVEirZUfiw=
golang.org/x/net v0.0.0-20220630215102-69896b714898/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-20181203162652-d668ce993890/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 h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20220630143837-2104d58473e0 h1:VnGaRqoLmqZH/3TMLJwYCEWkR4j1nuIU1U9TvbqsDUw=
golang.org/x/oauth2 v0.0.0-20220630143837-2104d58473e0/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
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=
@ -813,6 +821,7 @@ golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7w
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-20200120151820-655fe14d7479/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=
@ -825,7 +834,6 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -838,10 +846,12 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e h1:XMgFehsDnnLGtjvjOfqWSUzt0alpTR1RSEuznObga2c=
golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/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-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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=
@ -849,9 +859,7 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
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.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=
@ -898,7 +906,6 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
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.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
@ -917,8 +924,8 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@ -971,8 +978,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
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 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
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/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -997,13 +1005,14 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7/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=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
@ -1051,4 +1060,5 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyz
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=