From 637c2f0deeaef04e14216b42ee7a42e8ea5ee23d Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Mon, 19 Aug 2024 16:46:42 +0200 Subject: [PATCH 01/18] refactor(runner): move network mirror creation into utils --- internal/runner/runner.go | 22 ++------------------- internal/utils/runner/network_mirror.go | 26 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 20 deletions(-) create mode 100644 internal/utils/runner/network_mirror.go diff --git a/internal/runner/runner.go b/internal/runner/runner.go index 5db065fe..a2b0797d 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -30,6 +30,7 @@ import ( "github.com/padok-team/burrito/internal/runner/terraform" "github.com/padok-team/burrito/internal/runner/terragrunt" + runnerutils "github.com/padok-team/burrito/internal/utils/runner" ) const PlanArtifact string = "/tmp/plan.out" @@ -213,7 +214,7 @@ func (r *Runner) init() error { if os.Getenv("HERMITCRAB_ENABLED") == "true" { log.Infof("Hermitcrab configuration detected, creating network mirror configuration...") - err := createNetworkMirrorConfig(os.Getenv("HERMITCRAB_URL")) + err := runnerutils.CreateNetworkMirrorConfig(WorkingDir, os.Getenv("HERMITCRAB_URL")) if err != nil { log.Errorf("error creating network mirror configuration: %s", err) } @@ -344,22 +345,3 @@ func getDiff(plan *tfjson.Plan) (bool, string) { } return diff, fmt.Sprintf("Plan: %d to create, %d to update, %d to delete", create, update, delete) } - -func createNetworkMirrorConfig(endpoint string) error { - terraformrcContent := fmt.Sprintf(` -provider_installation { - network_mirror { - url = "%s" - } -}`, endpoint) - filePath := fmt.Sprintf("%s/config.tfrc", WorkingDir) - err := os.WriteFile(filePath, []byte(terraformrcContent), 0644) - if err != nil { - return err - } - err = os.Setenv("TF_CLI_CONFIG_FILE", filePath) - if err != nil { - return err - } - return nil -} diff --git a/internal/utils/runner/network_mirror.go b/internal/utils/runner/network_mirror.go new file mode 100644 index 00000000..9c9d4d64 --- /dev/null +++ b/internal/utils/runner/network_mirror.go @@ -0,0 +1,26 @@ +package runner + +import ( + "fmt" + "os" +) + +// Creates a network mirror configuration file for Terraform with the given endpoint +func CreateNetworkMirrorConfig(targetPath string, endpoint string) error { + terraformrcContent := fmt.Sprintf(` +provider_installation { + network_mirror { + url = "%s" + } +}`, endpoint) + filePath := fmt.Sprintf("%s/config.tfrc", targetPath) + err := os.WriteFile(filePath, []byte(terraformrcContent), 0644) + if err != nil { + return err + } + err = os.Setenv("TF_CLI_CONFIG_FILE", filePath) + if err != nil { + return err + } + return nil +} From ab7d4e7fd1dbb4805fd35a73b6a88a58b38248cd Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Mon, 19 Aug 2024 16:53:04 +0200 Subject: [PATCH 02/18] refactor(runner): move getDiff to utils --- internal/runner/runner.go | 24 +----------------------- internal/utils/runner/plan_diff.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 23 deletions(-) create mode 100644 internal/utils/runner/plan_diff.go diff --git a/internal/runner/runner.go b/internal/runner/runner.go index a2b0797d..efd3f2af 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -263,7 +263,7 @@ func (r *Runner) plan() (string, error) { log.Errorf("error parsing terraform json plan: %s", err) return "", err } - _, shortDiff := getDiff(plan) + _, shortDiff := runnerutils.GetDiff(plan) err = r.datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "json", planJsonBytes) if err != nil { log.Errorf("could not put json plan in datastore: %s", err) @@ -323,25 +323,3 @@ func (r *Runner) apply() (string, error) { log.Infof("terraform apply ran successfully") return b64.StdEncoding.EncodeToString(sum[:]), nil } - -func getDiff(plan *tfjson.Plan) (bool, string) { - delete := 0 - create := 0 - update := 0 - for _, res := range plan.ResourceChanges { - if res.Change.Actions.Create() { - create++ - } - if res.Change.Actions.Delete() { - delete++ - } - if res.Change.Actions.Update() { - update++ - } - } - diff := false - if create+delete+update > 0 { - diff = true - } - return diff, fmt.Sprintf("Plan: %d to create, %d to update, %d to delete", create, update, delete) -} diff --git a/internal/utils/runner/plan_diff.go b/internal/utils/runner/plan_diff.go new file mode 100644 index 00000000..44cc9cf7 --- /dev/null +++ b/internal/utils/runner/plan_diff.go @@ -0,0 +1,30 @@ +package runner + +import ( + "fmt" + + tfjson "github.com/hashicorp/terraform-json" +) + +// Produces a diff summary from the given plan +func GetDiff(plan *tfjson.Plan) (bool, string) { + delete := 0 + create := 0 + update := 0 + for _, res := range plan.ResourceChanges { + if res.Change.Actions.Create() { + create++ + } + if res.Change.Actions.Delete() { + delete++ + } + if res.Change.Actions.Update() { + update++ + } + } + diff := false + if create+delete+update > 0 { + diff = true + } + return diff, fmt.Sprintf("Plan: %d to create, %d to update, %d to delete", create, update, delete) +} From 28203890e181afe6c7d555cc44191b180fd6152a Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Tue, 20 Aug 2024 10:44:57 +0200 Subject: [PATCH 03/18] refactor(runner): move clone to FetchRepositoryContent --- internal/runner/{clone.go => repository.go} | 11 ++++++++--- internal/runner/runner.go | 7 +++---- 2 files changed, 11 insertions(+), 7 deletions(-) rename internal/runner/{clone.go => repository.go} (70%) diff --git a/internal/runner/clone.go b/internal/runner/repository.go similarity index 70% rename from internal/runner/clone.go rename to internal/runner/repository.go index 6bff808d..ec14af84 100644 --- a/internal/runner/clone.go +++ b/internal/runner/repository.go @@ -7,19 +7,24 @@ import ( "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/go-git/go-git/v5/plumbing/transport/ssh" + configv1alpha1 "github.com/padok-team/burrito/api/v1alpha1" "github.com/padok-team/burrito/internal/burrito/config" log "github.com/sirupsen/logrus" ) -func clone(repository config.RepositoryConfig, URL, branch, path string) (*git.Repository, error) { - cloneOptions, err := getCloneOptions(repository, URL, branch, path) +// Fetch the content of the specified repository on the specified branch with git clone +// +// TODO: Fetch repo from datastore when repository controller is implemented +func FetchRepositoryContent(repo *configv1alpha1.TerraformRepository, branch string, config config.RepositoryConfig) (*git.Repository, error) { + log.Infof("fetching repository %s on %s branch with git clone", repo.Spec.Repository.Url, branch) + cloneOptions, err := getCloneOptions(config, repo.Spec.Repository.Url, branch) if err != nil { return &git.Repository{}, err } return git.PlainClone(WorkingDir, false, cloneOptions) } -func getCloneOptions(repository config.RepositoryConfig, URL, branch, path string) (*git.CloneOptions, error) { +func getCloneOptions(repository config.RepositoryConfig, URL, branch string) (*git.CloneOptions, error) { authMethod := "ssh" cloneOptions := &git.CloneOptions{ ReferenceName: plumbing.NewBranchReferenceName(branch), diff --git a/internal/runner/runner.go b/internal/runner/runner.go index efd3f2af..b1e2155d 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -195,14 +195,13 @@ func (r *Runner) init() error { } log.Infof("kubernetes resources successfully retrieved") - log.Infof("cloning repository %s %s branch", r.repository.Spec.Repository.Url, r.layer.Spec.Branch) - r.gitRepository, err = clone(r.config.Runner.Repository, r.repository.Spec.Repository.Url, r.layer.Spec.Branch, r.layer.Spec.Path) + r.gitRepository, err = FetchRepositoryContent(r.repository, r.layer.Spec.Branch, r.config.Runner.Repository) if err != nil { r.gitRepository = nil // reset git repository for the caller - log.Errorf("error cloning repository: %s", err) + log.Errorf("error fetching repository: %s", err) return err } - log.Infof("repository cloned successfully") + log.Infof("repository fetched successfully") log.Infof("installing binaries...") err = r.install() From cdc805a2bc0626952a866ea4edd8e909d7a30101 Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Tue, 20 Aug 2024 17:51:56 +0200 Subject: [PATCH 04/18] feat(runner): use tenv library to install binaries --- go.mod | 38 +- go.sum | 796 +++--------------- internal/runner/actions.go | 110 +++ internal/runner/runner.go | 170 +--- internal/runner/terraform/terraform.go | 133 --- internal/runner/terragrunt/terragrunt.go | 244 ------ internal/runner/tools/common.go | 8 + internal/runner/tools/install.go | 101 +++ internal/runner/tools/terraform/terraform.go | 86 ++ .../runner/tools/terragrunt/terragrunt.go | 88 ++ 10 files changed, 533 insertions(+), 1241 deletions(-) create mode 100644 internal/runner/actions.go delete mode 100644 internal/runner/terraform/terraform.go delete mode 100644 internal/runner/terragrunt/terragrunt.go create mode 100644 internal/runner/tools/common.go create mode 100644 internal/runner/tools/install.go create mode 100644 internal/runner/tools/terraform/terraform.go create mode 100644 internal/runner/tools/terragrunt/terragrunt.go diff --git a/go.mod b/go.mod index 4c1a1d4f..53b2e6b5 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/onsi/gomega v1.33.1 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 + github.com/tofuutils/tenv/v3 v3.1.0 google.golang.org/api v0.178.0 k8s.io/apimachinery v0.30.2 k8s.io/client-go v0.30.2 @@ -34,8 +35,14 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect + github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f // indirect + github.com/ProtonMail/gopenpgp/v2 v2.7.5 // indirect + github.com/PuerkitoBio/goquery v1.9.2 // indirect + github.com/agext/levenshtein v1.2.3 // indirect + github.com/andybalholm/cascadia v1.3.2 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/aws/aws-sdk-go-v2 v1.29.0 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 // indirect @@ -53,22 +60,21 @@ require ( github.com/aws/aws-sdk-go-v2/service/ssooidc v1.25.0 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.29.0 // indirect github.com/aws/smithy-go v1.20.2 // indirect - github.com/cloudflare/circl v1.3.7 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/cloudflare/circl v1.3.9 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/emirpasic/gods v1.18.1 // indirect + github.com/fatih/color v1.17.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.5.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-github/v56 v56.0.0 // indirect github.com/google/go-github/v62 v62.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect @@ -77,13 +83,16 @@ require ( github.com/googleapis/gax-go/v2 v2.12.4 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-retryablehttp v0.7.4 // indirect + github.com/hashicorp/hcl/v2 v2.21.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect @@ -93,13 +102,12 @@ require ( github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/skeema/knownhosts v1.2.2 // indirect github.com/sourcegraph/conc v0.3.0 // indirect - github.com/urfave/cli v1.22.4 // indirect github.com/urfave/cli/v2 v2.10.3 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect - github.com/zclconf/go-cty v1.14.0 // indirect + github.com/zclconf/go-cty v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect @@ -107,9 +115,9 @@ require ( go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 // indirect @@ -166,19 +174,19 @@ require ( github.com/prometheus/procfs v0.12.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/cobra v1.7.0 + github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.18.2 github.com/subosito/gotenv v1.6.0 // indirect github.com/xanzy/go-gitlab v0.93.2 go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.24.0 // indirect - golang.org/x/net v0.26.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.20.0 - golang.org/x/sys v0.21.0 // indirect - golang.org/x/term v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.5.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/protobuf v1.34.1 // indirect diff --git a/go.sum b/go.sum index 200d9882..04e888fb 100644 --- a/go.sum +++ b/go.sum @@ -1,282 +1,119 @@ 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.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= cloud.google.com/go v0.112.2 h1:ZaGT6LiG7dBzi6zNOvVZwacaXlmf3lRqnC4DQzqyRQw= cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbDms= cloud.google.com/go/auth v0.3.0 h1:PRyzEpGfx/Z9e8+lHsbkoUVXD0gnu4MNmm7Gp8TQNIs= cloud.google.com/go/auth v0.3.0/go.mod h1:lBv6NKTWp8E3LPzmO1TbiiRKc4drLOfHsgmlH9ogv5w= cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4= cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/iam v1.1.8 h1:r7umDwhj+BQyz0ScZMp4QrGXjSTI3ZINnpgU2nlB/K0= cloud.google.com/go/iam v1.1.8/go.mod h1:GvE6lyMmfxXauzNq8NbgJbeVQNspG+tcdL/W8QO1+zE= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.41.0 h1:RusiwatSu6lHeEXe3kglxakAmAbfV+rhtPqA6i8RBx0= cloud.google.com/go/storage v1.41.0/go.mod h1:J1WCa/Z2FcgdEDuPUY8DxT5I+d9mFKsCepp5vR6Sq80= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v46.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 h1:FDif4R1+UUR+00q6wquyX90K7A8dN+R5E8GEadoP7sU= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2/go.mod h1:aiYBYui4BJ/BJCAIKs92XiPyQfTaBWqvHujDwKb6CBU= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 h1:U2rTu3Ef+7w9FHKIAXM6ZyqF3UOWJZ12zIm8zECAFfg= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc= github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0 h1:jBQA3cKT4L2rWMpgE7Yt3Hwh2aUj8KXjIGLxjHeYNNo= github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0/go.mod h1:4OG6tQ9EOP/MT0NMjDlRzWoVFxfu9rN9B2X+tlSVktg= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0 h1:AifHbc4mg0x9zW52WOpKbsHaDKuRhlI7TVl47thgQ70= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0/go.mod h1:T5RfihdXtBDxt1Ch2wobif3TvzTdumDy29kahv6AV9A= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2 h1:YUUxeiOWgdAQE3pXt2H7QXzZs0q8UBjgRbl56qo8GYM= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2/go.mod h1:dmXQgZuiSubAecswZE+Sm8jkvEa7kQgTPVRvwL/nd0E= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= -github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= -github.com/Azure/go-autorest/autorest v0.11.0/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= -github.com/Azure/go-autorest/autorest v0.11.5/go.mod h1:foo3aIXRQ90zFve3r0QiDsrjGDUwWhKl0ZOQy1CT14k= -github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= -github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= -github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= -github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= -github.com/Azure/go-autorest/autorest/adal v0.9.2/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.1/go.mod h1:ea90/jvmnAwDrSooLH4sRIehEPtG/EPUXavDh31MnA4= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.0/go.mod h1:JljT387FplPzBA31vUcvsetLKF3pec5bdAxjVU4kI2s= -github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc= -github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= -github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= -github.com/Azure/go-autorest/autorest/validation v0.3.0/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= -github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= 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/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg= github.com/ProtonMail/go-crypto v1.1.0-alpha.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= -github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ekTTXpdwKYF8eBlsYsDVoggDAuAjoK66k= +github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw= +github.com/ProtonMail/gopenpgp/v2 v2.7.5 h1:STOY3vgES59gNgoOt2w0nyHBjKViB/qSg7NjbQWPJkA= +github.com/ProtonMail/gopenpgp/v2 v2.7.5/go.mod h1:IhkNEDaxec6NyzSI0PlxapinnwPVIESk8/76da3Ct3g= +github.com/PuerkitoBio/goquery v1.9.2 h1:4/wZksC3KgkQw7SQgkKotmKljk0M6V8TUvA8Wb4yPeE= +github.com/PuerkitoBio/goquery v1.9.2/go.mod h1:GHPCaP0ODyyxqcNoFGYlAprUFH81NuRPd0GX3Zu2Mvk= +github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= +github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss= +github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= -github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= -github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= -github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.30.0/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= -github.com/aws/aws-sdk-go v1.34.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= -github.com/aws/aws-sdk-go v1.53.10 h1:3enP5l5WtezT9Ql+XZqs56JBf5YUd/FEzTCg///OIGY= -github.com/aws/aws-sdk-go v1.53.10/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.53.16 h1:8oZjKQO/ml1WLUZw5hvF7pvYjPf8o9f57Wldoy/q9Qc= -github.com/aws/aws-sdk-go v1.53.16/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go v1.53.21 h1:vAXk3mJQqveg1H3uZaUBaGXrKWa97hc9zBhudsDZugA= github.com/aws/aws-sdk-go v1.53.21/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go-v2 v1.27.0 h1:7bZWKoXhzI+mMR/HjdMx8ZCC5+6fY0lS5tr0bbgiLlo= -github.com/aws/aws-sdk-go-v2 v1.27.0/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= -github.com/aws/aws-sdk-go-v2 v1.27.1 h1:xypCL2owhog46iFxBKKpBcw+bPTX/RJzwNj8uSilENw= -github.com/aws/aws-sdk-go-v2 v1.27.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= github.com/aws/aws-sdk-go-v2 v1.29.0 h1:uMlEecEwgp2gs6CsM6ugquNHr6mg0LHylPBR8u5Ojac= github.com/aws/aws-sdk-go-v2 v1.29.0/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 h1:x6xsQXGSmW6frevwDA+vi/wqhp1ct18mVXYN08/93to= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2/go.mod h1:lPprDr1e6cJdyYeGXnRaJoP4Md+cDBvi2eOj00BlGmg= -github.com/aws/aws-sdk-go-v2/config v1.27.16 h1:knpCuH7laFVGYTNd99Ns5t+8PuRjDn4HnnZK48csipM= -github.com/aws/aws-sdk-go-v2/config v1.27.16/go.mod h1:vutqgRhDUktwSge3hrC3nkuirzkJ4E/mLj5GvI0BQas= -github.com/aws/aws-sdk-go-v2/config v1.27.17 h1:L0JZN7Gh7pT6u5CJReKsLhGKparqNKui+mcpxMXjDZc= -github.com/aws/aws-sdk-go-v2/config v1.27.17/go.mod h1:MzM3balLZeaafYcPz8IihAmam/aCz6niPQI0FdprxW0= github.com/aws/aws-sdk-go-v2/config v1.27.20 h1:oQSn/KNUMV54X0FBEDQQ2ymNfcKyMT81ar8gyvMzzqs= github.com/aws/aws-sdk-go-v2/config v1.27.20/go.mod h1:IbEMotJrWc3Bh7++HXZDlviHZP7kHrkHU3PNl9e17po= -github.com/aws/aws-sdk-go-v2/credentials v1.17.16 h1:7d2QxY83uYl0l58ceyiSpxg9bSbStqBC6BeEeHEchwo= -github.com/aws/aws-sdk-go-v2/credentials v1.17.16/go.mod h1:Ae6li/6Yc6eMzysRL2BXlPYvnrLLBg3D11/AmOjw50k= -github.com/aws/aws-sdk-go-v2/credentials v1.17.17 h1:b3Dk9uxQByS9sc6r0sc2jmxsJKO75eOcb9nNEiaUBLM= -github.com/aws/aws-sdk-go-v2/credentials v1.17.17/go.mod h1:e4khg9iY08LnFK/HXQDWMf9GDaiMari7jWPnXvKAuBU= github.com/aws/aws-sdk-go-v2/credentials v1.17.20 h1:VYTCplAeOeBv5InTtrmF61OIwD4aHKryg3KZ6hf7dsI= github.com/aws/aws-sdk-go-v2/credentials v1.17.20/go.mod h1:ktubcFYvbN8++72jVM9IJoQH6Q2TP+Z7r2VbV1AaESU= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.3 h1:dQLK4TjtnlRGb0czOht2CevZ5l6RSyRWAnKeGd7VAFE= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.3/go.mod h1:TL79f2P6+8Q7dTsILpiVST+AL9lkF6PPGI167Ny0Cjw= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.4 h1:0cSfTYYL9qiRcdi4Dvz+8s3JUgNR2qvbgZkXcwPEEEk= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.4/go.mod h1:Wjn5O9eS7uSi7vlPKt/v0MLTncANn9EMmoDvnzJli6o= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.7 h1:54QUEXjkE1SlxHmRA3gBXA52j/ZSAgdOfAFGv1NsPCY= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.7/go.mod h1:bQRjJsdSMzmo/qbtGeBtPbIMp1IgQ+9R9jYJLm12uJA= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.7 h1:lf/8VTF2cM+N4SLzaYJERKEWAXq8MOMpZfU6wEPWsPk= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.7/go.mod h1:4SjkU7QiqK2M9oozyMzfZ/23LmUY+h3oFqhdeP5OMiI= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.8 h1:RnLB7p6aaFMRfyQkD6ckxR7myCC9SABIqSz4czYUUbU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.8/go.mod h1:XH7dQJd+56wEbP1I4e4Duo+QhSMxNArE8VP7NuUOTeM= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.11 h1:ltkhl3I9ddcRR3Dsy+7bOFFq546O8OYsfNEXVIyuOSE= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.11/go.mod h1:H4D8JoCFNJwnT7U5U8iwgG24n71Fx2I/ZP/18eYFr9g= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.7 h1:4OYVp0705xu8yjdyoWix0r9wPIRXnIzzOoUpQVHIJ/g= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.7/go.mod h1:vd7ESTEvI76T2Na050gODNmNU7+OyKrIKroYTu4ABiI= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.8 h1:jzApk2f58L9yW9q1GEab3BMMFWUkkiZhyrRUtbwUbKU= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.8/go.mod h1:WqO+FftfO3tGePUtQxPXM6iODVfqMwsVMgTbG/ZXIdQ= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.11 h1:+BgX2AY7yV4ggSwa80z/yZIJX+e0jnNxjMLVyfpSXM0= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.11/go.mod h1:DlBATBSDCz30BCdRFldmyLsAzJwi2pdQ+YSdJTHhTUI= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.7 h1:/FUtT3xsoHO3cfh+I/kCbcMCN98QZRsiFet/V8QkWSs= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.7/go.mod h1:MaCAgWpGooQoCWZnMur97rGn5dp350w2+CeiV5406wE= github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.8 h1:jH33S0y5Bo5ZVML62JgZhjd/LrtU+vbR8W7XnIE3Srk= github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.8/go.mod h1:hD5YwHLOy6k7d6kqcn3me1bFWHOtzhaXstMd6BpdB68= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.9 h1:UXqEWQI0n+q0QixzU0yUUQBZXRd5037qdInTIHFTl98= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.9/go.mod h1:xP6Gq6fzGZT8w/ZN+XvGMZ2RU1LeEs7b2yUP5DN8NY4= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.10 h1:pkYC5zTOSPXEYJj56b2SOik9AL432i5MT1YVTQbKOK0= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.10/go.mod h1:/WNsBOlKWZCG3PMh2aSp8vkyyT/clpMZqOtrnIKqGfk= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.9 h1:Wx0rlZoEJR7JwlSZcHnEa7CNjrSIyVxMFWGAaXy4fJY= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.9/go.mod h1:aVMHdE0aHO3v+f/iw01fmXV/5DbfQ3Bi9nN7nd9bE9Y= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.10 h1:7kZqP7akv0enu6ykJhb9OYlw16oOrSy+Epus8o/VqMY= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.10/go.mod h1:gYVF3nM1ApfTRDj9pvdhootBb8WbiIejuqn4w8ruMes= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.13 h1:3A8vxp65nZy6aMlSCBvpIyxIbAN0DOSxaPDZuzasxuU= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.13/go.mod h1:IxJ/pMQ/Y+MDFGo6pQRyqzKKwtGMHb5IWp5PXSQr8dM= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.7 h1:uO5XR6QGBcmPyo2gxofYJLFkcVQ4izOoGDNenlZhTEk= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.7/go.mod h1:feeeAYfAcwTReM6vbwjEyDmiGho+YgBhaFULuXDW8kc= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.8 h1:iQNXVs1vtaq+y9M90M4ZIVNORje0qXTscqHLqoOnFS0= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.8/go.mod h1:yUQPRlWqGG0lfNsmjbRWKVwgilfBtZTOFSLEYALlAig= -github.com/aws/aws-sdk-go-v2/service/s3 v1.54.3 h1:57NtjG+WLims0TxIQbjTqebZUKDM03DfM11ANAekW0s= -github.com/aws/aws-sdk-go-v2/service/s3 v1.54.3/go.mod h1:739CllldowZiPPsDFcJHNF4FXrVxaSGVnZ9Ez9Iz9hc= github.com/aws/aws-sdk-go-v2/service/s3 v1.54.4 h1:4p9SCdZBO0PdEXLTF2fcQuxOEkEiqPQpK824cP2VKRo= github.com/aws/aws-sdk-go-v2/service/s3 v1.54.4/go.mod h1:oSkRFuHVWmUY4Ssk16ErGzBqvYEbvORJFzFXzWhTB2s= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.9 h1:aD7AGQhvPuAxlSUfo0CWU7s6FpkbyykMhGYMvlqTjVs= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.9/go.mod h1:c1qtZUWtygI6ZdvKppzCSXsDOq5I4luJPZ0Ud3juFCA= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.10 h1:ItKVmFwbyb/ZnCWf+nu3XBVmUirpO9eGEQd7urnBA0s= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.10/go.mod h1:5XKooCTi9VB/xZmJDvh7uZ+v3uQ7QdX6diOyhvPA+/w= github.com/aws/aws-sdk-go-v2/service/sso v1.21.0 h1:P0zUA+5liaoNILI/btBBQHC09PFPyRJr+w+Xt9KHKck= github.com/aws/aws-sdk-go-v2/service/sso v1.21.0/go.mod h1:0bmRzdsq9/iNyP02H4UV0ZRjFx6qQBqRvfCJ4trFgjE= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.3 h1:Pav5q3cA260Zqez42T9UhIlsd9QeypszRPwC9LdSSsQ= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.3/go.mod h1:9lmoVDVLz/yUZwLaQ676TK02fhCu4+PgRSmMaKR1ozk= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.4 h1:QMSCYDg3Iyls0KZc/dk3JtS2c1lFfqbmYO10qBPPkJk= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.4/go.mod h1:MZ/PVYU/mRbmSF6WK3ybCYHjA2mig8utVokDEVLDgE0= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.25.0 h1:jPV8U9r3msO9ECm9geW8PGjU/rz8vfPTPmIBbA83W3M= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.25.0/go.mod h1:B3G77bQDCmhp0RV0P/J9Kd4/qsymdWVhzTe3btAtywE= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.10 h1:69tpbPED7jKPyzMcrwSvhWcJ9bPnZsZs18NT40JwM0g= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.10/go.mod h1:0Aqn1MnEuitqfsCNyKsdKLhDUOr4txD/g19EfiUqgws= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.11 h1:HYS0csS7UJxdYRoG+bGgUYrSwVnV3/ece/wHm90TApM= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.11/go.mod h1:QXnthRM35zI92048MMwfFChjFmoufTdhtHmouwNfhhU= github.com/aws/aws-sdk-go-v2/service/sts v1.29.0 h1:dqW4XRwPE/poWSqVntpeXLHzpPK6AOfKmL9QWDYl9aw= github.com/aws/aws-sdk-go-v2/service/sts v1.29.0/go.mod h1:j8+hrxlmLR8ZQo6ytTAls/JFrt5bVisuS6PD8gw2VBw= github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q= github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= -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/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bombsimon/logrusr/v4 v4.1.0 h1:uZNPbwusB0eUXlO8hIUwStE6Lr5bLN6IgYgG+75kuh4= github.com/bombsimon/logrusr/v4 v4.1.0/go.mod h1:pjfHC5e59CvjTBIU3V3sGhFWFAnsnhOR03TRc6im0l8= -github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/bradleyfalzon/ghinstallation/v2 v2.8.0 h1:yUmoVv70H3J4UOqxqsee39+KlXxNEDfTbAp8c/qULKk= -github.com/bradleyfalzon/ghinstallation/v2 v2.8.0/go.mod h1:fmPmvCiBWhJla3zDv9ZTQSZc8AbwyRnGW1yg5ep1Pcs= github.com/bradleyfalzon/ghinstallation/v2 v2.11.0 h1:R9d0v+iobRHSaE4wKUnXFiZp53AL4ED5MzgEMwGTZag= github.com/bradleyfalzon/ghinstallation/v2 v2.11.0/go.mod h1:0LWKQwOHewXO/1acI6TtyE0Xc4ObDb2rFN7eHBAG71M= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/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/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= -github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE= +github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU= 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/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -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/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-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.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -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/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= -github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -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/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= -github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= -github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v0.0.0-20200109221225-a4f60165b7a3/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= -github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= -github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= -github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= @@ -285,32 +122,23 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= -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.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 h1:skJKxRtNmevLqnayafdLe2AsenqRupVmzZSqrvb5caU= -github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= @@ -321,12 +149,6 @@ github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMj github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -334,39 +156,16 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= -github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= -github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-playground/webhooks v5.17.0+incompatible h1:Ea3zLJXlnlIFweIujDxdneq512xO4k9cYwAuZ3VuPJo= github.com/go-playground/webhooks v5.17.0+incompatible/go.mod h1:rMsxoY7bQzIPF9Ni55rTCyLG2af55f9IWgJ1ao3JiZA= -github.com/go-sql-driver/mysql v1.4.1/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-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/gofrs/flock v0.7.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.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= @@ -376,34 +175,21 @@ github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= 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 h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= 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= -github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -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.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/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -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/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -416,340 +202,171 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-containerregistry v0.0.0-20200110202235-f4fb41bf00a3/go.mod h1:2wIuQute9+hhWqvL3vEI7YB0EKluF4WcPzI1eAliazk= github.com/google/go-github/v50 v50.2.0 h1:j2FyongEHlO9nxXLc+LP3wuBSVU9mVxfpdYUexMpIfk= github.com/google/go-github/v50 v50.2.0/go.mod h1:VBY8FB6yPIjrtKhozXv4FQupxKLS6H4m6xFZlT43q8Q= -github.com/google/go-github/v56 v56.0.0 h1:TysL7dMa/r7wsQi44BjqlwaHvwlFlqkK8CtBWCX3gb4= -github.com/google/go-github/v56 v56.0.0/go.mod h1:D8cdcX98YWJvi7TLo7zM4/h8ZTx6u6fwGEkCdisopo0= github.com/google/go-github/v62 v62.0.0 h1:/6mGCaRywZz9MuHyw9gD1CwsbmBX8GWsbFkwMmHdhl4= github.com/google/go-github/v62 v62.0.0/go.mod h1:EMxeUqGJq2xRu9DYBMwel/mr7kZrzUOfQmmpYrZn2a4= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/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= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= -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-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= -github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= -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.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= -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.12.4 h1:9gWcmF85Wvq4ryPFvGFaOgPIs1AQX0d0bcbGw4Z96qg= github.com/googleapis/gax-go/v2 v2.12.4/go.mod h1:KYEYLorsnIGDi/rPC8b5TdlB9kbKoFubselGIoBMCwI= -github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= -github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= -github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/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-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/gruntwork-io/go-commons v0.8.0 h1:k/yypwrPqSeYHevLlEDmvmgQzcyTwrlZGRaxEM6G0ro= -github.com/gruntwork-io/go-commons v0.8.0/go.mod h1:gtp0yTtIBExIZp7vyIV9I0XQkVwiQZze678hvDXof78= -github.com/gruntwork-io/go-commons v0.8.2 h1:2jrQH6ou6GxShXpNmxhVuVktp5E2so115nSESbbDOj0= -github.com/gruntwork-io/go-commons v0.8.2/go.mod h1:aH1kYhkEgb7+RRMDVVKFXBBX0KfECzEhp1UYmU12oO4= github.com/gruntwork-io/go-commons v0.17.1 h1:2KS9wAqrgeOTWj33DSHzDNJ1FCprptWdLFqej+wB8x0= github.com/gruntwork-io/go-commons v0.17.1/go.mod h1:S98JcR7irPD1bcruSvnqupg+WSJEJ6xaM89fpUZVISk= -github.com/gruntwork-io/gruntwork-cli v0.7.0/go.mod h1:jp6Z7NcLF2avpY8v71fBx6hds9eOFPELSuD/VPv7w00= -github.com/gruntwork-io/kubergrunt v0.6.10/go.mod h1:AjSwJPP107t8pihDgJCWCG/RG92Q1oiRXL/OdR6OiaQ= -github.com/gruntwork-io/terratest v0.30.0/go.mod h1:7dNmTD2zDKUEVqfmvcUU5c9mZi+986mcXNzhzqPYPg8= -github.com/gruntwork-io/terratest v0.32.9/go.mod h1:FckR+7ks472IJfSKUPfPvnJfSxV1LKGWGMJ9m/LHegE= 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.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= -github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= 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.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA= github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= -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-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -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.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hc-install v0.6.4 h1:QLqlM56/+SIIGvGcfFiwMY3z5WGXT066suo/v9Km8e0= github.com/hashicorp/hc-install v0.6.4/go.mod h1:05LWLy8TD842OtgcfBbOT0WMoInBMUSHjmDx10zuBIA= 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/hcl/v2 v2.8.2/go.mod h1:bQTN5mpo+jewjJgh8jr0JUguIi7qPHUF6yIfAEN3jqY= +github.com/hashicorp/hcl/v2 v2.21.0 h1:lve4q/o/2rqwYOgUg3y3V2YPyD1/zkCLGjIV74Jit14= +github.com/hashicorp/hcl/v2 v2.21.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= github.com/hashicorp/terraform-exec v0.19.0 h1:FpqZ6n50Tk95mItTSS9BjeOVUb4eg81SpgVtZNNtFSM= github.com/hashicorp/terraform-exec v0.19.0/go.mod h1:tbxUpe3JKruE9Cuf65mycSIT8KiNPZ0FkuTE3H4urQg= github.com/hashicorp/terraform-json v0.17.1 h1:eMfvh/uWggKmY7Pmb3T85u86E2EQg6EQHgyRwf3RkyA= github.com/hashicorp/terraform-json v0.17.1/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/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.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -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/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -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/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8= github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -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.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.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/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/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= -github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= -github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= 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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -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 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/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/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= -github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= github.com/onsi/ginkgo/v2 v2.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU= github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= -github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= -github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= -github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= -github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= -github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/oracle/oci-go-sdk v7.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= -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.0/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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= -github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= -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.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= -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/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= -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.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -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.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -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.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= 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.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= 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/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/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/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/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -757,45 +374,25 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -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.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA= -github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/tofuutils/tenv/v3 v3.1.0 h1:1c5fpzYfoejjMdGFByKAPMMY4YD1jT7Au3x+tAzsbow= +github.com/tofuutils/tenv/v3 v3.1.0/go.mod h1:406l66WcRqwhf6qV6l+RFJ27oWE+jC8RrlfB4gQtzx8= github.com/urfave/cli/v2 v2.10.3 h1:oi571Fxz5aHugfBAJd5nkwSk3fzATXtMlpxdLylSCMo= github.com/urfave/cli/v2 v2.10.3/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/vdemeester/k8s-pkg-credentialprovider v0.0.0-20200107171650-7c61ffa44238/go.mod h1:JwQJCMWpUDqjZrB5jpw0f5VbN7U95zxFy1ZDpoEarGo= -github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/xanzy/go-gitlab v0.93.2 h1:kNNf3BYNYn/Zkig0B89fma12l36VLcYSGu7OnaRlRDg= github.com/xanzy/go-gitlab v0.93.2/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= -github.com/zclconf/go-cty v1.14.0 h1:/Xrd39K7DXbHzlisFP9c4pHao4yyf+/Ug9LEz+Y/yhc= -github.com/zclconf/go-cty v1.14.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.hein.dev/go-version v0.1.0/go.mod h1:WOEm7DWMroRe5GdUgHMvx+Pji5WWIpMuXmK/3foylXs= -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= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ= +github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= @@ -810,223 +407,122 @@ go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucg go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= -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/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -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-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -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-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= -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-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= -golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180811021610-c39426892332/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-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-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-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-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-20200202094626-16171245cfb2/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-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= 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.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= 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-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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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-20190502175342-a43fa875dd82/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-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190812172437-4e8604ab3aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/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-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/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-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= -golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= 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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -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/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/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-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= -golang.org/x/tools v0.0.0-20190812233024-afc3694995b6/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/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-20190920225731-5eefd052ad72/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-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-20191205215504-7b8c8591a921/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-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200113040837-eac381796e91/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= -golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= @@ -1035,32 +531,12 @@ golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSm golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.6.1-0.20190607001116-5213b8090861/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4= -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.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.178.0 h1:yoW/QMI4bRVCHF+NWOTa4cL8MoWL3Jnuc7FlcFF91Ok= google.golang.org/api v0.178.0/go.mod h1:84/k2v8DFpDRebpGcooklv/lais3MEfqpaBLA12gl2U= 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.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-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-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda h1:wu/KJm9KJwpfHWhkkZGohVC6KRrc1oJNr4jwtQMOQXw= google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda/go.mod h1:g2LLCvCeCSir/JJSWosk19BR4NVxGqHUC6rxIRsd7Aw= @@ -1069,14 +545,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 h1:DujSIu+2tC9Ht0aPNA7jgj23Iq8Ewi5sgkQ++wdvonE= google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= 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.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -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.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= @@ -1089,125 +559,47 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi 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/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/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.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= 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.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= 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= -k8s.io/api v0.16.8/go.mod h1:a8EOdYHO8en+YHhPBLiW5q+3RfHTr7wxTqqp7emJ7PM= -k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI= -k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA= -k8s.io/api v0.19.3/go.mod h1:VF+5FT1B74Pw3KxMdKyinLo+zynBaMBiAfGMuldcNDs= -k8s.io/api v0.30.1 h1:kCm/6mADMdbAxmIh0LBjS54nQBE+U4KmbCfIkF5CpJY= -k8s.io/api v0.30.1/go.mod h1:ddbN2C0+0DIiPntan/bye3SW3PdwLa11/0yqwvuRrJM= k8s.io/api v0.30.2 h1:+ZhRj+28QT4UOH+BKznu4CBgPWgkXO7XAvMcMl0qKvI= k8s.io/api v0.30.2/go.mod h1:ULg5g9JvOev2dG0u2hig4Z7tQ2hHIuS+m8MNZ+X6EmI= k8s.io/apiextensions-apiserver v0.30.1 h1:4fAJZ9985BmpJG6PkoxVRpXv9vmPUOVzl614xarePws= k8s.io/apiextensions-apiserver v0.30.1/go.mod h1:R4GuSrlhgq43oRY9sF2IToFh7PVlF1JjfWdoG3pixk4= -k8s.io/apimachinery v0.16.8/go.mod h1:Xk2vD2TRRpuWYLQNM6lT9R7DSFZUYG03SarNkbGrnKE= -k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= -k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= -k8s.io/apimachinery v0.19.3/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= -k8s.io/apimachinery v0.30.1 h1:ZQStsEfo4n65yAdlGTfP/uSHMQSoYzU/oeEbkmF7P2U= -k8s.io/apimachinery v0.30.1/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= k8s.io/apimachinery v0.30.2 h1:fEMcnBj6qkzzPGSVsAZtQThU62SmQ4ZymlXRC5yFSCg= k8s.io/apimachinery v0.30.2/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= -k8s.io/apiserver v0.17.0/go.mod h1:ABM+9x/prjINN6iiffRVNCBR2Wk7uY4z+EtEGZD48cg= -k8s.io/client-go v0.16.8/go.mod h1:WmPuN0yJTKHXoklExKxzo3jSXmr3EnN+65uaTb5VuNs= -k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k= -k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw= -k8s.io/client-go v0.19.3/go.mod h1:+eEMktZM+MG0KO+PTkci8xnbCZHvj9TqR6Q1XDUIJOM= -k8s.io/client-go v0.30.1 h1:uC/Ir6A3R46wdkgCV3vbLyNOYyCJ8oZnjtJGKfytl/Q= -k8s.io/client-go v0.30.1/go.mod h1:wrAqLNs2trwiCH/wxxmT/x3hKVH9PuV0GGW0oDoHVqc= k8s.io/client-go v0.30.2 h1:sBIVJdojUNPDU/jObC+18tXWcTJVcwyqS9diGdWHk50= k8s.io/client-go v0.30.2/go.mod h1:JglKSWULm9xlJLx4KCkfLLQ7XwtlbflV6uFFSHTMgVs= -k8s.io/cloud-provider v0.17.0/go.mod h1:Ze4c3w2C0bRsjkBUoHpFi+qWe3ob1wI2/7cUn+YQIDE= -k8s.io/code-generator v0.0.0-20191121015212-c4c8f8345c7e/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= -k8s.io/code-generator v0.16.8/go.mod h1:wFdrXdVi/UC+xIfLi+4l9elsTT/uEF61IfcN2wOLULQ= -k8s.io/component-base v0.16.8/go.mod h1:Q8UWOWShpP3MZZny4n/15gOncfaaVtc9SbCdkM5MhUE= -k8s.io/component-base v0.17.0/go.mod h1:rKuRAokNMY2nn2A6LP/MiwpoaMRHpfRnrPaUJJj1Yoc= -k8s.io/csi-translation-lib v0.17.0/go.mod h1:HEF7MEz7pOLJCnxabi45IPkhSsE/KmxPQksuCrHKWls= -k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= -k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= -k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= -k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= -k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/legacy-cloud-providers v0.17.0/go.mod h1:DdzaepJ3RtRy+e5YhNtrCYwlgyK87j/5+Yfp0L9Syp8= -k8s.io/sample-controller v0.16.8/go.mod h1:aXlORS1ekU77qhGybB5t3JORDurzDpWgvMYxmCsiuos= -k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= -modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= -modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= -modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= -modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -sigs.k8s.io/aws-iam-authenticator v0.5.1/go.mod h1:yPDLi58MDx1UtCrRMOykLm1IyKKPGHgcGCafcbn2s3E= -sigs.k8s.io/controller-runtime v0.18.3 h1:B5Wmmo8WMWK7izei+2LlXLVDGzMwAHBNLX68lwtlSR4= -sigs.k8s.io/controller-runtime v0.18.3/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg= sigs.k8s.io/controller-runtime v0.18.4 h1:87+guW1zhvuPLh1PHybKdYFLU0YJp4FhJRmiHvm5BZw= sigs.k8s.io/controller-runtime v0.18.4/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= -sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= -sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= -sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= -sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/internal/runner/actions.go b/internal/runner/actions.go new file mode 100644 index 00000000..e0a4d808 --- /dev/null +++ b/internal/runner/actions.go @@ -0,0 +1,110 @@ +package runner + +import ( + "crypto/sha256" + b64 "encoding/base64" + "encoding/json" + "errors" + "os" + "strconv" + + tfjson "github.com/hashicorp/terraform-json" + configv1alpha1 "github.com/padok-team/burrito/api/v1alpha1" + runnerutils "github.com/padok-team/burrito/internal/utils/runner" + log "github.com/sirupsen/logrus" +) + +const PlanArtifact string = "/tmp/plan.out" + +func (r *Runner) plan() (string, error) { + log.Infof("starting terraform plan") + if r.exec == nil { + err := errors.New("terraform or terragrunt binary not installed") + return "", err + } + err := r.exec.Plan(PlanArtifact) + if err != nil { + log.Errorf("error executing terraform plan: %s", err) + return "", err + } + planJsonBytes, err := r.exec.Show(PlanArtifact, "json") + if err != nil { + log.Errorf("error getting terraform plan json: %s", err) + return "", err + } + prettyPlan, err := r.exec.Show(PlanArtifact, "pretty") + if err != nil { + log.Errorf("error getting terraform pretty plan: %s", err) + return "", err + } + log.Infof("sending plan to datastore") + err = r.datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "pretty", prettyPlan) + if err != nil { + log.Errorf("could not put pretty plan in datastore: %s", err) + } + plan := &tfjson.Plan{} + err = json.Unmarshal(planJsonBytes, plan) + if err != nil { + log.Errorf("error parsing terraform json plan: %s", err) + return "", err + } + _, shortDiff := runnerutils.GetDiff(plan) + err = r.datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "json", planJsonBytes) + if err != nil { + log.Errorf("could not put json plan in datastore: %s", err) + } + err = r.datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "short", []byte(shortDiff)) + if err != nil { + log.Errorf("could not put short plan in datastore: %s", err) + } + planBin, err := os.ReadFile(PlanArtifact) + if err != nil { + log.Errorf("could not read plan output: %s", err) + return "", err + } + sum := sha256.Sum256(planBin) + err = r.datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "bin", planBin) + if err != nil { + log.Errorf("could not put plan binary in cache: %s", err) + return "", err + } + log.Infof("terraform plan ran successfully") + return b64.StdEncoding.EncodeToString(sum[:]), nil +} + +func (r *Runner) apply() (string, error) { + log.Infof("starting terraform apply") + if r.exec == nil { + err := errors.New("terraform or terragrunt binary not installed") + return "", err + } + log.Info("getting plan binary in datastore at key") + plan, err := r.datastore.GetPlan(r.layer.Namespace, r.layer.Name, r.run.Spec.Artifact.Run, r.run.Spec.Artifact.Attempt, "bin") + if err != nil { + log.Errorf("could not get plan artifact: %s", err) + return "", err + } + sum := sha256.Sum256(plan) + err = os.WriteFile(PlanArtifact, plan, 0644) + if err != nil { + log.Errorf("could not write plan artifact to disk: %s", err) + return "", err + } + log.Print("launching terraform apply") + if configv1alpha1.GetApplyWithoutPlanArtifactEnabled(r.repository, r.layer) { + log.Infof("applying without reusing plan artifact from previous plan run") + err = r.exec.Apply("") + } else { + err = r.exec.Apply(PlanArtifact) + } + if err != nil { + log.Errorf("error executing terraform apply: %s", err) + return "", err + } + err = r.datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "short", []byte("Apply Successful")) + if err != nil { + log.Errorf("could not put short plan in datastore: %s", err) + } + log.Infof("terraform apply ran successfully") + return b64.StdEncoding.EncodeToString(sum[:]), nil +} diff --git a/internal/runner/runner.go b/internal/runner/runner.go index b1e2155d..6440c3f9 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -2,7 +2,6 @@ package runner import ( "context" - "crypto/sha256" "errors" "fmt" "os" @@ -11,11 +10,7 @@ import ( log "github.com/sirupsen/logrus" - b64 "encoding/base64" - "encoding/json" - "github.com/go-git/go-git/v5" - tfjson "github.com/hashicorp/terraform-json" configv1alpha1 "github.com/padok-team/burrito/api/v1alpha1" "github.com/padok-team/burrito/internal/annotations" "github.com/padok-team/burrito/internal/burrito/config" @@ -28,17 +23,15 @@ import ( clientgoscheme "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/padok-team/burrito/internal/runner/terraform" - "github.com/padok-team/burrito/internal/runner/terragrunt" + "github.com/padok-team/burrito/internal/runner/tools" runnerutils "github.com/padok-team/burrito/internal/utils/runner" ) -const PlanArtifact string = "/tmp/plan.out" const WorkingDir string = "/runner/repository" type Runner struct { config *config.Config - exec TerraformExec + exec tools.TerraformExec datastore datastore.Client client client.Client layer *configv1alpha1.TerraformLayer @@ -47,14 +40,6 @@ type Runner struct { gitRepository *git.Repository } -type TerraformExec interface { - Install() error - Init(string) error - Plan() error - Apply(bool) error - Show(string) ([]byte, error) -} - func New(c *config.Config) *Runner { return &Runner{ config: c, @@ -109,6 +94,19 @@ func (r *Runner) Exec() error { return err } +func newK8SClient() (client.Client, error) { + scheme := runtime.NewScheme() + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + utilruntime.Must(configv1alpha1.AddToScheme(scheme)) + cl, err := client.New(ctrl.GetConfigOrDie(), client.Options{ + Scheme: scheme, + }) + if err != nil { + return nil, err + } + return cl, err +} + func (r *Runner) getResources() error { layer := &configv1alpha1.TerraformLayer{} log.Infof("getting layer %s/%s", r.config.Runner.Layer.Namespace, r.config.Runner.Layer.Name) @@ -145,49 +143,15 @@ func (r *Runner) getResources() error { return nil } -func newK8SClient() (client.Client, error) { - scheme := runtime.NewScheme() - utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - utilruntime.Must(configv1alpha1.AddToScheme(scheme)) - cl, err := client.New(ctrl.GetConfigOrDie(), client.Options{ - Scheme: scheme, - }) - if err != nil { - return nil, err - } - return cl, err -} - -func (r *Runner) install() error { - terraformVersion := configv1alpha1.GetTerraformVersion(r.repository, r.layer) - terraformExec := terraform.NewTerraform(terraformVersion, PlanArtifact, r.config.Runner.RunnerBinaryPath) - terraformRuntime := "terraform" - if configv1alpha1.GetTerragruntEnabled(r.repository, r.layer) { - terraformRuntime = "terragrunt" - } - switch terraformRuntime { - case "terraform": - log.Infof("using terraform") - r.exec = terraformExec - case "terragrunt": - log.Infof("using terragrunt") - r.exec = terragrunt.NewTerragrunt(terraformExec, configv1alpha1.GetTerragruntVersion(r.repository, r.layer), PlanArtifact, r.config.Runner.RunnerBinaryPath) - } - err := r.exec.Install() - if err != nil { - return err - } - return nil -} - func (r *Runner) init() error { - log.Infof("retrieving linked TerraformLayer and TerraformRepository") cl, err := newK8SClient() if err != nil { log.Errorf("error creating kubernetes client: %s", err) return err } r.client = cl + + log.Infof("retrieving linked TerraformLayer and TerraformRepository") err = r.getResources() if err != nil { log.Errorf("error getting kubernetes resources: %s", err) @@ -204,7 +168,12 @@ func (r *Runner) init() error { log.Infof("repository fetched successfully") log.Infof("installing binaries...") - err = r.install() + err = os.Chdir(fmt.Sprintf("%s/%s", WorkingDir, r.layer.Spec.Path)) // need to cd into the repo to detect tf versions + if err != nil { + log.Errorf("error changing directory: %s", err) + return err + } + r.exec, err = tools.InstallBinaries(r.layer, r.repository, r.config.Runner.RunnerBinaryPath) if err != nil { log.Errorf("error installing binaries: %s", err) return err @@ -229,96 +198,3 @@ func (r *Runner) init() error { } return nil } - -func (r *Runner) plan() (string, error) { - log.Infof("starting terraform plan") - if r.exec == nil { - err := errors.New("terraform or terragrunt binary not installed") - return "", err - } - err := r.exec.Plan() - if err != nil { - log.Errorf("error executing terraform plan: %s", err) - return "", err - } - planJsonBytes, err := r.exec.Show("json") - if err != nil { - log.Errorf("error getting terraform plan json: %s", err) - return "", err - } - prettyPlan, err := r.exec.Show("pretty") - if err != nil { - log.Errorf("error getting terraform pretty plan: %s", err) - return "", err - } - log.Infof("sending plan to datastore") - err = r.datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "pretty", prettyPlan) - if err != nil { - log.Errorf("could not put pretty plan in datastore: %s", err) - } - plan := &tfjson.Plan{} - err = json.Unmarshal(planJsonBytes, plan) - if err != nil { - log.Errorf("error parsing terraform json plan: %s", err) - return "", err - } - _, shortDiff := runnerutils.GetDiff(plan) - err = r.datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "json", planJsonBytes) - if err != nil { - log.Errorf("could not put json plan in datastore: %s", err) - } - err = r.datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "short", []byte(shortDiff)) - if err != nil { - log.Errorf("could not put short plan in datastore: %s", err) - } - planBin, err := os.ReadFile(PlanArtifact) - if err != nil { - log.Errorf("could not read plan output: %s", err) - return "", err - } - sum := sha256.Sum256(planBin) - err = r.datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "bin", planBin) - if err != nil { - log.Errorf("could not put plan binary in cache: %s", err) - return "", err - } - log.Infof("terraform plan ran successfully") - return b64.StdEncoding.EncodeToString(sum[:]), nil -} - -func (r *Runner) apply() (string, error) { - log.Infof("starting terraform apply") - if r.exec == nil { - err := errors.New("terraform or terragrunt binary not installed") - return "", err - } - log.Info("getting plan binary in datastore at key") - plan, err := r.datastore.GetPlan(r.layer.Namespace, r.layer.Name, r.run.Spec.Artifact.Run, r.run.Spec.Artifact.Attempt, "bin") - if err != nil { - log.Errorf("could not get plan artifact: %s", err) - return "", err - } - sum := sha256.Sum256(plan) - err = os.WriteFile(PlanArtifact, plan, 0644) - if err != nil { - log.Errorf("could not write plan artifact to disk: %s", err) - return "", err - } - log.Print("launching terraform apply") - if configv1alpha1.GetApplyWithoutPlanArtifactEnabled(r.repository, r.layer) { - log.Infof("applying without reusing plan artifact from previous plan run") - err = r.exec.Apply(false) - } else { - err = r.exec.Apply(true) - } - if err != nil { - log.Errorf("error executing terraform apply: %s", err) - return "", err - } - err = r.datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "short", []byte("Apply Successful")) - if err != nil { - log.Errorf("could not put short plan in datastore: %s", err) - } - log.Infof("terraform apply ran successfully") - return b64.StdEncoding.EncodeToString(sum[:]), nil -} diff --git a/internal/runner/terraform/terraform.go b/internal/runner/terraform/terraform.go deleted file mode 100644 index 48d4dd5b..00000000 --- a/internal/runner/terraform/terraform.go +++ /dev/null @@ -1,133 +0,0 @@ -package terraform - -import ( - "context" - "encoding/json" - "errors" - "io" - "os" - - "github.com/hashicorp/go-version" - install "github.com/hashicorp/hc-install" - "github.com/hashicorp/hc-install/fs" - "github.com/hashicorp/hc-install/product" - "github.com/hashicorp/hc-install/releases" - "github.com/hashicorp/hc-install/src" - "github.com/hashicorp/terraform-exec/tfexec" -) - -type Terraform struct { - exec *tfexec.Terraform - version string - ExecPath string - planArtifactPath string - runnerBinaryPath string -} - -func NewTerraform(version, planArtifactPath string, runnerBinaryPath string) *Terraform { - return &Terraform{ - version: version, - planArtifactPath: planArtifactPath, - runnerBinaryPath: runnerBinaryPath, - } -} - -func (t *Terraform) Install() error { - terraformVersion, err := version.NewVersion(t.version) - if err != nil { - return err - } - i := install.NewInstaller() - version := version.Must(terraformVersion, nil) - fs := fs.ExactVersion{ - Product: product.Terraform, - Version: version, - ExtraPaths: []string{ - t.runnerBinaryPath, - }, - } - releases := releases.ExactVersion{ - Product: product.Terraform, - Version: version, - InstallDir: t.runnerBinaryPath, - } - execPath, err := i.Ensure(context.Background(), []src.Source{ - &fs, - &releases, - }) - if err != nil { - return err - } - t.ExecPath = execPath - return nil -} - -func (t *Terraform) Init(workingDir string) error { - exec, err := tfexec.NewTerraform(workingDir, t.ExecPath) - if err != nil { - return err - } - t.exec = exec - err = t.exec.Init(context.Background(), tfexec.Upgrade(true)) - if err != nil { - return err - } - return nil -} - -func (t *Terraform) Plan() error { - t.verbose() - _, err := t.exec.Plan(context.Background(), tfexec.Out(t.planArtifactPath)) - if err != nil { - return err - } - return nil -} - -func (t *Terraform) Apply(usePlanArtifact bool) error { - t.verbose() - applyOpts := []tfexec.ApplyOption{} - if usePlanArtifact { - applyOpts = append(applyOpts, tfexec.DirOrPlan(t.planArtifactPath)) - } - - err := t.exec.Apply(context.Background(), applyOpts...) - if err != nil { - return err - } - return nil -} - -func (t *Terraform) Show(mode string) ([]byte, error) { - t.silent() - switch mode { - case "json": - planJson, err := t.exec.ShowPlanFile(context.TODO(), t.planArtifactPath) - if err != nil { - return nil, err - } - planJsonBytes, err := json.Marshal(planJson) - if err != nil { - return nil, err - } - return planJsonBytes, nil - case "pretty": - plan, err := t.exec.ShowPlanFileRaw(context.TODO(), t.planArtifactPath) - if err != nil { - return nil, err - } - return []byte(plan), nil - default: - return nil, errors.New("invalid mode") - } -} - -func (t *Terraform) silent() { - t.exec.SetStdout(io.Discard) - t.exec.SetStderr(io.Discard) -} - -func (t *Terraform) verbose() { - t.exec.SetStdout(os.Stdout) - t.exec.SetStderr(os.Stderr) -} diff --git a/internal/runner/terragrunt/terragrunt.go b/internal/runner/terragrunt/terragrunt.go deleted file mode 100644 index 39b6064d..00000000 --- a/internal/runner/terragrunt/terragrunt.go +++ /dev/null @@ -1,244 +0,0 @@ -package terragrunt - -import ( - "crypto/sha256" - "errors" - "fmt" - "io" - "net/http" - "os" - "os/exec" - "path/filepath" - "runtime" - "strings" - - "github.com/padok-team/burrito/internal/runner/terraform" - log "github.com/sirupsen/logrus" -) - -type Terragrunt struct { - execPath string - planArtifactPath string - version string - workingDir string - terraform *terraform.Terraform - runnerBinaryPath string -} - -func NewTerragrunt(terraformExec *terraform.Terraform, terragruntVersion, planArtifactPath string, runnerBinaryPath string) *Terragrunt { - return &Terragrunt{ - version: terragruntVersion, - terraform: terraformExec, - planArtifactPath: planArtifactPath, - runnerBinaryPath: runnerBinaryPath, - } -} - -func verbose(cmd *exec.Cmd) { - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr -} - -func (t *Terragrunt) Install() error { - err := t.terraform.Install() - if err != nil { - return err - } - - path, err := ensureTerragrunt(t.version, t.runnerBinaryPath) - if err != nil { - return err - } - t.execPath = path - return nil -} - -func (t *Terragrunt) getDefaultOptions(command string) []string { - return []string{ - command, - "--terragrunt-tfpath", - t.terraform.ExecPath, - "--terragrunt-working-dir", - t.workingDir, - "-no-color", - } -} - -func (t *Terragrunt) Init(workingDir string) error { - t.workingDir = workingDir - cmd := exec.Command(t.execPath, t.getDefaultOptions("init")...) - verbose(cmd) - cmd.Dir = t.workingDir - if err := cmd.Run(); err != nil { - return err - } - return nil -} - -func (t *Terragrunt) Plan() error { - options := append(t.getDefaultOptions("plan"), "-out", t.planArtifactPath) - cmd := exec.Command(t.execPath, options...) - verbose(cmd) - cmd.Dir = t.workingDir - if err := cmd.Run(); err != nil { - return err - } - return nil -} - -func (t *Terragrunt) Apply(usePlanArtifact bool) error { - options := append(t.getDefaultOptions("apply"), "-auto-approve") - if usePlanArtifact { - options = append(options, t.planArtifactPath) - } - - cmd := exec.Command(t.execPath, options...) - verbose(cmd) - cmd.Dir = t.workingDir - if err := cmd.Run(); err != nil { - return err - } - return nil -} - -func (t *Terragrunt) Show(mode string) ([]byte, error) { - options := t.getDefaultOptions("show") - switch mode { - case "json": - options = append(options, "-json", t.planArtifactPath) - case "pretty": - options = append(options, t.planArtifactPath) - default: - return nil, errors.New("invalid mode") - } - cmd := exec.Command(t.execPath, options...) - cmd.Dir = t.workingDir - output, err := cmd.Output() - - if err != nil { - return nil, err - } - return output, nil -} - -func ensureTerragrunt(version string, runnerBinaryPath string) (string, error) { - files, err := os.ReadDir(runnerBinaryPath) - if err != nil { - return "", err - } - - trustedHash, err := getTerragruntSHA256(version) - if err != nil { - return "", err - } - - for _, file := range files { - if !file.IsDir() { - runnerBinaryFullPath := filepath.Join(runnerBinaryPath, file.Name()) - hash, err := calculateFileSHA256(runnerBinaryFullPath) - if err != nil { - return "", err - } - - if hash == trustedHash { - err = os.Chmod(runnerBinaryFullPath, 0755) - if err != nil { - return "", err - } - log.Infof("Terragrunt binary found at %s, using it", runnerBinaryFullPath) - return filepath.Abs(runnerBinaryFullPath) - } - - } - } - - log.Infof("Terragrunt binary not found, downloading it... (Consider packaging binaries within your runner image to mitigate eventual network expenses)") - path, err := downloadTerragrunt(version, runnerBinaryPath) - log.Infof("Downloaded terragrunt binaries to %s", path) - if err != nil { - return "", err - } - - return path, nil -} - -func calculateFileSHA256(filename string) (string, error) { - file, err := os.Open(filename) - if err != nil { - return "", err - } - defer file.Close() - - hash := sha256.New() - - if _, err := io.Copy(hash, file); err != nil { - return "", err - } - - return fmt.Sprintf("%x", hash.Sum(nil)), nil -} - -func getTerragruntSHA256(version string) (string, error) { - cpuArch := runtime.GOARCH - response, err := http.Get(fmt.Sprintf("https://github.com/gruntwork-io/terragrunt/releases/download/v%s/SHA256SUMS", version)) - if err != nil { - return "", err - } - defer response.Body.Close() - - body, err := io.ReadAll(response.Body) - if err != nil { - return "", err - } - - lines := strings.Split(string(body), "\n") - for _, line := range lines { - parts := strings.Fields(line) - if len(parts) != 2 { - continue - } - sha := parts[0] - filename := parts[1] - - if strings.Contains(filename, fmt.Sprintf("linux_%s", cpuArch)) { - return sha, nil - } - } - - return "", errors.New("could not find a hash for this architecture in SHA256SUMS file") -} - -func downloadTerragrunt(version string, runnerBinaryPath string) (string, error) { - cpuArch := runtime.GOARCH - - url := fmt.Sprintf("https://github.com/gruntwork-io/terragrunt/releases/download/v%s/terragrunt_linux_%s", version, cpuArch) - - response, err := http.Get(url) - if err != nil { - return "", err - } - defer response.Body.Close() - - filename := fmt.Sprintf("%s/terragrunt_%s", runnerBinaryPath, cpuArch) - file, err := os.Create(filename) - if err != nil { - return "", err - } - defer file.Close() - - _, err = io.Copy(file, response.Body) - if err != nil { - return "", err - } - - err = os.Chmod(filename, 0755) - if err != nil { - return "", err - } - - filepath, err := filepath.Abs(filename) - if err != nil { - return "", err - } - return filepath, nil -} diff --git a/internal/runner/tools/common.go b/internal/runner/tools/common.go new file mode 100644 index 00000000..0770acaf --- /dev/null +++ b/internal/runner/tools/common.go @@ -0,0 +1,8 @@ +package tools + +type TerraformExec interface { + Init(string) error + Plan(string) error + Apply(string) error + Show(string, string) ([]byte, error) +} diff --git a/internal/runner/tools/install.go b/internal/runner/tools/install.go new file mode 100644 index 00000000..90e7be0b --- /dev/null +++ b/internal/runner/tools/install.go @@ -0,0 +1,101 @@ +package tools + +import ( + "path/filepath" + + "github.com/hashicorp/hcl/v2/hclparse" + configv1alpha1 "github.com/padok-team/burrito/api/v1alpha1" + tf "github.com/padok-team/burrito/internal/runner/tools/terraform" + tg "github.com/padok-team/burrito/internal/runner/tools/terragrunt" + log "github.com/sirupsen/logrus" + tenvconfig "github.com/tofuutils/tenv/v3/config" + "github.com/tofuutils/tenv/v3/versionmanager" + "github.com/tofuutils/tenv/v3/versionmanager/builder" +) + +type tenvWrapper = versionmanager.VersionManager + +// Creates a `tenv` wrapper for the given tool (Terraform/Terragrunt/OpenTofu) +func newTenvWrapper(binaryPath string, toolName string) (*tenvWrapper, error) { + conf, err := tenvconfig.InitConfigFromEnv() + if err != nil { + return nil, err + } + conf.ForceQuiet = true + conf.RootPath = binaryPath + conf.InitDisplayer(true) + hclParser := hclparse.NewParser() + versionManager := builder.Builders[toolName](&conf, hclParser) + + return &versionManager, nil +} + +// Detect if the tool is already installed and compatible with the version constraint +// Return the version of the tool found locally, or the version to install +func Detect(binaryPath, toolName, versionConstraint string) (string, error) { + tenvWrapper, err := newTenvWrapper(binaryPath, toolName) + if err != nil { + return "", err + } + + if versionConstraint == "" { + log.Infof("no version constraint specified for %s, searching for constraint in codebase", toolName) + versionConstraint, err = tenvWrapper.Resolve("latest-allowed") + if err != nil { + return "", err + } + } + version, err := tenvWrapper.Evaluate(versionConstraint, true) + if err == versionmanager.ErrNoCompatibleLocally { + log.Infof("compatible %s version %s found remotely", toolName, version) + return version, nil + } + if err != nil { + return "", err + } + // TODO: check integrity of local version! + log.Infof("found compatible %s version %s already installed", toolName, version) + + return version, nil +} + +// Install the tool with the given version, do noting if already installed +func Install(binaryPath, toolName, version string) error { + tenvWrapper, err := newTenvWrapper(binaryPath, toolName) + if err != nil { + return err + } + return tenvWrapper.Install(version) +} + +// If not already on the system, install Terraform and, if needed, Terragrunt binaries +func InstallBinaries(layer *configv1alpha1.TerraformLayer, repo *configv1alpha1.TerraformRepository, binaryPath string) (TerraformExec, error) { + terraformVersion := configv1alpha1.GetTerraformVersion(repo, layer) + terraformVersion, err := Detect(binaryPath, "terraform", terraformVersion) + if err != nil { + return nil, err + } + if err := Install(binaryPath, "terraform", terraformVersion); err != nil { + return nil, err + } + tf := &tf.Terraform{ + ExecPath: filepath.Join(binaryPath, "Terraform", terraformVersion, "terraform"), + } + + if configv1alpha1.GetTerragruntEnabled(repo, layer) { + terragruntVersion := configv1alpha1.GetTerragruntVersion(repo, layer) + terragruntVersion, err := Detect(binaryPath, "terragrunt", terragruntVersion) + if err != nil { + return nil, err + } + if err := Install(binaryPath, "terragrunt", terragruntVersion); err != nil { + return nil, err + } + return &tg.Terragrunt{ + ExecPath: filepath.Join(binaryPath, "Terragrunt", terragruntVersion, "terragrunt"), + Terraform: tf, + }, nil + } + + return tf, nil +} diff --git a/internal/runner/tools/terraform/terraform.go b/internal/runner/tools/terraform/terraform.go new file mode 100644 index 00000000..3884b29b --- /dev/null +++ b/internal/runner/tools/terraform/terraform.go @@ -0,0 +1,86 @@ +package terraform + +import ( + "context" + "encoding/json" + "errors" + "io" + "os" + + "github.com/hashicorp/terraform-exec/tfexec" +) + +type Terraform struct { + exec *tfexec.Terraform + ExecPath string +} + +func (t *Terraform) Init(workingDir string) error { + exec, err := tfexec.NewTerraform(workingDir, t.ExecPath) + if err != nil { + return err + } + t.exec = exec + err = t.exec.Init(context.Background(), tfexec.Upgrade(true)) + if err != nil { + return err + } + return nil +} + +func (t *Terraform) Plan(planArtifactPath string) error { + t.verbose() + _, err := t.exec.Plan(context.Background(), tfexec.Out(planArtifactPath)) + if err != nil { + return err + } + return nil +} + +func (t *Terraform) Apply(planArtifactPath string) error { + t.verbose() + applyOpts := []tfexec.ApplyOption{} + if planArtifactPath != "" { + applyOpts = append(applyOpts, tfexec.DirOrPlan(planArtifactPath)) + } + + err := t.exec.Apply(context.Background(), applyOpts...) + if err != nil { + return err + } + return nil +} + +func (t *Terraform) Show(planArtifactPath, mode string) ([]byte, error) { + t.silent() + switch mode { + case "json": + planJson, err := t.exec.ShowPlanFile(context.TODO(), planArtifactPath) + if err != nil { + return nil, err + } + planJsonBytes, err := json.Marshal(planJson) + if err != nil { + return nil, err + } + return planJsonBytes, nil + case "pretty": + plan, err := t.exec.ShowPlanFileRaw(context.TODO(), planArtifactPath) + if err != nil { + return nil, err + } + return []byte(plan), nil + default: + return nil, errors.New("invalid mode") + } +} + +func (t *Terraform) silent() { + t.exec.SetStdout(io.Discard) + t.exec.SetStderr(io.Discard) +} + +func (t *Terraform) verbose() { + t.exec.SetStdout(os.Stdout) + t.exec.SetStderr(os.Stderr) +} diff --git a/internal/runner/tools/terragrunt/terragrunt.go b/internal/runner/tools/terragrunt/terragrunt.go new file mode 100644 index 00000000..78f4d126 --- /dev/null +++ b/internal/runner/tools/terragrunt/terragrunt.go @@ -0,0 +1,88 @@ +package terragrunt + +import ( + "errors" + "os" + "os/exec" + + "github.com/padok-team/burrito/internal/runner/tools/terraform" +) + +type Terragrunt struct { + ExecPath string + WorkingDir string + Terraform *terraform.Terraform +} + +func verbose(cmd *exec.Cmd) { + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr +} + +func (t *Terragrunt) getDefaultOptions(command string) []string { + return []string{ + command, + "--terragrunt-tfpath", + t.Terraform.ExecPath, + "--terragrunt-working-dir", + t.WorkingDir, + "-no-color", + } +} + +func (t *Terragrunt) Init(workingDir string) error { + t.WorkingDir = workingDir + cmd := exec.Command(t.ExecPath, t.getDefaultOptions("init")...) + verbose(cmd) + cmd.Dir = t.WorkingDir + if err := cmd.Run(); err != nil { + return err + } + return nil +} + +func (t *Terragrunt) Plan(planArtifactPath string) error { + options := append(t.getDefaultOptions("plan"), "-out", planArtifactPath) + cmd := exec.Command(t.ExecPath, options...) + verbose(cmd) + cmd.Dir = t.WorkingDir + if err := cmd.Run(); err != nil { + return err + } + return nil +} + +func (t *Terragrunt) Apply(planArtifactPath string) error { + options := append(t.getDefaultOptions("apply"), "-auto-approve") + if planArtifactPath != "" { + options = append(options, planArtifactPath) + } + + cmd := exec.Command(t.ExecPath, options...) + verbose(cmd) + cmd.Dir = t.WorkingDir + if err := cmd.Run(); err != nil { + return err + } + return nil +} + +func (t *Terragrunt) Show(planArtifactPath, mode string) ([]byte, error) { + options := t.getDefaultOptions("show") + switch mode { + case "json": + options = append(options, "-json", planArtifactPath) + case "pretty": + options = append(options, planArtifactPath) + default: + return nil, errors.New("invalid mode") + } + cmd := exec.Command(t.ExecPath, options...) + cmd.Dir = t.WorkingDir + output, err := cmd.Output() + + if err != nil { + return nil, err + } + return output, nil +} From dada9fe2cf92cbba8eaf4bd3150eb878b40cec65 Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Wed, 21 Aug 2024 11:14:11 +0200 Subject: [PATCH 05/18] fix(runner): correct name for hermitcrab env vars --- internal/burrito/config/config.go | 1 + internal/controllers/terraformrun/pod.go | 8 ++------ internal/runner/runner.go | 4 ++-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/internal/burrito/config/config.go b/internal/burrito/config/config.go index e052d75f..86814732 100644 --- a/internal/burrito/config/config.go +++ b/internal/burrito/config/config.go @@ -124,6 +124,7 @@ type Layer struct { type HermitcrabConfig struct { Enabled bool `mapstructure:"enabled"` CertificateSecretName string `mapstructure:"certificateSecretName"` + URL string `mapstructure:"url"` } type ServerConfig struct { diff --git a/internal/controllers/terraformrun/pod.go b/internal/controllers/terraformrun/pod.go index f1e5a6b2..d3ed73da 100644 --- a/internal/controllers/terraformrun/pod.go +++ b/internal/controllers/terraformrun/pod.go @@ -125,11 +125,11 @@ func (r *Reconciler) getPod(run *configv1alpha1.TerraformRun, layer *configv1alp mountCA(&defaultSpec, r.Config.Hermitcrab.CertificateSecretName, "burrito-hermitcrab-ca") defaultSpec.Containers[0].Env = append(defaultSpec.Containers[0].Env, corev1.EnvVar{ - Name: "HERMITCRAB_ENABLED", + Name: "BURRITO_HERMITCRAB_ENABLED", Value: "true", }, corev1.EnvVar{ - Name: "HERMITCRAB_URL", + Name: "BURRITO_HERMITCRAB_URL", Value: fmt.Sprintf("https://burrito-hermitcrab.%s.svc.cluster.local/v1/providers/", r.Config.Controller.MainNamespace), }, ) @@ -315,10 +315,6 @@ func defaultPodSpec(config *config.Config, layer *configv1alpha1.TerraformLayer, Name: "SSH_KNOWN_HOSTS", Value: "/home/burrito/.ssh/known_hosts", }, - { - Name: "BURRITO_DATASTORE_HOSTNAME", - Value: config.Datastore.Hostname, - }, }, }, }, diff --git a/internal/runner/runner.go b/internal/runner/runner.go index 6440c3f9..fb5a33e3 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -180,9 +180,9 @@ func (r *Runner) init() error { } log.Infof("binaries successfully installed") - if os.Getenv("HERMITCRAB_ENABLED") == "true" { + if r.config.Hermitcrab.Enabled { log.Infof("Hermitcrab configuration detected, creating network mirror configuration...") - err := runnerutils.CreateNetworkMirrorConfig(WorkingDir, os.Getenv("HERMITCRAB_URL")) + err := runnerutils.CreateNetworkMirrorConfig(WorkingDir, r.config.Hermitcrab.URL) if err != nil { log.Errorf("error creating network mirror configuration: %s", err) } From bcd055baa3790e8a3d29c88e6251ac289aeffe8f Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Wed, 21 Aug 2024 12:47:26 +0200 Subject: [PATCH 06/18] refactor(runner): rework exec and init functions --- internal/runner/actions.go | 23 +++++- internal/runner/repository.go | 2 +- internal/runner/runner.go | 100 ++++++++++++------------ internal/runner/tools/install.go | 1 + internal/utils/k8s_client.go | 24 ++++++ internal/utils/runner/network_mirror.go | 3 + 6 files changed, 99 insertions(+), 54 deletions(-) create mode 100644 internal/utils/k8s_client.go diff --git a/internal/runner/actions.go b/internal/runner/actions.go index e0a4d808..084b688c 100644 --- a/internal/runner/actions.go +++ b/internal/runner/actions.go @@ -16,7 +16,24 @@ import ( const PlanArtifact string = "/tmp/plan.out" -func (r *Runner) plan() (string, error) { +// Run the `init` command +func (r *Runner) execInit() error { + log.Infof("launching terraform init in %s", r.workingDir) + if r.exec == nil { + err := errors.New("terraform or terragrunt binary not installed") + return err + } + err := r.exec.Init(r.workingDir) + if err != nil { + log.Errorf("error executing terraform init: %s", err) + return err + } + return nil +} + +// Run the `plan` command and save the plan artifact in the datastore +// Returns the sha256 sum of the plan artifact +func (r *Runner) execPlan() (string, error) { log.Infof("starting terraform plan") if r.exec == nil { err := errors.New("terraform or terragrunt binary not installed") @@ -72,7 +89,9 @@ func (r *Runner) plan() (string, error) { return b64.StdEncoding.EncodeToString(sum[:]), nil } -func (r *Runner) apply() (string, error) { +// Run the `apply` command, by default with the plan artifact from the previous plan run +// Returns the sha256 sum of the plan artifact used +func (r *Runner) execApply() (string, error) { log.Infof("starting terraform apply") if r.exec == nil { err := errors.New("terraform or terragrunt binary not installed") diff --git a/internal/runner/repository.go b/internal/runner/repository.go index ec14af84..ceaee10c 100644 --- a/internal/runner/repository.go +++ b/internal/runner/repository.go @@ -21,7 +21,7 @@ func FetchRepositoryContent(repo *configv1alpha1.TerraformRepository, branch str if err != nil { return &git.Repository{}, err } - return git.PlainClone(WorkingDir, false, cloneOptions) + return git.PlainClone(RepositoryDir, false, cloneOptions) } func getCloneOptions(repository config.RepositoryConfig, URL, branch string) (*git.CloneOptions, error) { diff --git a/internal/runner/runner.go b/internal/runner/runner.go index fb5a33e3..907a6a68 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "os" + "path/filepath" "strconv" "time" @@ -15,19 +16,16 @@ import ( "github.com/padok-team/burrito/internal/annotations" "github.com/padok-team/burrito/internal/burrito/config" datastore "github.com/padok-team/burrito/internal/datastore/client" - "k8s.io/apimachinery/pkg/runtime" + "github.com/padok-team/burrito/internal/utils" "k8s.io/apimachinery/pkg/types" - ctrl "sigs.k8s.io/controller-runtime" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - clientgoscheme "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" "github.com/padok-team/burrito/internal/runner/tools" runnerutils "github.com/padok-team/burrito/internal/utils/runner" ) -const WorkingDir string = "/runner/repository" +const RepositoryDir string = "/runner/repository" type Runner struct { config *config.Config @@ -38,6 +36,7 @@ type Runner struct { run *configv1alpha1.TerraformRun repository *configv1alpha1.TerraformRepository gitRepository *git.Repository + workingDir string } func New(c *config.Config) *Runner { @@ -46,6 +45,7 @@ func New(c *config.Config) *Runner { } } +// Entrypoint function of the runner. Initializes the runner, executes the action and updates the layer annotations. func (r *Runner) Exec() error { client := datastore.NewDefaultClient(r.config.Datastore) r.datastore = client @@ -55,58 +55,53 @@ func (r *Runner) Exec() error { err := r.init() if err != nil { log.Errorf("error initializing runner: %s", err) + return err } - if r.gitRepository != nil { - ref, _ := r.gitRepository.Head() - commit = ref.Hash().String() + + err = r.execInit() + if err != nil { + log.Errorf("error executing init: %s", err) + return err } + ann := map[string]string{} + ref, _ := r.gitRepository.Head() + commit := ref.Hash().String() + switch r.config.Runner.Action { case "plan": - sum, err := r.plan() - ann[annotations.LastPlanDate] = time.Now().Format(time.UnixDate) - if err == nil { - ann[annotations.LastPlanCommit] = commit + sum, err := r.execPlan() + if err != nil { + return err } + ann[annotations.LastPlanDate] = time.Now().Format(time.UnixDate) ann[annotations.LastPlanRun] = fmt.Sprintf("%s/%s", r.run.Name, strconv.Itoa(r.run.Status.Retries)) ann[annotations.LastPlanSum] = sum + ann[annotations.LastPlanCommit] = commit + case "apply": - sum, err := r.apply() + sum, err := r.execApply() + if err != nil { + return err + } ann[annotations.LastApplyDate] = time.Now().Format(time.UnixDate) ann[annotations.LastApplySum] = sum - if err == nil { - ann[annotations.LastApplyCommit] = commit - } + ann[annotations.LastApplyCommit] = commit default: - err = errors.New("unrecognized runner action, if this is happening there might be a version mismatch between the controller and runner") + return errors.New("unrecognized runner action, if this is happening there might be a version mismatch between the controller and runner") } + err = annotations.Add(context.TODO(), r.client, r.layer, ann) if err != nil { - log.Errorf("error during runner execution: %s", err) - } - - annotErr := annotations.Add(context.TODO(), r.client, r.layer, ann) - if annotErr != nil { log.Errorf("could not update terraform layer annotations: %s", err) + return err } log.Infof("successfully updated terraform layer annotations") - return err -} - -func newK8SClient() (client.Client, error) { - scheme := runtime.NewScheme() - utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - utilruntime.Must(configv1alpha1.AddToScheme(scheme)) - cl, err := client.New(ctrl.GetConfigOrDie(), client.Options{ - Scheme: scheme, - }) - if err != nil { - return nil, err - } - return cl, err + return nil } +// Retrieve linked resources (layer, run, repository) from the Kubernetes API. func (r *Runner) getResources() error { layer := &configv1alpha1.TerraformLayer{} log.Infof("getting layer %s/%s", r.config.Runner.Layer.Namespace, r.config.Runner.Layer.Name) @@ -119,6 +114,8 @@ func (r *Runner) getResources() error { } log.Infof("successfully retrieved layer") r.layer = layer + r.workingDir = filepath.Join(RepositoryDir, r.layer.Spec.Path) + r.run = &configv1alpha1.TerraformRun{} log.Infof("getting run %s/%s", layer.Namespace, layer.Status.LastRun.Name) err = r.client.Get(context.TODO(), types.NamespacedName{ @@ -129,6 +126,7 @@ func (r *Runner) getResources() error { return err } log.Infof("successfully retrieved run") + repository := &configv1alpha1.TerraformRepository{} log.Infof("getting repo %s/%s", layer.Spec.Repository.Namespace, layer.Spec.Repository.Name) err = r.client.Get(context.TODO(), types.NamespacedName{ @@ -140,16 +138,27 @@ func (r *Runner) getResources() error { } log.Infof("successfully retrieved repo") r.repository = repository + + log.Infof("kubernetes resources successfully retrieved") return nil } +// Initialize the runner's clients, retrieve linked resources (layer, run, repository), +// fetch the repository content, install the binaries and configure Hermitcrab mirror. func (r *Runner) init() error { - cl, err := newK8SClient() + kubeClient, err := utils.NewK8SClient() if err != nil { log.Errorf("error creating kubernetes client: %s", err) return err } - r.client = cl + r.client = kubeClient + + datastoreClient := datastore.NewDefaultClient() + if r.config.Datastore.TLS { + log.Info("using TLS for datastore") + datastoreClient.Scheme = "https" + } + r.datastore = datastoreClient log.Infof("retrieving linked TerraformLayer and TerraformRepository") err = r.getResources() @@ -157,18 +166,16 @@ func (r *Runner) init() error { log.Errorf("error getting kubernetes resources: %s", err) return err } - log.Infof("kubernetes resources successfully retrieved") r.gitRepository, err = FetchRepositoryContent(r.repository, r.layer.Spec.Branch, r.config.Runner.Repository) if err != nil { - r.gitRepository = nil // reset git repository for the caller log.Errorf("error fetching repository: %s", err) return err } log.Infof("repository fetched successfully") log.Infof("installing binaries...") - err = os.Chdir(fmt.Sprintf("%s/%s", WorkingDir, r.layer.Spec.Path)) // need to cd into the repo to detect tf versions + err = os.Chdir(r.workingDir) // need to cd into the repo to detect tf versions if err != nil { log.Errorf("error changing directory: %s", err) return err @@ -178,23 +185,14 @@ func (r *Runner) init() error { log.Errorf("error installing binaries: %s", err) return err } - log.Infof("binaries successfully installed") if r.config.Hermitcrab.Enabled { log.Infof("Hermitcrab configuration detected, creating network mirror configuration...") - err := runnerutils.CreateNetworkMirrorConfig(WorkingDir, r.config.Hermitcrab.URL) + err := runnerutils.CreateNetworkMirrorConfig(RepositoryDir, r.config.Hermitcrab.URL) if err != nil { log.Errorf("error creating network mirror configuration: %s", err) } - log.Infof("network mirror configuration created") } - workingDir := fmt.Sprintf("%s/%s", WorkingDir, r.layer.Spec.Path) - log.Infof("Launching terraform init in %s", workingDir) - err = r.exec.Init(workingDir) - if err != nil { - log.Errorf("error executing terraform init: %s", err) - return err - } return nil } diff --git a/internal/runner/tools/install.go b/internal/runner/tools/install.go index 90e7be0b..89c1bb47 100644 --- a/internal/runner/tools/install.go +++ b/internal/runner/tools/install.go @@ -97,5 +97,6 @@ func InstallBinaries(layer *configv1alpha1.TerraformLayer, repo *configv1alpha1. }, nil } + log.Infof("binaries successfully installed") return tf, nil } diff --git a/internal/utils/k8s_client.go b/internal/utils/k8s_client.go new file mode 100644 index 00000000..e6539302 --- /dev/null +++ b/internal/utils/k8s_client.go @@ -0,0 +1,24 @@ +package utils + +import ( + configv1alpha1 "github.com/padok-team/burrito/api/v1alpha1" + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// Create a new Kubernetes client with standard resources and Burrito CRDs +func NewK8SClient() (client.Client, error) { + scheme := runtime.NewScheme() + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + utilruntime.Must(configv1alpha1.AddToScheme(scheme)) + cl, err := client.New(ctrl.GetConfigOrDie(), client.Options{ + Scheme: scheme, + }) + if err != nil { + return nil, err + } + return cl, err +} diff --git a/internal/utils/runner/network_mirror.go b/internal/utils/runner/network_mirror.go index 9c9d4d64..1ae5c371 100644 --- a/internal/utils/runner/network_mirror.go +++ b/internal/utils/runner/network_mirror.go @@ -3,6 +3,8 @@ package runner import ( "fmt" "os" + + log "github.com/sirupsen/logrus" ) // Creates a network mirror configuration file for Terraform with the given endpoint @@ -22,5 +24,6 @@ provider_installation { if err != nil { return err } + log.Infof("network mirror configuration created") return nil } From bb33736f26f6aba28c90e08a506f65a4573da4ea Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Wed, 21 Aug 2024 17:54:37 +0200 Subject: [PATCH 07/18] refactor(runner): split the Exec function --- cmd/runner/start.go | 1 + internal/burrito/config/config.go | 2 + internal/runner/actions.go | 58 ++++++++-- internal/runner/repository.go | 6 +- internal/runner/runner.go | 173 ++++++++++++------------------ 5 files changed, 124 insertions(+), 116 deletions(-) diff --git a/cmd/runner/start.go b/cmd/runner/start.go index 32543871..813b487c 100644 --- a/cmd/runner/start.go +++ b/cmd/runner/start.go @@ -21,5 +21,6 @@ func buildRunnerStartCmd(app *burrito.App) *cobra.Command { cmd.Flags().StringVar(&app.Config.Runner.SSHKnownHostsConfigMapName, "ssh-known-hosts-cm-name", "burrito-ssh-known-hosts", "configmap name to get known hosts file from") cmd.Flags().StringVar(&app.Config.Runner.RunnerBinaryPath, "runner-binary-path", "/runner/bin", "binary path where the runner can expect to find terraform or terragrunt binaries") + cmd.Flags().StringVar(&app.Config.Runner.RepositoryPath, "repository-path", "/runner/repository", "path where the runner fetches the Git repository to work on") return cmd } diff --git a/internal/burrito/config/config.go b/internal/burrito/config/config.go index 86814732..076a99e8 100644 --- a/internal/burrito/config/config.go +++ b/internal/burrito/config/config.go @@ -114,6 +114,7 @@ type RunnerConfig struct { Repository RepositoryConfig `mapstructure:"repository"` SSHKnownHostsConfigMapName string `mapstructure:"sshKnownHostsConfigMapName"` RunnerBinaryPath string `mapstructure:"runnerBinaryPath"` + RepositoryPath string `mapstructure:"repositoryPath"` } type Layer struct { @@ -223,6 +224,7 @@ func TestConfig() *Config { }, Runner: RunnerConfig{ SSHKnownHostsConfigMapName: "burrito-ssh-known-hosts", + Layer: Layer{}, }, } } diff --git a/internal/runner/actions.go b/internal/runner/actions.go index 084b688c..9126f2b2 100644 --- a/internal/runner/actions.go +++ b/internal/runner/actions.go @@ -1,23 +1,67 @@ package runner import ( + "context" "crypto/sha256" b64 "encoding/base64" "encoding/json" "errors" + "fmt" "os" "strconv" + "time" tfjson "github.com/hashicorp/terraform-json" configv1alpha1 "github.com/padok-team/burrito/api/v1alpha1" + "github.com/padok-team/burrito/internal/annotations" runnerutils "github.com/padok-team/burrito/internal/utils/runner" log "github.com/sirupsen/logrus" ) const PlanArtifact string = "/tmp/plan.out" +// Execute the actions defined in the runner configuration. The runner must +// be initialized. +func (r *Runner) ExecAction() error { + ann := map[string]string{} + ref, _ := r.gitRepository.Head() + commit := ref.Hash().String() + + switch r.config.Runner.Action { + case "plan": + sum, err := r.execPlan() + if err != nil { + return err + } + ann[annotations.LastPlanDate] = time.Now().Format(time.UnixDate) + ann[annotations.LastPlanRun] = fmt.Sprintf("%s/%s", r.run.Name, strconv.Itoa(r.run.Status.Retries)) + ann[annotations.LastPlanSum] = sum + ann[annotations.LastPlanCommit] = commit + + case "apply": + sum, err := r.execApply() + if err != nil { + return err + } + ann[annotations.LastApplyDate] = time.Now().Format(time.UnixDate) + ann[annotations.LastApplySum] = sum + ann[annotations.LastApplyCommit] = commit + default: + return errors.New("unrecognized runner action, if this is happening there might be a version mismatch between the controller and runner") + } + + err := annotations.Add(context.TODO(), r.Client, r.layer, ann) + if err != nil { + log.Errorf("could not update terraform layer annotations: %s", err) + return err + } + log.Infof("successfully updated terraform layer annotations") + + return nil +} + // Run the `init` command -func (r *Runner) execInit() error { +func (r *Runner) ExecInit() error { log.Infof("launching terraform init in %s", r.workingDir) if r.exec == nil { err := errors.New("terraform or terragrunt binary not installed") @@ -55,7 +99,7 @@ func (r *Runner) execPlan() (string, error) { return "", err } log.Infof("sending plan to datastore") - err = r.datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "pretty", prettyPlan) + err = r.Datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "pretty", prettyPlan) if err != nil { log.Errorf("could not put pretty plan in datastore: %s", err) } @@ -66,11 +110,11 @@ func (r *Runner) execPlan() (string, error) { return "", err } _, shortDiff := runnerutils.GetDiff(plan) - err = r.datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "json", planJsonBytes) + err = r.Datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "json", planJsonBytes) if err != nil { log.Errorf("could not put json plan in datastore: %s", err) } - err = r.datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "short", []byte(shortDiff)) + err = r.Datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "short", []byte(shortDiff)) if err != nil { log.Errorf("could not put short plan in datastore: %s", err) } @@ -80,7 +124,7 @@ func (r *Runner) execPlan() (string, error) { return "", err } sum := sha256.Sum256(planBin) - err = r.datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "bin", planBin) + err = r.Datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "bin", planBin) if err != nil { log.Errorf("could not put plan binary in cache: %s", err) return "", err @@ -98,7 +142,7 @@ func (r *Runner) execApply() (string, error) { return "", err } log.Info("getting plan binary in datastore at key") - plan, err := r.datastore.GetPlan(r.layer.Namespace, r.layer.Name, r.run.Spec.Artifact.Run, r.run.Spec.Artifact.Attempt, "bin") + plan, err := r.Datastore.GetPlan(r.layer.Namespace, r.layer.Name, r.run.Spec.Artifact.Run, r.run.Spec.Artifact.Attempt, "bin") if err != nil { log.Errorf("could not get plan artifact: %s", err) return "", err @@ -120,7 +164,7 @@ func (r *Runner) execApply() (string, error) { log.Errorf("error executing terraform apply: %s", err) return "", err } - err = r.datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "short", []byte("Apply Successful")) + err = r.Datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "short", []byte("Apply Successful")) if err != nil { log.Errorf("could not put short plan in datastore: %s", err) } diff --git a/internal/runner/repository.go b/internal/runner/repository.go index ceaee10c..6b8a64be 100644 --- a/internal/runner/repository.go +++ b/internal/runner/repository.go @@ -15,13 +15,13 @@ import ( // Fetch the content of the specified repository on the specified branch with git clone // // TODO: Fetch repo from datastore when repository controller is implemented -func FetchRepositoryContent(repo *configv1alpha1.TerraformRepository, branch string, config config.RepositoryConfig) (*git.Repository, error) { +func FetchRepositoryContent(repo *configv1alpha1.TerraformRepository, branch string, config *config.Config) (*git.Repository, error) { log.Infof("fetching repository %s on %s branch with git clone", repo.Spec.Repository.Url, branch) - cloneOptions, err := getCloneOptions(config, repo.Spec.Repository.Url, branch) + cloneOptions, err := getCloneOptions(config.Runner.Repository, repo.Spec.Repository.Url, branch) if err != nil { return &git.Repository{}, err } - return git.PlainClone(RepositoryDir, false, cloneOptions) + return git.PlainClone(config.Runner.RepositoryPath, false, cloneOptions) } func getCloneOptions(repository config.RepositoryConfig, URL, branch string) (*git.CloneOptions, error) { diff --git a/internal/runner/runner.go b/internal/runner/runner.go index 907a6a68..aebd7081 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -2,36 +2,26 @@ package runner import ( "context" - "errors" - "fmt" "os" "path/filepath" - "strconv" - "time" - - log "github.com/sirupsen/logrus" "github.com/go-git/go-git/v5" configv1alpha1 "github.com/padok-team/burrito/api/v1alpha1" - "github.com/padok-team/burrito/internal/annotations" "github.com/padok-team/burrito/internal/burrito/config" datastore "github.com/padok-team/burrito/internal/datastore/client" + "github.com/padok-team/burrito/internal/runner/tools" "github.com/padok-team/burrito/internal/utils" + runnerutils "github.com/padok-team/burrito/internal/utils/runner" + log "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/padok-team/burrito/internal/runner/tools" - runnerutils "github.com/padok-team/burrito/internal/utils/runner" ) -const RepositoryDir string = "/runner/repository" - type Runner struct { config *config.Config exec tools.TerraformExec - datastore datastore.Client - client client.Client + Datastore datastore.Client + Client client.Client layer *configv1alpha1.TerraformLayer run *configv1alpha1.TerraformRun repository *configv1alpha1.TerraformRepository @@ -45,129 +35,58 @@ func New(c *config.Config) *Runner { } } -// Entrypoint function of the runner. Initializes the runner, executes the action and updates the layer annotations. +// Entrypoint function of the runner. Initializes the runner and executes its action. func (r *Runner) Exec() error { - client := datastore.NewDefaultClient(r.config.Datastore) - r.datastore = client - var commit string - ann := map[string]string{} - - err := r.init() - if err != nil { - log.Errorf("error initializing runner: %s", err) - return err - } - - err = r.execInit() - if err != nil { - log.Errorf("error executing init: %s", err) - return err - } - - ann := map[string]string{} - ref, _ := r.gitRepository.Head() - commit := ref.Hash().String() - - switch r.config.Runner.Action { - case "plan": - sum, err := r.execPlan() - if err != nil { - return err - } - ann[annotations.LastPlanDate] = time.Now().Format(time.UnixDate) - ann[annotations.LastPlanRun] = fmt.Sprintf("%s/%s", r.run.Name, strconv.Itoa(r.run.Status.Retries)) - ann[annotations.LastPlanSum] = sum - ann[annotations.LastPlanCommit] = commit - - case "apply": - sum, err := r.execApply() - if err != nil { - return err - } - ann[annotations.LastApplyDate] = time.Now().Format(time.UnixDate) - ann[annotations.LastApplySum] = sum - ann[annotations.LastApplyCommit] = commit - default: - return errors.New("unrecognized runner action, if this is happening there might be a version mismatch between the controller and runner") - } - - err = annotations.Add(context.TODO(), r.client, r.layer, ann) - if err != nil { - log.Errorf("could not update terraform layer annotations: %s", err) - return err - } - log.Infof("successfully updated terraform layer annotations") - - return nil -} - -// Retrieve linked resources (layer, run, repository) from the Kubernetes API. -func (r *Runner) getResources() error { - layer := &configv1alpha1.TerraformLayer{} - log.Infof("getting layer %s/%s", r.config.Runner.Layer.Namespace, r.config.Runner.Layer.Name) - err := r.client.Get(context.TODO(), types.NamespacedName{ - Namespace: r.config.Runner.Layer.Namespace, - Name: r.config.Runner.Layer.Name, - }, layer) + err := r.initClients() if err != nil { + log.Errorf("error initializing runner clients: %s", err) return err } - log.Infof("successfully retrieved layer") - r.layer = layer - r.workingDir = filepath.Join(RepositoryDir, r.layer.Spec.Path) - r.run = &configv1alpha1.TerraformRun{} - log.Infof("getting run %s/%s", layer.Namespace, layer.Status.LastRun.Name) - err = r.client.Get(context.TODO(), types.NamespacedName{ - Namespace: layer.Namespace, - Name: r.config.Runner.Run, - }, r.run) + err = r.Init() if err != nil { + log.Errorf("error initializing runner: %s", err) return err } - log.Infof("successfully retrieved run") - repository := &configv1alpha1.TerraformRepository{} - log.Infof("getting repo %s/%s", layer.Spec.Repository.Namespace, layer.Spec.Repository.Name) - err = r.client.Get(context.TODO(), types.NamespacedName{ - Namespace: layer.Spec.Repository.Namespace, - Name: layer.Spec.Repository.Name, - }, repository) + err = r.ExecInit() if err != nil { + log.Errorf("error executing init: %s", err) return err } - log.Infof("successfully retrieved repo") - r.repository = repository - log.Infof("kubernetes resources successfully retrieved") - return nil + return r.ExecAction() } -// Initialize the runner's clients, retrieve linked resources (layer, run, repository), -// fetch the repository content, install the binaries and configure Hermitcrab mirror. -func (r *Runner) init() error { +// Initialize the runner clients (kubernetes, datastore). +func (r *Runner) initClients() error { kubeClient, err := utils.NewK8SClient() if err != nil { log.Errorf("error creating kubernetes client: %s", err) return err } - r.client = kubeClient + r.Client = kubeClient datastoreClient := datastore.NewDefaultClient() if r.config.Datastore.TLS { log.Info("using TLS for datastore") datastoreClient.Scheme = "https" } - r.datastore = datastoreClient + r.Datastore = datastoreClient + return nil +} +// Initialize the runner: retrieve linked resources (layer, run, repository), +// fetch the repository content, install the binaries and configure Hermitcrab mirror. +func (r *Runner) Init() error { log.Infof("retrieving linked TerraformLayer and TerraformRepository") - err = r.getResources() + err := r.getResources() if err != nil { log.Errorf("error getting kubernetes resources: %s", err) return err } - r.gitRepository, err = FetchRepositoryContent(r.repository, r.layer.Spec.Branch, r.config.Runner.Repository) + r.gitRepository, err = FetchRepositoryContent(r.repository, r.layer.Spec.Branch, r.config) if err != nil { log.Errorf("error fetching repository: %s", err) return err @@ -188,7 +107,7 @@ func (r *Runner) init() error { if r.config.Hermitcrab.Enabled { log.Infof("Hermitcrab configuration detected, creating network mirror configuration...") - err := runnerutils.CreateNetworkMirrorConfig(RepositoryDir, r.config.Hermitcrab.URL) + err := runnerutils.CreateNetworkMirrorConfig(r.config.Runner.RepositoryPath, r.config.Hermitcrab.URL) if err != nil { log.Errorf("error creating network mirror configuration: %s", err) } @@ -196,3 +115,45 @@ func (r *Runner) init() error { return nil } + +// Retrieve linked resources (layer, run, repository) from the Kubernetes API. +func (r *Runner) getResources() error { + layer := &configv1alpha1.TerraformLayer{} + log.Infof("getting layer %s/%s", r.config.Runner.Layer.Namespace, r.config.Runner.Layer.Name) + err := r.Client.Get(context.TODO(), types.NamespacedName{ + Namespace: r.config.Runner.Layer.Namespace, + Name: r.config.Runner.Layer.Name, + }, layer) + if err != nil { + return err + } + log.Infof("successfully retrieved layer") + r.layer = layer + r.workingDir = filepath.Join(r.config.Runner.RepositoryPath, r.layer.Spec.Path) + + r.run = &configv1alpha1.TerraformRun{} + log.Infof("getting run %s/%s", layer.Namespace, layer.Status.LastRun.Name) + err = r.Client.Get(context.TODO(), types.NamespacedName{ + Namespace: layer.Namespace, + Name: r.config.Runner.Run, + }, r.run) + if err != nil { + return err + } + log.Infof("successfully retrieved run") + + repository := &configv1alpha1.TerraformRepository{} + log.Infof("getting repo %s/%s", layer.Spec.Repository.Namespace, layer.Spec.Repository.Name) + err = r.Client.Get(context.TODO(), types.NamespacedName{ + Namespace: layer.Spec.Repository.Namespace, + Name: layer.Spec.Repository.Name, + }, repository) + if err != nil { + return err + } + log.Infof("successfully retrieved repo") + r.repository = repository + + log.Infof("kubernetes resources successfully retrieved") + return nil +} From 5839ce58b89c922b314bf818400be26204cef480 Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Wed, 21 Aug 2024 17:55:35 +0200 Subject: [PATCH 08/18] test(runner): add first E2E test --- .gitignore | 3 + internal/runner/runner_test.go | 130 +++++++++++++++++++++ internal/runner/testdata/nominal-case.yaml | 22 ++++ internal/runner/testdata/repo.yaml | 8 ++ 4 files changed, 163 insertions(+) create mode 100644 internal/runner/runner_test.go create mode 100644 internal/runner/testdata/nominal-case.yaml create mode 100644 internal/runner/testdata/repo.yaml diff --git a/.gitignore b/.gitignore index 42b16ed2..54e12c11 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,9 @@ Dockerfile.cross .terraform/ +# Artifact generated by tests +test.out/* + # Test binary, build with `go test -c` *.test diff --git a/internal/runner/runner_test.go b/internal/runner/runner_test.go new file mode 100644 index 00000000..193d1ab5 --- /dev/null +++ b/internal/runner/runner_test.go @@ -0,0 +1,130 @@ +package runner_test + +import ( + "context" + "os" + "path/filepath" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + configv1alpha1 "github.com/padok-team/burrito/api/v1alpha1" + "github.com/padok-team/burrito/internal/annotations" + "github.com/padok-team/burrito/internal/burrito/config" + datastore "github.com/padok-team/burrito/internal/datastore/client" + "github.com/padok-team/burrito/internal/runner" + utils "github.com/padok-team/burrito/internal/testing" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment + +func TestRunner(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Runner Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("../..", "manifests", "crds")}, + ErrorIfCRDPathMissing: true, + } + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = configv1alpha1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + Expect(err).NotTo(HaveOccurred()) + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) + utils.LoadResources(k8sClient, "testdata") + + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) +}) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) + +func generateTestConfig() *config.Config { + conf := config.TestConfig() + cwd, _ := os.Getwd() + conf.Runner.RunnerBinaryPath = filepath.Join(cwd, "bin", "tenv-binaries") + conf.Runner.RepositoryPath = filepath.Join(cwd, "test.out", "runner-repository") + _ = os.MkdirAll(conf.Runner.RepositoryPath, 0755) + _ = os.MkdirAll(conf.Runner.RunnerBinaryPath, 0755) + + return conf +} + +// Remove the repository and the binaries directories +func cleanup(conf *config.Config) { + _ = os.RemoveAll(conf.Runner.RepositoryPath) + _ = os.RemoveAll(conf.Runner.RunnerBinaryPath) +} + +func executeRunner(r *runner.Runner) error { + r.Datastore = datastore.NewMockClient() + r.Client = k8sClient + err := r.Init() + if err != nil { + return err + } + err = r.ExecInit() + if err != nil { + return err + } + return r.ExecAction() +} + +var _ = Describe("End-to-End Runner Tests", func() { + var err error + Describe("Nominal Case", func() { + Describe("When Runner is launched for running a Plan", Ordered, func() { + var conf *config.Config + BeforeAll(func() { + conf = generateTestConfig() + conf.Runner.Action = "plan" + conf.Runner.Layer.Name = "nominal-case-1" + conf.Runner.Layer.Namespace = "default" + conf.Runner.Run = "nominal-case-1-plan" + + runner := runner.New(conf) + err = executeRunner(runner) + }) + AfterAll(func() { + cleanup(conf) + }) + It("should not return an error", func() { + Expect(err).NotTo(HaveOccurred()) + }) + It("should have updated the TerraformLayer annotations", func() { + layer := &configv1alpha1.TerraformLayer{} + err := k8sClient.Get(context.TODO(), client.ObjectKey{Namespace: "default", Name: "nominal-case-1"}, layer) + Expect(err).NotTo(HaveOccurred()) + Expect(layer.Annotations).To(HaveKey(annotations.LastPlanDate)) + Expect(layer.Annotations).To(HaveKey(annotations.LastPlanRun)) + Expect(layer.Annotations).To(HaveKey(annotations.LastPlanSum)) + Expect(layer.Annotations).To(HaveKey(annotations.LastPlanCommit)) + }) + }) + }) +}) diff --git a/internal/runner/testdata/nominal-case.yaml b/internal/runner/testdata/nominal-case.yaml new file mode 100644 index 00000000..f3401631 --- /dev/null +++ b/internal/runner/testdata/nominal-case.yaml @@ -0,0 +1,22 @@ +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformLayer +metadata: + name: nominal-case-1 + namespace: default +spec: + branch: main + path: terraform/ + repository: + name: burrito-examples + namespace: default +--- +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformRun +metadata: + name: nominal-case-1-plan + namespace: default +spec: + action: plan + layer: + name: nominal-case-1 + namespace: default diff --git a/internal/runner/testdata/repo.yaml b/internal/runner/testdata/repo.yaml new file mode 100644 index 00000000..43053ace --- /dev/null +++ b/internal/runner/testdata/repo.yaml @@ -0,0 +1,8 @@ +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformRepository +metadata: + name: burrito-examples + namespace: default +spec: + repository: + url: https://github.com/padok-team/burrito-examples From 3c98286c4e5a52d13fec48358c44b76e889c07a6 Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Wed, 21 Aug 2024 18:13:07 +0200 Subject: [PATCH 09/18] test(runner): add tf apply E2E test --- internal/runner/runner_test.go | 28 ++++++++++++++++++++++ internal/runner/testdata/nominal-case.yaml | 13 ++++++++++ internal/runner/tools/install.go | 16 ++++++------- 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/internal/runner/runner_test.go b/internal/runner/runner_test.go index 193d1ab5..0ab90c8f 100644 --- a/internal/runner/runner_test.go +++ b/internal/runner/runner_test.go @@ -126,5 +126,33 @@ var _ = Describe("End-to-End Runner Tests", func() { Expect(layer.Annotations).To(HaveKey(annotations.LastPlanCommit)) }) }) + Describe("When Runner is launched for running an Apply", Ordered, func() { + var conf *config.Config + BeforeAll(func() { + conf = generateTestConfig() + conf.Runner.Action = "apply" + conf.Runner.Layer.Name = "nominal-case-1" + conf.Runner.Layer.Namespace = "default" + conf.Runner.Run = "nominal-case-1-apply" + + runner := runner.New(conf) + err = executeRunner(runner) + }) + AfterAll(func() { + cleanup(conf) + }) + It("should not return an error", func() { + Expect(err).NotTo(HaveOccurred()) + }) + It("should have updated the TerraformLayer annotations", func() { + layer := &configv1alpha1.TerraformLayer{} + err := k8sClient.Get(context.TODO(), client.ObjectKey{Namespace: "default", Name: "nominal-case-1"}, layer) + Expect(err).NotTo(HaveOccurred()) + Expect(layer.Annotations).To(HaveKey(annotations.LastApplyDate)) + Expect(layer.Annotations).To(HaveKey(annotations.LastApplySum)) + Expect(layer.Annotations).To(HaveKey(annotations.LastPlanCommit)) + }) + }) + }) }) diff --git a/internal/runner/testdata/nominal-case.yaml b/internal/runner/testdata/nominal-case.yaml index f3401631..497100ff 100644 --- a/internal/runner/testdata/nominal-case.yaml +++ b/internal/runner/testdata/nominal-case.yaml @@ -9,6 +9,8 @@ spec: repository: name: burrito-examples namespace: default + remediationStrategy: + applyWithoutPlanArtifact: true --- apiVersion: config.terraform.padok.cloud/v1alpha1 kind: TerraformRun @@ -20,3 +22,14 @@ spec: layer: name: nominal-case-1 namespace: default +--- +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformRun +metadata: + name: nominal-case-1-apply + namespace: default +spec: + action: apply + layer: + name: nominal-case-1 + namespace: default diff --git a/internal/runner/tools/install.go b/internal/runner/tools/install.go index 89c1bb47..691c697b 100644 --- a/internal/runner/tools/install.go +++ b/internal/runner/tools/install.go @@ -30,9 +30,9 @@ func newTenvWrapper(binaryPath string, toolName string) (*tenvWrapper, error) { return &versionManager, nil } -// Detect if the tool is already installed and compatible with the version constraint +// detect if the tool is already installed and compatible with the version constraint // Return the version of the tool found locally, or the version to install -func Detect(binaryPath, toolName, versionConstraint string) (string, error) { +func detect(binaryPath, toolName, versionConstraint string) (string, error) { tenvWrapper, err := newTenvWrapper(binaryPath, toolName) if err != nil { return "", err @@ -59,8 +59,8 @@ func Detect(binaryPath, toolName, versionConstraint string) (string, error) { return version, nil } -// Install the tool with the given version, do noting if already installed -func Install(binaryPath, toolName, version string) error { +// install the tool with the given version, do noting if already installed +func install(binaryPath, toolName, version string) error { tenvWrapper, err := newTenvWrapper(binaryPath, toolName) if err != nil { return err @@ -71,11 +71,11 @@ func Install(binaryPath, toolName, version string) error { // If not already on the system, install Terraform and, if needed, Terragrunt binaries func InstallBinaries(layer *configv1alpha1.TerraformLayer, repo *configv1alpha1.TerraformRepository, binaryPath string) (TerraformExec, error) { terraformVersion := configv1alpha1.GetTerraformVersion(repo, layer) - terraformVersion, err := Detect(binaryPath, "terraform", terraformVersion) + terraformVersion, err := detect(binaryPath, "terraform", terraformVersion) if err != nil { return nil, err } - if err := Install(binaryPath, "terraform", terraformVersion); err != nil { + if err := install(binaryPath, "terraform", terraformVersion); err != nil { return nil, err } tf := &tf.Terraform{ @@ -84,11 +84,11 @@ func InstallBinaries(layer *configv1alpha1.TerraformLayer, repo *configv1alpha1. if configv1alpha1.GetTerragruntEnabled(repo, layer) { terragruntVersion := configv1alpha1.GetTerragruntVersion(repo, layer) - terragruntVersion, err := Detect(binaryPath, "terragrunt", terragruntVersion) + terragruntVersion, err := detect(binaryPath, "terragrunt", terragruntVersion) if err != nil { return nil, err } - if err := Install(binaryPath, "terragrunt", terragruntVersion); err != nil { + if err := install(binaryPath, "terragrunt", terragruntVersion); err != nil { return nil, err } return &tg.Terragrunt{ From 2662e1ac4591dbba6070bb04023198ab1709b106 Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Wed, 21 Aug 2024 18:52:55 +0200 Subject: [PATCH 10/18] test(runner): add tests for hermitcrab and resources --- internal/runner/actions.go | 18 +++++----- internal/runner/runner.go | 40 +++++++++++++--------- internal/runner/runner_test.go | 61 ++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 25 deletions(-) diff --git a/internal/runner/actions.go b/internal/runner/actions.go index 9126f2b2..69a27dac 100644 --- a/internal/runner/actions.go +++ b/internal/runner/actions.go @@ -34,7 +34,7 @@ func (r *Runner) ExecAction() error { return err } ann[annotations.LastPlanDate] = time.Now().Format(time.UnixDate) - ann[annotations.LastPlanRun] = fmt.Sprintf("%s/%s", r.run.Name, strconv.Itoa(r.run.Status.Retries)) + ann[annotations.LastPlanRun] = fmt.Sprintf("%s/%s", r.Run.Name, strconv.Itoa(r.Run.Status.Retries)) ann[annotations.LastPlanSum] = sum ann[annotations.LastPlanCommit] = commit @@ -50,7 +50,7 @@ func (r *Runner) ExecAction() error { return errors.New("unrecognized runner action, if this is happening there might be a version mismatch between the controller and runner") } - err := annotations.Add(context.TODO(), r.Client, r.layer, ann) + err := annotations.Add(context.TODO(), r.Client, r.Layer, ann) if err != nil { log.Errorf("could not update terraform layer annotations: %s", err) return err @@ -99,7 +99,7 @@ func (r *Runner) execPlan() (string, error) { return "", err } log.Infof("sending plan to datastore") - err = r.Datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "pretty", prettyPlan) + err = r.Datastore.PutPlan(r.Layer.Namespace, r.Layer.Name, r.Run.Name, strconv.Itoa(r.Run.Status.Retries), "pretty", prettyPlan) if err != nil { log.Errorf("could not put pretty plan in datastore: %s", err) } @@ -110,11 +110,11 @@ func (r *Runner) execPlan() (string, error) { return "", err } _, shortDiff := runnerutils.GetDiff(plan) - err = r.Datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "json", planJsonBytes) + err = r.Datastore.PutPlan(r.Layer.Namespace, r.Layer.Name, r.Run.Name, strconv.Itoa(r.Run.Status.Retries), "json", planJsonBytes) if err != nil { log.Errorf("could not put json plan in datastore: %s", err) } - err = r.Datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "short", []byte(shortDiff)) + err = r.Datastore.PutPlan(r.Layer.Namespace, r.Layer.Name, r.Run.Name, strconv.Itoa(r.Run.Status.Retries), "short", []byte(shortDiff)) if err != nil { log.Errorf("could not put short plan in datastore: %s", err) } @@ -124,7 +124,7 @@ func (r *Runner) execPlan() (string, error) { return "", err } sum := sha256.Sum256(planBin) - err = r.Datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "bin", planBin) + err = r.Datastore.PutPlan(r.Layer.Namespace, r.Layer.Name, r.Run.Name, strconv.Itoa(r.Run.Status.Retries), "bin", planBin) if err != nil { log.Errorf("could not put plan binary in cache: %s", err) return "", err @@ -142,7 +142,7 @@ func (r *Runner) execApply() (string, error) { return "", err } log.Info("getting plan binary in datastore at key") - plan, err := r.Datastore.GetPlan(r.layer.Namespace, r.layer.Name, r.run.Spec.Artifact.Run, r.run.Spec.Artifact.Attempt, "bin") + plan, err := r.Datastore.GetPlan(r.Layer.Namespace, r.Layer.Name, r.Run.Spec.Artifact.Run, r.Run.Spec.Artifact.Attempt, "bin") if err != nil { log.Errorf("could not get plan artifact: %s", err) return "", err @@ -154,7 +154,7 @@ func (r *Runner) execApply() (string, error) { return "", err } log.Print("launching terraform apply") - if configv1alpha1.GetApplyWithoutPlanArtifactEnabled(r.repository, r.layer) { + if configv1alpha1.GetApplyWithoutPlanArtifactEnabled(r.Repository, r.Layer) { log.Infof("applying without reusing plan artifact from previous plan run") err = r.exec.Apply("") } else { @@ -164,7 +164,7 @@ func (r *Runner) execApply() (string, error) { log.Errorf("error executing terraform apply: %s", err) return "", err } - err = r.Datastore.PutPlan(r.layer.Namespace, r.layer.Name, r.run.Name, strconv.Itoa(r.run.Status.Retries), "short", []byte("Apply Successful")) + err = r.Datastore.PutPlan(r.Layer.Namespace, r.Layer.Name, r.Run.Name, strconv.Itoa(r.Run.Status.Retries), "short", []byte("Apply Successful")) if err != nil { log.Errorf("could not put short plan in datastore: %s", err) } diff --git a/internal/runner/runner.go b/internal/runner/runner.go index aebd7081..10757bd5 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -22,9 +22,9 @@ type Runner struct { exec tools.TerraformExec Datastore datastore.Client Client client.Client - layer *configv1alpha1.TerraformLayer - run *configv1alpha1.TerraformRun - repository *configv1alpha1.TerraformRepository + Layer *configv1alpha1.TerraformLayer + Run *configv1alpha1.TerraformRun + Repository *configv1alpha1.TerraformRepository gitRepository *git.Repository workingDir string } @@ -80,13 +80,13 @@ func (r *Runner) initClients() error { // fetch the repository content, install the binaries and configure Hermitcrab mirror. func (r *Runner) Init() error { log.Infof("retrieving linked TerraformLayer and TerraformRepository") - err := r.getResources() + err := r.GetResources() if err != nil { log.Errorf("error getting kubernetes resources: %s", err) return err } - r.gitRepository, err = FetchRepositoryContent(r.repository, r.layer.Spec.Branch, r.config) + r.gitRepository, err = FetchRepositoryContent(r.Repository, r.Layer.Spec.Branch, r.config) if err != nil { log.Errorf("error fetching repository: %s", err) return err @@ -99,7 +99,7 @@ func (r *Runner) Init() error { log.Errorf("error changing directory: %s", err) return err } - r.exec, err = tools.InstallBinaries(r.layer, r.repository, r.config.Runner.RunnerBinaryPath) + r.exec, err = tools.InstallBinaries(r.Layer, r.Repository, r.config.Runner.RunnerBinaryPath) if err != nil { log.Errorf("error installing binaries: %s", err) return err @@ -107,17 +107,24 @@ func (r *Runner) Init() error { if r.config.Hermitcrab.Enabled { log.Infof("Hermitcrab configuration detected, creating network mirror configuration...") - err := runnerutils.CreateNetworkMirrorConfig(r.config.Runner.RepositoryPath, r.config.Hermitcrab.URL) - if err != nil { - log.Errorf("error creating network mirror configuration: %s", err) - } + return r.EnableHermitcrab() } return nil } +// Enable Hermitcrab network mirror configuration. +func (r *Runner) EnableHermitcrab() error { + log.Infof("Hermitcrab configuration detected, creating network mirror configuration...") + err := runnerutils.CreateNetworkMirrorConfig(r.config.Runner.RepositoryPath, r.config.Hermitcrab.URL) + if err != nil { + log.Errorf("error creating network mirror configuration: %s", err) + } + return err +} + // Retrieve linked resources (layer, run, repository) from the Kubernetes API. -func (r *Runner) getResources() error { +func (r *Runner) GetResources() error { layer := &configv1alpha1.TerraformLayer{} log.Infof("getting layer %s/%s", r.config.Runner.Layer.Namespace, r.config.Runner.Layer.Name) err := r.Client.Get(context.TODO(), types.NamespacedName{ @@ -128,19 +135,20 @@ func (r *Runner) getResources() error { return err } log.Infof("successfully retrieved layer") - r.layer = layer - r.workingDir = filepath.Join(r.config.Runner.RepositoryPath, r.layer.Spec.Path) + r.Layer = layer + r.workingDir = filepath.Join(r.config.Runner.RepositoryPath, r.Layer.Spec.Path) - r.run = &configv1alpha1.TerraformRun{} + run := &configv1alpha1.TerraformRun{} log.Infof("getting run %s/%s", layer.Namespace, layer.Status.LastRun.Name) err = r.Client.Get(context.TODO(), types.NamespacedName{ Namespace: layer.Namespace, Name: r.config.Runner.Run, - }, r.run) + }, run) if err != nil { return err } log.Infof("successfully retrieved run") + r.Run = run repository := &configv1alpha1.TerraformRepository{} log.Infof("getting repo %s/%s", layer.Spec.Repository.Namespace, layer.Spec.Repository.Name) @@ -152,7 +160,7 @@ func (r *Runner) getResources() error { return err } log.Infof("successfully retrieved repo") - r.repository = repository + r.Repository = repository log.Infof("kubernetes resources successfully retrieved") return nil diff --git a/internal/runner/runner_test.go b/internal/runner/runner_test.go index 0ab90c8f..b90f23f4 100644 --- a/internal/runner/runner_test.go +++ b/internal/runner/runner_test.go @@ -156,3 +156,64 @@ var _ = Describe("End-to-End Runner Tests", func() { }) }) + +var _ = Describe("Runner Tests", func() { + var err error + Describe("Nominal Case", func() { + Describe("When Hermitcrab is enabled", Ordered, func() { + var conf *config.Config + BeforeAll(func() { + conf = generateTestConfig() + conf.Hermitcrab.Enabled = true + conf.Hermitcrab.URL = "http://hermitcrab.local" + + runner := runner.New(conf) + err = runner.EnableHermitcrab() + }) + AfterAll(func() { + cleanup(conf) + }) + It("should not return an error", func() { + Expect(err).NotTo(HaveOccurred()) + }) + It("should have created a network mirror configuration file that contains the URL", func() { + content, err := os.ReadFile(filepath.Join(conf.Runner.RepositoryPath, "config.tfrc")) + Expect(err).NotTo(HaveOccurred()) + Expect(string(content)).To(ContainSubstring("http://hermitcrab.local")) + }) + It("should have set the TF_CLI_CONFIG_FILE environment variable", func() { + Expect(os.Getenv("TF_CLI_CONFIG_FILE")).NotTo(BeEmpty()) + }) + }) + Describe("When all resources are present (layer, run, repository)", Ordered, func() { + var conf *config.Config + var runnerInstance *runner.Runner + BeforeAll(func() { + conf = generateTestConfig() + conf.Runner.Action = "apply" + conf.Runner.Layer.Name = "nominal-case-1" + conf.Runner.Layer.Namespace = "default" + conf.Runner.Run = "nominal-case-1-apply" + + runnerInstance = runner.New(conf) + runnerInstance.Client = k8sClient + err = runnerInstance.GetResources() + }) + AfterAll(func() { + cleanup(conf) + }) + It("should not return an error", func() { + Expect(err).NotTo(HaveOccurred()) + }) + It("should have retrieved the layer", func() { + Expect(runnerInstance.Layer).NotTo(BeNil()) + }) + It("should have retrieved the run", func() { + Expect(runnerInstance.Run).NotTo(BeNil()) + }) + It("should have retrieved the repository", func() { + Expect(runnerInstance.Repository).NotTo(BeNil()) + }) + }) + }) +}) From 41d462cbd6744a1b85633512b0f16125a87e3109 Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Wed, 21 Aug 2024 20:30:30 +0200 Subject: [PATCH 11/18] test(runner): refactor tests to not be parallel --- internal/runner/runner.go | 11 +++-------- internal/runner/runner_test.go | 15 ++++----------- internal/runner/tools/install.go | 17 +++++++++++++++-- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/internal/runner/runner.go b/internal/runner/runner.go index 10757bd5..fad454e7 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -2,7 +2,6 @@ package runner import ( "context" - "os" "path/filepath" "github.com/go-git/go-git/v5" @@ -86,6 +85,8 @@ func (r *Runner) Init() error { return err } + r.workingDir = filepath.Join(r.config.Runner.RepositoryPath, r.Layer.Spec.Path) + r.gitRepository, err = FetchRepositoryContent(r.Repository, r.Layer.Spec.Branch, r.config) if err != nil { log.Errorf("error fetching repository: %s", err) @@ -94,12 +95,7 @@ func (r *Runner) Init() error { log.Infof("repository fetched successfully") log.Infof("installing binaries...") - err = os.Chdir(r.workingDir) // need to cd into the repo to detect tf versions - if err != nil { - log.Errorf("error changing directory: %s", err) - return err - } - r.exec, err = tools.InstallBinaries(r.Layer, r.Repository, r.config.Runner.RunnerBinaryPath) + r.exec, err = tools.InstallBinaries(r.Layer, r.Repository, r.config.Runner.RunnerBinaryPath, r.workingDir) if err != nil { log.Errorf("error installing binaries: %s", err) return err @@ -136,7 +132,6 @@ func (r *Runner) GetResources() error { } log.Infof("successfully retrieved layer") r.Layer = layer - r.workingDir = filepath.Join(r.config.Runner.RepositoryPath, r.Layer.Spec.Path) run := &configv1alpha1.TerraformRun{} log.Infof("getting run %s/%s", layer.Namespace, layer.Status.LastRun.Name) diff --git a/internal/runner/runner_test.go b/internal/runner/runner_test.go index b90f23f4..490f8528 100644 --- a/internal/runner/runner_test.go +++ b/internal/runner/runner_test.go @@ -95,10 +95,10 @@ func executeRunner(r *runner.Runner) error { return r.ExecAction() } -var _ = Describe("End-to-End Runner Tests", func() { +var _ = Describe("Runner Tests", func() { var err error - Describe("Nominal Case", func() { - Describe("When Runner is launched for running a Plan", Ordered, func() { + Describe("Nominal Case", Ordered, func() { + Describe("End-to-End - When Runner is launched for running a Plan", Ordered, func() { var conf *config.Config BeforeAll(func() { conf = generateTestConfig() @@ -126,7 +126,7 @@ var _ = Describe("End-to-End Runner Tests", func() { Expect(layer.Annotations).To(HaveKey(annotations.LastPlanCommit)) }) }) - Describe("When Runner is launched for running an Apply", Ordered, func() { + Describe("End-to-End - When Runner is launched for running an Apply", Ordered, func() { var conf *config.Config BeforeAll(func() { conf = generateTestConfig() @@ -153,13 +153,6 @@ var _ = Describe("End-to-End Runner Tests", func() { Expect(layer.Annotations).To(HaveKey(annotations.LastPlanCommit)) }) }) - - }) -}) - -var _ = Describe("Runner Tests", func() { - var err error - Describe("Nominal Case", func() { Describe("When Hermitcrab is enabled", Ordered, func() { var conf *config.Config BeforeAll(func() { diff --git a/internal/runner/tools/install.go b/internal/runner/tools/install.go index 691c697b..70c68f6e 100644 --- a/internal/runner/tools/install.go +++ b/internal/runner/tools/install.go @@ -1,6 +1,7 @@ package tools import ( + "os" "path/filepath" "github.com/hashicorp/hcl/v2/hclparse" @@ -69,9 +70,21 @@ func install(binaryPath, toolName, version string) error { } // If not already on the system, install Terraform and, if needed, Terragrunt binaries -func InstallBinaries(layer *configv1alpha1.TerraformLayer, repo *configv1alpha1.TerraformRepository, binaryPath string) (TerraformExec, error) { +func InstallBinaries(layer *configv1alpha1.TerraformLayer, repo *configv1alpha1.TerraformRepository, binaryPath, workingDir string) (TerraformExec, error) { + cwd, err := os.Getwd() + if err != nil { + log.Errorf("error getting current working directory: %s", err) + return nil, err + } + err = os.Chdir(workingDir) // need to cd into the repo to detect tf versions + if err != nil { + log.Errorf("error changing directory: %s", err) + return nil, err + } + defer os.Chdir(cwd) + terraformVersion := configv1alpha1.GetTerraformVersion(repo, layer) - terraformVersion, err := detect(binaryPath, "terraform", terraformVersion) + terraformVersion, err = detect(binaryPath, "terraform", terraformVersion) if err != nil { return nil, err } From 8f4fdd28f0972fcd2512e8f13bbe6f489e184646 Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Thu, 22 Aug 2024 10:54:09 +0200 Subject: [PATCH 12/18] test(runner): add cases for tg and bin versions --- internal/runner/runner_test.go | 142 +++++++++++++++++++-- internal/runner/testdata/nominal-case.yaml | 66 ++++++++++ 2 files changed, 197 insertions(+), 11 deletions(-) diff --git a/internal/runner/runner_test.go b/internal/runner/runner_test.go index 490f8528..4c68c363 100644 --- a/internal/runner/runner_test.go +++ b/internal/runner/runner_test.go @@ -27,6 +27,9 @@ var cfg *rest.Config var k8sClient client.Client var testEnv *envtest.Environment +const binaryPath string = "bin/tenv-binaries" +const repositoryPath string = "test.out/runner-repository" + func TestRunner(t *testing.T) { RegisterFailHandler(Fail) @@ -56,29 +59,38 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) Expect(k8sClient).NotTo(BeNil()) + + // create directory for terraform/terragrunt binaries (to re-use them between tests) + cwd, err := os.Getwd() + Expect(err).NotTo(HaveOccurred()) + err = os.MkdirAll(filepath.Join(cwd, binaryPath), 0755) + Expect(err).NotTo(HaveOccurred()) }) var _ = AfterSuite(func() { By("tearing down the test environment") err := testEnv.Stop() Expect(err).NotTo(HaveOccurred()) + cwd, err := os.Getwd() + Expect(err).NotTo(HaveOccurred()) + err = os.RemoveAll(filepath.Join(cwd, binaryPath)) + Expect(err).NotTo(HaveOccurred()) }) func generateTestConfig() *config.Config { conf := config.TestConfig() - cwd, _ := os.Getwd() - conf.Runner.RunnerBinaryPath = filepath.Join(cwd, "bin", "tenv-binaries") - conf.Runner.RepositoryPath = filepath.Join(cwd, "test.out", "runner-repository") - _ = os.MkdirAll(conf.Runner.RepositoryPath, 0755) - _ = os.MkdirAll(conf.Runner.RunnerBinaryPath, 0755) - + cwd, err := os.Getwd() + Expect(err).NotTo(HaveOccurred()) + conf.Runner.RunnerBinaryPath = filepath.Join(cwd, binaryPath) + conf.Runner.RepositoryPath = filepath.Join(cwd, repositoryPath) + err = os.MkdirAll(conf.Runner.RepositoryPath, 0755) + Expect(err).NotTo(HaveOccurred()) return conf } // Remove the repository and the binaries directories func cleanup(conf *config.Config) { _ = os.RemoveAll(conf.Runner.RepositoryPath) - _ = os.RemoveAll(conf.Runner.RunnerBinaryPath) } func executeRunner(r *runner.Runner) error { @@ -98,7 +110,7 @@ func executeRunner(r *runner.Runner) error { var _ = Describe("Runner Tests", func() { var err error Describe("Nominal Case", Ordered, func() { - Describe("End-to-End - When Runner is launched for running a Plan", Ordered, func() { + Describe("End-to-End - When Runner is launched for running a Terraform plan", Ordered, func() { var conf *config.Config BeforeAll(func() { conf = generateTestConfig() @@ -126,7 +138,7 @@ var _ = Describe("Runner Tests", func() { Expect(layer.Annotations).To(HaveKey(annotations.LastPlanCommit)) }) }) - Describe("End-to-End - When Runner is launched for running an Apply", Ordered, func() { + Describe("End-to-End - When Runner is launched for running a Terraform apply", Ordered, func() { var conf *config.Config BeforeAll(func() { conf = generateTestConfig() @@ -153,6 +165,61 @@ var _ = Describe("Runner Tests", func() { Expect(layer.Annotations).To(HaveKey(annotations.LastPlanCommit)) }) }) + Describe("End-to-End - When Runner is launched for running a Terragrunt plan", Ordered, func() { + var conf *config.Config + BeforeAll(func() { + conf = generateTestConfig() + conf.Runner.Action = "plan" + conf.Runner.Layer.Name = "nominal-case-2" + conf.Runner.Layer.Namespace = "default" + conf.Runner.Run = "nominal-case-2-plan" + + runner := runner.New(conf) + err = executeRunner(runner) + }) + AfterAll(func() { + cleanup(conf) + }) + It("should not return an error", func() { + Expect(err).NotTo(HaveOccurred()) + }) + It("should have updated the TerraformLayer annotations", func() { + layer := &configv1alpha1.TerraformLayer{} + err := k8sClient.Get(context.TODO(), client.ObjectKey{Namespace: "default", Name: "nominal-case-2"}, layer) + Expect(err).NotTo(HaveOccurred()) + Expect(layer.Annotations).To(HaveKey(annotations.LastPlanDate)) + Expect(layer.Annotations).To(HaveKey(annotations.LastPlanRun)) + Expect(layer.Annotations).To(HaveKey(annotations.LastPlanSum)) + Expect(layer.Annotations).To(HaveKey(annotations.LastPlanCommit)) + }) + }) + Describe("End-to-End - When Runner is launched for running Terragrunt apply", Ordered, func() { + var conf *config.Config + BeforeAll(func() { + conf = generateTestConfig() + conf.Runner.Action = "apply" + conf.Runner.Layer.Name = "nominal-case-2" + conf.Runner.Layer.Namespace = "default" + conf.Runner.Run = "nominal-case-2-apply" + + runner := runner.New(conf) + err = executeRunner(runner) + }) + AfterAll(func() { + cleanup(conf) + }) + It("should not return an error", func() { + Expect(err).NotTo(HaveOccurred()) + }) + It("should have updated the TerraformLayer annotations", func() { + layer := &configv1alpha1.TerraformLayer{} + err := k8sClient.Get(context.TODO(), client.ObjectKey{Namespace: "default", Name: "nominal-case-2"}, layer) + Expect(err).NotTo(HaveOccurred()) + Expect(layer.Annotations).To(HaveKey(annotations.LastApplyDate)) + Expect(layer.Annotations).To(HaveKey(annotations.LastApplySum)) + Expect(layer.Annotations).To(HaveKey(annotations.LastPlanCommit)) + }) + }) Describe("When Hermitcrab is enabled", Ordered, func() { var conf *config.Config BeforeAll(func() { @@ -165,6 +232,7 @@ var _ = Describe("Runner Tests", func() { }) AfterAll(func() { cleanup(conf) + _ = os.Unsetenv("TF_CLI_CONFIG_FILE") }) It("should not return an error", func() { Expect(err).NotTo(HaveOccurred()) @@ -183,10 +251,10 @@ var _ = Describe("Runner Tests", func() { var runnerInstance *runner.Runner BeforeAll(func() { conf = generateTestConfig() - conf.Runner.Action = "apply" + conf.Runner.Action = "plan" conf.Runner.Layer.Name = "nominal-case-1" conf.Runner.Layer.Namespace = "default" - conf.Runner.Run = "nominal-case-1-apply" + conf.Runner.Run = "nominal-case-1-plan" runnerInstance = runner.New(conf) runnerInstance.Client = k8sClient @@ -208,5 +276,57 @@ var _ = Describe("Runner Tests", func() { Expect(runnerInstance.Repository).NotTo(BeNil()) }) }) + Describe("When binaries versions are specified in layer", Ordered, func() { + var conf *config.Config + var runnerInstance *runner.Runner + BeforeAll(func() { + conf = generateTestConfig() + conf.Runner.Layer.Name = "nominal-case-2" + conf.Runner.Layer.Namespace = "default" + conf.Runner.Run = "nominal-case-2-plan" + + runnerInstance = runner.New(conf) + runnerInstance.Client = k8sClient + err = runnerInstance.Init() + }) + AfterAll(func() { + cleanup(conf) + }) + It("should not return an error", func() { + Expect(err).NotTo(HaveOccurred()) + }) + It("should have installed Terraform version 1.7.5", func() { + _, err := os.Stat(filepath.Join(conf.Runner.RunnerBinaryPath, "Terraform", "1.7.5", "terraform")) + Expect(err).NotTo(HaveOccurred()) + }) + It("should have installed Terragrunt version 0.66.9", func() { + _, err := os.Stat(filepath.Join(conf.Runner.RunnerBinaryPath, "Terragrunt", "0.66.9", "terragrunt")) + Expect(err).NotTo(HaveOccurred()) + }) + }) + Describe("When Terraform version is specified in the codebase", Ordered, func() { + var conf *config.Config + var runnerInstance *runner.Runner + BeforeAll(func() { + conf = generateTestConfig() + conf.Runner.Layer.Name = "nominal-case-3" + conf.Runner.Layer.Namespace = "default" + conf.Runner.Run = "nominal-case-3-plan" + + runnerInstance = runner.New(conf) + runnerInstance.Client = k8sClient + err = runnerInstance.Init() + }) + AfterAll(func() { + cleanup(conf) + }) + It("should not return an error", func() { + Expect(err).NotTo(HaveOccurred()) + }) + It("should have installed Terraform version 1.7.5", func() { + _, err := os.Stat(filepath.Join(conf.Runner.RunnerBinaryPath, "Terraform", "1.7.5", "terraform")) + Expect(err).NotTo(HaveOccurred()) + }) + }) }) }) diff --git a/internal/runner/testdata/nominal-case.yaml b/internal/runner/testdata/nominal-case.yaml index 497100ff..acefe2f1 100644 --- a/internal/runner/testdata/nominal-case.yaml +++ b/internal/runner/testdata/nominal-case.yaml @@ -33,3 +33,69 @@ spec: layer: name: nominal-case-1 namespace: default +--- +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformLayer +metadata: + name: nominal-case-2 + namespace: default +spec: + branch: main + path: terragrunt/random-pets/test/ + repository: + name: burrito-examples + namespace: default + remediationStrategy: + applyWithoutPlanArtifact: true + terraform: + version: "1.7.5" + terragrunt: + enabled: true + version: "0.66.9" +--- +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformRun +metadata: + name: nominal-case-2-plan + namespace: default +spec: + action: plan + layer: + name: nominal-case-2 + namespace: default +--- +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformRun +metadata: + name: nominal-case-2-apply + namespace: default +spec: + action: apply + layer: + name: nominal-case-2 + namespace: default +--- +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformLayer +metadata: + name: nominal-case-3 + namespace: default +spec: + branch: main + path: terraform-with-version/ + repository: + name: burrito-examples + namespace: default + remediationStrategy: + applyWithoutPlanArtifact: true +--- +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformRun +metadata: + name: nominal-case-3-plan + namespace: default +spec: + action: plan + layer: + name: nominal-case-3 + namespace: default From 24d084a5550a20910aaf6eb241cbb1e179ac63c9 Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Thu, 22 Aug 2024 11:12:21 +0200 Subject: [PATCH 13/18] test(runner): add error cases --- internal/runner/runner_test.go | 115 +++++++++++++++++++++++ internal/runner/testdata/error-case.yaml | 87 +++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 internal/runner/testdata/error-case.yaml diff --git a/internal/runner/runner_test.go b/internal/runner/runner_test.go index 4c68c363..cfa9d2e6 100644 --- a/internal/runner/runner_test.go +++ b/internal/runner/runner_test.go @@ -329,4 +329,119 @@ var _ = Describe("Runner Tests", func() { }) }) }) + Describe("Error Cases", Ordered, func() { + Describe("When repository fails to fetch", Ordered, func() { + var conf *config.Config + BeforeAll(func() { + conf = generateTestConfig() + conf.Runner.Action = "plan" + conf.Runner.Layer.Name = "error-case-1" + conf.Runner.Layer.Namespace = "default" + conf.Runner.Run = "error-case-1-plan" + + runner := runner.New(conf) + err = executeRunner(runner) + }) + AfterAll(func() { + cleanup(conf) + }) + It("should return an error", func() { + Expect(err).To(HaveOccurred()) + }) + It("should not have updated the TerraformLayer annotations", func() { + layer := &configv1alpha1.TerraformLayer{} + err := k8sClient.Get(context.TODO(), client.ObjectKey{Namespace: "default", Name: "error-case-1"}, layer) + Expect(err).NotTo(HaveOccurred()) + Expect(layer.Annotations).NotTo(HaveKey(annotations.LastPlanDate)) + Expect(layer.Annotations).NotTo(HaveKey(annotations.LastPlanSum)) + Expect(layer.Annotations).NotTo(HaveKey(annotations.LastPlanCommit)) + Expect(layer.Annotations).NotTo(HaveKey(annotations.LastPlanRun)) + }) + }) + Describe("When binaries version constraint are malformed", Ordered, func() { + var conf *config.Config + BeforeAll(func() { + conf = generateTestConfig() + conf.Runner.Action = "plan" + conf.Runner.Layer.Name = "error-case-2" + conf.Runner.Layer.Namespace = "default" + conf.Runner.Run = "error-case-2-plan" + + runner := runner.New(conf) + err = executeRunner(runner) + }) + AfterAll(func() { + cleanup(conf) + }) + It("should return an error", func() { + Expect(err).To(HaveOccurred()) + }) + It("should not have updated the TerraformLayer annotations", func() { + layer := &configv1alpha1.TerraformLayer{} + err := k8sClient.Get(context.TODO(), client.ObjectKey{Namespace: "default", Name: "error-case-2"}, layer) + Expect(err).NotTo(HaveOccurred()) + Expect(layer.Annotations).NotTo(HaveKey(annotations.LastPlanDate)) + Expect(layer.Annotations).NotTo(HaveKey(annotations.LastPlanSum)) + Expect(layer.Annotations).NotTo(HaveKey(annotations.LastPlanCommit)) + Expect(layer.Annotations).NotTo(HaveKey(annotations.LastPlanRun)) + }) + }) + Describe("When binaries version does not exist", Ordered, func() { + var conf *config.Config + BeforeAll(func() { + conf = generateTestConfig() + conf.Runner.Action = "plan" + conf.Runner.Layer.Name = "error-case-3" + conf.Runner.Layer.Namespace = "default" + conf.Runner.Run = "error-case-3-plan" + + runner := runner.New(conf) + err = executeRunner(runner) + }) + AfterAll(func() { + cleanup(conf) + }) + It("should return an error", func() { + Expect(err).To(HaveOccurred()) + }) + It("should not have updated the TerraformLayer annotations", func() { + layer := &configv1alpha1.TerraformLayer{} + err := k8sClient.Get(context.TODO(), client.ObjectKey{Namespace: "default", Name: "error-case-3"}, layer) + Expect(err).NotTo(HaveOccurred()) + Expect(layer.Annotations).NotTo(HaveKey(annotations.LastPlanDate)) + Expect(layer.Annotations).NotTo(HaveKey(annotations.LastPlanSum)) + Expect(layer.Annotations).NotTo(HaveKey(annotations.LastPlanCommit)) + Expect(layer.Annotations).NotTo(HaveKey(annotations.LastPlanRun)) + }) + }) + Describe("When linked resources do not exist", Ordered, func() { + var conf *config.Config + var runnerInstance *runner.Runner + BeforeAll(func() { + conf = generateTestConfig() + conf.Runner.Action = "plan" + conf.Runner.Layer.Name = "non-existent-layer" + conf.Runner.Layer.Namespace = "default" + conf.Runner.Run = "non-existent-run" + + runnerInstance = runner.New(conf) + err = executeRunner(runnerInstance) + }) + AfterAll(func() { + cleanup(conf) + }) + It("should return an error", func() { + Expect(err).To(HaveOccurred()) + }) + It("should have a nil layer", func() { + Expect(runnerInstance.Layer).To(BeNil()) + }) + It("should have a nil run", func() { + Expect(runnerInstance.Run).To(BeNil()) + }) + It("should have a nil repository", func() { + Expect(runnerInstance.Repository).To(BeNil()) + }) + }) + }) }) diff --git a/internal/runner/testdata/error-case.yaml b/internal/runner/testdata/error-case.yaml new file mode 100644 index 00000000..a6f126c7 --- /dev/null +++ b/internal/runner/testdata/error-case.yaml @@ -0,0 +1,87 @@ +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformRepository +metadata: + name: error-case-1 + namespace: default +spec: + repository: + url: https://github.com/padok-team/burrito-examples-non-existent-repo +--- +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformLayer +metadata: + name: error-case-1 + namespace: default +spec: + branch: main + path: terraform/ + repository: + name: error-case-1 + namespace: default + remediationStrategy: + applyWithoutPlanArtifact: true +--- +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformRun +metadata: + name: error-case-1-plan + namespace: default +spec: + action: plan + layer: + name: error-case-1 + namespace: default +--- +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformLayer +metadata: + name: error-case-2 + namespace: default +spec: + branch: main + path: terraform/ + repository: + name: burrito-examples + namespace: default + remediationStrategy: + applyWithoutPlanArtifact: true + terraform: + version: "invalid version constraint" +--- +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformRun +metadata: + name: error-case-2-plan + namespace: default +spec: + action: plan + layer: + name: error-case-2 + namespace: default +--- +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformLayer +metadata: + name: error-case-3 + namespace: default +spec: + branch: main + path: terraform/ + repository: + name: burrito-examples + namespace: default + remediationStrategy: + applyWithoutPlanArtifact: true + terraform: + version: "1.7.4242" +--- +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformRun +metadata: + name: error-case-3-plan + namespace: default +spec: + action: plan + layer: + name: error-case-2 + namespace: default From 4cd93a019b1f1f9147b105f03f8e4e2070e5c582 Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Thu, 22 Aug 2024 11:15:46 +0200 Subject: [PATCH 14/18] fix(runner): check error from defered os.Chdir --- internal/runner/tools/install.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/runner/tools/install.go b/internal/runner/tools/install.go index 70c68f6e..2e74cdad 100644 --- a/internal/runner/tools/install.go +++ b/internal/runner/tools/install.go @@ -81,7 +81,12 @@ func InstallBinaries(layer *configv1alpha1.TerraformLayer, repo *configv1alpha1. log.Errorf("error changing directory: %s", err) return nil, err } - defer os.Chdir(cwd) + defer func() { + err := os.Chdir(cwd) + if err != nil { + log.Errorf("error changing directory back to %s: %s", cwd, err) + } + }() terraformVersion := configv1alpha1.GetTerraformVersion(repo, layer) terraformVersion, err = detect(binaryPath, "terraform", terraformVersion) From 4d141a52b11afd9016d60a68d3479f11569477ae Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Thu, 22 Aug 2024 11:25:03 +0200 Subject: [PATCH 15/18] chore(deps): run go mod tidy after runner refactor --- go.mod | 5 ++--- go.sum | 8 ++++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 53b2e6b5..4c510e3f 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/ghodss/yaml v1.0.0 github.com/gruntwork-io/go-commons v0.17.1 github.com/hashicorp/go-multierror v1.1.1 + github.com/hashicorp/hcl/v2 v2.21.0 github.com/hashicorp/terraform-json v0.17.1 github.com/onsi/ginkgo/v2 v2.17.3 github.com/onsi/gomega v1.33.1 @@ -85,7 +86,6 @@ require ( github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-retryablehttp v0.7.4 // indirect - github.com/hashicorp/hcl/v2 v2.21.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect @@ -149,8 +149,7 @@ require ( github.com/google/go-github/v50 v50.2.0 github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/go-version v1.7.0 - github.com/hashicorp/hc-install v0.6.4 + github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/terraform-exec v0.19.0 github.com/imdario/mergo v0.3.15 // indirect diff --git a/go.sum b/go.sum index 04e888fb..69ebe0c8 100644 --- a/go.sum +++ b/go.sum @@ -166,6 +166,8 @@ github.com/go-playground/webhooks v5.17.0+incompatible h1:Ea3zLJXlnlIFweIujDxdne github.com/go-playground/webhooks v5.17.0+incompatible/go.mod h1:rMsxoY7bQzIPF9Ni55rTCyLG2af55f9IWgJ1ao3JiZA= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= +github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= @@ -239,8 +241,8 @@ github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZn github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.6.4 h1:QLqlM56/+SIIGvGcfFiwMY3z5WGXT066suo/v9Km8e0= -github.com/hashicorp/hc-install v0.6.4/go.mod h1:05LWLy8TD842OtgcfBbOT0WMoInBMUSHjmDx10zuBIA= +github.com/hashicorp/hc-install v0.6.0 h1:fDHnU7JNFNSQebVKYhHZ0va1bC6SrPQ8fpebsvNr2w4= +github.com/hashicorp/hc-install v0.6.0/go.mod h1:10I912u3nntx9Umo1VAeYPUUuehk0aRQJYpMwbX5wQA= 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/hcl/v2 v2.21.0 h1:lve4q/o/2rqwYOgUg3y3V2YPyD1/zkCLGjIV74Jit14= @@ -393,6 +395,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ= github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= +github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= From 6bca8767e515285a2f1943a03055032fe6e0d1f2 Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Thu, 22 Aug 2024 14:56:30 +0200 Subject: [PATCH 16/18] docs(runner): update docs for tenv and runner refacto --- docs/examples/terraform-layer.yaml | 2 -- docs/guides/iac-drift-detection.md | 10 ++++------ docs/guides/pr-mr-workflow.md | 4 ++-- docs/operator-manual/architecture.md | 7 +++---- docs/user-guide/terraform-version.md | 18 ++++++++++++------ 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/docs/examples/terraform-layer.yaml b/docs/examples/terraform-layer.yaml index b3572d1a..612d737b 100644 --- a/docs/examples/terraform-layer.yaml +++ b/docs/examples/terraform-layer.yaml @@ -11,5 +11,3 @@ spec: repository: name: my-repository namespace: burrito-project - terraform: - version: 1.3.1 diff --git a/docs/guides/iac-drift-detection.md b/docs/guides/iac-drift-detection.md index a931ac9a..76d9cbea 100644 --- a/docs/guides/iac-drift-detection.md +++ b/docs/guides/iac-drift-detection.md @@ -72,14 +72,14 @@ Here is the content of the `TerraformRepository` resource that you have created apiVersion: config.terraform.padok.cloud/v1alpha1 kind: TerraformRepository metadata: - name: my-repo + name: my-repository namespace: burrito-project spec: repository: - url: git@github.com:padok-team/burrito-examples.git + url: https://github.com/padok-team/burrito-examples ``` -Create a `TerraformLayer` resource in the `burrito-system` namespace, referencing the `TerraformRepository` you just created. For now, the autoApply is set to false, so the layer will only plan the Terraform code and not apply it. +Create a `TerraformLayer` resource in the `burrito-system` namespace, referencing the `TerraformRepository` you just created. For now, the `autoApply` is set to false, so the layer will only plan the Terraform code and not apply it. ```bash kubectl apply -f https://raw.githubusercontent.com/padok-team/burrito/main/docs/examples/terraform-layer.yaml @@ -99,8 +99,6 @@ spec: repository: name: my-repository namespace: burrito-project - terraform: - version: 1.3.1 ``` Check that your Terraform code is being planned by Burrito: @@ -135,7 +133,7 @@ kubectl port-forward svc/burrito-server -n burrito-system 8080:80 ![Burrito drift example](../assets/demo/drift-example.png) -Activate the autoApply feature by updating the `TerraformLayer` resource: +Activate the `autoApply` feature by updating the `TerraformLayer` resource: ```bash kubectl patch tfl my-layer -n burrito-project --type merge --patch '{"spec":{"remediationStrategy":{"autoApply":true}}}' diff --git a/docs/guides/pr-mr-workflow.md b/docs/guides/pr-mr-workflow.md index 0572e95d..bdb1db66 100644 --- a/docs/guides/pr-mr-workflow.md +++ b/docs/guides/pr-mr-workflow.md @@ -44,7 +44,7 @@ Configure a webhook in your GitHub repository to point to the exposed `burrito-s kind: Secret metadata: name: burrito-webhook-secret - namespace: burrito + namespace: burrito-system type: Opaque stringData: burrito-webhook-secret: @@ -86,7 +86,7 @@ my-layer-pr-1-rxvrt ApplyNeeded my-repository update-tf-code terraform The Burrito server should have commented on the PR/MR with the plan output. You can check the comments on the PR/MR to see the plan output. -![Pul request comment demo](../assets/demo/pr-demo.png) +![Pull request comment demo](../assets/demo/pr-demo.png) Set the `autoApply` field to `true` in the TerraformLayer resource to automatically apply the Terraform code upon merging the PR/MR. diff --git a/docs/operator-manual/architecture.md b/docs/operator-manual/architecture.md index 63a6fc71..1922b2f7 100644 --- a/docs/operator-manual/architecture.md +++ b/docs/operator-manual/architecture.md @@ -86,9 +86,8 @@ The `TerraformRun` controller also creates and deletes the [Kubernetes leases](h ### The runners -The runner image implementation heavily relies on Golang libraries provided by Hashicorp such as [`tfexec`](https://github.com/hashicorp/terraform-exec) and [`hc-install`](https://github.com/hashicorp/hc-install) which allows us to dynamically download and use any version of the Terraform binary. -Thus, we support any existing version of Terraform. +The runner implementation relies on [`tenv`](https://github.com/tofuutils/tenv), a tool from the community which allows us to dynamically download and use any version of Terraform, Terragrunt or OpenTofu (coming soon). Thus, we support any existing version of Terraform. -The runners also support any existing version of [Terragrunt](https://terragrunt.gruntwork.io/). +If no version constraint is set in the TerraformLayer resource or in the TerraformRepository resource, `tenv` will detect which version of Terraform/Terragrunt/OpenTofu to use by looking at the version constraints in your code. -The runner is responsible to update the annotations of the layer it is associated with to store information about what commit was plan/apply and when. +The runner is responsible to update the annotations of the layer it is associated to to store information about what commit was planned/applied and when. diff --git a/docs/user-guide/terraform-version.md b/docs/user-guide/terraform-version.md index c9babc43..1d3f7f2d 100644 --- a/docs/user-guide/terraform-version.md +++ b/docs/user-guide/terraform-version.md @@ -1,10 +1,12 @@ -# Choose a terraform/terragrunt version +# Configure a Terraform/Terragrunt/OpenTofu version -For now, Burrito doesn't auto-detect the terraform or terragrunt version used in your repository. You have to specify it in the `TerraformRepository` or `TerraformLayer` resource. +By leveraging [`tenv`](https://github.com/tofuutils/tenv), Burrito auto-detects the Terraform, Terragrunt or OpenTofu version used in your repository, with version constraints set in your code (see [`tenv`'s README](https://github.com/tofuutils/tenv/blob/main/README.md)). -## Choose terraform version +Additionally, you can to specify version constraints in the `TerraformRepository` or `TerraformLayer` resource as described below. -Both `TerraformRepository` and `TerraformLayer` expose a `spec.terrafrom.version` map field. +## Choose Terraform version + +Both `TerraformRepository` and `TerraformLayer` expose a `spec.terraform.version` map field that support version constraints as described in the [Terraform documentation](https://www.terraform.io/docs/language/expressions/version-constraints.html). If the field is specified for a given `TerraformRepository` it will be applied by default to all `TerraformLayer` linked to it. @@ -12,7 +14,7 @@ If the field is specified for a given `TerraformLayer` it will take precedence o ## Enable Terragrunt -You can specify usage of terragrunt as follow: +You can specify usage of Terragrunt with the `spec.terraform.terragrunt` map as follow: ```yaml apiVersion: config.terraform.padok.cloud/v1alpha1 @@ -21,7 +23,7 @@ metadata: name: random-pets-terragrunt spec: terraform: - version: "1.3.1" + version: "~> 1.3.0" terragrunt: enabled: true version: "0.44.5" @@ -36,3 +38,7 @@ spec: !!! info This configuration can be specified at the `TerraformRepository` level to be enabled by default in each of its layers. + +## Use OpenTofu instead of Terraform + +(coming soon) From 5a78e3c7035a1dde52494cb11dd968c1e68949a5 Mon Sep 17 00:00:00 2001 From: Luca Corrieri Date: Thu, 22 Aug 2024 14:58:02 +0200 Subject: [PATCH 17/18] docs: fix info callouts --- docs/getting-started.md | 2 +- docs/operator-manual/pr-mr-workflow.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index 717e0d69..f18d86b1 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -62,7 +62,7 @@ spec: ``` !!! info -You can also connect to a public repository by omitting `spec.repository.secretName` in your `TerraformRepository` definition. + You can also connect to a public repository by omitting `spec.repository.secretName` in your `TerraformRepository` definition. ## 3. Synchronize a terraform layer diff --git a/docs/operator-manual/pr-mr-workflow.md b/docs/operator-manual/pr-mr-workflow.md index b50dbbcb..0b6b51c6 100644 --- a/docs/operator-manual/pr-mr-workflow.md +++ b/docs/operator-manual/pr-mr-workflow.md @@ -3,14 +3,14 @@

!!! info -In this documentation all references to pull requests can be change to merge requests for GitLab. However, the resulting Kubernetes object will still be named `TerraformPullRequest`. + In this documentation all references to pull requests can be change to merge requests for GitLab. However, the resulting Kubernetes object will still be named `TerraformPullRequest`. ## Components ### The server !!! info -For more information about the server, see the [architectural overview](./architecture.md) documentation. + For more information about the server, see the [architectural overview](./architecture.md) documentation. Upon receiving a Pull Request creation event, the server creates a `TerraformPullRequest` resource. @@ -35,7 +35,7 @@ The status of a `TerraformPulLRequest` is defined using the [conditions standard - `IsCommentUpToDate`. This condition is used to check if the controller needs to send a comment to a pull request. This is checked by comparing the last discovered commit and the last commit for which a comment was already sent. !!! info -We use annotations to store information. + We use annotations to store information. With those 3 conditions, we defined 3 states: From 1214ad353e5887111b50182985ab36ee7c7629c3 Mon Sep 17 00:00:00 2001 From: Alan Date: Mon, 2 Sep 2024 16:38:06 +0200 Subject: [PATCH 18/18] fix(runner): merge messed with datastore initialization --- internal/runner/runner.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/internal/runner/runner.go b/internal/runner/runner.go index fad454e7..66ccdd6a 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -66,11 +66,7 @@ func (r *Runner) initClients() error { } r.Client = kubeClient - datastoreClient := datastore.NewDefaultClient() - if r.config.Datastore.TLS { - log.Info("using TLS for datastore") - datastoreClient.Scheme = "https" - } + datastoreClient := datastore.NewDefaultClient(r.config.Datastore) r.Datastore = datastoreClient return nil }