From a974ef7dbe56b6e9699f6ec446402527a7610666 Mon Sep 17 00:00:00 2001 From: David Gamero Date: Mon, 20 May 2024 18:32:46 -0400 Subject: [PATCH] sign --- cmd/root.go | 1 + cmd/validate.go | 111 ++++ cmd/validate_test.go | 97 ++++ cmd/validate_test_helpers.go | 12 + go.mod | 85 ++- go.sum | 508 ++++++++++-------- pkg/safeguards/constants.go | 72 +++ pkg/safeguards/constants_test.go | 114 ++++ pkg/safeguards/helpers.go | 276 ++++++++++ pkg/safeguards/helpers_test.go | 67 +++ .../container-allowed-images/constraint.yaml | 12 + .../container-allowed-images/template.yaml | 43 ++ .../container-enforce-probes/constraint.yaml | 15 + .../container-enforce-probes/template.yaml | 95 ++++ .../container-resource-limits/constraint.yaml | 14 + .../container-resource-limits/template.yaml | 263 +++++++++ .../constraint.yaml | 13 + .../template.yaml | 76 +++ .../constraint.yaml | 11 + .../template.yaml | 111 ++++ .../pod-enforce-antiaffinity/constraint.yaml | 9 + .../pod-enforce-antiaffinity/template.yaml | 25 + .../v1.0.0/restricted-taints/constraint.yaml | 11 + .../v1.0.0/restricted-taints/template.yaml | 43 ++ .../unique-service-selectors/constraint.yaml | 9 + .../unique-service-selectors/template.yaml | 70 +++ pkg/safeguards/manifestresults.go | 100 ++++ pkg/safeguards/manifestresults_test.go | 240 +++++++++ .../tests/all/error/all-error-manifest-1.yaml | 20 + .../tests/all/error/all-error-manifest-2.yaml | 20 + .../all/success/all-success-manifest-1.yaml | 52 ++ .../all/success/all-success-manifest-2.yaml | 52 ++ .../CAI-error-manifest.yaml | 20 + .../CAI-success-manifest.yaml | 20 + .../CEP-error-manifest.yaml | 30 ++ .../CEP-success-manifest.yaml | 39 ++ .../CRL-error-manifest.yaml | 8 + .../CRL-success-manifest.yaml | 12 + .../CRIP-error-manifest.yaml | 15 + .../CRIP-success-manifest.yaml | 17 + .../DBPDB-error-manifest.yaml | 13 + .../DBPDB-success-manifest.yaml | 13 + pkg/safeguards/tests/not-yaml/readme.md | 1 + .../PEA-error-manifest.yaml | 21 + .../PEA-success-manifest.yaml | 49 ++ .../restricted-taints/RT-error-manifest.yaml | 13 + .../RT-success-manifest.yaml | 13 + .../USS-error-manifest.yaml | 25 + .../USS-success-manifest.yaml | 25 + pkg/safeguards/types.go | 25 + 50 files changed, 2784 insertions(+), 222 deletions(-) create mode 100644 cmd/validate.go create mode 100644 cmd/validate_test.go create mode 100644 cmd/validate_test_helpers.go create mode 100644 pkg/safeguards/constants.go create mode 100644 pkg/safeguards/constants_test.go create mode 100644 pkg/safeguards/helpers.go create mode 100644 pkg/safeguards/helpers_test.go create mode 100644 pkg/safeguards/lib/v1.0.0/container-allowed-images/constraint.yaml create mode 100644 pkg/safeguards/lib/v1.0.0/container-allowed-images/template.yaml create mode 100644 pkg/safeguards/lib/v1.0.0/container-enforce-probes/constraint.yaml create mode 100644 pkg/safeguards/lib/v1.0.0/container-enforce-probes/template.yaml create mode 100644 pkg/safeguards/lib/v1.0.0/container-resource-limits/constraint.yaml create mode 100644 pkg/safeguards/lib/v1.0.0/container-resource-limits/template.yaml create mode 100644 pkg/safeguards/lib/v1.0.0/container-restricted-image-pulls/constraint.yaml create mode 100644 pkg/safeguards/lib/v1.0.0/container-restricted-image-pulls/template.yaml create mode 100644 pkg/safeguards/lib/v1.0.0/disallowed-bad-pod-disruption-budgets/constraint.yaml create mode 100644 pkg/safeguards/lib/v1.0.0/disallowed-bad-pod-disruption-budgets/template.yaml create mode 100644 pkg/safeguards/lib/v1.0.0/pod-enforce-antiaffinity/constraint.yaml create mode 100644 pkg/safeguards/lib/v1.0.0/pod-enforce-antiaffinity/template.yaml create mode 100644 pkg/safeguards/lib/v1.0.0/restricted-taints/constraint.yaml create mode 100644 pkg/safeguards/lib/v1.0.0/restricted-taints/template.yaml create mode 100644 pkg/safeguards/lib/v1.0.0/unique-service-selectors/constraint.yaml create mode 100644 pkg/safeguards/lib/v1.0.0/unique-service-selectors/template.yaml create mode 100644 pkg/safeguards/manifestresults.go create mode 100644 pkg/safeguards/manifestresults_test.go create mode 100644 pkg/safeguards/tests/all/error/all-error-manifest-1.yaml create mode 100644 pkg/safeguards/tests/all/error/all-error-manifest-2.yaml create mode 100644 pkg/safeguards/tests/all/success/all-success-manifest-1.yaml create mode 100644 pkg/safeguards/tests/all/success/all-success-manifest-2.yaml create mode 100644 pkg/safeguards/tests/container-allowed-images/CAI-error-manifest.yaml create mode 100644 pkg/safeguards/tests/container-allowed-images/CAI-success-manifest.yaml create mode 100644 pkg/safeguards/tests/container-enforce-probes/CEP-error-manifest.yaml create mode 100644 pkg/safeguards/tests/container-enforce-probes/CEP-success-manifest.yaml create mode 100644 pkg/safeguards/tests/container-resource-limits/CRL-error-manifest.yaml create mode 100644 pkg/safeguards/tests/container-resource-limits/CRL-success-manifest.yaml create mode 100644 pkg/safeguards/tests/container-restricted-image-pulls/CRIP-error-manifest.yaml create mode 100644 pkg/safeguards/tests/container-restricted-image-pulls/CRIP-success-manifest.yaml create mode 100644 pkg/safeguards/tests/disallowed-bad-pod-disruption-budgets/DBPDB-error-manifest.yaml create mode 100644 pkg/safeguards/tests/disallowed-bad-pod-disruption-budgets/DBPDB-success-manifest.yaml create mode 100644 pkg/safeguards/tests/not-yaml/readme.md create mode 100644 pkg/safeguards/tests/pod-enforce-antiaffinity/PEA-error-manifest.yaml create mode 100644 pkg/safeguards/tests/pod-enforce-antiaffinity/PEA-success-manifest.yaml create mode 100644 pkg/safeguards/tests/restricted-taints/RT-error-manifest.yaml create mode 100644 pkg/safeguards/tests/restricted-taints/RT-success-manifest.yaml create mode 100644 pkg/safeguards/tests/unique-service-selectors/USS-error-manifest.yaml create mode 100644 pkg/safeguards/tests/unique-service-selectors/USS-success-manifest.yaml create mode 100644 pkg/safeguards/types.go diff --git a/cmd/root.go b/cmd/root.go index b8969816a..da2cfebdf 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -39,6 +39,7 @@ For more information, please visit the Draft Github page: https://github.com/Azu logrus.SetOutput(&logger.OutputSplitter{}) logrus.SetFormatter(new(logger.CustomFormatter)) }, + SilenceErrors: true, } // Execute adds all child commands to the root command and sets flags appropriately. diff --git a/cmd/validate.go b/cmd/validate.go new file mode 100644 index 000000000..0df3232a7 --- /dev/null +++ b/cmd/validate.go @@ -0,0 +1,111 @@ +package cmd + +import ( + "context" + "fmt" + "path" + + "github.com/Azure/draft/pkg/safeguards" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +type validateCmd struct { + manifestPath string + imagePullSecret bool +} + +func init() { + rootCmd.AddCommand(newValidateCmd()) +} + +func newValidateCmd() *cobra.Command { + vc := &validateCmd{} + + var cmd = &cobra.Command{ + Use: "validate", + Short: "Validates manifests against AKS best practices", + Long: `This command validates manifests against several AKS best practices.`, + RunE: func(cmd *cobra.Command, args []string) error { + if err := vc.run(cmd); err != nil { + return err + } + return nil + }, + } + + f := cmd.Flags() + + f.StringVarP(&vc.manifestPath, "manifest", "m", "", "'manifest' asks for the path to the manifest") + f.BoolVarP(&vc.imagePullSecret, "imagePullSecret", "s", false, "'imagePullSecret' enables the Safeguard that checks for usage of an image pull secret within the manifest(s)") + + return cmd +} + +// run is our entry point to GetManifestResults +func (vc *validateCmd) run(c *cobra.Command) error { + if vc.manifestPath == "" { + return fmt.Errorf("path to the manifests cannot be empty") + } + + // AddSafeguardCRIP just adds Container Restricted Image Pulls to the list of safeguards the client will review + // against the given manifest + if vc.imagePullSecret { + safeguards.AddSafeguardCRIP() + } + + ctx := context.Background() + isDir, err := safeguards.IsDirectory(vc.manifestPath) + if err != nil { + return fmt.Errorf("not a valid file or directory: %w", err) + } + + var manifestFiles []safeguards.ManifestFile + if isDir { + manifestFiles, err = safeguards.GetManifestFiles(vc.manifestPath) + if err != nil { + return err + } + } else if safeguards.IsYAML(vc.manifestPath) { + manifestFiles = append(manifestFiles, safeguards.ManifestFile{ + Name: path.Base(vc.manifestPath), + Path: vc.manifestPath, + }) + } else { + return fmt.Errorf("expected at least one .yaml or .yml file within given path") + } + + log.Debugf("validating manifests") + manifestViolations, err := safeguards.GetManifestResults(ctx, manifestFiles) + if err != nil { + log.Errorf("validating safeguards: %s", err.Error()) + return err + } + + anyViolationsFound := false + for _, v := range manifestViolations { + log.Printf("Analyzing %s for violations", v.Name) + manifestHasViolations := false + // returning the full list of violations after each manifest is checked + for file, violations := range v.ObjectViolations { + log.Printf(" %s:", file) + for _, violation := range violations { + log.Printf(" ❌ %s", violation) + anyViolationsFound = true + manifestHasViolations = true + } + } + if !manifestHasViolations { + log.Printf(" ✅ no violations found.") + } + } + + if anyViolationsFound { + c.SilenceUsage = true // suppress default Cobra behaviour of printing usage on all errors + return fmt.Errorf("violations found") + } else { + log.Printf("✅ No violations found in \"%s\".", vc.manifestPath) + } + + return nil +} diff --git a/cmd/validate_test.go b/cmd/validate_test.go new file mode 100644 index 000000000..d6fd91ab9 --- /dev/null +++ b/cmd/validate_test.go @@ -0,0 +1,97 @@ +package cmd + +import ( + "context" + "os" + "path" + "path/filepath" + + "testing" + + "github.com/Azure/draft/pkg/safeguards" + "github.com/stretchr/testify/assert" +) + +// TestIsDirectory tests the isDirectory function for proper returns +func TestIsDirectory(t *testing.T) { + testWd, _ := os.Getwd() + pathTrue := testWd + pathFalse := path.Join(testWd, "validate.go") + pathError := "" + + isDir, err := safeguards.IsDirectory(pathTrue) + assert.True(t, isDir) + assert.Nil(t, err) + + isDir, err = safeguards.IsDirectory(pathFalse) + assert.False(t, isDir) + assert.Nil(t, err) + + isDir, err = safeguards.IsDirectory(pathError) + assert.False(t, isDir) + assert.NotNil(t, err) +} + +// TestIsYAML tests the isYAML function for proper returns +func TestIsYAML(t *testing.T) { + dirNotYaml, _ := filepath.Abs("../pkg/safeguards/tests/not-yaml") + dirYaml, _ := filepath.Abs("../pkg/safeguards/tests/all/success") + fileNotYaml, _ := filepath.Abs("../pkg/safeguards/tests/not-yaml/readme.md") + fileYaml, _ := filepath.Abs("../pkg/safeguards/tests/all/success/all-success-manifest-1.yaml") + + assert.False(t, safeguards.IsYAML(fileNotYaml)) + assert.True(t, safeguards.IsYAML(fileYaml)) + + manifestFiles, err := safeguards.GetManifestFiles(dirNotYaml) + assert.Nil(t, manifestFiles) + assert.NotNil(t, err) + + manifestFiles, err = safeguards.GetManifestFiles(dirYaml) + assert.NotNil(t, manifestFiles) + assert.Nil(t, err) +} + +// TestRunValidate tests the run command for `draft validate` for proper returns +func TestRunValidate(t *testing.T) { + ctx := context.TODO() + manifestFilesEmpty := []safeguards.ManifestFile{} + manifestPathDirectorySuccess, _ := filepath.Abs("../pkg/safeguards/tests/all/success") + manifestPathDirectoryError, _ := filepath.Abs("../pkg/safeguards/tests/all/error") + manifestPathFileSuccess, _ := filepath.Abs("../pkg/safeguards/tests/all/success/all-success-manifest-1.yaml") + manifestPathFileError, _ := filepath.Abs("../pkg/safeguards/tests/all/error/all-error-manifest-1.yaml") + var manifestFiles []safeguards.ManifestFile + + // Scenario 1: empty manifest path should error + _, err := safeguards.GetManifestResults(ctx, manifestFilesEmpty) + assert.NotNil(t, err) + + // Scenario 2a: manifest path leads to a directory of manifestFiles - expect success + manifestFiles, err = safeguards.GetManifestFiles(manifestPathDirectorySuccess) + assert.Nil(t, err) + v, err := safeguards.GetManifestResults(ctx, manifestFiles) + assert.Nil(t, err) + numViolations := countTestViolations(v) + assert.Equal(t, numViolations, 0) + + // Scenario 2b: manifest path leads to a directory of manifestFiles - expect failure + manifestFiles, err = safeguards.GetManifestFiles(manifestPathDirectoryError) + assert.Nil(t, err) + v, err = safeguards.GetManifestResults(ctx, manifestFiles) + assert.Nil(t, err) + numViolations = countTestViolations(v) + assert.Greater(t, numViolations, 0) + + // Scenario 3a: manifest path leads to one manifest file - expect success + manifestFiles, err = safeguards.GetManifestFiles(manifestPathFileSuccess) + v, err = safeguards.GetManifestResults(ctx, manifestFiles) + assert.Nil(t, err) + numViolations = countTestViolations(v) + assert.Equal(t, numViolations, 0) + + // Scenario 3b: manifest path leads to one manifest file - expect failure + manifestFiles, err = safeguards.GetManifestFiles(manifestPathFileError) + v, err = safeguards.GetManifestResults(ctx, manifestFiles) + assert.Nil(t, err) + numViolations = countTestViolations(v) + assert.Greater(t, numViolations, 0) +} diff --git a/cmd/validate_test_helpers.go b/cmd/validate_test_helpers.go new file mode 100644 index 000000000..4fd638b12 --- /dev/null +++ b/cmd/validate_test_helpers.go @@ -0,0 +1,12 @@ +package cmd + +import "github.com/Azure/draft/pkg/safeguards" + +func countTestViolations(results []safeguards.ManifestResult) int { + numViolations := 0 + for _, r := range results { + numViolations += len(r.ObjectViolations) + } + + return numViolations +} diff --git a/go.mod b/go.mod index 6ff1a307c..92744a314 100644 --- a/go.mod +++ b/go.mod @@ -12,52 +12,86 @@ require ( github.com/fatih/color v1.16.0 github.com/ghodss/yaml v1.0.0 github.com/hashicorp/go-version v1.6.0 - github.com/instrumenta/kubeval v0.16.1 + github.com/instrumenta/kubeval v0.16.0 github.com/ivanpirog/coloredcobra v1.0.1 github.com/jbrukh/bayesian v0.0.0-20231117143245-13ae6f916c7a github.com/manifoldco/promptui v0.9.0 github.com/microsoftgraph/msgraph-sdk-go v1.38.0 + github.com/open-policy-agent/frameworks/constraint v0.0.0-20240516222118-7d1bd0255f52 + github.com/open-policy-agent/gatekeeper/v3 v3.16.0 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.9.0 go.uber.org/mock v0.4.0 golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f + golang.org/x/mod v0.17.0 gopkg.in/yaml.v3 v3.0.1 helm.sh/helm/v3 v3.14.4 - k8s.io/api v0.30.0 - k8s.io/cli-runtime v0.30.0 - k8s.io/client-go v0.30.0 + k8s.io/api v0.29.3 + k8s.io/apimachinery v0.29.3 + k8s.io/cli-runtime v0.29.0 + k8s.io/client-go v0.29.3 sigs.k8s.io/kustomize/api v0.17.1 sigs.k8s.io/kustomize/kyaml v0.17.0 ) require ( + github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/Microsoft/hcsshim v0.11.4 // indirect + github.com/OneOfOne/xxhash v1.2.8 // indirect + github.com/agnivade/levenshtein v1.1.1 // indirect + github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect + github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect github.com/cjlapao/common-go v0.0.39 // indirect + github.com/containerd/containerd v1.7.14 // indirect + github.com/containerd/log v0.1.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/distribution/reference v0.5.0 // indirect + github.com/docker/cli v25.0.1+incompatible // indirect + github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/docker v25.0.5+incompatible // indirect + github.com/docker/docker-credential-helpers v0.7.0 // indirect + github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-metrics v0.0.1 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/evanphx/json-patch/v5 v5.8.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-errors/errors v1.4.2 // indirect + github.com/go-ini/ini v1.67.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.4 // indirect + github.com/gobwas/glob v0.2.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect + github.com/golang/glog v1.2.1 // indirect github.com/golang/protobuf v1.5.4 // indirect + github.com/google/cel-go v0.17.7 // indirect github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/mux v1.8.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.17.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.7.7 // indirect @@ -71,36 +105,67 @@ require ( github.com/microsoft/kiota-serialization-multipart-go v1.0.0 // indirect github.com/microsoft/kiota-serialization-text-go v1.0.0 // indirect github.com/microsoftgraph/msgraph-sdk-go-core v1.1.0 // indirect + github.com/moby/locker v1.0.1 // indirect github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/open-policy-agent/opa v0.63.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc6 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_golang v1.19.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.48.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/std-uritemplate/std-uritemplate/go v0.0.55 // indirect + github.com/stoewer/go-strcase v1.2.0 // indirect + github.com/tchap/go-patricia/v2 v2.3.1 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect + github.com/yashtewari/glob-intersection v0.2.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/sdk v1.21.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect + go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/oauth2 v0.17.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect + golang.org/x/time v0.5.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240311132316-a219d84964c2 // indirect + google.golang.org/grpc v1.62.1 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/apimachinery v0.30.0 // indirect + k8s.io/apiextensions-apiserver v0.29.3 // indirect + k8s.io/apiserver v0.29.3 // indirect + k8s.io/component-base v0.29.3 // indirect k8s.io/klog/v2 v2.120.1 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect + oras.land/oras-go v1.2.5 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 // indirect + sigs.k8s.io/controller-runtime v0.17.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/go.sum b/go.sum index d853ad219..3240a37c9 100644 --- a/go.sum +++ b/go.sum @@ -1,16 +1,6 @@ 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/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= 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= @@ -26,27 +16,51 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg6 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/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +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/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= +github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= +github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= +github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= +github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= +github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= +github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= 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/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18= +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= 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/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A= github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE= +github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= +github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng= +github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 h1:3uZCA/BLTIu+DqCfguByNMJa2HVHpXvjfy0Dy7g6fuA= +github.com/bytecodealliance/wasmtime-go/v3 v3.0.2/go.mod h1:RnUjnIXxEJcL6BgCvNyzCCRzZcxCgsZCi+RNlvYor5Q= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.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 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= @@ -56,11 +70,18 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/cjlapao/common-go v0.0.39 h1:bAAUrj2B9v0kMzbAOhzjSmiyDy+rd56r2sy7oEiQLlA= github.com/cjlapao/common-go v0.0.39/go.mod h1:M3dzazLjTjEtZJbbxoA5ZDiGCiHmpwqW9l4UWaddwOA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= +github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= +github.com/containerd/containerd v1.7.14 h1:H/XLzbnGuenZEGK+v0RkwTdv2u1QFAruMe5N0GNPJwA= +github.com/containerd/containerd v1.7.14/go.mod h1:YMC9Qt5yzNqXx/fO4j/5yYVIHXSRrlB3H7sxkUTvspg= +github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= +github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -70,23 +91,63 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs 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/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg= +github.com/dgraph-io/badger/v3 v3.2103.5/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= +github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc= +github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI= +github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= +github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= 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 v25.0.1+incompatible h1:mFpqnrS6Hsm3v1k7Wa/BO23oz0k121MTbTO1lpcGSkU= +github.com/docker/cli v25.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= +github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v25.0.5+incompatible h1:UmQydMduGkrD5nQde1mecF/YnSbTOaPeFIeP5C4W+DE= +github.com/docker/docker v25.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= +github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= +github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= +github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= +github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +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/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= +github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= +github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= 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/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/foxcpp/go-mockdns v1.1.0 h1:jI0rD8M0wuYAxL7r/ynTrCQQq0BVqfB99Vgk7DlmewI= +github.com/foxcpp/go-mockdns v1.1.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +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 v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 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-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= +github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= 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= @@ -95,6 +156,8 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 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.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.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= @@ -103,17 +166,21 @@ github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+ github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= 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/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 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-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= +github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +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 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= @@ -123,10 +190,18 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU 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.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.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/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= +github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= +github.com/google/cel-go v0.17.7 h1:6ebJFzu1xO2n7TLtN+UBqShGBhlD85bhvglh5DpcfqQ= +github.com/google/cel-go v0.17.7/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= +github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= +github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= 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= @@ -135,77 +210,63 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 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/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/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/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/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= +github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/hashicorp/errwrap v0.0.0-20180715044906-d6c0cd880357/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v0.0.0-20180717150148-3d5d8f294aa0/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= +github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= 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/instrumenta/kubeval v0.16.1 h1:PticHzCrCqRjwfse1YmlgsN5313Du1PyJ2QnRGVNdVg= -github.com/instrumenta/kubeval v0.16.1/go.mod h1:K9fO5e4B/bznyi5cKzthudanzcPzPBP2OuB5uE9G1TU= +github.com/instrumenta/kubeval v0.16.0 h1:chEeSLN4XaZfumn3YQ/ScZAkXZhoTXROIsG34rnX+Cw= +github.com/instrumenta/kubeval v0.16.0/go.mod h1:cD+P/oZrBwOnaIHXrqvKPuN353KPxGomnsXSXf8pFJs= github.com/ivanpirog/coloredcobra v1.0.1 h1:aURSdEmlR90/tSiWS0dMjdwOvCVUeYLfltLfbgNxrN4= github.com/ivanpirog/coloredcobra v1.0.1/go.mod h1:iho4nEKcnwZFiniGSdcgdvRgZNjxm+h20acv8vqmN6Q= github.com/jbrukh/bayesian v0.0.0-20231117143245-13ae6f916c7a h1:zSc8tkEGo49/E6cQ9o00si0L9Q/Lu1Hsg8JWKCvzEDU= github.com/jbrukh/bayesian v0.0.0-20231117143245-13ae6f916c7a/go.mod h1:SELxwZQq/mPnfPCR2mchLmT4TQaPJvYtLcCtDWSM7vM= -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 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.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/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= 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/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= +github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/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.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= @@ -217,17 +278,16 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.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= @@ -252,28 +312,44 @@ github.com/microsoftgraph/msgraph-sdk-go v1.38.0 h1:pxVMih65Iul2yIUVE5PUqdw5Q4eF github.com/microsoftgraph/msgraph-sdk-go v1.38.0/go.mod h1:u/ciVhK5eBqzQvsVnTVdeEl+Jgy9WbUoUHHKgcw54hk= github.com/microsoftgraph/msgraph-sdk-go-core v1.1.0 h1:NB7c/n4Knj+TLaLfjsahhSqoUqoN/CtyNB0XIe/nJnM= github.com/microsoftgraph/msgraph-sdk-go-core v1.1.0/go.mod h1:M3w/5IFJ1u/DpwOyjsjNSVEA43y1rLOeX58suyfBhGk= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= +github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= +github.com/mitchellh/mapstructure v0.0.0-20180715050151-f15292f7a699/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= +github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= +github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= +github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-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-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/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +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/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/onsi/ginkgo/v2 v2.14.0 h1:vSmGj2Z5YPb9JwCWT6z6ihcUvDhuXLc3sJiqd3jMKAY= +github.com/onsi/ginkgo/v2 v2.14.0/go.mod h1:JkUdW7JkN0V6rFvsHcJ478egV3XH9NxpD27Hal/PhZw= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/open-policy-agent/frameworks/constraint v0.0.0-20240516222118-7d1bd0255f52 h1:OBGvVstmpUAwbc7SFPMvrqF44CwlWb6CdySGMynh15k= +github.com/open-policy-agent/frameworks/constraint v0.0.0-20240516222118-7d1bd0255f52/go.mod h1:h0dz0Kt9xs2MOZchiVsy1nuYr/tw4iR4cMnTkieQifs= +github.com/open-policy-agent/gatekeeper/v3 v3.16.0 h1:isRR3bG8ENukT9/rLlueON7ee9FSn0JGqz6VtZiWhnw= +github.com/open-policy-agent/gatekeeper/v3 v3.16.0/go.mod h1:xuSrEcmbyAfssw5Blx2quxWfF6Pwecrs/8rq9feHY6s= +github.com/open-policy-agent/opa v0.63.0 h1:ztNNste1v8kH0/vJMJNquE45lRvqwrM5mY9Ctr9xIXw= +github.com/open-policy-agent/opa v0.63.0/go.mod h1:9VQPqEfoB2N//AToTxzZ1pVTVPUoF2Mhd64szzjWPpU= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc6 h1:XDqvyKsJEbRtATzkgItUqBA7QHk58yxX1Ov9HERHNqU= +github.com/opencontainers/image-spec v1.1.0-rc6/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/pelletier/go-toml v0.0.0-20180724185102-c2dbbc24a979/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= +github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/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= @@ -283,46 +359,50 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE 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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= 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/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +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.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= +github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +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/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= 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/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/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/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/afero v1.1.1/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= github.com/spf13/cobra v0.0.0-20180820174524-ff0d02e85550/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/jwalterweatherman v0.0.0-20180814060501-14d3d4c51834/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v0.0.0-20180821114517-d929dcbb1086/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.1.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/std-uritemplate/std-uritemplate/go v0.0.55 h1:muSH037g97K7U2f94G9LUuE8tZlJsoSSrPsO9V281WY= github.com/std-uritemplate/std-uritemplate/go v0.0.55/go.mod h1:rG/bqh/ThY4xE5de7Rap3vaDkYUT76B0GPJ0loYeTTc= +github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -331,14 +411,15 @@ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes= +github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -347,174 +428,169 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v0.0.0-20180816142147-da425ebb7609/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= +github.com/yashtewari/glob-intersection v0.2.0 h1:8iuHdN88yYuCzCdjt0gDe+6bAhUwBeEWqThExu54RFg= +github.com/yashtewari/glob-intersection v0.2.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= +github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= +github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE= +github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= +github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= +github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= +go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k= +go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= +go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0= +go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= +go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao= +go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= +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= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= 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.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= -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/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +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.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-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.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-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= 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.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= 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/sys v0.0.0-20180823144017-11551d06cbcc/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.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180821044426-4ea2f632f6e9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.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.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/text v0.0.0-20180810153555-6e3c4e7365dd/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -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/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +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-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/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-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.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +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/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= +gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= 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.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= 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-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 h1:rIo7ocm2roD9DcFIX67Ym8icoGCKSARAiPljFhh5suQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240311132316-a219d84964c2 h1:9IZDv+/GcI6u+a4jRFRLxQs0RUCfavGfoOgEW6jpkI0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240311132316-a219d84964c2/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -523,51 +599,59 @@ 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.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= 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.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -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.4/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.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.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= +gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= helm.sh/helm/v3 v3.14.4 h1:6FSpEfqyDalHq3kUr4gOMThhgY55kXUEjdQoyODYnrM= helm.sh/helm/v3 v3.14.4/go.mod h1:Tje7LL4gprZpuBNTbG34d1Xn5NmRT3OWfBRwpOSer9I= 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.30.0 h1:siWhRq7cNjy2iHssOB9SCGNCl2spiF1dO3dABqZ8niA= -k8s.io/api v0.30.0/go.mod h1:OPlaYhoHs8EQ1ql0R/TsUgaRPhpKNxIMrKQfWUp8QSE= -k8s.io/apimachinery v0.30.0 h1:qxVPsyDM5XS96NIh9Oj6LavoVFYff/Pon9cZeDIkHHA= -k8s.io/apimachinery v0.30.0/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= -k8s.io/cli-runtime v0.30.0 h1:0vn6/XhOvn1RJ2KJOC6IRR2CGqrpT6QQF4+8pYpWQ48= -k8s.io/cli-runtime v0.30.0/go.mod h1:vATpDMATVTMA79sZ0YUCzlMelf6rUjoBzlp+RnoM+cg= -k8s.io/client-go v0.30.0 h1:sB1AGGlhY/o7KCyCEQ0bPWzYDL0pwOZO4vAtTSh/gJQ= -k8s.io/client-go v0.30.0/go.mod h1:g7li5O5256qe6TYdAMyX/otJqMhIiGgTapdLchhmOaY= +k8s.io/api v0.29.3 h1:2ORfZ7+bGC3YJqGpV0KSDDEVf8hdGQ6A03/50vj8pmw= +k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80= +k8s.io/apiextensions-apiserver v0.29.3 h1:9HF+EtZaVpFjStakF4yVufnXGPRppWFEQ87qnO91YeI= +k8s.io/apiextensions-apiserver v0.29.3/go.mod h1:po0XiY5scnpJfFizNGo6puNU6Fq6D70UJY2Cb2KwAVc= +k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU= +k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU= +k8s.io/apiserver v0.29.3 h1:xR7ELlJ/BZSr2n4CnD3lfA4gzFivh0wwfNfz9L0WZcE= +k8s.io/apiserver v0.29.3/go.mod h1:hrvXlwfRulbMbBgmWRQlFru2b/JySDpmzvQwwk4GUOs= +k8s.io/cli-runtime v0.29.0 h1:q2kC3cex4rOBLfPOnMSzV2BIrrQlx97gxHJs21KxKS4= +k8s.io/cli-runtime v0.29.0/go.mod h1:VKudXp3X7wR45L+nER85YUzOQIru28HQpXr0mTdeCrk= +k8s.io/client-go v0.29.3 h1:R/zaZbEAxqComZ9FHeQwOh3Y1ZUs7FaHKZdQtIc2WZg= +k8s.io/client-go v0.29.3/go.mod h1:tkDisCvgPfiRpxGnOORfkljmS+UrW+WtXAy2fTvXJB0= +k8s.io/component-base v0.29.3 h1:Oq9/nddUxlnrCuuR2K/jp6aflVvc0uDvxMzAWxnGzAo= +k8s.io/component-base v0.29.3/go.mod h1:Yuj33XXjuOk2BAaHsIGHhCKZQAgYKhqIxIjIr2UXYio= 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-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo= +oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 h1:TgtAeesdhpm2SGwkQasmbeqDo8th5wOBA5h/AjTKA4I= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0/go.mod h1:VHVDI/KrK4fjnV61bE2g3sA7tiETLn8sooImelsCx3Y= +sigs.k8s.io/controller-runtime v0.17.3 h1:65QmN7r3FWgTxDMz9fvGnO1kbf2nu+acg9p2R9oYYYk= +sigs.k8s.io/controller-runtime v0.17.3/go.mod h1:N0jpP5Lo7lMTF9aL56Z/B2oWBJjey6StQM0jRbKQXtY= 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/kustomize/api v0.17.1 h1:MYJBOP/yQ3/5tp4/sf6HiiMfNNyO97LmtnirH9SLNr4= @@ -576,6 +660,6 @@ sigs.k8s.io/kustomize/kyaml v0.17.0 h1:G2bWs03V9Ur2PinHLzTUJ8Ded+30SzXZKiO92SRDs sigs.k8s.io/kustomize/kyaml v0.17.0/go.mod h1:6lxkYF1Cv9Ic8g/N7I86cvxNc5iinUo/P2vKsHNmpyE= 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.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/pkg/safeguards/constants.go b/pkg/safeguards/constants.go new file mode 100644 index 000000000..5ddff8552 --- /dev/null +++ b/pkg/safeguards/constants.go @@ -0,0 +1,72 @@ +package safeguards + +import ( + "fmt" +) + +const ( + Constraint_CAI = "container-allowed-images" + Constraint_CEP = "container-enforce-probes" + Constraint_CRL = "container-resource-limits" + Constraint_CRIP = "container-restricted-image-pulls" + Constraint_DBPDB = "disallowed-bad-pod-disruption-budgets" + Constraint_PEA = "pod-enforce-antiaffinity" + Constraint_RT = "restricted-taints" + Constraint_USS = "unique-service-selectors" + Constraint_all = "all" +) + +var selectedVersion = "v1.0.0" + +var supportedVersions = []string{selectedVersion} + +const ( + templateFileName = "template.yaml" + constraintFileName = "constraint.yaml" +) + +var Safeguard_CRIP = Safeguard{ + name: Constraint_CRIP, + templatePath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_CRIP, templateFileName), + constraintPath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_CRIP, constraintFileName), +} + +var safeguards = []Safeguard{ + { + name: Constraint_CAI, + templatePath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_CAI, templateFileName), + constraintPath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_CAI, constraintFileName), + }, + { + name: Constraint_CEP, + templatePath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_CEP, templateFileName), + constraintPath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_CEP, constraintFileName), + }, + { + name: Constraint_CRL, + templatePath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_CRL, templateFileName), + constraintPath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_CRL, constraintFileName), + }, + { + name: Constraint_DBPDB, + templatePath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_DBPDB, templateFileName), + constraintPath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_DBPDB, constraintFileName), + }, + { + name: Constraint_PEA, + templatePath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_PEA, templateFileName), + constraintPath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_PEA, constraintFileName), + }, + { + name: Constraint_RT, + templatePath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_RT, templateFileName), + constraintPath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_RT, constraintFileName), + }, + { + name: Constraint_USS, + templatePath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_USS, templateFileName), + constraintPath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_USS, constraintFileName), + }, +} + +var safeguardsTesting = append(safeguards, Safeguard_CRIP) diff --git a/pkg/safeguards/constants_test.go b/pkg/safeguards/constants_test.go new file mode 100644 index 000000000..dca381c7e --- /dev/null +++ b/pkg/safeguards/constants_test.go @@ -0,0 +1,114 @@ +package safeguards + +import "fmt" + +type TestManifest struct { + Name string + SuccessPaths []string + ErrorPaths []string +} + +const testManifestDirectory = "tests" + +var testDeployments = []TestManifest{ + testManifest_CAI, + testManifest_CEP, + testManifest_CL, + testManifest_CRIP, + testManifest_DBPDB, + testManifest_PEA, + testManifest_RT, + testManifest_USS, + testManifest_all, +} + +var testError_CAI_Standard = fmt.Sprintf("%s/%s/%s", testManifestDirectory, Constraint_CAI, "CAI-error-manifest.yaml") + +var testSuccess_CAI_Standard = fmt.Sprintf("%s/%s/%s", testManifestDirectory, Constraint_CAI, "CAI-success-manifest.yaml") + +var testManifest_CAI = TestManifest{ + Name: Constraint_CAI, + SuccessPaths: []string{testSuccess_CAI_Standard}, + ErrorPaths: []string{testError_CAI_Standard}, +} + +var testError_CEP_Standard = fmt.Sprintf("%s/%s/%s", testManifestDirectory, Constraint_CEP, "CEP-error-manifest.yaml") + +var testSuccess_CEP_Standard = fmt.Sprintf("%s/%s/%s", testManifestDirectory, Constraint_CEP, "CEP-success-manifest.yaml") + +var testManifest_CEP = TestManifest{ + Name: Constraint_CEP, + SuccessPaths: []string{testSuccess_CEP_Standard}, + ErrorPaths: []string{testError_CEP_Standard}, +} + +var testError_CRL_Standard = fmt.Sprintf("%s/%s/%s", testManifestDirectory, Constraint_CRL, "CRL-error-manifest.yaml") + +var testSuccess_CRL_Standard = fmt.Sprintf("%s/%s/%s", testManifestDirectory, Constraint_CRL, "CRL-success-manifest.yaml") + +var testManifest_CL = TestManifest{ + Name: Constraint_CRL, + SuccessPaths: []string{testSuccess_CRL_Standard}, + ErrorPaths: []string{testError_CRL_Standard}, +} + +var testError_CRIP_Standard = fmt.Sprintf("%s/%s/%s", testManifestDirectory, Constraint_CRIP, "CRIP-error-manifest.yaml") + +var testSuccess_CRIP_Standard = fmt.Sprintf("%s/%s/%s", testManifestDirectory, Constraint_CRIP, "CRIP-success-manifest.yaml") + +var testManifest_CRIP = TestManifest{ + Name: Constraint_CRIP, + SuccessPaths: []string{testSuccess_CRIP_Standard}, + ErrorPaths: []string{testError_CRIP_Standard}, +} + +var testError_DBPDB_Standard = fmt.Sprintf("%s/%s/%s", testManifestDirectory, Constraint_DBPDB, "DBPDB-error-manifest.yaml") + +var testSuccess_DBPDB_Standard = fmt.Sprintf("%s/%s/%s", testManifestDirectory, Constraint_DBPDB, "DBPDB-success-manifest.yaml") + +var testManifest_DBPDB = TestManifest{ + Name: Constraint_DBPDB, + SuccessPaths: []string{testSuccess_DBPDB_Standard}, + ErrorPaths: []string{testError_DBPDB_Standard}, +} + +var testError_PEA_Standard = fmt.Sprintf("%s/%s/%s", testManifestDirectory, Constraint_PEA, "PEA-error-manifest.yaml") + +var testSuccess_PEA_Standard = fmt.Sprintf("%s/%s/%s", testManifestDirectory, Constraint_PEA, "PEA-success-manifest.yaml") + +var testManifest_PEA = TestManifest{ + Name: Constraint_PEA, + SuccessPaths: []string{testSuccess_PEA_Standard}, + ErrorPaths: []string{testError_PEA_Standard}, +} + +var testError_RT_Standard = fmt.Sprintf("%s/%s/%s", testManifestDirectory, Constraint_RT, "RT-error-manifest.yaml") + +var testSuccess_RT_Standard = fmt.Sprintf("%s/%s/%s", testManifestDirectory, Constraint_RT, "RT-success-manifest.yaml") + +var testManifest_RT = TestManifest{ + Name: Constraint_RT, + SuccessPaths: []string{testSuccess_RT_Standard}, + ErrorPaths: []string{testError_RT_Standard}, +} + +var testError_USS_Standard = fmt.Sprintf("%s/%s/%s", testManifestDirectory, Constraint_USS, "USS-error-manifest.yaml") + +var testSuccess_USS_Standard = fmt.Sprintf("%s/%s/%s", testManifestDirectory, Constraint_USS, "USS-success-manifest.yaml") + +var testManifest_USS = TestManifest{ + Name: Constraint_USS, + SuccessPaths: []string{testSuccess_USS_Standard}, + ErrorPaths: []string{testError_USS_Standard}, +} + +var testError_all_Standard_1 = fmt.Sprintf("%s/%s/%s/%s", testManifestDirectory, Constraint_all, "error", "all-error-manifest-1.yaml") +var testError_all_Standard_2 = fmt.Sprintf("%s/%s/%s/%s", testManifestDirectory, Constraint_all, "error", "all-error-manifest-2.yaml") +var testSuccess_all_Standard_1 = fmt.Sprintf("%s/%s/%s/%s", testManifestDirectory, Constraint_all, "success", "all-success-manifest-1.yaml") +var testSuccess_all_Standard_2 = fmt.Sprintf("%s/%s/%s/%s", testManifestDirectory, Constraint_all, "success", "all-success-manifest-2.yaml") + +var testManifest_all = TestManifest{ + Name: "all", + SuccessPaths: []string{testSuccess_all_Standard_1, testSuccess_all_Standard_2}, + ErrorPaths: []string{testError_all_Standard_1, testError_all_Standard_2}, +} diff --git a/pkg/safeguards/helpers.go b/pkg/safeguards/helpers.go new file mode 100644 index 000000000..18301273e --- /dev/null +++ b/pkg/safeguards/helpers.go @@ -0,0 +1,276 @@ +package safeguards + +import ( + "bufio" + "context" + "fmt" + "io/fs" + "os" + "path/filepath" + + constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego" + "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" + api "github.com/open-policy-agent/gatekeeper/v3/apis" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator/reader" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + log "github.com/sirupsen/logrus" + + "golang.org/x/mod/semver" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" +) + +// retrieves the constraint client that does all rego code related operations +func getConstraintClient() (*constraintclient.Client, error) { + driver, err := rego.New() + if err != nil { + return nil, fmt.Errorf("could not create rego driver: %w", err) + } + + c, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) + if err != nil { + return nil, fmt.Errorf("could not create constraint client: %w", err) + } + + return c, nil +} + +// sorts the list of supported safeguards versions and returns the last item in the list +func getLatestSafeguardsVersion() string { + semver.Sort(supportedVersions) + return supportedVersions[len(supportedVersions)-1] +} + +func updateSafeguardPaths(safeguardList *[]Safeguard) { + for _, sg := range *safeguardList { + sg.templatePath = fmt.Sprintf("%s/%s/%s", selectedVersion, sg.name, templateFileName) + sg.constraintPath = fmt.Sprintf("%s/%s/%s", selectedVersion, sg.name, constraintFileName) + } +} + +// adds Safeguard_CRIP to full list of Safeguards +func AddSafeguardCRIP() { + fc.Safeguards = append(fc.Safeguards, Safeguard_CRIP) +} + +// methods for retrieval of manifest, constraint templates, and constraints +func (fc FileCrawler) ReadManifests(path string) ([]*unstructured.Unstructured, error) { + file, err := os.Open(path) + if err != nil { + return nil, fmt.Errorf("opening file %q: %w", path, err) + } + defer file.Close() + + manifests, err := reader.ReadK8sResources(bufio.NewReader(file)) + if err != nil { + return nil, fmt.Errorf("reading file %q: %w", path, err) + } + + return manifests, nil +} + +func GetScheme() *runtime.Scheme { + var s = runtime.NewScheme() + _ = clientgoscheme.AddToScheme(s) + _ = api.AddToScheme(s) + return s +} + +func (fc FileCrawler) ReadConstraintTemplates() ([]*templates.ConstraintTemplate, error) { + var constraintTemplates []*templates.ConstraintTemplate + + for _, sg := range fc.Safeguards { + ct, err := reader.ReadTemplate(GetScheme(), fc.constraintFS, sg.templatePath) + if err != nil { + return nil, fmt.Errorf("reading template: %w", err) + } + constraintTemplates = append(constraintTemplates, ct) + } + + return constraintTemplates, nil +} + +func (fc FileCrawler) ReadConstraintTemplate(name string) (*templates.ConstraintTemplate, error) { + var constraintTemplate *templates.ConstraintTemplate + + for _, sg := range fc.Safeguards { + if sg.name == name { + ct, err := reader.ReadTemplate(GetScheme(), fc.constraintFS, sg.templatePath) + if err != nil { + return nil, fmt.Errorf("could not read template: %w", err) + } + constraintTemplate = ct + } + } + if constraintTemplate == nil { + return nil, fmt.Errorf("no constraint template exists with name: %s", name) + } + + return constraintTemplate, nil +} + +func (fc FileCrawler) ReadConstraints() ([]*unstructured.Unstructured, error) { + var constraints []*unstructured.Unstructured + + for _, sg := range fc.Safeguards { + u, err := reader.ReadConstraint(fc.constraintFS, sg.constraintPath) + if err != nil { + return nil, fmt.Errorf("could not add constraint: %w", err) + } + + constraints = append(constraints, u) + } + + return constraints, nil +} + +func (fc FileCrawler) ReadConstraint(name string) (*unstructured.Unstructured, error) { + var constraint *unstructured.Unstructured + + for _, sg := range fc.Safeguards { + if sg.name == name { + c, err := reader.ReadConstraint(fc.constraintFS, sg.constraintPath) + if err != nil { + return nil, fmt.Errorf("could not add constraint: %w", err) + } + + constraint = c + } + } + if constraint == nil { + return nil, fmt.Errorf("no constraint exists with name: %s", name) + } + + return constraint, nil +} + +// loads constraint templates, constraints into constraint client +func loadConstraintTemplates(ctx context.Context, c *constraintclient.Client, constraintTemplates []*templates.ConstraintTemplate) error { + // AddTemplate adds the template source code to OPA and registers the CRD with the client for + // schema validation on calls to AddConstraint. On error, the responses return value + // will still be populated so that partial results can be analyzed. + for _, ct := range constraintTemplates { + _, err := c.AddTemplate(ctx, ct) + if err != nil { + return fmt.Errorf("could not add template: %w", err) + } + } + + return nil +} + +func loadConstraints(ctx context.Context, c *constraintclient.Client, constraints []*unstructured.Unstructured) error { + // AddConstraint validates the constraint and, if valid, inserts it into OPA. + // On error, the responses return value will still be populated so that + // partial results can be analyzed. + for _, con := range constraints { + _, err := c.AddConstraint(ctx, con) + if err != nil { + return fmt.Errorf("could not add constraint: %w", err) + } + } + + return nil +} + +func loadManifestObjects(ctx context.Context, c *constraintclient.Client, objects []*unstructured.Unstructured) error { + // AddData inserts the provided data into OPA for every target that can handle the data. + // On error, the responses return value will still be populated so that + // partial results can be analyzed. + for _, o := range objects { + _, err := c.AddData(ctx, o) + if err != nil { + return fmt.Errorf("could not add data: %w", err) + } + } + + return nil +} + +// IsDirectory determines if a file represented by path is a directory or not +func IsDirectory(path string) (bool, error) { + fileInfo, err := os.Stat(path) + if err != nil { + return false, err + } + + return fileInfo.IsDir(), nil +} + +// IsYAML determines if a file is of the YAML extension or not +func IsYAML(path string) bool { + return filepath.Ext(path) == ".yaml" || filepath.Ext(path) == ".yml" +} + +// GetManifestFiles uses filepath.Walk to retrieve a list of the manifest files within the given manifest path +func GetManifestFiles(p string) ([]ManifestFile, error) { + var manifestFiles []ManifestFile + + err := filepath.Walk(p, func(walkPath string, info fs.FileInfo, err error) error { + manifest := ManifestFile{} + // skip when walkPath is just given path and also a directory + if p == walkPath && info.IsDir() { + return nil + } + + if err != nil { + return fmt.Errorf("error walking path %s with error: %w", walkPath, err) + } + + if !info.IsDir() && info.Name() != "" && IsYAML(walkPath) { + log.Debugf("%s is not a directory, appending to manifestFiles", info.Name()) + + manifest.Name = info.Name() + manifest.Path = walkPath + manifestFiles = append(manifestFiles, manifest) + } else if !IsYAML(p) { + log.Debugf("%s is not a manifest file, skipping...", info.Name()) + } else { + log.Debugf("%s is a directory, skipping...", info.Name()) + } + + return nil + }) + if err != nil { + return nil, fmt.Errorf("could not walk directory: %w", err) + } + if len(manifestFiles) == 0 { + return nil, fmt.Errorf("no manifest files found within given path") + } + + return manifestFiles, nil +} + +// getObjectViolations executes validation on manifests based on loaded constraint templates and returns a map of manifest name to list of objectViolations +func getObjectViolations(ctx context.Context, c *constraintclient.Client, objects []*unstructured.Unstructured) (map[string][]string, error) { + // Review makes sure the provided object satisfies all stored constraints. + // On error, the responses return value will still be populated so that + // partial results can be analyzed. + + var results = make(map[string][]string) // map of object name to slice of objectViolations + + for _, o := range objects { + objectViolations := []string{} + log.Debugf("Reviewing %s...", o.GetName()) + res, err := c.Review(ctx, o) + if err != nil { + return results, fmt.Errorf("could not review objects: %w", err) + } + + for _, v := range res.ByTarget { + for _, result := range v.Results { + if result.Msg != "" { + objectViolations = append(objectViolations, result.Msg) + } + } + } + + if len(objectViolations) > 0 { + results[o.GetName()] = objectViolations + } + } + + return results, nil +} diff --git a/pkg/safeguards/helpers_test.go b/pkg/safeguards/helpers_test.go new file mode 100644 index 000000000..255b7caab --- /dev/null +++ b/pkg/safeguards/helpers_test.go @@ -0,0 +1,67 @@ +package safeguards + +import ( + "context" + "testing" + + constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" + "github.com/stretchr/testify/assert" +) + +func validateOneTestManifestFail(ctx context.Context, t *testing.T, c *constraintclient.Client, testFc FileCrawler, testManifestPaths []string) { + for _, path := range testManifestPaths { + errManifests, err := testFc.ReadManifests(path) + assert.Nil(t, err) + + err = loadManifestObjects(ctx, c, errManifests) + assert.Nil(t, err) + + // error case - should throw error + violations, err := getObjectViolations(ctx, c, errManifests) + assert.Nil(t, err) + assert.Greater(t, len(violations), 0) + } +} + +func validateOneTestManifestSuccess(ctx context.Context, t *testing.T, c *constraintclient.Client, testFc FileCrawler, testManifestPaths []string) { + for _, path := range testManifestPaths { + successManifests, err := testFc.ReadManifests(path) + assert.Nil(t, err) + + err = loadManifestObjects(ctx, c, successManifests) + assert.Nil(t, err) + + // success case - should not throw error + violations, err := getObjectViolations(ctx, c, successManifests) + assert.Nil(t, err) + assert.Equal(t, 0, len(violations)) + } +} + +func validateAllTestManifestsFail(ctx context.Context, t *testing.T, c *constraintclient.Client, testFc FileCrawler, testManifestPaths []string) { + for _, path := range testManifestPaths { + manifestFiles, err := GetManifestFiles(path) + assert.Nil(t, err) + + // error case - should throw error + results, err := GetManifestResults(ctx, manifestFiles) + for _, mr := range results { + assert.Nil(t, err) + assert.Greater(t, mr.ViolationsCount, 0) + } + } +} + +func validateAllTestManifestsSuccess(ctx context.Context, t *testing.T, c *constraintclient.Client, testFc FileCrawler, testManifestPaths []string) { + for _, path := range testManifestPaths { + manifestFiles, err := GetManifestFiles(path) + assert.Nil(t, err) + + // success case - should not throw error + results, err := GetManifestResults(ctx, manifestFiles) + for _, mr := range results { + assert.Nil(t, err) + assert.Equal(t, mr.ViolationsCount, 0) + } + } +} diff --git a/pkg/safeguards/lib/v1.0.0/container-allowed-images/constraint.yaml b/pkg/safeguards/lib/v1.0.0/container-allowed-images/constraint.yaml new file mode 100644 index 000000000..e7570d3ab --- /dev/null +++ b/pkg/safeguards/lib/v1.0.0/container-allowed-images/constraint.yaml @@ -0,0 +1,12 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sAzureV2ContainerAllowedImages +metadata: + name: v2-container-allowed-images +spec: + match: + kinds: + - apiGroups: ["apps"] + kinds: ["Deployment"] + parameters: + imageRegex: ".*" + excludedContainers: [] \ No newline at end of file diff --git a/pkg/safeguards/lib/v1.0.0/container-allowed-images/template.yaml b/pkg/safeguards/lib/v1.0.0/container-allowed-images/template.yaml new file mode 100644 index 000000000..f479c503d --- /dev/null +++ b/pkg/safeguards/lib/v1.0.0/container-allowed-images/template.yaml @@ -0,0 +1,43 @@ +apiVersion: templates.gatekeeper.sh/v1beta1 +kind: ConstraintTemplate +metadata: + name: k8sazurev2containerallowedimages +spec: + crd: + spec: + names: + kind: K8sAzureV2ContainerAllowedImages + validation: + # Schema for the `parameters` field + openAPIV3Schema: + properties: + imageRegex: + type: string + excludedContainers: + type: array + items: + type: string + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package k8sazurev2containerallowedimages + + violation[{"msg": msg}] { + container := input_containers[_] + not input_container_excluded(container.name) + not regex.match(input.parameters.imageRegex, container.image) + msg := sprintf("Container image %v for container %v has not been allowed.", [container.image, container.name]) + } + + input_containers[c] { + c := input.review.object.spec.template.spec.containers[_] + } + input_containers[c] { + c := input.review.object.spec.template.spec.initContainers[_] + } + input_containers[c] { + c := input.review.object.spec.template.spec.ephemeralContainers[_] + } + input_container_excluded(field) { + field == input.parameters.excludedContainers[_] + } \ No newline at end of file diff --git a/pkg/safeguards/lib/v1.0.0/container-enforce-probes/constraint.yaml b/pkg/safeguards/lib/v1.0.0/container-enforce-probes/constraint.yaml new file mode 100644 index 000000000..927f4c101 --- /dev/null +++ b/pkg/safeguards/lib/v1.0.0/container-enforce-probes/constraint.yaml @@ -0,0 +1,15 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sAzureV2ContainerEnforceProbes +metadata: + name: v2-container-enforce-probes +spec: + match: + kinds: + - apiGroups: ["apps"] + kinds: ["Deployment"] + - apiGroups: [""] + kinds: ["Pod"] + parameters: + enforceProbes : ["livenessProbe", "readinessProbe"] + excludedContainers: [] + excludedImages: [] diff --git a/pkg/safeguards/lib/v1.0.0/container-enforce-probes/template.yaml b/pkg/safeguards/lib/v1.0.0/container-enforce-probes/template.yaml new file mode 100644 index 000000000..de51ce954 --- /dev/null +++ b/pkg/safeguards/lib/v1.0.0/container-enforce-probes/template.yaml @@ -0,0 +1,95 @@ +apiVersion: templates.gatekeeper.sh/v1beta1 +kind: ConstraintTemplate +metadata: + name: k8sazurev2containerenforceprobes +spec: + crd: + spec: + names: + kind: K8sAzureV2ContainerEnforceProbes + validation: + openAPIV3Schema: + properties: + enforceProbes: + type: array + items: + type: string + excludedContainers: + type: array + items: + type: string + excludedImages: + description: >- + Any container that uses an image that matches an entry in this list will be excluded + from enforcement. Prefix-matching can be signified with `*`. For example: `my-image-*`. + It is recommended that users use the fully-qualified Docker image name (e.g. start with a domain name) + in order to avoid unexpectedly excluding images from an untrusted repository. + type: array + items: + type: string + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package k8sazurev2containerenforceprobes + + import data.lib.exclude_container_image.is_excluded + + # Rule: + ## Parameter enforceProbes is one string array that will define which kinds of probes to be enforced for all the containers (init container excludes). The allowed values could be livenessProbes and readinessProbes for now + ## Once certain probe is enforces, e.g. livenessProbes, the policy will check on all containers(except init) if they have livenessProbes field. Besides, the probes should at least have defined one of the probe_types, "tcpSocket", "httpGet" or "exec" + + probe_type_set = probe_types { + probe_types := {type | type := ["tcpSocket", "httpGet", "exec"][_]} + } + violation[{"msg": msg}] { + container := input_containers[_] + not input_container_excluded(container.name) + not is_excluded(container) + probe := input.parameters.enforceProbes[_] + probe_is_missing(container, probe) + msg := get_violation_message(container, input.review, probe) + } + probe_is_missing(ctr, probe) = true { + not ctr[probe] + } + probe_is_missing(ctr, probe) = true { + probe_field_empty(ctr, probe) + } + probe_field_empty(ctr, probe) = true { + probe_fields := {field | ctr[probe][field]} + diff_fields := probe_type_set - probe_fields + count(diff_fields) == count(probe_type_set) + } + get_violation_message(container, review, probe) = msg { + msg := sprintf("Container <%v> in your Deployment <%v> has no <%v>. Required probes: %v", [container.name, review.object.metadata.name, probe, input.parameters.enforceProbes]) + } + + input_containers[c] { + c := input.review.object.spec.template.spec.containers[_] + } + + input_containers[c] { + c := input.review.object.spec.containers[_] + } + + input_container_excluded(field) { + field == input.parameters.excludedContainers[_] + } + libs: + - | + package lib.exclude_container_image + is_excluded(container) { + exclude_images := object.get(object.get(input, "parameters", {}), "excludedImages", []) + img := container.image + exclusion := exclude_images[_] + _matches_exclusion(img, exclusion) + } + _matches_exclusion(img, exclusion) { + not endswith(exclusion, "*") + exclusion == img + } + _matches_exclusion(img, exclusion) { + endswith(exclusion, "*") + prefix := trim_suffix(exclusion, "*") + startswith(img, prefix) + } diff --git a/pkg/safeguards/lib/v1.0.0/container-resource-limits/constraint.yaml b/pkg/safeguards/lib/v1.0.0/container-resource-limits/constraint.yaml new file mode 100644 index 000000000..d84442dd8 --- /dev/null +++ b/pkg/safeguards/lib/v1.0.0/container-resource-limits/constraint.yaml @@ -0,0 +1,14 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sAzureV3ContainerLimits +metadata: + name: v3-container-limits +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + cpuLimit : "200m" + memoryLimit: "1Gi" + excludedContainers: [] + excludedImages: [] diff --git a/pkg/safeguards/lib/v1.0.0/container-resource-limits/template.yaml b/pkg/safeguards/lib/v1.0.0/container-resource-limits/template.yaml new file mode 100644 index 000000000..ec28ec2b4 --- /dev/null +++ b/pkg/safeguards/lib/v1.0.0/container-resource-limits/template.yaml @@ -0,0 +1,263 @@ +apiVersion: templates.gatekeeper.sh/v1beta1 +kind: ConstraintTemplate +metadata: + name: k8sazurev3containerlimits +spec: + crd: + spec: + names: + kind: K8sAzureV3ContainerLimits + validation: + # Schema for the `parameters` field + openAPIV3Schema: + properties: + cpuLimit: + type: string + memoryLimit: + type: string + excludedContainers: + type: array + items: + type: string + excludedImages: + description: >- + Any container that uses an image that matches an entry in this list will be excluded + from enforcement. Prefix-matching can be signified with `*`. For example: `my-image-*`. + It is recommended that users use the fully-qualified Docker image name (e.g. start with a domain name) + in order to avoid unexpectedly excluding images from an untrusted repository. + type: array + items: + type: string + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package k8sazurev3containerlimits + + import data.lib.exclude_container_image.is_excluded + + missing(obj, field) = true { + not obj[field] + } + + missing(obj, field) = true { + obj[field] == "" + } + + canonify_cpu(orig) = new { + is_number(orig) + new := orig * 1000 + } + + canonify_cpu(orig) = new { + not is_number(orig) + endswith(orig, "m") + new := to_number(replace(orig, "m", "")) + } + + canonify_cpu(orig) = new { + not is_number(orig) + not endswith(orig, "m") + re_match("^[0-9]+(\\.[0-9]+)?$", orig) + new := to_number(orig) * 1000 + } + + # 10 ** 21 + mem_multiple("E") = 1000000000000000000000 { true } + + # 10 ** 18 + mem_multiple("P") = 1000000000000000000 { true } + + # 10 ** 15 + mem_multiple("T") = 1000000000000000 { true } + + # 10 ** 12 + mem_multiple("G") = 1000000000000 { true } + + # 10 ** 9 + mem_multiple("M") = 1000000000 { true } + + # 10 ** 6 + mem_multiple("k") = 1000000 { true } + + # 10 ** 3 + mem_multiple("") = 1000 { true } + + # Kubernetes accepts millibyte precision when it probably shouldn't. + # https://github.com/kubernetes/kubernetes/issues/28741 + # 10 ** 0 + mem_multiple("m") = 1 { true } + + # 1000 * 2 ** 10 + mem_multiple("Ki") = 1024000 { true } + + # 1000 * 2 ** 20 + mem_multiple("Mi") = 1048576000 { true } + + # 1000 * 2 ** 30 + mem_multiple("Gi") = 1073741824000 { true } + + # 1000 * 2 ** 40 + mem_multiple("Ti") = 1099511627776000 { true } + + # 1000 * 2 ** 50 + mem_multiple("Pi") = 1125899906842624000 { true } + + # 1000 * 2 ** 60 + mem_multiple("Ei") = 1152921504606846976000 { true } + + get_suffix(mem) = suffix { + not is_string(mem) + suffix := "" + } + + get_suffix(mem) = suffix { + is_string(mem) + count(mem) > 0 + suffix := substring(mem, count(mem) - 1, -1) + mem_multiple(suffix) + } + + get_suffix(mem) = suffix { + is_string(mem) + count(mem) > 1 + suffix := substring(mem, count(mem) - 2, -1) + mem_multiple(suffix) + } + + get_suffix(mem) = suffix { + is_string(mem) + count(mem) > 1 + not mem_multiple(substring(mem, count(mem) - 1, -1)) + not mem_multiple(substring(mem, count(mem) - 2, -1)) + suffix := "" + } + + get_suffix(mem) = suffix { + is_string(mem) + count(mem) == 1 + not mem_multiple(substring(mem, count(mem) - 1, -1)) + suffix := "" + } + + get_suffix(mem) = suffix { + is_string(mem) + count(mem) == 0 + suffix := "" + } + + canonify_mem(orig) = new { + is_number(orig) + new := orig * 1000 + } + + canonify_mem(orig) = new { + not is_number(orig) + suffix := get_suffix(orig) + raw := replace(orig, suffix, "") + re_match("^[0-9]+(\\.[0-9]+)?$", raw) + new := to_number(raw) * mem_multiple(suffix) + } + + violation[{"msg": msg}] { + general_violation[{"msg": msg, "field": "containers"}] + } + + violation[{"msg": msg}] { + general_violation[{"msg": msg, "field": "initContainers"}] + } + + general_violation[{"msg": msg, "field": field}] { + container := input.review.object.spec[field][_] + not input_container_excluded(container.name) + not is_excluded(container) + cpu_orig := container.resources.limits.cpu + not canonify_cpu(cpu_orig) + msg := sprintf("container <%v> cpu limit <%v> could not be parsed", [container.name, cpu_orig]) + } + + general_violation[{"msg": msg, "field": field}] { + container := input.review.object.spec[field][_] + not input_container_excluded(container.name) + not is_excluded(container) + mem_orig := container.resources.limits.memory + not canonify_mem(mem_orig) + msg := sprintf("container <%v> memory limit <%v> could not be parsed", [container.name, mem_orig]) + } + + general_violation[{"msg": msg, "field": field}] { + container := input.review.object.spec[field][_] + not input_container_excluded(container.name) + not is_excluded(container) + not container.resources + msg := sprintf("container <%v> has no resource limits", [container.name]) + } + + general_violation[{"msg": msg, "field": field}] { + container := input.review.object.spec[field][_] + not input_container_excluded(container.name) + not is_excluded(container) + not container.resources.limits + msg := sprintf("container <%v> has no resource limits", [container.name]) + } + + general_violation[{"msg": msg, "field": field}] { + container := input.review.object.spec[field][_] + not input_container_excluded(container.name) + not is_excluded(container) + missing(container.resources.limits, "cpu") + msg := sprintf("container <%v> has no cpu limit", [container.name]) + } + + general_violation[{"msg": msg, "field": field}] { + container := input.review.object.spec[field][_] + not input_container_excluded(container.name) + not is_excluded(container) + missing(container.resources.limits, "memory") + msg := sprintf("container <%v> has no memory limit", [container.name]) + } + + general_violation[{"msg": msg, "field": field}] { + container := input.review.object.spec[field][_] + not input_container_excluded(container.name) + not is_excluded(container) + cpu_orig := container.resources.limits.cpu + cpu := canonify_cpu(cpu_orig) + max_cpu_orig := input.parameters.cpuLimit + max_cpu := canonify_cpu(max_cpu_orig) + cpu > max_cpu + msg := sprintf("container <%v> cpu limit <%v> is higher than the maximum allowed of <%v>", [container.name, cpu_orig, max_cpu_orig]) + } + + general_violation[{"msg": msg, "field": field}] { + container := input.review.object.spec[field][_] + not input_container_excluded(container.name) + not is_excluded(container) + mem_orig := container.resources.limits.memory + mem := canonify_mem(mem_orig) + max_mem_orig := input.parameters.memoryLimit + max_mem := canonify_mem(max_mem_orig) + mem > max_mem + msg := sprintf("container <%v> memory limit <%v> is higher than the maximum allowed of <%v>", [container.name, mem_orig, max_mem_orig]) + } + + input_container_excluded(field) { + field == input.parameters.excludedContainers[_] + } + libs: + - | + package lib.exclude_container_image + is_excluded(container) { + exclude_images := object.get(object.get(input, "parameters", {}), "excludedImages", []) + img := container.image + exclusion := exclude_images[_] + _matches_exclusion(img, exclusion) + } + _matches_exclusion(img, exclusion) { + not endswith(exclusion, "*") + exclusion == img + } + _matches_exclusion(img, exclusion) { + endswith(exclusion, "*") + prefix := trim_suffix(exclusion, "*") + startswith(img, prefix) + } diff --git a/pkg/safeguards/lib/v1.0.0/container-restricted-image-pulls/constraint.yaml b/pkg/safeguards/lib/v1.0.0/container-restricted-image-pulls/constraint.yaml new file mode 100644 index 000000000..397ec3f6e --- /dev/null +++ b/pkg/safeguards/lib/v1.0.0/container-restricted-image-pulls/constraint.yaml @@ -0,0 +1,13 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sAzureV1ContainerRestrictedImagePulls +metadata: + name: v1-container-restricted-image-pulls +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + - apiGroups: ["apps"] + kinds: ["Deployment"] + parameters: + excludedImages: [] diff --git a/pkg/safeguards/lib/v1.0.0/container-restricted-image-pulls/template.yaml b/pkg/safeguards/lib/v1.0.0/container-restricted-image-pulls/template.yaml new file mode 100644 index 000000000..1b0fef2d6 --- /dev/null +++ b/pkg/safeguards/lib/v1.0.0/container-restricted-image-pulls/template.yaml @@ -0,0 +1,76 @@ +apiVersion: templates.gatekeeper.sh/v1beta1 +kind: ConstraintTemplate +metadata: + name: k8sazurev1containerrestrictedimagepulls +spec: + crd: + spec: + names: + kind: K8sAzureV1ContainerRestrictedImagePulls + validation: + # Schema for the `parameters` field + openAPIV3Schema: + properties: + excludedImages: + type: array + items: + type: string + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package k8sazurev1containerrestrictedimagepulls + + has_key(object, key) { + _ = object[key] + } + + violation[{"msg": msg}] { + container := input_containers[_] + not is_excluded(container) + not has_key(input.review.object.spec, "imagePullSecrets") + namespace := input.review.namespace + pod := input.review.object.metadata.name + msg := sprintf("%s in %s does not have imagePullSecrets. Unauthenticated image pulls are not recommended.", [pod, namespace]) + } + + input_containers[c] { + c := input.review.object.spec.containers[_] + } + + input_containers[c] { + c := input.review.object.spec.initContainers[_] + } + + input_containers[c] { + c := input.review.object.spec.ephemeralContainers[_] + } + + input_containers[c] { + c := input.review.object.spec.template.spec.containers[_] + } + + input_containers[c] { + c := input.review.object.spec.template.spec.initContainers[_] + } + + input_containers[c] { + c := input.review.object.spec.template.spec.ephemeralContainers[_] + } + + is_excluded(container) { + exclude_images := object.get(object.get(input, "parameters", {}), "excludedImages", []) + img := container.image + exclusion := exclude_images[_] + matches_exclusion(img, exclusion) + } + + matches_exclusion(img, exclusion) { + not endswith(exclusion, "*") + exclusion == img + } + + matches_exclusion(img, exclusion) { + endswith(exclusion, "*") + prefix := trim_suffix(exclusion, "*") + startswith(img, prefix) + } diff --git a/pkg/safeguards/lib/v1.0.0/disallowed-bad-pod-disruption-budgets/constraint.yaml b/pkg/safeguards/lib/v1.0.0/disallowed-bad-pod-disruption-budgets/constraint.yaml new file mode 100644 index 000000000..b7cdf7dac --- /dev/null +++ b/pkg/safeguards/lib/v1.0.0/disallowed-bad-pod-disruption-budgets/constraint.yaml @@ -0,0 +1,11 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sAzureV1DisallowedBadPodDisruptionBudgets +metadata: + name: v1-disallowed-bad-pod-disruption-budgets +spec: + match: + kinds: + - apiGroups: ["apps"] + kinds: ["Deployment", "ReplicaSet", "StatefulSet"] + - apiGroups: ["policy"] + kinds: ["PodDisruptionBudget"] \ No newline at end of file diff --git a/pkg/safeguards/lib/v1.0.0/disallowed-bad-pod-disruption-budgets/template.yaml b/pkg/safeguards/lib/v1.0.0/disallowed-bad-pod-disruption-budgets/template.yaml new file mode 100644 index 000000000..57be9db90 --- /dev/null +++ b/pkg/safeguards/lib/v1.0.0/disallowed-bad-pod-disruption-budgets/template.yaml @@ -0,0 +1,111 @@ +apiVersion: templates.gatekeeper.sh/v1beta1 +kind: ConstraintTemplate +metadata: + name: k8sazurev1disallowedbadpoddisruptionbudgets + annotations: + metadata.gatekeeper.sh/title: "Pod Disruption Budget" + metadata.gatekeeper.sh/version: 1.0.0 + metadata.gatekeeper.sh/requires-sync-data: | + "[ + [ + { + "groups": ["policy"], + "versions": ["v1"], + "kinds": ["PodDisruptionBudget"] + }, + { + "groups": ["apps"], + "versions": ["v1"], + "kinds": ["StatefulSet", "ReplicaSet", "Deployment"] + } + ] + ]" + description: Prevents customers from applying bad Pod Disruption Budgets +spec: + crd: + spec: + names: + kind: K8sAzureV1DisallowedBadPodDisruptionBudgets + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package k8sazurev1disallowedbadpoddisruptionbudgets + + violation[{"msg": msg}] { + input.review.kind.kind == "PodDisruptionBudget" + pdb := input.review.object + not valid_pdb_max_unavailable(pdb) + msg := sprintf( + "PodDisruptionBudget <%s> has maxUnavailable of 0, only positive integers are allowed for maxUnavailable", + [pdb.metadata.name] + ) + } + + violation[{"msg": msg}] { + obj := input.review.object + pdb := data.inventory.namespace[obj.metadata.namespace]["policy/v1"].PodDisruptionBudget[_] + obj.spec.selector.matchLabels == pdb.spec.selector.matchLabels + not valid_pdb_max_unavailable(pdb) + msg := sprintf( + "%s <%s> has been selected by PodDisruptionBudget <%s> but has maxUnavailable of 0, only positive integers are allowed for maxUnavailable", + [obj.kind, obj.metadata.name, pdb.metadata.name] + ) + } + + violation[{"msg": msg}] { + obj := input.review.object + pdb := data.inventory.namespace[obj.metadata.namespace]["policy/v1"].PodDisruptionBudget[_] + obj.spec.selector.matchLabels == pdb.spec.selector.matchLabels + not valid_pdb_min_available(obj, pdb) + msg := sprintf("%s <%s> has %d replica(s) but PodDisruptionBudget <%s> has minAvailable of %d, only positive integers less than %d are allowed for minAvailable", + [obj.kind, obj.metadata.name, obj.spec.replicas, pdb.metadata.name, pdb.spec.minAvailable, obj.spec.replicas]) + } + + violation[{"msg":msg}] { + input.review.kind.kind == "PodDisruptionBudget" + pdb := input.review.object + + matchingDeploys := {x | x.spec.selector.matchLabels == pdb.spec.selector.matchLabels; x = data.inventory.namespace[pdb.metadata.namespace]["apps/v1"].Deployment[_]} + deploy := matchingDeploys[_] + not valid_pdb_min_available(deploy, pdb) + + msg := sprintf("PodDisruptionBudget %s specifies minAvailable of %d, but matching Deployment %s has %d replicas. minAvailable should be less than %d",[pdb.metadata.name,pdb.spec.minAvailable,deploy.metadata.name,deploy.spec.replicas,deploy.spec.replicas]) + } + + violation[{"msg":msg}] { + input.review.kind.kind == "PodDisruptionBudget" + pdb := input.review.object + + matchingSS := {x | x.spec.selector.matchLabels == pdb.spec.selector.matchLabels; x = data.inventory.namespace[pdb.metadata.namespace]["apps/v1"].StatefulSet[_]} + ss := matchingSS[_] + not valid_pdb_min_available(ss, pdb) + + msg := sprintf("PodDisruptionBudget %s specifies minAvailable of %d, but matching StatefulSet %s has %d replicas. minAvailable should be less than %d",[pdb.metadata.name,pdb.spec.minAvailable,ss.metadata.name,ss.spec.replicas,ss.spec.replicas]) + } + + violation[{"msg":msg}] { + input.review.kind.kind == "PodDisruptionBudget" + pdb := input.review.object + + matchingRS := {x | x.spec.selector.matchLabels == pdb.spec.selector.matchLabels; x = data.inventory.namespace[pdb.metadata.namespace]["apps/v1"].ReplicaSet[_]} + rs := matchingRS[_] + not valid_pdb_min_available(rs, pdb) + + msg := sprintf("PodDisruptionBudget %s specifies minAvailable of %d, but matching ReplicaSet %s has %d replicas. minAvailable should be less than %d",[pdb.metadata.name,pdb.spec.minAvailable,rs.metadata.name,rs.spec.replicas,rs.spec.replicas]) + } + + valid_pdb_min_available(obj, pdb) { + # default to -1 if minAvailable is not set so valid_pdb_min_available is always true + # for objects with >= 0 replicas. If minAvailable defaults to >= 0, objects with + # replicas field might violate this constraint if they are equal to the default set here + min_available := object.get(pdb.spec, "minAvailable", -1) + obj.spec.replicas > min_available + } + + valid_pdb_max_unavailable(pdb) { + # default to 1 if maxUnavailable is not set so valid_pdb_max_unavailable always returns true. + # If maxUnavailable defaults to 0, it violates this constraint because all pods needs to be + # available and no pods can be evicted voluntarily + max_unavailable := object.get(pdb.spec, "maxUnavailable", 1) + max_unavailable > 0 + } \ No newline at end of file diff --git a/pkg/safeguards/lib/v1.0.0/pod-enforce-antiaffinity/constraint.yaml b/pkg/safeguards/lib/v1.0.0/pod-enforce-antiaffinity/constraint.yaml new file mode 100644 index 000000000..a2e037dcc --- /dev/null +++ b/pkg/safeguards/lib/v1.0.0/pod-enforce-antiaffinity/constraint.yaml @@ -0,0 +1,9 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sAzureV1AntiAffinityRules +metadata: + name: v1-multiple-replicas-need-anti-affinity +spec: + match: + kinds: + - apiGroups: ["apps"] + kinds: ["Deployment","StatefulSet","ReplicationController","ReplicaSet"] \ No newline at end of file diff --git a/pkg/safeguards/lib/v1.0.0/pod-enforce-antiaffinity/template.yaml b/pkg/safeguards/lib/v1.0.0/pod-enforce-antiaffinity/template.yaml new file mode 100644 index 000000000..6e6545883 --- /dev/null +++ b/pkg/safeguards/lib/v1.0.0/pod-enforce-antiaffinity/template.yaml @@ -0,0 +1,25 @@ +apiVersion: templates.gatekeeper.sh/v1beta1 +kind: ConstraintTemplate +metadata: + name: k8sazurev1antiaffinityrules + annotations: + description: Requires deployments with multiple replicas have pod anti affinity rules +spec: + crd: + spec: + names: + kind: K8sAzureV1AntiAffinityRules + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package k8sazurev1antiaffinityrules + + missing_affinity(obj) { + not obj.affinity.podAntiAffinity + } + + violation[{"msg": msg}] { + input.review.object.spec.replicas > 1 + missing_affinity(input.review.object.spec.template.spec) + msg := sprintf("%s with %d replicas should have pod anti-affinity rules set to avoid disruptions due to nodes crashing", [input.review.kind.kind, input.review.object.spec.replicas]) + } \ No newline at end of file diff --git a/pkg/safeguards/lib/v1.0.0/restricted-taints/constraint.yaml b/pkg/safeguards/lib/v1.0.0/restricted-taints/constraint.yaml new file mode 100644 index 000000000..1ac015a6c --- /dev/null +++ b/pkg/safeguards/lib/v1.0.0/restricted-taints/constraint.yaml @@ -0,0 +1,11 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sAzureV1ReservedTaints +metadata: + name: v1-system-reserved-taints +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Node"] + parameters: + reservedTaints: ["CriticalAddonsOnly"] \ No newline at end of file diff --git a/pkg/safeguards/lib/v1.0.0/restricted-taints/template.yaml b/pkg/safeguards/lib/v1.0.0/restricted-taints/template.yaml new file mode 100644 index 000000000..ee17e48e8 --- /dev/null +++ b/pkg/safeguards/lib/v1.0.0/restricted-taints/template.yaml @@ -0,0 +1,43 @@ +apiVersion: templates.gatekeeper.sh/v1beta1 +kind: ConstraintTemplate +metadata: + name: k8sazurev1reservedtaints + annotations: + description: Restricts the CriticalAddonsOnly taint to just the system pool +spec: + crd: + spec: + names: + kind: K8sAzureV1ReservedTaints + validation: + openAPIV3Schema: + type: object + properties: + reservedTaints: + type: array + items: + type: string + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package k8sazurev1reservedtaints + + is_system_pool(node) { + node.metadata.labels["kubernetes.azure.com/mode"] == "system" + } + + is_system_pool(node) { + node.metadata.labels["kubernetes.azure.com/mode"] == "System" + } + + violation[{"msg": msg}] { + node := input.review.object + # did the customer try to add a taint with key "CriticalAddonsOnly" to a non-system pool? + taints := {x | x = node.spec.taints[_].key} + not is_system_pool(node) + taint := taints[_] + restrictedTaint := input.parameters.reservedTaints[_] + regex.match(restrictedTaint,taint) + + msg := sprintf("Taint with key <%s> is reserved for the system pool only",[taint]) + } \ No newline at end of file diff --git a/pkg/safeguards/lib/v1.0.0/unique-service-selectors/constraint.yaml b/pkg/safeguards/lib/v1.0.0/unique-service-selectors/constraint.yaml new file mode 100644 index 000000000..695fde133 --- /dev/null +++ b/pkg/safeguards/lib/v1.0.0/unique-service-selectors/constraint.yaml @@ -0,0 +1,9 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sAzureV1UniqueServiceSelector +metadata: + name: v1-unique-service-selector +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Service"] \ No newline at end of file diff --git a/pkg/safeguards/lib/v1.0.0/unique-service-selectors/template.yaml b/pkg/safeguards/lib/v1.0.0/unique-service-selectors/template.yaml new file mode 100644 index 000000000..9a97ac5ee --- /dev/null +++ b/pkg/safeguards/lib/v1.0.0/unique-service-selectors/template.yaml @@ -0,0 +1,70 @@ +apiVersion: templates.gatekeeper.sh/v1beta1 +kind: ConstraintTemplate +metadata: + name: k8sazurev1uniqueserviceselector + annotations: + metadata.gatekeeper.sh/title: "Unique Service Selectors" + metadata.gatekeeper.sh/version: 1.0.0 + metadata.gatekeeper.sh/requires-sync-data: | + "[ + [ + { + "groups": [""], + "versions": ["v1"], + "kinds": ["Service"] + } + ] + ]" + description: >- + Requires Services to have unique selectors within a namespace. + Selectors are considered the same if they have identical keys and values. + Selectors may share a key/value pair so long as there is at least one + distinct key/value pair between them. + + https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service +spec: + crd: + spec: + names: + kind: K8sAzureV1UniqueServiceSelector + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package k8sazurev1uniqueserviceselector + + make_apiversion(kind) = apiVersion { + g := kind.group + v := kind.version + g != "" + apiVersion = sprintf("%s/%s", [g, v]) + } + + make_apiversion(kind) = apiVersion { + kind.group == "" + apiVersion = kind.version + } + + identical(obj, review) { + obj.metadata.namespace == review.object.metadata.namespace + obj.metadata.name == review.object.metadata.name + obj.kind == review.kind.kind + obj.apiVersion == make_apiversion(review.kind) + } + + flatten_selector(obj) = flattened { + selectors := [s | s = concat(":", [key, val]); val = obj.spec.selector[key]] + flattened := concat(",", sort(selectors)) + } + + violation[{"msg": msg}] { + input.review.kind.kind == "Service" + input.review.kind.version == "v1" + input.review.kind.group == "" + input_namespace := input.review.object.metadata.namespace + input_selector := flatten_selector(input.review.object) + other := data.inventory.namespace[input_namespace]["v1"].Service[_] + not identical(other, input.review) + other_selector := flatten_selector(other) + input_selector == other_selector + msg := sprintf("same selector as service <%s> in namespace <%s>", [other.metadata.name, input_namespace]) + } \ No newline at end of file diff --git a/pkg/safeguards/manifestresults.go b/pkg/safeguards/manifestresults.go new file mode 100644 index 000000000..23d6df6a6 --- /dev/null +++ b/pkg/safeguards/manifestresults.go @@ -0,0 +1,100 @@ +package safeguards + +import ( + "context" + "embed" + "fmt" + + log "github.com/sirupsen/logrus" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +//go:embed lib +var embedFS embed.FS + +var fc FileCrawler + +// primes the scheme to be able to interpret beta templates +func init() { + + selectedVersion = getLatestSafeguardsVersion() + updateSafeguardPaths(&safeguards) + + fc = FileCrawler{ + Safeguards: safeguards, + constraintFS: embedFS, + } +} + +// GetManifestResults takes in a list of manifest files and returns a slice of ManifestViolation structs +func GetManifestResults(ctx context.Context, manifestFiles []ManifestFile) ([]ManifestResult, error) { + if len(manifestFiles) == 0 { + return nil, fmt.Errorf("path cannot be empty") + } + + manifestResults := make([]ManifestResult, 0) + + // constraint client instantiation + c, err := getConstraintClient() + if err != nil { + return manifestResults, err + } + + // retrieval of templates, constraints, and deployment + constraintTemplates, err := fc.ReadConstraintTemplates() + if err != nil { + return manifestResults, err + } + constraints, err := fc.ReadConstraints() + if err != nil { + return manifestResults, err + } + + // loading of templates, constraints into constraint client + err = loadConstraintTemplates(ctx, c, constraintTemplates) + if err != nil { + return manifestResults, err + } + err = loadConstraints(ctx, c, constraints) + if err != nil { + return manifestResults, err + } + + // organized map of manifest object by file name + manifestMap := make(map[string][]*unstructured.Unstructured, 0) + // aggregate of every manifest object into one list + allManifestObjects := []*unstructured.Unstructured{} + for _, m := range manifestFiles { + manifestObjects, err := fc.ReadManifests(m.Path) // read all the objects stored in a single file + if err != nil { + log.Errorf("reading objects %s", err.Error()) + return manifestResults, err + } + + allManifestObjects = append(allManifestObjects, manifestObjects...) + manifestMap[m.Name] = manifestObjects + } + + if len(allManifestObjects) > 0 { + err = loadManifestObjects(ctx, c, allManifestObjects) + } + + for _, m := range manifestFiles { + var objectViolations map[string][]string + + // validation of deployment manifest with constraints, templates loaded + objectViolations, err = getObjectViolations(ctx, c, manifestMap[m.Name]) + if err != nil { + log.Errorf("validating objects: %s", err.Error()) + return manifestResults, err + } + manifestResults = append(manifestResults, ManifestResult{ + Name: m.Name, + ObjectViolations: objectViolations, + ViolationsCount: len(objectViolations), + }) + } + + return manifestResults, nil +} diff --git a/pkg/safeguards/manifestresults_test.go b/pkg/safeguards/manifestresults_test.go new file mode 100644 index 000000000..729032feb --- /dev/null +++ b/pkg/safeguards/manifestresults_test.go @@ -0,0 +1,240 @@ +package safeguards + +import ( + "context" + "testing" + + "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" + "github.com/stretchr/testify/assert" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +var ctx = context.Background() +var testFc FileCrawler + +func init() { + selectedVersion = getLatestSafeguardsVersion() + updateSafeguardPaths(&safeguardsTesting) + + testFc = FileCrawler{ + Safeguards: safeguardsTesting, + constraintFS: embedFS, + } +} + +// TestValidateDeployment_ContainerAllowedImages tests our Container Allowed Images manifest +func TestValidateDeployment_ContainerAllowedImages(t *testing.T) { + // instantiate constraint client + c, err := getConstraintClient() + assert.Nil(t, err) + + // retrieving template, constraint, and deployments + constraintTemplate, err := testFc.ReadConstraintTemplate(testManifest_CAI.Name) + assert.Nil(t, err) + constraint, err := testFc.ReadConstraint(testManifest_CAI.Name) + assert.Nil(t, err) + + // load template, constraint into constraint client + err = loadConstraintTemplates(ctx, c, []*templates.ConstraintTemplate{constraintTemplate}) + assert.Nil(t, err) + err = loadConstraints(ctx, c, []*unstructured.Unstructured{constraint}) + assert.Nil(t, err) + + // validating deployment manifests + // tbarnes94: disabling failure case until we finalize logic on imageRegex for allowed images + //validateOneTestManifestFail(ctx, t, c, testFc, testManifest_CAI.ErrorPaths) + validateOneTestManifestSuccess(ctx, t, c, testFc, testManifest_CAI.SuccessPaths) +} + +// TestValidateDeployment_ContainerEnforceProbes tests our Container Enforce Probes manifest +func TestValidateDeployment_ContainerEnforceProbes(t *testing.T) { + // instantiate constraint client + c, err := getConstraintClient() + assert.Nil(t, err) + + // retrieving template, constraint, and deployments + constraintTemplate, err := testFc.ReadConstraintTemplate(testManifest_CEP.Name) + assert.Nil(t, err) + constraint, err := testFc.ReadConstraint(testManifest_CEP.Name) + assert.Nil(t, err) + + // load template, constraint into constraint client + err = loadConstraintTemplates(ctx, c, []*templates.ConstraintTemplate{constraintTemplate}) + assert.Nil(t, err) + err = loadConstraints(ctx, c, []*unstructured.Unstructured{constraint}) + assert.Nil(t, err) + + // validating deployment manifests + validateOneTestManifestFail(ctx, t, c, testFc, testManifest_CEP.ErrorPaths) + validateOneTestManifestSuccess(ctx, t, c, testFc, testManifest_CEP.SuccessPaths) +} + +// TestValidateDeployment_ContainerResourceLimits tests our Container Resource Limits manifest +func TestValidateDeployment_ContainerResourceLimits(t *testing.T) { + // instantiate constraint client + c, err := getConstraintClient() + assert.Nil(t, err) + + // retrieving template, constraint, and deployments + constraintTemplate, err := testFc.ReadConstraintTemplate(testManifest_CL.Name) + assert.Nil(t, err) + constraint, err := testFc.ReadConstraint(testManifest_CL.Name) + assert.Nil(t, err) + + // load template, constraint into constraint client + err = loadConstraintTemplates(ctx, c, []*templates.ConstraintTemplate{constraintTemplate}) + assert.Nil(t, err) + err = loadConstraints(ctx, c, []*unstructured.Unstructured{constraint}) + assert.Nil(t, err) + + // validating deployment manifests + validateOneTestManifestFail(ctx, t, c, testFc, testManifest_CL.ErrorPaths) + validateOneTestManifestSuccess(ctx, t, c, testFc, testManifest_CL.SuccessPaths) +} + +// TestValidateDeployment_ContainerRestrictedImagePulls tests our Container Restricted Image Pulls manifest +func TestValidateDeployment_ContainerRestrictedImagePulls(t *testing.T) { + // instantiate constraint client + c, err := getConstraintClient() + assert.Nil(t, err) + + // retrieving template, constraint, and deployments + constraintTemplate, err := testFc.ReadConstraintTemplate(testManifest_CRIP.Name) + assert.Nil(t, err) + constraint, err := testFc.ReadConstraint(testManifest_CRIP.Name) + assert.Nil(t, err) + + // load template, constraint into constraint client + err = loadConstraintTemplates(ctx, c, []*templates.ConstraintTemplate{constraintTemplate}) + assert.Nil(t, err) + err = loadConstraints(ctx, c, []*unstructured.Unstructured{constraint}) + assert.Nil(t, err) + + // validating deployment manifests + validateOneTestManifestFail(ctx, t, c, testFc, testManifest_CRIP.ErrorPaths) + validateOneTestManifestSuccess(ctx, t, c, testFc, testManifest_CRIP.SuccessPaths) +} + +// TestValidateDeployment_DisallowedBadPodDisruptionBudget tests our Disallowed Bad Pod Disruption Budget manifest +func TestValidateDeployment_DisallowedBadPodDisruptionBudget(t *testing.T) { + // instantiate constraint client + c, err := getConstraintClient() + assert.Nil(t, err) + + // retrieving template, constraint, and deployments + constraintTemplate, err := testFc.ReadConstraintTemplate(testManifest_DBPDB.Name) + assert.Nil(t, err) + constraint, err := testFc.ReadConstraint(testManifest_DBPDB.Name) + assert.Nil(t, err) + + // load template, constraint into constraint client + err = loadConstraintTemplates(ctx, c, []*templates.ConstraintTemplate{constraintTemplate}) + assert.Nil(t, err) + err = loadConstraints(ctx, c, []*unstructured.Unstructured{constraint}) + assert.Nil(t, err) + + // validating deployment manifests + validateOneTestManifestFail(ctx, t, c, testFc, testManifest_DBPDB.ErrorPaths) + validateOneTestManifestSuccess(ctx, t, c, testFc, testManifest_DBPDB.SuccessPaths) +} + +// TestValidateDeployment_PodEnforceAntiaffinity tests our Pod Enforce Antiaffinity manifest +func TestValidateDeployment_PodEnforceAntiaffinity(t *testing.T) { + // instantiate constraint client + c, err := getConstraintClient() + assert.Nil(t, err) + + // retrieving template, constraint, and deployments + constraintTemplate, err := testFc.ReadConstraintTemplate(testManifest_PEA.Name) + assert.Nil(t, err) + constraint, err := testFc.ReadConstraint(testManifest_PEA.Name) + assert.Nil(t, err) + + // load template, constraint into constraint client + err = loadConstraintTemplates(ctx, c, []*templates.ConstraintTemplate{constraintTemplate}) + assert.Nil(t, err) + err = loadConstraints(ctx, c, []*unstructured.Unstructured{constraint}) + assert.Nil(t, err) + + // validating deployment manifests + validateOneTestManifestFail(ctx, t, c, testFc, testManifest_PEA.ErrorPaths) + validateOneTestManifestSuccess(ctx, t, c, testFc, testManifest_PEA.SuccessPaths) +} + +// TestValidateDeployment_RestrictedTaints tests our Restricted Taints manifest +func TestValidateDeployment_RestrictedTaints(t *testing.T) { + // instantiate constraint client + c, err := getConstraintClient() + assert.Nil(t, err) + + // retrieving template, constraint, and deployments + constraintTemplate, err := testFc.ReadConstraintTemplate(testManifest_RT.Name) + assert.Nil(t, err) + constraint, err := testFc.ReadConstraint(testManifest_RT.Name) + assert.Nil(t, err) + + // load template, constraint into constraint client + err = loadConstraintTemplates(ctx, c, []*templates.ConstraintTemplate{constraintTemplate}) + assert.Nil(t, err) + err = loadConstraints(ctx, c, []*unstructured.Unstructured{constraint}) + assert.Nil(t, err) + + // validating deployment manifests + validateOneTestManifestFail(ctx, t, c, testFc, testManifest_RT.ErrorPaths) + validateOneTestManifestSuccess(ctx, t, c, testFc, testManifest_RT.SuccessPaths) +} + +// TestValidateDeployment_UniqueServiceSelectors tests our Unique Service Selectors manifest +func TestValidateDeployment_UniqueServiceSelectors(t *testing.T) { + // instantiate constraint client + c, err := getConstraintClient() + assert.Nil(t, err) + + // retrieving template, constraint, and deployments + constraintTemplate, err := testFc.ReadConstraintTemplate(testManifest_USS.Name) + assert.Nil(t, err) + constraint, err := testFc.ReadConstraint(testManifest_USS.Name) + assert.Nil(t, err) + + // load template, constraint into constraint client + err = loadConstraintTemplates(ctx, c, []*templates.ConstraintTemplate{constraintTemplate}) + assert.Nil(t, err) + err = loadConstraints(ctx, c, []*unstructured.Unstructured{constraint}) + assert.Nil(t, err) + + // validating deployment manifests + validateOneTestManifestFail(ctx, t, c, testFc, testManifest_USS.ErrorPaths) + validateOneTestManifestSuccess(ctx, t, c, testFc, testManifest_USS.SuccessPaths) +} + +// TestValidateDeployment_All tests all of our manifests in a few given manifest files +func TestValidateDeployment_All(t *testing.T) { + // instantiate constraint client + c, err := getConstraintClient() + assert.Nil(t, err) + + var testTemplates []*templates.ConstraintTemplate + var testConstraints []*unstructured.Unstructured + for _, sg := range safeguards { + // retrieving template, constraint, and deployments + constraintTemplate, err := testFc.ReadConstraintTemplate(sg.name) + assert.Nil(t, err) + testTemplates = append(testTemplates, constraintTemplate) + + constraint, err := testFc.ReadConstraint(sg.name) + assert.Nil(t, err) + testConstraints = append(testConstraints, constraint) + + } + + // load template, constraint into constraint client + err = loadConstraintTemplates(ctx, c, testTemplates) + assert.Nil(t, err) + err = loadConstraints(ctx, c, testConstraints) + assert.Nil(t, err) + + // validating deployment manifests + validateAllTestManifestsFail(ctx, t, c, testFc, testManifest_all.ErrorPaths) + validateAllTestManifestsSuccess(ctx, t, c, testFc, testManifest_all.SuccessPaths) +} diff --git a/pkg/safeguards/tests/all/error/all-error-manifest-1.yaml b/pkg/safeguards/tests/all/error/all-error-manifest-1.yaml new file mode 100644 index 000000000..156e79fb9 --- /dev/null +++ b/pkg/safeguards/tests/all/error/all-error-manifest-1.yaml @@ -0,0 +1,20 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-deployment-1 + labels: + app: my-app + environment: production +spec: + replicas: 3 + selector: + matchLabels: + app: my-app + template: + metadata: + labels: + app: my-app + spec: + containers: + - name: badcontainer + image: badimage \ No newline at end of file diff --git a/pkg/safeguards/tests/all/error/all-error-manifest-2.yaml b/pkg/safeguards/tests/all/error/all-error-manifest-2.yaml new file mode 100644 index 000000000..9428d5b73 --- /dev/null +++ b/pkg/safeguards/tests/all/error/all-error-manifest-2.yaml @@ -0,0 +1,20 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-deployment-2 + labels: + app: my-app + environment: production +spec: + replicas: 3 + selector: + matchLabels: + app: my-app + template: + metadata: + labels: + app: my-app + spec: + containers: + - name: badcontainer + image: badimage \ No newline at end of file diff --git a/pkg/safeguards/tests/all/success/all-success-manifest-1.yaml b/pkg/safeguards/tests/all/success/all-success-manifest-1.yaml new file mode 100644 index 000000000..97c1f0d22 --- /dev/null +++ b/pkg/safeguards/tests/all/success/all-success-manifest-1.yaml @@ -0,0 +1,52 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-deployment-1 + labels: + app: my-app + environment: production +spec: + replicas: 3 + selector: + matchLabels: + app: my-app + template: + metadata: + labels: + app: my-app + spec: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - store + topologyKey: "kubernetes.io/hostname" + containers: + - name: my-container + image: nginx:latest + resources: + limits: + cpu: "200m" + memory: "1Gi" + livenessProbe: + httpGet: + path: /healthz + port: 8080 + httpHeaders: + - name: my-liveness-probe + value: awesome + initialDelaySeconds: 3 + periodSeconds: 3 + readinessProbe: + httpGet: + path: /healthz + port: 8080 + httpHeaders: + - name: my-readiness-probe + value: awesome + initialDelaySeconds: 3 + periodSeconds: 3 \ No newline at end of file diff --git a/pkg/safeguards/tests/all/success/all-success-manifest-2.yaml b/pkg/safeguards/tests/all/success/all-success-manifest-2.yaml new file mode 100644 index 000000000..fb80b3a3f --- /dev/null +++ b/pkg/safeguards/tests/all/success/all-success-manifest-2.yaml @@ -0,0 +1,52 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-deployment-2 + labels: + app: my-app + environment: production +spec: + replicas: 3 + selector: + matchLabels: + app: my-app + template: + metadata: + labels: + app: my-app + spec: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - store + topologyKey: "kubernetes.io/hostname" + containers: + - name: my-container + image: nginx:latest + resources: + limits: + cpu: "200m" + memory: "1Gi" + livenessProbe: + httpGet: + path: /healthz + port: 8080 + httpHeaders: + - name: my-liveness-probe + value: awesome + initialDelaySeconds: 3 + periodSeconds: 3 + readinessProbe: + httpGet: + path: /healthz + port: 8080 + httpHeaders: + - name: my-readiness-probe + value: awesome + initialDelaySeconds: 3 + periodSeconds: 3 \ No newline at end of file diff --git a/pkg/safeguards/tests/container-allowed-images/CAI-error-manifest.yaml b/pkg/safeguards/tests/container-allowed-images/CAI-error-manifest.yaml new file mode 100644 index 000000000..797d537f8 --- /dev/null +++ b/pkg/safeguards/tests/container-allowed-images/CAI-error-manifest.yaml @@ -0,0 +1,20 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cai-error-manifest + labels: + app: my-app + environment: production +spec: + replicas: 3 + selector: + matchLabels: + app: my-app + template: + metadata: + labels: + app: my-app + spec: + containers: + - name: badcontainer + image: badimage \ No newline at end of file diff --git a/pkg/safeguards/tests/container-allowed-images/CAI-success-manifest.yaml b/pkg/safeguards/tests/container-allowed-images/CAI-success-manifest.yaml new file mode 100644 index 000000000..3d6dcb9ae --- /dev/null +++ b/pkg/safeguards/tests/container-allowed-images/CAI-success-manifest.yaml @@ -0,0 +1,20 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cai-success-manifest + labels: + app: my-app + environment: production +spec: + replicas: 3 + selector: + matchLabels: + app: my-app + template: + metadata: + labels: + app: my-app + spec: + containers: + - name: my-container + image: nginx:latest \ No newline at end of file diff --git a/pkg/safeguards/tests/container-enforce-probes/CEP-error-manifest.yaml b/pkg/safeguards/tests/container-enforce-probes/CEP-error-manifest.yaml new file mode 100644 index 000000000..5b36c87f3 --- /dev/null +++ b/pkg/safeguards/tests/container-enforce-probes/CEP-error-manifest.yaml @@ -0,0 +1,30 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-deployment + labels: + app: my-app + environment: production + testLabel3: randomlabel +spec: + replicas: 3 + selector: + matchLabels: + app: my-app + template: + metadata: + labels: + app: my-app + spec: + containers: + - name: badcontainer + image: badimage + livenessProbe: + httpGet: + path: /healthz + port: 8080 + httpHeaders: + - name: badprobe + value: awesome + initialDelaySeconds: 3 + periodSeconds: 3 \ No newline at end of file diff --git a/pkg/safeguards/tests/container-enforce-probes/CEP-success-manifest.yaml b/pkg/safeguards/tests/container-enforce-probes/CEP-success-manifest.yaml new file mode 100644 index 000000000..f61019bc0 --- /dev/null +++ b/pkg/safeguards/tests/container-enforce-probes/CEP-success-manifest.yaml @@ -0,0 +1,39 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-deployment + labels: + app: my-app + environment: production + testLabel3: randomlabel +spec: + replicas: 3 + selector: + matchLabels: + app: my-app + template: + metadata: + labels: + app: my-app + spec: + containers: + - name: my-container + image: nginx:latest + livenessProbe: + httpGet: + path: /healthz + port: 8080 + httpHeaders: + - name: my-liveness-probe + value: awesome + initialDelaySeconds: 3 + periodSeconds: 3 + readinessProbe: + httpGet: + path: /healthz + port: 8080 + httpHeaders: + - name: my-readiness-probe + value: awesome + initialDelaySeconds: 3 + periodSeconds: 3 \ No newline at end of file diff --git a/pkg/safeguards/tests/container-resource-limits/CRL-error-manifest.yaml b/pkg/safeguards/tests/container-resource-limits/CRL-error-manifest.yaml new file mode 100644 index 000000000..256b4c7d6 --- /dev/null +++ b/pkg/safeguards/tests/container-resource-limits/CRL-error-manifest.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Pod +metadata: + name: crl-error-manifest +spec: + containers: + - name: badcontainer + image: badimage diff --git a/pkg/safeguards/tests/container-resource-limits/CRL-success-manifest.yaml b/pkg/safeguards/tests/container-resource-limits/CRL-success-manifest.yaml new file mode 100644 index 000000000..439fc0fe9 --- /dev/null +++ b/pkg/safeguards/tests/container-resource-limits/CRL-success-manifest.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Pod +metadata: + name: crl-success-manifest +spec: + containers: + - name: my-container + image: nginx:latest + resources: + limits: + cpu: "200m" + memory: "1Gi" diff --git a/pkg/safeguards/tests/container-restricted-image-pulls/CRIP-error-manifest.yaml b/pkg/safeguards/tests/container-restricted-image-pulls/CRIP-error-manifest.yaml new file mode 100644 index 000000000..a951bfe8a --- /dev/null +++ b/pkg/safeguards/tests/container-restricted-image-pulls/CRIP-error-manifest.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: violation-example + namespace: default + labels: + app: scenario-container-allowed-images-violation +spec: + nodeSelector: + kubernetes.io/os: linux + containers: + - name: container1 + image: mcr.microsoft.com/oss/nginx/nginx:1.17.3-alpine + ports: + - containerPort: 8080 diff --git a/pkg/safeguards/tests/container-restricted-image-pulls/CRIP-success-manifest.yaml b/pkg/safeguards/tests/container-restricted-image-pulls/CRIP-success-manifest.yaml new file mode 100644 index 000000000..b5d4a9e7f --- /dev/null +++ b/pkg/safeguards/tests/container-restricted-image-pulls/CRIP-success-manifest.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Pod +metadata: + name: pass-example + namespace: default + labels: + app: scenario-container-allowed-images +spec: + nodeSelector: + kubernetes.io/os: linux + containers: + - name: container1 + image: mcr.microsoft.com/aks/policy/allowed:v1.0.0 # detects this field + ports: + - containerPort: 8080 + imagePullSecrets: + - name: my-secret diff --git a/pkg/safeguards/tests/disallowed-bad-pod-disruption-budgets/DBPDB-error-manifest.yaml b/pkg/safeguards/tests/disallowed-bad-pod-disruption-budgets/DBPDB-error-manifest.yaml new file mode 100644 index 000000000..052e0434b --- /dev/null +++ b/pkg/safeguards/tests/disallowed-bad-pod-disruption-budgets/DBPDB-error-manifest.yaml @@ -0,0 +1,13 @@ +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: error-pdb + labels: + app: my-error-pdb + environment: production +spec: + minAvailable: 0 + maxUnavailable: 0 + selector: + matchLabels: + app: my-error-pdb \ No newline at end of file diff --git a/pkg/safeguards/tests/disallowed-bad-pod-disruption-budgets/DBPDB-success-manifest.yaml b/pkg/safeguards/tests/disallowed-bad-pod-disruption-budgets/DBPDB-success-manifest.yaml new file mode 100644 index 000000000..755e7251b --- /dev/null +++ b/pkg/safeguards/tests/disallowed-bad-pod-disruption-budgets/DBPDB-success-manifest.yaml @@ -0,0 +1,13 @@ +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: success-pdb + labels: + app: my-success-pdb + environment: production +spec: + minAvailable: 5 + maxUnavailable: 1 + selector: + matchLabels: + app: my-success-pdb diff --git a/pkg/safeguards/tests/not-yaml/readme.md b/pkg/safeguards/tests/not-yaml/readme.md new file mode 100644 index 000000000..68a4528a6 --- /dev/null +++ b/pkg/safeguards/tests/not-yaml/readme.md @@ -0,0 +1 @@ +this is a test file \ No newline at end of file diff --git a/pkg/safeguards/tests/pod-enforce-antiaffinity/PEA-error-manifest.yaml b/pkg/safeguards/tests/pod-enforce-antiaffinity/PEA-error-manifest.yaml new file mode 100644 index 000000000..b6f9e8b81 --- /dev/null +++ b/pkg/safeguards/tests/pod-enforce-antiaffinity/PEA-error-manifest.yaml @@ -0,0 +1,21 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-deployment + labels: + app: my-app + environment: production + testLabel3: randomlabel +spec: + replicas: 3 + selector: + matchLabels: + app: my-app + template: + metadata: + labels: + app: my-app + spec: + containers: + - name: my-container + image: nginx:latest \ No newline at end of file diff --git a/pkg/safeguards/tests/pod-enforce-antiaffinity/PEA-success-manifest.yaml b/pkg/safeguards/tests/pod-enforce-antiaffinity/PEA-success-manifest.yaml new file mode 100644 index 000000000..c58b23b3b --- /dev/null +++ b/pkg/safeguards/tests/pod-enforce-antiaffinity/PEA-success-manifest.yaml @@ -0,0 +1,49 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-deployment + labels: + app: my-app + environment: production + testLabel3: randomlabel +spec: + replicas: 3 + selector: + matchLabels: + app: my-app + template: + metadata: + labels: + app: my-app + spec: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - store + topologyKey: "kubernetes.io/hostname" + containers: + - name: my-container + image: nginx:latest + livenessProbe: + httpGet: + path: /healthz + port: 8080 + httpHeaders: + - name: my-liveness-probe + value: awesome + initialDelaySeconds: 3 + periodSeconds: 3 + readinessProbe: + httpGet: + path: /healthz + port: 8080 + httpHeaders: + - name: my-readiness-probe + value: awesome + initialDelaySeconds: 3 + periodSeconds: 3 \ No newline at end of file diff --git a/pkg/safeguards/tests/restricted-taints/RT-error-manifest.yaml b/pkg/safeguards/tests/restricted-taints/RT-error-manifest.yaml new file mode 100644 index 000000000..4dadee0b2 --- /dev/null +++ b/pkg/safeguards/tests/restricted-taints/RT-error-manifest.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Node +metadata: + name: my-error-node + labels: + app: my-error-node + kubernetes.azure.com/mode: "User" + environment: production +spec: + taints: + - key: "CriticalAddonsOnly" + effect: "NoSchedule" + value: "value" \ No newline at end of file diff --git a/pkg/safeguards/tests/restricted-taints/RT-success-manifest.yaml b/pkg/safeguards/tests/restricted-taints/RT-success-manifest.yaml new file mode 100644 index 000000000..89c040b97 --- /dev/null +++ b/pkg/safeguards/tests/restricted-taints/RT-success-manifest.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Node +metadata: + name: my-success-node + labels: + app: my-success-node + kubernetes.azure.com/mode: "User" + environment: production +spec: + taints: + - key: "UserDefinedKey" + effect: "NoSchedule" + value: "value" \ No newline at end of file diff --git a/pkg/safeguards/tests/unique-service-selectors/USS-error-manifest.yaml b/pkg/safeguards/tests/unique-service-selectors/USS-error-manifest.yaml new file mode 100644 index 000000000..0a7f83c76 --- /dev/null +++ b/pkg/safeguards/tests/unique-service-selectors/USS-error-manifest.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: Service +metadata: + name: my-service-1 + namespace: prod +spec: + selector: + app.kubernetes.io/name: MyApp + ports: + - protocol: TCP + port: 80 + targetPort: 9376 +--- +apiVersion: v1 +kind: Service +metadata: + name: my-service-2 + namespace: prod +spec: + selector: + app.kubernetes.io/name: MyApp + ports: + - protocol: TCP + port: 220 + targetPort: 9423 \ No newline at end of file diff --git a/pkg/safeguards/tests/unique-service-selectors/USS-success-manifest.yaml b/pkg/safeguards/tests/unique-service-selectors/USS-success-manifest.yaml new file mode 100644 index 000000000..e2611e6a8 --- /dev/null +++ b/pkg/safeguards/tests/unique-service-selectors/USS-success-manifest.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: Service +metadata: + name: my-service-1 + namespace: prod +spec: + selector: + app.kubernetes.io/name: MyApp1 + ports: + - protocol: TCP + port: 80 + targetPort: 9376 +--- +apiVersion: v1 +kind: Service +metadata: + name: my-service-2 + namespace: prod +spec: + selector: + app.kubernetes.io/name: MyApp2 + ports: + - protocol: TCP + port: 220 + targetPort: 9423 \ No newline at end of file diff --git a/pkg/safeguards/types.go b/pkg/safeguards/types.go new file mode 100644 index 000000000..bfa42c5dc --- /dev/null +++ b/pkg/safeguards/types.go @@ -0,0 +1,25 @@ +package safeguards + +import "io/fs" + +type FileCrawler struct { + Safeguards []Safeguard + constraintFS fs.FS +} + +type Safeguard struct { + name string + templatePath string + constraintPath string +} + +type ManifestFile struct { + Name string + Path string +} + +type ManifestResult struct { + Name string // the name of the manifest + ObjectViolations map[string][]string // a map of string object names to slice of string objectViolations + ViolationsCount int // a count of how many violations are associated with this manifest +}