diff --git a/api/http/handler/helm/helm_install.go b/api/http/handler/helm/helm_install.go index e77ee704a..1b6b55bff 100644 --- a/api/http/handler/helm/helm_install.go +++ b/api/http/handler/helm/helm_install.go @@ -6,7 +6,7 @@ import ( "os" "strings" - "github.com/portainer/portainer/api/http/middlewares" + "github.com/portainer/portainer/api/dataservices" "github.com/portainer/portainer/api/http/security" "github.com/portainer/portainer/api/kubernetes" "github.com/portainer/portainer/api/kubernetes/validation" @@ -19,7 +19,6 @@ import ( "github.com/rs/zerolog/log" "github.com/pkg/errors" - "golang.org/x/sync/errgroup" ) type installChartPayload struct { @@ -108,6 +107,23 @@ func (handler *Handler) installChart(r *http.Request, p installChartPayload, dry return nil, httperr.Err } + tokenData, err := security.RetrieveTokenData(r) + if err != nil { + return nil, errors.Wrap(err, "unable to retrieve user details from authentication token") + } + + var username string + if err := handler.dataStore.ViewTx(func(tx dataservices.DataStoreTx) error { + user, err := tx.User().Read(tokenData.ID) + if err != nil { + return errors.Wrap(err, "unable to load user information from the database") + } + username = user.Username + return nil + }); err != nil { + return nil, err + } + installOpts := options.InstallOptions{ Name: p.Name, Chart: p.Chart, @@ -117,6 +133,7 @@ func (handler *Handler) installChart(r *http.Request, p installChartPayload, dry Atomic: p.Atomic, DryRun: dryRun, KubernetesClusterAccess: clusterAccess, + HelmAppLabels: kubernetes.GetHelmAppLabels(p.Name, username), } if p.Values != "" { @@ -147,105 +164,5 @@ func (handler *Handler) installChart(r *http.Request, p installChartPayload, dry return nil, err } - if !installOpts.DryRun { - manifest, err := handler.applyPortainerLabelsToHelmAppManifest(r, installOpts, release.Manifest) - if err != nil { - return nil, err - } - if err := handler.updateHelmAppManifest(r, manifest, installOpts.Namespace); err != nil { - return nil, err - } - } - return release, nil } - -// applyPortainerLabelsToHelmAppManifest will patch all the resources deployed in the helm release manifest -// with portainer specific labels. This is to mark the resources as managed by portainer - hence the helm apps -// wont appear external in the portainer UI. -func (handler *Handler) applyPortainerLabelsToHelmAppManifest(r *http.Request, installOpts options.InstallOptions, manifest string) ([]byte, error) { - // Patch helm release by adding with portainer labels to all deployed resources - tokenData, err := security.RetrieveTokenData(r) - if err != nil { - return nil, errors.Wrap(err, "unable to retrieve user details from authentication token") - } - - user, err := handler.dataStore.User().Read(tokenData.ID) - if err != nil { - return nil, errors.Wrap(err, "unable to load user information from the database") - } - - appLabels := kubernetes.GetHelmAppLabels(installOpts.Name, user.Username) - - labeledManifest, err := kubernetes.AddAppLabels([]byte(manifest), appLabels) - if err != nil { - return nil, errors.Wrap(err, "failed to label helm release manifest") - } - - return labeledManifest, nil -} - -// updateHelmAppManifest will update the resources of helm release manifest with portainer labels using kubectl. -// The resources of the manifest will be updated in parallel and individuallly since resources of a chart -// can be deployed to different namespaces. -// NOTE: These updates will need to be re-applied when upgrading the helm release -func (handler *Handler) updateHelmAppManifest(r *http.Request, manifest []byte, namespace string) error { - endpoint, err := middlewares.FetchEndpoint(r) - if err != nil { - return errors.Wrap(err, "unable to find an endpoint on request context") - } - - tokenData, err := security.RetrieveTokenData(r) - if err != nil { - return errors.Wrap(err, "unable to retrieve user details from authentication token") - } - - // Extract list of YAML resources from Helm manifest - yamlResources, err := kubernetes.ExtractDocuments(manifest, nil) - if err != nil { - return errors.Wrap(err, "unable to extract documents from helm release manifest") - } - - // Deploy individual resources in parallel - g := new(errgroup.Group) - for _, resource := range yamlResources { - g.Go(func() error { - tmpfile, err := os.CreateTemp("", "helm-manifest-*.yaml") - if err != nil { - return errors.Wrap(err, "failed to create a tmp helm manifest file") - } - defer func() { - if err := tmpfile.Close(); err != nil { - log.Warn().Err(err).Msg("failed to close tmp helm manifest file") - } - - if err := os.Remove(tmpfile.Name()); err != nil { - log.Warn().Err(err).Msg("failed to remove tmp helm manifest file") - } - }() - - if _, err := tmpfile.Write(resource); err != nil { - return errors.Wrap(err, "failed to write a tmp helm manifest file") - } - - // get resource namespace, fallback to provided namespace if not explicit on resource - resourceNamespace, err := kubernetes.GetNamespace(resource) - if err != nil { - return err - } - if resourceNamespace == "" { - resourceNamespace = namespace - } - - _, err = handler.kubernetesDeployer.Deploy(tokenData.ID, endpoint, []string{tmpfile.Name()}, resourceNamespace) - - return err - }) - } - - if err := g.Wait(); err != nil { - return errors.Wrap(err, "unable to patch helm release using kubectl") - } - - return nil -} diff --git a/api/kubernetes/cli/resource_test.go b/api/kubernetes/cli/resource_test.go index 7b04b1c21..f10a7c3c9 100644 --- a/api/kubernetes/cli/resource_test.go +++ b/api/kubernetes/cli/resource_test.go @@ -74,7 +74,6 @@ func Test_GenerateYAML(t *testing.T) { name: portainer-ctx current-context: portainer-ctx kind: Config - preferences: {} users: - name: test-user user: diff --git a/app/react/kubernetes/helm/HelmApplicationView/ChartActions/UpgradeButton.tsx b/app/react/kubernetes/helm/HelmApplicationView/ChartActions/UpgradeButton.tsx index 90d142394..262541bfe 100644 --- a/app/react/kubernetes/helm/HelmApplicationView/ChartActions/UpgradeButton.tsx +++ b/app/react/kubernetes/helm/HelmApplicationView/ChartActions/UpgradeButton.tsx @@ -73,7 +73,7 @@ export function UpgradeButton({ const currentRepo = versions?.find( (v) => - v.Chart === release?.chart.metadata?.name && + v.Repo === release?.chartReference?.repoURL && v.AppVersion === release?.chart.metadata?.appVersion && v.Version === release?.chart.metadata?.version )?.Repo; diff --git a/app/react/kubernetes/helm/HelmApplicationView/ChartActions/UpgradeHelmModal.tsx b/app/react/kubernetes/helm/HelmApplicationView/ChartActions/UpgradeHelmModal.tsx index 875cf5d7b..41adfb566 100644 --- a/app/react/kubernetes/helm/HelmApplicationView/ChartActions/UpgradeHelmModal.tsx +++ b/app/react/kubernetes/helm/HelmApplicationView/ChartActions/UpgradeHelmModal.tsx @@ -146,7 +146,7 @@ export function UpgradeHelmModal({ diff --git a/build/build_binary.sh b/build/build_binary.sh index ca431bcb0..2ed3617e6 100755 --- a/build/build_binary.sh +++ b/build/build_binary.sh @@ -27,7 +27,7 @@ COMPOSE_VERSION=$(go list -m -f '{{.Version}}' github.com/docker/compose/v2) # Kubernetes SDK uses v0.x.y versioning, but official kubectl releases use v1.x.y # We need to transform the version (e.g., v0.33.2 -> v1.33.2) KUBECTL_VERSION=$(go list -modfile go.mod -m -f '{{.Version}}' k8s.io/kubectl | sed 's/^v0\./v1./' | sed 's/^0\./1./') -HELM_VERSION=$(go list -modfile go.mod -m -f '{{.Version}}' helm.sh/helm/v3) +HELM_VERSION=$(go list -modfile go.mod -m -f '{{.Version}}' helm.sh/helm/v4) # copy templates cp -r "./mustache-templates" "./dist" diff --git a/go.mod b/go.mod index 94b81221b..e817c8d50 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/aws/smithy-go v1.20.3 github.com/cbroglie/mustache v1.4.0 github.com/compose-spec/compose-go/v2 v2.9.1 - github.com/containerd/containerd v1.7.29 + github.com/containerd/containerd v1.7.30 github.com/dchest/uniuri v0.0.0-20200228104902-7aecb25e1fe5 github.com/docker/cli v28.5.1+incompatible github.com/docker/compose/v2 v2.40.3 @@ -42,7 +42,8 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pkg/errors v0.9.1 github.com/robfig/cron/v3 v3.0.1 - github.com/rs/zerolog v1.30.0 + github.com/rs/zerolog v1.34.0 + github.com/samber/slog-zerolog/v2 v2.9.1 github.com/segmentio/encoding v0.5.3 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.11.1 @@ -51,19 +52,19 @@ require ( go.etcd.io/bbolt v1.4.3 go.podman.io/image/v5 v5.37.0 go.yaml.in/yaml/v3 v3.0.4 - golang.org/x/crypto v0.45.0 + golang.org/x/crypto v0.46.0 golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 - golang.org/x/mod v0.29.0 + golang.org/x/mod v0.31.0 golang.org/x/oauth2 v0.30.0 - golang.org/x/sync v0.18.0 - helm.sh/helm/v3 v3.18.5 - k8s.io/api v0.33.3 - k8s.io/apimachinery v0.33.4 - k8s.io/cli-runtime v0.33.3 - k8s.io/client-go v0.33.3 - k8s.io/kubectl v0.33.3 - k8s.io/kubelet v0.33.2 - k8s.io/metrics v0.33.3 + golang.org/x/sync v0.19.0 + helm.sh/helm/v4 v4.1.1 + k8s.io/api v0.35.0 + k8s.io/apimachinery v0.35.0 + k8s.io/cli-runtime v0.35.0 + k8s.io/client-go v0.35.0 + k8s.io/kubectl v0.35.0 + k8s.io/kubelet v0.35.0 + k8s.io/metrics v0.35.0 oras.land/oras-go/v2 v2.6.0 software.sslmate.com/src/go-pkcs12 v0.0.0-20210415151418-c5206de65a78 ) @@ -75,13 +76,13 @@ require ( github.com/AlecAivazis/survey/v2 v2.3.7 // indirect github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect - github.com/BurntSushi/toml v1.5.0 // indirect + github.com/BurntSushi/toml v1.6.0 // indirect github.com/DefangLabs/secret-detector v0.0.0-20250403165618-22662109213e // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/Masterminds/squirrel v1.5.4 // indirect - github.com/ProtonMail/go-crypto v1.1.6 // indirect + github.com/ProtonMail/go-crypto v1.3.0 // indirect github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d // indirect github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect @@ -120,7 +121,7 @@ require ( github.com/containerd/typeurl/v2 v2.2.3 // indirect github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect github.com/containers/ocicrypt v1.2.1 // indirect - github.com/cyphar/filepath-securejoin v0.4.1 // indirect + github.com/cyphar/filepath-securejoin v0.6.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/buildx v0.29.1 // indirect @@ -131,45 +132,49 @@ require ( github.com/docker/go-connections v0.6.0 // indirect github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-units v0.5.0 // indirect + github.com/dylibso/observe-sdk/go v0.0.0-20240819160327-2d926c5d788a // indirect github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/emirpasic/gods v1.18.1 // indirect - github.com/evanphx/json-patch v5.9.11+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect + github.com/extism/go-sdk v1.7.1 // indirect github.com/fatih/camelcase v1.0.0 // indirect - github.com/fatih/color v1.15.0 // indirect + github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fluxcd/cli-utils v0.37.0-flux.1 // indirect github.com/fsnotify/fsevents v0.2.0 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-asn1-ber/asn1-ber v1.5.1 // indirect - github.com/go-errors/errors v1.4.2 // indirect + github.com/go-errors/errors v1.5.1 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.8.0 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-openapi/jsonpointer v0.21.1 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/swag v0.23.1 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/gofrs/flock v0.12.1 // indirect + github.com/gofrs/flock v0.13.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.3 // indirect - github.com/google/gnostic-models v0.6.9 // indirect + github.com/google/gnostic-models v0.7.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gosuri/uitable v0.0.4 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-version v1.7.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect + github.com/ianlancetaylor/demangle v0.0.0-20240805132620-81f5be970eca // indirect github.com/in-toto/in-toto-golang v0.9.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf // indirect @@ -189,7 +194,7 @@ require ( github.com/lib/pq v1.10.9 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/lithammer/dedent v1.1.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect @@ -217,7 +222,7 @@ require ( github.com/moby/sys/userns v0.1.0 // indirect github.com/moby/term v0.5.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/mschoch/smat v0.2.0 // indirect @@ -230,26 +235,30 @@ require ( github.com/pjbgf/sha1cd v0.3.2 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.22.0 // indirect + github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.62.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect + github.com/prometheus/common v0.66.1 // indirect + github.com/prometheus/procfs v0.17.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect - github.com/rubenv/sql-migrate v1.8.0 // indirect + github.com/rubenv/sql-migrate v1.8.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/samber/lo v1.52.0 // indirect + github.com/samber/slog-common v0.20.0 // indirect github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect github.com/secure-systems-lab/go-securesystemslib v0.9.1 // indirect github.com/segmentio/asm v1.1.3 // indirect - github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/sergi/go-diff v1.4.0 // indirect github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b // indirect github.com/shibumi/go-pathspec v1.3.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/skeema/knownhosts v1.3.1 // indirect github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect github.com/spf13/cast v1.7.0 // indirect - github.com/spf13/cobra v1.10.1 // indirect + github.com/spf13/cobra v1.10.2 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/stretchr/objx v0.5.2 // indirect + github.com/tetratelabs/wabin v0.0.0-20230304001439-f6f874872834 // indirect + github.com/tetratelabs/wazero v1.11.0 // indirect github.com/theupdateframework/notary v0.7.0 // indirect github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375 // indirect github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce // indirect @@ -271,7 +280,7 @@ require ( go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect go.opentelemetry.io/otel v1.41.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.35.0 // indirect @@ -285,33 +294,34 @@ require ( go.opentelemetry.io/proto/otlp v1.5.0 // indirect go.podman.io/storage v1.60.0 // indirect go.uber.org/mock v0.6.0 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/term v0.39.0 // indirect + golang.org/x/text v0.33.0 // indirect golang.org/x/time v0.12.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect google.golang.org/grpc v1.74.2 // indirect google.golang.org/protobuf v1.36.9 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.33.3 // indirect - k8s.io/apiserver v0.33.3 // indirect - k8s.io/component-base v0.33.3 // indirect - k8s.io/component-helpers v0.33.3 // indirect + k8s.io/apiextensions-apiserver v0.35.0 // indirect + k8s.io/apiserver v0.35.0 // indirect + k8s.io/component-base v0.35.0 // indirect + k8s.io/component-helpers v0.35.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect - k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect - sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect - sigs.k8s.io/kustomize/api v0.19.0 // indirect - sigs.k8s.io/kustomize/kyaml v0.19.0 // indirect + k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/controller-runtime v0.22.4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect + sigs.k8s.io/kustomize/api v0.20.1 // indirect + sigs.k8s.io/kustomize/kyaml v0.21.0 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect - sigs.k8s.io/yaml v1.5.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect tags.cncf.io/container-device-interface v1.0.1 // indirect ) diff --git a/go.sum b/go.sum index 52111dfcd..688542dae 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cyphar.com/go-pathrs v0.2.1 h1:9nx1vOgwVvX1mNBWDu93+vaceedpbsDqo+XuBGL40b8= +cyphar.com/go-pathrs v0.2.1/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc= dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= @@ -12,8 +14,8 @@ github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg6 github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28= github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= -github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= +github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/DefangLabs/secret-detector v0.0.0-20250403165618-22662109213e h1:rd4bOvKmDIx0WeTv9Qz+hghsgyjikFiPrseXHlKepO0= @@ -36,8 +38,8 @@ github.com/Microsoft/hcsshim v0.13.0/go.mod h1:9KWJ/8DgU+QzYGupX4tzMhRQE8h6w90lH github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= -github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw= -github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= +github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= github.com/RoaringBitmap/roaring/v2 v2.5.0 h1:TJ45qCM7D7fIEBwKd9zhoR0/S1egfnSSIzLU1e1eYLY= github.com/RoaringBitmap/roaring/v2 v2.5.0/go.mod h1:FiJcsfkGje/nZBZgCu0ZxCPOKD/hVXDS2dXi7/eUFE0= github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= @@ -142,8 +144,8 @@ github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJ github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins= github.com/containerd/console v1.0.5 h1:R0ymNeydRqH2DmakFNdmjR2k0t7UPuiOV/N/27/qqsc= github.com/containerd/console v1.0.5/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= -github.com/containerd/containerd v1.7.29 h1:90fWABQsaN9mJhGkoVnuzEY+o1XDPbg9BTC9QTAHnuE= -github.com/containerd/containerd v1.7.29/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs= +github.com/containerd/containerd v1.7.30 h1:/2vezDpLDVGGmkUXmlNPLCCNKHJ5BbC5tJB5JNzQhqE= +github.com/containerd/containerd v1.7.30/go.mod h1:fek494vwJClULlTpExsmOyKCMUAbuVjlFsJQc4/j44M= github.com/containerd/containerd/api v1.9.0 h1:HZ/licowTRazus+wt9fM6r/9BQO7S0vD5lMcWspGIg0= github.com/containerd/containerd/api v1.9.0/go.mod h1:GhghKFmTR3hNtyznBoQ0EMWr9ju5AqHjcZPsSpTKutI= github.com/containerd/containerd/v2 v2.1.5 h1:pWSmPxUszaLZKQPvOx27iD4iH+aM6o0BoN9+hg77cro= @@ -182,8 +184,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= -github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= -github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE= +github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -229,27 +231,33 @@ github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= +github.com/dylibso/observe-sdk/go v0.0.0-20240819160327-2d926c5d788a h1:UwSIFv5g5lIvbGgtf3tVwC7Ky9rmMFBp0RMs+6f6YqE= +github.com/dylibso/observe-sdk/go v0.0.0-20240819160327-2d926c5d788a/go.mod h1:C8DzXehI4zAbrdlbtOByKX6pfivJTBiV9Jjqv56Yd9Q= github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203 h1:XBBHcIb256gUJtLmY22n99HaZTz+r2Z51xUPi01m3wg= github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203/go.mod h1:E1jcSv8FaEny+OP/5k9UxZVw9YFWGj7eI4KR/iOBqCg= github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= -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/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= +github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= -github.com/evanphx/json-patch v5.9.11+incompatible h1:ixHHqfcGvxhWkniF1tWxBHA0yb4Z+d1UQi45df52xW8= -github.com/evanphx/json-patch v5.9.11+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= +github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2Wvf/TIe2xdyJxTlb6obmF18d8QdkxNDu4= github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc= +github.com/extism/go-sdk v1.7.1 h1:lWJos6uY+tRFdlIHR+SJjwFDApY7OypS/2nMhiVQ9Sw= +github.com/extism/go-sdk v1.7.1/go.mod h1:IT+Xdg5AZM9hVtpFUA+uZCJMge/hbvshl8bwzLtFyKA= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -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/fluxcd/cli-utils v0.37.0-flux.1 h1:k/VvPNT3tGa/l2N+qzHduaQr3GVbgoWS6nw7tGZz16w= +github.com/fluxcd/cli-utils v0.37.0-flux.1/go.mod h1:aND5wX3LuTFtB7eUT7vsWr8mmxRVSPR2Wkvbn0SqPfw= +github.com/foxcpp/go-mockdns v1.2.0 h1:omK3OrHRD1IWJz1FuFBCFquhXslXoF17OvBS6JPzZF0= +github.com/foxcpp/go-mockdns v1.2.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsevents v0.2.0 h1:BRlvlqjvNTfogHfeBOFvSC9N0Ddy+wzQCQukyoD7o/c= @@ -259,16 +267,16 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= -github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/g07cha/defender v0.0.0-20180505193036-5665c627c814 h1:gWvniJ4GbFfkf700kykAImbLiEMU0Q3QN9hQ26Js1pU= github.com/g07cha/defender v0.0.0-20180505193036-5665c627c814/go.mod h1:secRm32Ro77eD23BmPVbgLbWN+JWDw7pJszenjxI4bI= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us009o8= github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= -github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= +github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= github.com/go-git/go-billy/v5 v5.8.0 h1:I8hjc3LbBlXTtVuFNJuwYuMiHvQJDq1AT6u4DwDzZG0= @@ -289,14 +297,14 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/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-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +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.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic= +github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= +github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= @@ -308,8 +316,8 @@ github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlnd github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= -github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= +github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw= +github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0= github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -334,8 +342,8 @@ github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl76 github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= github.com/google/certificate-transparency-go v1.1.4 h1:hCyXHDbtqlr/lMXU0D4WgbalXL0Zk4dSWWMbPV8VrqY= github.com/google/certificate-transparency-go v1.1.4/go.mod h1:D6lvbfwckhNrbM9WVl1EVeMOyzC19mpIjMOI4nxBHtQ= -github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= -github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= +github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= +github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -349,8 +357,8 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17 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/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= -github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= +github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5 h1:xhMrHhTJ6zxu3gA4enFM9MLn9AY7613teCdFnlUVbSQ= +github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA= 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= @@ -370,8 +378,8 @@ github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -394,6 +402,8 @@ github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4Dvx github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/ianlancetaylor/demangle v0.0.0-20240805132620-81f5be970eca h1:T54Ema1DU8ngI+aef9ZhAhNGQhcRTrWxVeG07F+c/Rw= +github.com/ianlancetaylor/demangle v0.0.0-20240805132620-81f5be970eca/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= github.com/in-toto/in-toto-golang v0.9.0 h1:tHny7ac4KgtsfrG6ybU8gVOZux2H8jN05AXJ9EBM1XU= github.com/in-toto/in-toto-golang v0.9.0/go.mod h1:xsBVrVsHNsB61++S6Dy2vWosKhuA3lUTQd+eF9HdeMo= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -450,7 +460,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.2/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= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -473,15 +482,14 @@ github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM= github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= @@ -548,8 +556,9 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w 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/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/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/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= @@ -567,12 +576,12 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= -github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= -github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= +github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= -github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= +github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -582,8 +591,8 @@ github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJw github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww= github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.12.0 h1:6n5JV4Cf+4y0KNXW48TLj5DwfXpvWlxXplUkdTrmPb8= -github.com/opencontainers/selinux v1.12.0/go.mod h1:BTPX+bjVbWGXw7ZZWUbdENt8w0htPSrlgOOysQaU62U= +github.com/opencontainers/selinux v1.13.1 h1:A8nNeceYngH9Ow++M+VVEwJVpdFmrlxsN22F+ISDCJE= +github.com/opencontainers/selinux v1.13.1/go.mod h1:S10WXZ/osk2kWOYKy1x2f/eXF5ZHJoUs8UU/2caNRbg= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= @@ -595,8 +604,6 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -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/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -614,8 +621,8 @@ github.com/prometheus/client_golang v0.9.0-pre1.0.20180209125602-c332b6f63c06/go github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= -github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -624,14 +631,14 @@ github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvM github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= 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.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= -github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= +github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= +github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 h1:EaDatTxkdHG+U3Bk4EUr+DZ7fOGwTfezUiUJMaIcaho= github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5/go.mod h1:fyalQWdtzDBECAQFBJuQe5bzQ02jGd5Qcbgb97Flm7U= github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 h1:EfpWLLCyXw8PSM2/XNJLjI3Pb27yVE+gIAfeqp8LUCc= @@ -645,13 +652,19 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= -github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= -github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= -github.com/rubenv/sql-migrate v1.8.0 h1:dXnYiJk9k3wetp7GfQbKJcPHjVJL6YK19tKj8t2Ns0o= -github.com/rubenv/sql-migrate v1.8.0/go.mod h1:F2bGFBwCU+pnmbtNYDeKvSuvL6lBVtXDXUUv5t+u1qw= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= +github.com/rubenv/sql-migrate v1.8.1 h1:EPNwCvjAowHI3TnZ+4fQu3a915OpnQoPAjTXCGOy2U0= +github.com/rubenv/sql-migrate v1.8.1/go.mod h1:BTIKBORjzyxZDS6dzoiw6eAFYJ1iNlGAtjn4LGeVjS8= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/samber/lo v1.52.0 h1:Rvi+3BFHES3A8meP33VPAxiBZX/Aws5RxrschYGjomw= +github.com/samber/lo v1.52.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= +github.com/samber/slog-common v0.20.0 h1:WaLnm/aCvBJSk5nR5aXZTFBaV0B47A+AEaEOiZDeUnc= +github.com/samber/slog-common v0.20.0/go.mod h1:+Ozat1jgnnE59UAlmNX1IF3IByHsODnnwf9jUcBZ+m8= +github.com/samber/slog-zerolog/v2 v2.9.1 h1:RMOq8XqzfuGx1X0TEIlS9OXbbFmqLY2/wJppghz66YY= +github.com/samber/slog-zerolog/v2 v2.9.1/go.mod h1:DQYYve14WgCRN/XnKeHl4266jXK0DgYkYXkfZ4Fp98k= github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ= github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU= github.com/secure-systems-lab/go-securesystemslib v0.9.1 h1:nZZaNz4DiERIQguNy0cL5qTdn9lR8XKHf4RUyG1Sx3g= @@ -660,8 +673,8 @@ github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc= github.com/segmentio/asm v1.1.3/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg= github.com/segmentio/encoding v0.5.3 h1:OjMgICtcSFuNvQCdwqMCv9Tg7lEOXGwm1J5RPQccx6w= github.com/segmentio/encoding v0.5.3/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= +github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b h1:h+3JX2VoWTFuyQEo87pStk/a99dzIO1mM9KxIyLPGTU= github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc= github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI= @@ -685,8 +698,8 @@ github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94/go.mod h1:r2rcYCSwa1IEx github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431 h1:XTHrT015sxHyJ5FnQ0AeemSspZWaDq7DoTRW0EVsDCE= github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -698,8 +711,6 @@ github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c/go.mod h1:A8kyI5cUJhb8 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/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= @@ -708,11 +719,12 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.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.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/tetratelabs/wabin v0.0.0-20230304001439-f6f874872834 h1:ZF+QBjOI+tILZjBaFj3HgFonKXUcwgJ4djLb6i42S3Q= +github.com/tetratelabs/wabin v0.0.0-20230304001439-f6f874872834/go.mod h1:m9ymHTgNSEjuxvw8E7WWe4Pl4hZQHXONY8wE6dMLaRk= +github.com/tetratelabs/wazero v1.11.0 h1:+gKemEuKCTevU4d7ZTzlsvgd1uaToIDtlQlmNbwqYhA= +github.com/tetratelabs/wazero v1.11.0/go.mod h1:eV28rsN8Q+xwjogd7f4/Pp4xFxO7uOGbLcD/LzB1wiU= github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c= github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw= github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375 h1:QB54BJwA6x8QU9nHY3xJSZR2kX9bgpZekRKGkLTmEXA= @@ -785,8 +797,8 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0 h1:0tY123n7CdWMem7MOVdKOt0YfshufLCwfE5Bob+hQuM= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0/go.mod h1:CosX/aS4eHnG9D7nESYpV753l4j9q5j3SL/PUYd2lR8= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c= go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 h1:WzNab7hOOLzdDF/EoWCt4glhrbMPVMOO5JYTmpz36Ls= @@ -833,8 +845,12 @@ 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.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +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.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -855,8 +871,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -866,8 +882,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= -golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= +golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= +golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -888,8 +904,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= @@ -906,8 +922,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -925,8 +941,6 @@ golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-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-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -942,8 +956,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -955,8 +969,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= +golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= golang.org/x/text v0.3.0/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= @@ -971,8 +985,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -983,8 +997,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= -golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= 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= @@ -1013,8 +1027,8 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/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/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/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= @@ -1038,52 +1052,52 @@ 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.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= -helm.sh/helm/v3 v3.18.5 h1:Cc3Z5vd6kDrZq9wO9KxKLNEickiTho6/H/dBNRVSos4= -helm.sh/helm/v3 v3.18.5/go.mod h1:L/dXDR2r539oPlFP1PJqKAC1CUgqHJDLkxKpDGrWnyg= -k8s.io/api v0.33.3 h1:SRd5t//hhkI1buzxb288fy2xvjubstenEKL9K51KBI8= -k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE= -k8s.io/apiextensions-apiserver v0.33.3 h1:qmOcAHN6DjfD0v9kxL5udB27SRP6SG/MTopmge3MwEs= -k8s.io/apiextensions-apiserver v0.33.3/go.mod h1:oROuctgo27mUsyp9+Obahos6CWcMISSAPzQ77CAQGz8= -k8s.io/apimachinery v0.33.4 h1:SOf/JW33TP0eppJMkIgQ+L6atlDiP/090oaX0y9pd9s= -k8s.io/apimachinery v0.33.4/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= -k8s.io/apiserver v0.33.3 h1:Wv0hGc+QFdMJB4ZSiHrCgN3zL3QRatu56+rpccKC3J4= -k8s.io/apiserver v0.33.3/go.mod h1:05632ifFEe6TxwjdAIrwINHWE2hLwyADFk5mBsQa15E= -k8s.io/cli-runtime v0.33.3 h1:Dgy4vPjNIu8LMJBSvs8W0LcdV0PX/8aGG1DA1W8lklA= -k8s.io/cli-runtime v0.33.3/go.mod h1:yklhLklD4vLS8HNGgC9wGiuHWze4g7x6XQZ+8edsKEo= -k8s.io/client-go v0.33.3 h1:M5AfDnKfYmVJif92ngN532gFqakcGi6RvaOF16efrpA= -k8s.io/client-go v0.33.3/go.mod h1:luqKBQggEf3shbxHY4uVENAxrDISLOarxpTKMiUuujg= -k8s.io/component-base v0.33.3 h1:mlAuyJqyPlKZM7FyaoM/LcunZaaY353RXiOd2+B5tGA= -k8s.io/component-base v0.33.3/go.mod h1:ktBVsBzkI3imDuxYXmVxZ2zxJnYTZ4HAsVj9iF09qp4= -k8s.io/component-helpers v0.33.3 h1:fjWVORSQfI0WKzPeIFSju/gMD9sybwXBJ7oPbqQu6eM= -k8s.io/component-helpers v0.33.3/go.mod h1:7iwv+Y9Guw6X4RrnNQOyQlXcvJrVjPveHVqUA5dm31c= +helm.sh/helm/v4 v4.1.1 h1:juO/Vack3pNUBCX0emMvHL1RL27CEWwGyCd3HyP3mPA= +helm.sh/helm/v4 v4.1.1/go.mod h1:yH4qpYvTNBTHnkRSenhi1m7oEFKoN6iK3/rYyFJ00IQ= +k8s.io/api v0.35.0 h1:iBAU5LTyBI9vw3L5glmat1njFK34srdLmktWwLTprlY= +k8s.io/api v0.35.0/go.mod h1:AQ0SNTzm4ZAczM03QH42c7l3bih1TbAXYo0DkF8ktnA= +k8s.io/apiextensions-apiserver v0.35.0 h1:3xHk2rTOdWXXJM+RDQZJvdx0yEOgC0FgQ1PlJatA5T4= +k8s.io/apiextensions-apiserver v0.35.0/go.mod h1:E1Ahk9SADaLQ4qtzYFkwUqusXTcaV2uw3l14aqpL2LU= +k8s.io/apimachinery v0.35.0 h1:Z2L3IHvPVv/MJ7xRxHEtk6GoJElaAqDCCU0S6ncYok8= +k8s.io/apimachinery v0.35.0/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= +k8s.io/apiserver v0.35.0 h1:CUGo5o+7hW9GcAEF3x3usT3fX4f9r8xmgQeCBDaOgX4= +k8s.io/apiserver v0.35.0/go.mod h1:QUy1U4+PrzbJaM3XGu2tQ7U9A4udRRo5cyxkFX0GEds= +k8s.io/cli-runtime v0.35.0 h1:PEJtYS/Zr4p20PfZSLCbY6YvaoLrfByd6THQzPworUE= +k8s.io/cli-runtime v0.35.0/go.mod h1:VBRvHzosVAoVdP3XwUQn1Oqkvaa8facnokNkD7jOTMY= +k8s.io/client-go v0.35.0 h1:IAW0ifFbfQQwQmga0UdoH0yvdqrbwMdq9vIFEhRpxBE= +k8s.io/client-go v0.35.0/go.mod h1:q2E5AAyqcbeLGPdoRB+Nxe3KYTfPce1Dnu1myQdqz9o= +k8s.io/component-base v0.35.0 h1:+yBrOhzri2S1BVqyVSvcM3PtPyx5GUxCK2tinZz1G94= +k8s.io/component-base v0.35.0/go.mod h1:85SCX4UCa6SCFt6p3IKAPej7jSnF3L8EbfSyMZayJR0= +k8s.io/component-helpers v0.35.0 h1:wcXv7HJRksgVjM4VlXJ1CNFBpyDHruRI99RrBtrJceA= +k8s.io/component-helpers v0.35.0/go.mod h1:ahX0m/LTYmu7fL3W8zYiIwnQ/5gT28Ex4o2pymF63Co= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= -k8s.io/kubectl v0.33.3 h1:r/phHvH1iU7gO/l7tTjQk2K01ER7/OAJi8uFHHyWSac= -k8s.io/kubectl v0.33.3/go.mod h1:euj2bG56L6kUGOE/ckZbCoudPwuj4Kud7BR0GzyNiT0= -k8s.io/kubelet v0.33.2 h1:wxEau5/563oJb3j3KfrCKlNWWx35YlSgDLOYUBCQ0pg= -k8s.io/kubelet v0.33.2/go.mod h1:way8VCDTUMiX1HTOvJv7M3xS/xNysJI6qh7TOqMe5KM= -k8s.io/metrics v0.33.3 h1:9CcqBz15JZfISqwca33gdHS8I6XfsK1vA8WUdEnG70g= -k8s.io/metrics v0.33.3/go.mod h1:Aw+cdg4AYHw0HvUY+lCyq40FOO84awrqvJRTw0cmXDs= -k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= -k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/kubectl v0.35.0 h1:cL/wJKHDe8E8+rP3G7avnymcMg6bH6JEcR5w5uo06wc= +k8s.io/kubectl v0.35.0/go.mod h1:VR5/TSkYyxZwrRwY5I5dDq6l5KXmiCb+9w8IKplk3Qo= +k8s.io/kubelet v0.35.0 h1:8cgJHCBCKLYuuQ7/Pxb/qWbJfX1LXIw7790ce9xHq7c= +k8s.io/kubelet v0.35.0/go.mod h1:ciRzAXn7C4z5iB7FhG1L2CGPPXLTVCABDlbXt/Zz8YA= +k8s.io/metrics v0.35.0 h1:xVFoqtAGm2dMNJAcB5TFZJPCen0uEqqNt52wW7ABbX8= +k8s.io/metrics v0.35.0/go.mod h1:g2Up4dcBygZi2kQSEQVDByFs+VUwepJMzzQLJJLpq4M= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= oras.land/oras-go/v2 v2.6.0 h1:X4ELRsiGkrbeox69+9tzTu492FMUu7zJQW6eJU+I2oc= oras.land/oras-go/v2 v2.6.0/go.mod h1:magiQDfG6H1O9APp+rOsvCPcW1GD2MM7vgnKY0Y+u1o= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= -sigs.k8s.io/kustomize/api v0.19.0 h1:F+2HB2mU1MSiR9Hp1NEgoU2q9ItNOaBJl0I4Dlus5SQ= -sigs.k8s.io/kustomize/api v0.19.0/go.mod h1:/BbwnivGVcBh1r+8m3tH1VNxJmHSk1PzP5fkP6lbL1o= -sigs.k8s.io/kustomize/kyaml v0.19.0 h1:RFge5qsO1uHhwJsu3ipV7RNolC7Uozc0jUBC/61XSlA= -sigs.k8s.io/kustomize/kyaml v0.19.0/go.mod h1:FeKD5jEOH+FbZPpqUghBP8mrLjJ3+zD3/rf9NNu1cwY= -sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/controller-runtime v0.22.4 h1:GEjV7KV3TY8e+tJ2LCTxUTanW4z/FmNB7l327UfMq9A= +sigs.k8s.io/controller-runtime v0.22.4/go.mod h1:+QX1XUpTXN4mLoblf4tqr5CQcyHPAki2HLXqQMY6vh8= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I= +sigs.k8s.io/kustomize/api v0.20.1/go.mod h1:t6hUFxO+Ph0VxIk1sKp1WS0dOjbPCtLJ4p8aADLwqjM= +sigs.k8s.io/kustomize/kyaml v0.21.0 h1:7mQAf3dUwf0wBerWJd8rXhVcnkk5Tvn/q91cGkaP6HQ= +sigs.k8s.io/kustomize/kyaml v0.21.0/go.mod h1:hmxADesM3yUN2vbA5z1/YTBnzLJ1dajdqpQonwBL1FQ= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= -sigs.k8s.io/yaml v1.5.0 h1:M10b2U7aEUY6hRtU870n2VTPgR5RZiL/I6Lcc2F4NUQ= -sigs.k8s.io/yaml v1.5.0/go.mod h1:wZs27Rbxoai4C0f8/9urLZtZtF3avA3gKvGyPdDqTO4= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= software.sslmate.com/src/go-pkcs12 v0.0.0-20210415151418-c5206de65a78 h1:SqYE5+A2qvRhErbsXFfUEUmpWEKxxRSMgGLkvRAFOV4= software.sslmate.com/src/go-pkcs12 v0.0.0-20210415151418-c5206de65a78/go.mod h1:B7Wf0Ya4DHF9Yw+qfZuJijQYkWicqDa+79Ytmmq3Kjg= tags.cncf.io/container-device-interface v1.0.1 h1:KqQDr4vIlxwfYh0Ed/uJGVgX+CHAkahrgabg6Q8GYxc= diff --git a/pkg/libhelm/cache/cache.go b/pkg/libhelm/cache/cache.go index e555bc090..16cda44b0 100644 --- a/pkg/libhelm/cache/cache.go +++ b/pkg/libhelm/cache/cache.go @@ -7,7 +7,7 @@ import ( "github.com/patrickmn/go-cache" portainer "github.com/portainer/portainer/api" "github.com/rs/zerolog/log" - "helm.sh/helm/v3/pkg/registry" + "helm.sh/helm/v4/pkg/registry" ) // Cache manages Helm registry clients with TTL-based expiration diff --git a/pkg/libhelm/cache/manager.go b/pkg/libhelm/cache/manager.go index 6520b314c..fb0bbb8e4 100644 --- a/pkg/libhelm/cache/manager.go +++ b/pkg/libhelm/cache/manager.go @@ -5,7 +5,7 @@ import ( portainer "github.com/portainer/portainer/api" "github.com/rs/zerolog/log" - "helm.sh/helm/v3/pkg/registry" + "helm.sh/helm/v4/pkg/registry" ) var ( diff --git a/pkg/libhelm/options/install_options.go b/pkg/libhelm/options/install_options.go index ae419e8f8..1f6013267 100644 --- a/pkg/libhelm/options/install_options.go +++ b/pkg/libhelm/options/install_options.go @@ -21,7 +21,6 @@ type InstallOptions struct { // ValuesFile is a path to a YAML file with Helm values to apply. // File values are applied first; Values take precedence on conflicts. ValuesFile string - PostRenderer string HelmAppLabels map[string]string Atomic bool DryRun bool diff --git a/pkg/libhelm/release/release.go b/pkg/libhelm/release/release.go index 8dbdac81a..e8b64bf7d 100644 --- a/pkg/libhelm/release/release.go +++ b/pkg/libhelm/release/release.go @@ -1,7 +1,8 @@ package release import ( - "github.com/portainer/portainer/pkg/libhelm/time" + "time" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) diff --git a/pkg/libhelm/sdk/chartsources.go b/pkg/libhelm/sdk/chartsources.go index e37fe55b2..40a70cc50 100644 --- a/pkg/libhelm/sdk/chartsources.go +++ b/pkg/libhelm/sdk/chartsources.go @@ -29,6 +29,8 @@ package sdk // - RBAC security is enforced BEFORE reaching this caching layer (handler.getRegistryWithAccess) import ( + "os" + "path/filepath" "strings" "github.com/pkg/errors" @@ -37,8 +39,8 @@ import ( "github.com/portainer/portainer/pkg/libhelm/options" "github.com/portainer/portainer/pkg/registryhttp" "github.com/rs/zerolog/log" - "helm.sh/helm/v3/pkg/action" - "helm.sh/helm/v3/pkg/registry" + "helm.sh/helm/v4/pkg/action" + "helm.sh/helm/v4/pkg/registry" ) // IsOCIRegistry returns true if the registry is an OCI registry (not nil), false if it's an HTTP repository (nil) @@ -116,9 +118,21 @@ func shouldFlushCacheOnError(err error, registryID portainer.RegistryID) bool { } // authenticateChartSource handles both HTTP repositories and OCI registries -func authenticateChartSource(actionConfig *action.Configuration, registry *portainer.Registry) error { - // For HTTP repositories, no authentication needed (CE and EE) - if IsHTTPRepository(registry) { +func authenticateChartSource(actionConfig *action.Configuration, reg *portainer.Registry) error { + // For HTTP repositories, no authentication needed (CE and EE) so return default client + if IsHTTPRepository(reg) { + if actionConfig.RegistryClient != nil { + return nil + } + // Use a non-existent path so Helm initializes an empty credentials store + noCredsPath := filepath.Join(os.TempDir(), "portainer-helm-registry-no-creds") + defaultClient, err := registry.NewClient( + registry.ClientOptCredentialsFile(noCredsPath), + ) + if err != nil { + return errors.Wrap(err, "failed to create default registry client") + } + actionConfig.RegistryClient = defaultClient return nil } @@ -131,7 +145,7 @@ func authenticateChartSource(actionConfig *action.Configuration, registry *porta } // Validate registry credentials first - err := validateRegistryCredentials(registry) + err := validateRegistryCredentials(reg) if err != nil { log.Error(). Str("context", "HelmClient"). @@ -154,10 +168,10 @@ func authenticateChartSource(actionConfig *action.Configuration, registry *porta // 4. Credential files add complexity without solving the core rate limiting issue // Try to get cached registry client (registry ID-based key) - if cachedClient, found := cache.GetCachedRegistryClientByID(registry.ID); found { + if cachedClient, found := cache.GetCachedRegistryClientByID(reg.ID); found { log.Debug(). - Int("registry_id", int(registry.ID)). - Str("registry_url", registry.URL). + Int("registry_id", int(reg.ID)). + Str("registry_url", reg.URL). Str("context", "HelmClient"). Msg("Using cached registry client") @@ -167,16 +181,16 @@ func authenticateChartSource(actionConfig *action.Configuration, registry *porta // Cache miss - perform login and cache the result log.Debug(). - Int("registry_id", int(registry.ID)). - Str("registry_url", registry.URL). + Int("registry_id", int(reg.ID)). + Str("registry_url", reg.URL). Str("context", "HelmClient"). Msg("Cache miss - creating new registry client") - registryClient, err := createOCIRegistryClient(registry) + registryClient, err := createOCIRegistryClient(reg) if err != nil { log.Error(). Str("context", "HelmClient"). - Str("registry_url", registry.URL). + Str("registry_url", reg.URL). Err(err). Msg("Failed to create registry client") return errors.Wrap(err, "failed to create registry client") @@ -184,10 +198,10 @@ func authenticateChartSource(actionConfig *action.Configuration, registry *porta // Cache the client if login was successful (registry ID-based key) if registryClient != nil { - cache.SetCachedRegistryClientByID(registry.ID, registryClient) + cache.SetCachedRegistryClientByID(reg.ID, registryClient) log.Debug(). - Int("registry_id", int(registry.ID)). - Str("registry_url", registry.URL). + Int("registry_id", int(reg.ID)). + Str("registry_url", reg.URL). Str("context", "HelmClient"). Msg("Registry client cached successfully") } diff --git a/pkg/libhelm/sdk/chartsources_test.go b/pkg/libhelm/sdk/chartsources_test.go index 1802242d7..c21b59990 100644 --- a/pkg/libhelm/sdk/chartsources_test.go +++ b/pkg/libhelm/sdk/chartsources_test.go @@ -11,8 +11,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "helm.sh/helm/v3/pkg/action" - "helm.sh/helm/v3/pkg/registry" + "helm.sh/helm/v4/pkg/action" + "helm.sh/helm/v4/pkg/registry" ) func init() { @@ -281,12 +281,12 @@ func TestLoginToOCIRegistry(t *testing.T) { } func TestAuthenticateChartSource(t *testing.T) { - t.Run("should do nothing for HTTP repo (nil registry)", func(t *testing.T) { + t.Run("should do return default client for HTTP repo", func(t *testing.T) { is := assert.New(t) actionConfig := &action.Configuration{} err := authenticateChartSource(actionConfig, nil) require.NoError(t, err) - is.Nil(actionConfig.RegistryClient) + is.NotNil(actionConfig.RegistryClient) }) t.Run("should do nothing if registry client already set", func(t *testing.T) { diff --git a/pkg/libhelm/sdk/client.go b/pkg/libhelm/sdk/client.go index 945bcf9f5..3315ee4e8 100644 --- a/pkg/libhelm/sdk/client.go +++ b/pkg/libhelm/sdk/client.go @@ -4,8 +4,9 @@ import ( "github.com/pkg/errors" "github.com/portainer/portainer/pkg/libhelm/options" "github.com/rs/zerolog/log" - "helm.sh/helm/v3/pkg/action" - "helm.sh/helm/v3/pkg/cli" + slogzerolog "github.com/samber/slog-zerolog/v2" + "helm.sh/helm/v4/pkg/action" + "helm.sh/helm/v4/pkg/cli" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/client-go/discovery" "k8s.io/client-go/discovery/cached/memory" @@ -28,11 +29,18 @@ func (hspm *HelmSDKPackageManager) initActionConfig(actionConfig *action.Configu namespace = "default" } + // Setup logging for Helm SDK using zerolog + logger := log.With().Str("context", "HelmClient").Logger() + logOptions := slogzerolog.Option{ + Logger: &(logger), + } + actionConfig.SetLogger(logOptions.NewZerologHandler()) + if k8sAccess == nil { // Use default kubeconfig settings := cli.New() clientGetter := settings.RESTClientGetter() - return actionConfig.Init(clientGetter, namespace, "secret", hspm.logf) + return actionConfig.Init(clientGetter, namespace, "secret") } // Create client config @@ -52,7 +60,7 @@ func (hspm *HelmSDKPackageManager) initActionConfig(actionConfig *action.Configu return err } - return actionConfig.Init(clientGetter, namespace, "secret", hspm.logf) + return actionConfig.Init(clientGetter, namespace, "secret") } // generateConfigAPI generates a new kubeconfig configuration @@ -147,11 +155,3 @@ func (c *clientConfigGetter) ToRESTMapper() (meta.RESTMapper, error) { func (c *clientConfigGetter) ToRawKubeConfigLoader() clientcmd.ClientConfig { return c.clientConfig } - -// logf is a log helper function for Helm -func (hspm *HelmSDKPackageManager) logf(format string, v ...any) { - // Use zerolog for structured logging - log.Debug(). - Str("context", "HelmClient"). - Msgf(format, v...) -} diff --git a/pkg/libhelm/sdk/client_test.go b/pkg/libhelm/sdk/client_test.go index ce087c77c..318f6bacd 100644 --- a/pkg/libhelm/sdk/client_test.go +++ b/pkg/libhelm/sdk/client_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v4/pkg/action" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd/api" ) diff --git a/pkg/libhelm/sdk/common.go b/pkg/libhelm/sdk/common.go index d532e9313..c982cc5dd 100644 --- a/pkg/libhelm/sdk/common.go +++ b/pkg/libhelm/sdk/common.go @@ -15,13 +15,16 @@ import ( "github.com/portainer/portainer/pkg/libhelm/options" "github.com/portainer/portainer/pkg/libhelm/release" "github.com/rs/zerolog/log" - "helm.sh/helm/v3/pkg/action" - "helm.sh/helm/v3/pkg/chart" - "helm.sh/helm/v3/pkg/chart/loader" - "helm.sh/helm/v3/pkg/cli" - "helm.sh/helm/v3/pkg/downloader" - "helm.sh/helm/v3/pkg/getter" - "helm.sh/helm/v3/pkg/repo" + "helm.sh/helm/v4/pkg/action" + "helm.sh/helm/v4/pkg/chart" + v2chart "helm.sh/helm/v4/pkg/chart/v2" + "helm.sh/helm/v4/pkg/chart/v2/loader" + "helm.sh/helm/v4/pkg/cli" + "helm.sh/helm/v4/pkg/downloader" + "helm.sh/helm/v4/pkg/getter" + sdkrelease "helm.sh/helm/v4/pkg/release" + releasev1 "helm.sh/helm/v4/pkg/release/v1" + repo "helm.sh/helm/v4/pkg/repo/v1" ) // Helm chart reference label constants @@ -35,7 +38,7 @@ const ( // loadAndValidateChartWithPathOptions locates and loads the chart, and validates it. // it also checks for chart dependencies and updates them if necessary. // it returns the chart information. -func (hspm *HelmSDKPackageManager) loadAndValidateChartWithPathOptions(chartPathOptions *action.ChartPathOptions, chartName, version string, repoURL string, dependencyUpdate bool, operation string) (*chart.Chart, error) { +func (hspm *HelmSDKPackageManager) loadAndValidateChartWithPathOptions(chartPathOptions *action.ChartPathOptions, chartName, version string, repoURL string, dependencyUpdate bool, operation string) (*v2chart.Chart, error) { chartPath, err := chartPathOptions.LocateChart(chartName, hspm.settings) if err != nil { log.Error(). @@ -60,9 +63,18 @@ func (hspm *HelmSDKPackageManager) loadAndValidateChartWithPathOptions(chartPath Msg("Failed to load chart for helm " + operation) return nil, errors.Wrap(err, "failed to load chart for helm "+operation) } + chartAcessor, err := chart.NewDefaultAccessor(chartReq) + if err != nil { + log.Error(). + Str("context", "HelmClient"). + Str("chart_path", chartPath). + Err(err). + Msg("Failed to make chart accessor for helm " + operation) + return nil, errors.Wrap(err, "failed to make chart accessor for helm "+operation) + } // Check chart dependencies to make sure all are present in /charts - if chartDependencies := chartReq.Metadata.Dependencies; chartDependencies != nil { + if chartDependencies := chartAcessor.MetaDependencies(); chartDependencies != nil { if err := action.CheckDependencies(chartReq, chartDependencies); err != nil { err = errors.Wrap(err, "failed to check chart dependencies for helm "+operation) if !dependencyUpdate { @@ -208,8 +220,8 @@ func ensureHelmDirectoriesExist(settings *cli.EnvSettings) error { return errors.Wrapf(err, "failed to create directory: %s", dir) } - // Create an empty registry config file - if _, err := os.Create(settings.RegistryConfig); err != nil { + // Create an empty registry config file with default yaml structure + if err := os.WriteFile(settings.RegistryConfig, []byte("{}"), 0600); err != nil { log.Error(). Str("context", "helm_sdk_dirs"). Str("file", settings.RegistryConfig). @@ -296,3 +308,15 @@ func extractChartReferenceAnnotations(annotations map[string]string) release.Cha RegistryID: int64(registryID), } } + +// releaserToV1Release converts a release.Releaser interface to a concrete v1.Release type +func releaserToV1Release(rel sdkrelease.Releaser) (*releasev1.Release, error) { + switch r := rel.(type) { + case releasev1.Release: + return &r, nil + case *releasev1.Release: + return r, nil + default: + return nil, fmt.Errorf("unsupported release type: %T", rel) + } +} diff --git a/pkg/libhelm/sdk/get.go b/pkg/libhelm/sdk/get.go index 1d72bb0e3..2bb4346b7 100644 --- a/pkg/libhelm/sdk/get.go +++ b/pkg/libhelm/sdk/get.go @@ -5,10 +5,9 @@ import ( "github.com/portainer/portainer/pkg/libhelm/options" "github.com/portainer/portainer/pkg/libhelm/release" - "github.com/portainer/portainer/pkg/libhelm/time" "github.com/rs/zerolog/log" - "helm.sh/helm/v3/pkg/action" - sdkrelease "helm.sh/helm/v3/pkg/release" + "helm.sh/helm/v4/pkg/action" + releasev1 "helm.sh/helm/v4/pkg/release/v1" ) // Get implements the HelmPackageManager interface by using the Helm SDK to get a release. @@ -55,7 +54,16 @@ func (hspm *HelmSDKPackageManager) Get(getOptions options.GetOptions) (*release. return nil, err } - return convert(release, values), nil + v1Release, err := releaserToV1Release(release) + if err != nil { + log.Error(). + Str("context", "HelmClient"). + Str("namespace", getOptions.Namespace). + Str("name", getOptions.Name). + Err(err).Msg("Failed to convert release to v1") + return nil, err + } + return convert(v1Release, values), nil } // Helm status is just an extended helm get command with resources added on (when flagged), so use the status client with the optional show resources flag @@ -63,7 +71,6 @@ func (hspm *HelmSDKPackageManager) Get(getOptions options.GetOptions) (*release. // https://github.com/helm/helm/blob/0199b748aaea3091852d16687c9f9f809061777c/pkg/action/status.go#L48-L82 func (hspm *HelmSDKPackageManager) initStatusClient(actionConfig *action.Configuration, getOptions options.GetOptions) (*action.Status, error) { statusClient := action.NewStatus(actionConfig) - statusClient.ShowResources = getOptions.ShowResources if getOptions.Revision > 0 { statusClient.Version = getOptions.Revision } @@ -71,52 +78,52 @@ func (hspm *HelmSDKPackageManager) initStatusClient(actionConfig *action.Configu return statusClient, nil } -func convert(sdkRelease *sdkrelease.Release, values release.Values) *release.Release { - resources, err := parseResources(sdkRelease.Info.Resources) +func convert(releasev1 *releasev1.Release, values release.Values) *release.Release { + resources, err := parseResources(releasev1.Info.Resources) if err != nil { log.Warn(). Str("context", "HelmClient"). - Str("namespace", sdkRelease.Namespace). - Str("name", sdkRelease.Name). + Str("namespace", releasev1.Namespace). + Str("name", releasev1.Name). Err(err).Msg("Failed to parse resources") } // Parse stack ID from annotations -> int stackID := 0 - if sdkRelease.Chart != nil && sdkRelease.Chart.Metadata != nil { - if s, ok := sdkRelease.Chart.Metadata.Annotations[StackIDAnnotation]; ok && s != "" { + if releasev1.Chart != nil && releasev1.Chart.Metadata != nil { + if s, ok := releasev1.Chart.Metadata.Annotations[StackIDAnnotation]; ok && s != "" { if id, err := strconv.Atoi(s); err == nil { stackID = id } else { log.Warn(). Str("context", "HelmClient"). - Str("namespace", sdkRelease.Namespace). - Str("name", sdkRelease.Name). + Str("namespace", releasev1.Namespace). + Str("name", releasev1.Name). Err(err).Msg("Failed to parse stack id from annotations") } } } release := &release.Release{ - Name: sdkRelease.Name, - Namespace: sdkRelease.Namespace, - Version: sdkRelease.Version, + Name: releasev1.Name, + Namespace: releasev1.Namespace, + Version: releasev1.Version, Info: &release.Info{ - Status: release.Status(sdkRelease.Info.Status), - Notes: sdkRelease.Info.Notes, + Status: release.Status(releasev1.Info.Status), + Notes: releasev1.Info.Notes, Resources: resources, - Description: sdkRelease.Info.Description, - LastDeployed: time.Time(sdkRelease.Info.LastDeployed), + Description: releasev1.Info.Description, + LastDeployed: releasev1.Info.LastDeployed, }, - Manifest: sdkRelease.Manifest, + Manifest: releasev1.Manifest, Chart: release.Chart{ Metadata: &release.Metadata{ - Name: sdkRelease.Chart.Metadata.Name, - Version: sdkRelease.Chart.Metadata.Version, - AppVersion: sdkRelease.Chart.Metadata.AppVersion, + Name: releasev1.Chart.Metadata.Name, + Version: releasev1.Chart.Metadata.Version, + AppVersion: releasev1.Chart.Metadata.AppVersion, }, }, Values: values, - ChartReference: extractChartReferenceAnnotations(sdkRelease.Chart.Metadata.Annotations), + ChartReference: extractChartReferenceAnnotations(releasev1.Chart.Metadata.Annotations), StackID: stackID, } diff --git a/pkg/libhelm/sdk/get_test.go b/pkg/libhelm/sdk/get_test.go index 2bc90081b..da71aaec1 100644 --- a/pkg/libhelm/sdk/get_test.go +++ b/pkg/libhelm/sdk/get_test.go @@ -5,22 +5,22 @@ import ( libhelmrelease "github.com/portainer/portainer/pkg/libhelm/release" "github.com/stretchr/testify/assert" - "helm.sh/helm/v3/pkg/chart" - sdkrelease "helm.sh/helm/v3/pkg/release" + chartv2 "helm.sh/helm/v4/pkg/chart/v2" + releasev1 "helm.sh/helm/v4/pkg/release/v1" ) func Test_Convert(t *testing.T) { t.Run("successfully maps a sdk release to a release", func(t *testing.T) { is := assert.New(t) - release := sdkrelease.Release{ + release := releasev1.Release{ Name: "releaseName", Version: 1, - Info: &sdkrelease.Info{ + Info: &releasev1.Info{ Status: "deployed", }, - Chart: &chart.Chart{ - Metadata: &chart.Metadata{ + Chart: &chartv2.Chart{ + Metadata: &chartv2.Metadata{ Name: "chartName", Version: "chartVersion", AppVersion: "chartAppVersion", @@ -40,15 +40,15 @@ func Test_Convert(t *testing.T) { t.Run("extracts stack ID from annotations", func(t *testing.T) { is := assert.New(t) - release := sdkrelease.Release{ + release := releasev1.Release{ Name: "stack-release", Namespace: "app-namespace", Version: 2, - Info: &sdkrelease.Info{ + Info: &releasev1.Info{ Status: "deployed", }, - Chart: &chart.Chart{ - Metadata: &chart.Metadata{ + Chart: &chartv2.Chart{ + Metadata: &chartv2.Metadata{ Name: "myapp", Version: "2.1.0", Annotations: map[string]string{ @@ -71,15 +71,15 @@ func Test_Convert(t *testing.T) { t.Run("handles invalid stack ID gracefully", func(t *testing.T) { is := assert.New(t) - release := sdkrelease.Release{ + release := releasev1.Release{ Name: "release", Namespace: "default", Version: 1, - Info: &sdkrelease.Info{ + Info: &releasev1.Info{ Status: "deployed", }, - Chart: &chart.Chart{ - Metadata: &chart.Metadata{ + Chart: &chartv2.Chart{ + Metadata: &chartv2.Metadata{ Name: "chart", Version: "1.0.0", Annotations: map[string]string{ @@ -99,15 +99,15 @@ func Test_Convert(t *testing.T) { t.Run("handles empty stack ID annotation", func(t *testing.T) { is := assert.New(t) - release := sdkrelease.Release{ + release := releasev1.Release{ Name: "release", Namespace: "default", Version: 1, - Info: &sdkrelease.Info{ + Info: &releasev1.Info{ Status: "deployed", }, - Chart: &chart.Chart{ - Metadata: &chart.Metadata{ + Chart: &chartv2.Chart{ + Metadata: &chartv2.Metadata{ Name: "chart", Version: "1.0.0", Annotations: map[string]string{ @@ -126,15 +126,15 @@ func Test_Convert(t *testing.T) { t.Run("handles missing annotations", func(t *testing.T) { is := assert.New(t) - release := sdkrelease.Release{ + release := releasev1.Release{ Name: "release", Namespace: "default", Version: 1, - Info: &sdkrelease.Info{ + Info: &releasev1.Info{ Status: "deployed", }, - Chart: &chart.Chart{ - Metadata: &chart.Metadata{ + Chart: &chartv2.Chart{ + Metadata: &chartv2.Metadata{ Name: "chart", Version: "1.0.0", Annotations: nil, @@ -155,15 +155,15 @@ func Test_Convert(t *testing.T) { t.Run("extracts registry ID from annotations", func(t *testing.T) { is := assert.New(t) - release := sdkrelease.Release{ + release := releasev1.Release{ Name: "release", Namespace: "default", Version: 1, - Info: &sdkrelease.Info{ + Info: &releasev1.Info{ Status: "deployed", }, - Chart: &chart.Chart{ - Metadata: &chart.Metadata{ + Chart: &chartv2.Chart{ + Metadata: &chartv2.Metadata{ Name: "chart", Version: "1.0.0", Annotations: map[string]string{ diff --git a/pkg/libhelm/sdk/history.go b/pkg/libhelm/sdk/history.go index 109ab68aa..ff021a841 100644 --- a/pkg/libhelm/sdk/history.go +++ b/pkg/libhelm/sdk/history.go @@ -5,10 +5,9 @@ import ( "github.com/portainer/portainer/pkg/libhelm/options" "github.com/portainer/portainer/pkg/libhelm/release" - "github.com/portainer/portainer/pkg/libhelm/time" "github.com/rs/zerolog/log" - "helm.sh/helm/v3/pkg/action" - sdkrelease "helm.sh/helm/v3/pkg/release" + "helm.sh/helm/v4/pkg/action" + sdkrelease "helm.sh/helm/v4/pkg/release" ) // GetHistory implements the HelmPackageManager interface by using the Helm SDK to get a release. @@ -43,7 +42,11 @@ func (hspm *HelmSDKPackageManager) GetHistory(historyOptions options.HistoryOpti var result []*release.Release for _, r := range history { - result = append(result, convertHistory(r)) + converted, err := convertHistory(r) + if err != nil { + return nil, err + } + result = append(result, converted) } // sort the result by version (latest first) @@ -54,22 +57,27 @@ func (hspm *HelmSDKPackageManager) GetHistory(historyOptions options.HistoryOpti return result, nil } -func convertHistory(sdkRelease *sdkrelease.Release) *release.Release { +func convertHistory(r sdkrelease.Releaser) (*release.Release, error) { + v1Release, err := releaserToV1Release(r) + if err != nil { + log.Error().Err(err).Msg("Failed to convert release") + return nil, err + } return &release.Release{ - Name: sdkRelease.Name, - Namespace: sdkRelease.Namespace, - Version: sdkRelease.Version, + Name: v1Release.Name, + Namespace: v1Release.Namespace, + Version: v1Release.Version, Info: &release.Info{ - Status: release.Status(sdkRelease.Info.Status), - Notes: sdkRelease.Info.Notes, - LastDeployed: time.Time(sdkRelease.Info.LastDeployed), + Status: release.Status(v1Release.Info.Status), + Notes: v1Release.Info.Notes, + LastDeployed: v1Release.Info.LastDeployed, }, Chart: release.Chart{ Metadata: &release.Metadata{ - Name: sdkRelease.Chart.Metadata.Name, - Version: sdkRelease.Chart.Metadata.Version, - AppVersion: sdkRelease.Chart.Metadata.AppVersion, + Name: v1Release.Chart.Metadata.Name, + Version: v1Release.Chart.Metadata.Version, + AppVersion: v1Release.Chart.Metadata.AppVersion, }, }, - } + }, nil } diff --git a/pkg/libhelm/sdk/history_test.go b/pkg/libhelm/sdk/history_test.go index 718911697..c7732a37d 100644 --- a/pkg/libhelm/sdk/history_test.go +++ b/pkg/libhelm/sdk/history_test.go @@ -4,8 +4,9 @@ import ( "testing" "github.com/stretchr/testify/assert" - "helm.sh/helm/v3/pkg/chart" - sdkrelease "helm.sh/helm/v3/pkg/release" + "github.com/stretchr/testify/require" + chart "helm.sh/helm/v4/pkg/chart/v2" + sdkrelease "helm.sh/helm/v4/pkg/release/v1" ) func Test_ConvertHistory(t *testing.T) { @@ -27,7 +28,8 @@ func Test_ConvertHistory(t *testing.T) { }, } - result := convertHistory(&release) + result, err := convertHistory(&release) + require.NoError(t, err) is.Equal(release.Name, result.Name) }) } diff --git a/pkg/libhelm/sdk/install.go b/pkg/libhelm/sdk/install.go index 627fb6e1f..e797934e4 100644 --- a/pkg/libhelm/sdk/install.go +++ b/pkg/libhelm/sdk/install.go @@ -8,8 +8,8 @@ import ( "github.com/portainer/portainer/pkg/libhelm/options" "github.com/portainer/portainer/pkg/libhelm/release" "github.com/rs/zerolog/log" - "helm.sh/helm/v3/pkg/action" - "helm.sh/helm/v3/pkg/postrender" + "helm.sh/helm/v4/pkg/action" + "helm.sh/helm/v4/pkg/kube" ) // Install implements the HelmPackageManager interface by using the Helm SDK to install a chart. @@ -125,21 +125,32 @@ func (hspm *HelmSDKPackageManager) install(installOpts options.InstallOptions) ( } return nil, errors.Wrap(err, "helm was not able to install the chart for helm release installation") } + v1Release, err := releaserToV1Release(helmRelease) + if err != nil { + log.Error(). + Str("context", "HelmClient"). + Str("chart", installOpts.Chart). + Str("name", installOpts.Name). + Str("namespace", installOpts.Namespace). + Err(err). + Msg("Failed to convert helm release to v1 release for helm release installation") + return nil, errors.Wrap(err, "helm was not able to convert helm release to v1 release") + } return &release.Release{ - Name: helmRelease.Name, - Namespace: helmRelease.Namespace, + Name: v1Release.Name, + Namespace: v1Release.Namespace, Chart: release.Chart{ Metadata: &release.Metadata{ - Name: helmRelease.Chart.Metadata.Name, - Version: helmRelease.Chart.Metadata.Version, - AppVersion: helmRelease.Chart.Metadata.AppVersion, - Annotations: helmRelease.Chart.Metadata.Annotations, + Name: v1Release.Chart.Metadata.Name, + Version: v1Release.Chart.Metadata.Version, + AppVersion: v1Release.Chart.Metadata.AppVersion, + Annotations: v1Release.Chart.Metadata.Annotations, }, }, - Labels: helmRelease.Labels, - Version: helmRelease.Version, - Manifest: helmRelease.Manifest, + Labels: v1Release.Labels, + Version: v1Release.Version, + Manifest: v1Release.Manifest, }, nil } @@ -149,10 +160,16 @@ func initInstallClient(actionConfig *action.Configuration, installOpts options.I installClient := action.NewInstall(actionConfig) installClient.DependencyUpdate = true installClient.ReleaseName = installOpts.Name - installClient.Wait = installOpts.Wait + if installOpts.Wait { + installClient.WaitStrategy = kube.StatusWatcherStrategy + } else { + installClient.WaitStrategy = kube.HookOnlyStrategy + } installClient.Timeout = installOpts.Timeout installClient.Version = installOpts.Version - installClient.DryRun = installOpts.DryRun + if installOpts.DryRun { + installClient.DryRunStrategy = action.DryRunClient + } installClient.TakeOwnership = installOpts.TakeOwnership installClient.CreateNamespace = installOpts.CreateNamespace err := configureChartPathOptions(&installClient.ChartPathOptions, installOpts.Version, installOpts.Repo, installOpts.Registry) @@ -172,15 +189,8 @@ func initInstallClient(actionConfig *action.Configuration, installOpts options.I installClient.Namespace = installOpts.Namespace } - switch { - case len(installOpts.HelmAppLabels) > 0: + if len(installOpts.HelmAppLabels) > 0 { installClient.PostRenderer = &appLabelsPostRenderer{labels: installOpts.HelmAppLabels} - case installOpts.PostRenderer != "": - postRenderer, err := postrender.NewExec(installOpts.PostRenderer) - if err != nil { - return nil, errors.Wrap(err, "failed to create post renderer") - } - installClient.PostRenderer = postRenderer } return installClient, nil diff --git a/pkg/libhelm/sdk/label_post_renderer.go b/pkg/libhelm/sdk/label_post_renderer.go index f38a3a568..5e5e85ceb 100644 --- a/pkg/libhelm/sdk/label_post_renderer.go +++ b/pkg/libhelm/sdk/label_post_renderer.go @@ -5,11 +5,11 @@ import ( "github.com/portainer/portainer/api/kubernetes" "github.com/rs/zerolog/log" - "helm.sh/helm/v3/pkg/postrender" + "helm.sh/helm/v4/pkg/postrenderer" ) // Ensure appLabelsPostRenderer implements the postrender.PostRenderer interface. -var _ postrender.PostRenderer = &appLabelsPostRenderer{} +var _ postrenderer.PostRenderer = &appLabelsPostRenderer{} // appLabelsPostRenderer is an in-process Helm post-renderer that injects // Portainer app labels into every Kubernetes resource in the rendered manifests. diff --git a/pkg/libhelm/sdk/list.go b/pkg/libhelm/sdk/list.go index 6e688d1b6..ee7bb63e1 100644 --- a/pkg/libhelm/sdk/list.go +++ b/pkg/libhelm/sdk/list.go @@ -8,8 +8,9 @@ import ( "github.com/portainer/portainer/pkg/libhelm/options" "github.com/portainer/portainer/pkg/libhelm/release" "github.com/rs/zerolog/log" - "helm.sh/helm/v3/pkg/action" - sdkrelease "helm.sh/helm/v3/pkg/release" + "helm.sh/helm/v4/pkg/action" + sdkrelease "helm.sh/helm/v4/pkg/release" + releasev1 "helm.sh/helm/v4/pkg/release/v1" ) // List implements the HelmPackageManager interface by using the Helm SDK to list releases. @@ -36,6 +37,7 @@ func (hspm *HelmSDKPackageManager) List(listOpts options.ListOptions) ([]release Str("context", "HelmClient"). Err(err). Msg("Failed to initialize helm list client") + return nil, errors.Wrap(err, "failed to initialize helm list client") } // Run the list operation @@ -49,14 +51,22 @@ func (hspm *HelmSDKPackageManager) List(listOpts options.ListOptions) ([]release } // Convert from SDK release type to our release element type and return - return convertToReleaseElements(releases), nil + return convertToReleaseElements(releases) } // convertToReleaseElements converts from the SDK release type to our release element type -func convertToReleaseElements(releases []*sdkrelease.Release) []release.ReleaseElement { - elements := make([]release.ReleaseElement, len(releases)) +func convertToReleaseElements(ls []sdkrelease.Releaser) ([]release.ReleaseElement, error) { + rls := make([]*releasev1.Release, 0, len(ls)) + for _, val := range ls { + rel, err := releaserToV1Release(val) + if err != nil { + return nil, errors.Wrap(err, "failed to convert releaser to v1 release") + } + rls = append(rls, rel) + } + elements := make([]release.ReleaseElement, len(rls)) - for i, rel := range releases { + for i, rel := range rls { chartName := fmt.Sprintf("%s-%s", rel.Chart.Metadata.Name, rel.Chart.Metadata.Version) elements[i] = release.ReleaseElement{ @@ -70,7 +80,7 @@ func convertToReleaseElements(releases []*sdkrelease.Release) []release.ReleaseE } } - return elements + return elements, nil } // initListClient initializes the list client with the given options diff --git a/pkg/libhelm/sdk/list_test.go b/pkg/libhelm/sdk/list_test.go index c2f0ac43c..b376bb25c 100644 --- a/pkg/libhelm/sdk/list_test.go +++ b/pkg/libhelm/sdk/list_test.go @@ -2,24 +2,27 @@ package sdk import ( "testing" + "time" "github.com/stretchr/testify/assert" - "helm.sh/helm/v3/pkg/chart" - "helm.sh/helm/v3/pkg/release" - "helm.sh/helm/v3/pkg/time" + "github.com/stretchr/testify/require" + chart "helm.sh/helm/v4/pkg/chart/v2" + release "helm.sh/helm/v4/pkg/release" + "helm.sh/helm/v4/pkg/release/common" + releasev1 "helm.sh/helm/v4/pkg/release/v1" ) func Test_ConvertToReleaseElements(t *testing.T) { is := assert.New(t) // Create mock releases - releases := []*release.Release{ + releases := []*releasev1.Release{ { Name: "release1", Namespace: "default", Version: 1, - Info: &release.Info{ - Status: release.StatusDeployed, + Info: &releasev1.Info{ + Status: common.StatusDeployed, LastDeployed: time.Now(), }, Chart: &chart.Chart{ @@ -34,8 +37,8 @@ func Test_ConvertToReleaseElements(t *testing.T) { Name: "release2", Namespace: "kube-system", Version: 2, - Info: &release.Info{ - Status: release.StatusFailed, + Info: &releasev1.Info{ + Status: common.StatusFailed, LastDeployed: time.Now(), }, Chart: &chart.Chart{ @@ -48,8 +51,13 @@ func Test_ConvertToReleaseElements(t *testing.T) { }, } - // Convert to release elements - elements := convertToReleaseElements(releases) + // Convert to release elements using the releasor interface + var releasors []release.Releaser + for _, r := range releases { + releasors = append(releasors, r) + } + elements, err := convertToReleaseElements(releasors) + require.NoError(t, err) // Verify conversion is.Len(elements, 2, "should return 2 release elements") @@ -58,7 +66,7 @@ func Test_ConvertToReleaseElements(t *testing.T) { is.Equal("release1", elements[0].Name, "first release name should be release1") is.Equal("default", elements[0].Namespace, "first release namespace should be default") is.Equal("1", elements[0].Revision, "first release revision should be 1") - is.Equal(string(release.StatusDeployed), elements[0].Status, "first release status should be deployed") + is.Equal(string(common.StatusDeployed), elements[0].Status, "first release status should be deployed") is.Equal("chart1-1.0.0", elements[0].Chart, "first release chart should be chart1-1.0.0") is.Equal("1.0.0", elements[0].AppVersion, "first release app version should be 1.0.0") @@ -66,7 +74,7 @@ func Test_ConvertToReleaseElements(t *testing.T) { is.Equal("release2", elements[1].Name, "second release name should be release2") is.Equal("kube-system", elements[1].Namespace, "second release namespace should be kube-system") is.Equal("2", elements[1].Revision, "second release revision should be 2") - is.Equal(string(release.StatusFailed), elements[1].Status, "second release status should be failed") + is.Equal(string(common.StatusFailed), elements[1].Status, "second release status should be failed") is.Equal("chart2-2.0.0", elements[1].Chart, "second release chart should be chart2-2.0.0") is.Equal("2.0.0", elements[1].AppVersion, "second release app version should be 2.0.0") } diff --git a/pkg/libhelm/sdk/manager.go b/pkg/libhelm/sdk/manager.go index 1ac33db24..9e553d63b 100644 --- a/pkg/libhelm/sdk/manager.go +++ b/pkg/libhelm/sdk/manager.go @@ -3,7 +3,7 @@ package sdk import ( "time" - "helm.sh/helm/v3/pkg/cli" + "helm.sh/helm/v4/pkg/cli" ) // HelmSDKPackageManager is a wrapper for the helm SDK which implements HelmPackageManager diff --git a/pkg/libhelm/sdk/release.go b/pkg/libhelm/sdk/release.go index 76f6840ff..f2f4b4b8e 100644 --- a/pkg/libhelm/sdk/release.go +++ b/pkg/libhelm/sdk/release.go @@ -5,9 +5,10 @@ import ( "github.com/pkg/errors" "github.com/portainer/portainer/pkg/libhelm/options" - "helm.sh/helm/v3/pkg/action" - "helm.sh/helm/v3/pkg/release" - "helm.sh/helm/v3/pkg/storage/driver" + "helm.sh/helm/v4/pkg/action" + "helm.sh/helm/v4/pkg/release/common" + releasev1 "helm.sh/helm/v4/pkg/release/v1" + "helm.sh/helm/v4/pkg/storage/driver" ) func (hspm *HelmSDKPackageManager) doesReleaseExist(releaseName, namespace string, clusterAccess *options.KubernetesClusterAccess) (bool, error) { @@ -26,7 +27,17 @@ func (hspm *HelmSDKPackageManager) doesReleaseExist(releaseName, namespace strin } versions, err := historyClient.Run(releaseName) - if errors.Is(err, driver.ErrReleaseNotFound) || isReleaseUninstalled(versions) { + + releases := make([]*releasev1.Release, 0, len(versions)) + for _, val := range versions { + rel, err := releaserToV1Release(val) + if err != nil { + return false, fmt.Errorf("failed to convert helm release to helm release v1: %w", err) + } + releases = append(releases, rel) + } + + if errors.Is(err, driver.ErrReleaseNotFound) || isReleaseUninstalled(releases) { return false, nil } else if err != nil { return false, fmt.Errorf("failed to get history: %w", err) @@ -35,8 +46,8 @@ func (hspm *HelmSDKPackageManager) doesReleaseExist(releaseName, namespace strin return true, nil } -func isReleaseUninstalled(versions []*release.Release) bool { - return len(versions) > 0 && versions[len(versions)-1].Info.Status == release.StatusUninstalled +func isReleaseUninstalled(versions []*releasev1.Release) bool { + return len(versions) > 0 && versions[len(versions)-1].Info.Status == common.StatusUninstalled } func (hspm *HelmSDKPackageManager) initHistoryClient(actionConfig *action.Configuration, namespace string, clusterAccess *options.KubernetesClusterAccess) (*action.History, error) { diff --git a/pkg/libhelm/sdk/rollback.go b/pkg/libhelm/sdk/rollback.go index 9b5caac8e..5af2ea21b 100644 --- a/pkg/libhelm/sdk/rollback.go +++ b/pkg/libhelm/sdk/rollback.go @@ -7,7 +7,8 @@ import ( "github.com/portainer/portainer/pkg/libhelm/options" "github.com/portainer/portainer/pkg/libhelm/release" "github.com/rs/zerolog/log" - "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v4/pkg/action" + "helm.sh/helm/v4/pkg/kube" ) // Rollback would implement the HelmPackageManager interface by using the Helm SDK to rollback a release to a previous revision. @@ -62,25 +63,36 @@ func (hspm *HelmSDKPackageManager) Rollback(rollbackOpts options.RollbackOptions Msg("Failed to get status after rollback") return nil, errors.Wrap(err, "failed to get status after rollback") } + releaseV1, err := releaserToV1Release(rel) + if err != nil { + log.Error(). + Str("context", "HelmClient"). + Str("name", rollbackOpts.Name). + Str("namespace", rollbackOpts.Namespace). + Int("revision", rollbackOpts.Version). + Err(err). + Msg("Failed to convert release to v1 after rollback") + return nil, errors.Wrap(err, "failed to convert release to v1 after rollback") + } return &release.Release{ - Name: rel.Name, - Namespace: rel.Namespace, - Version: rel.Version, + Name: releaseV1.Name, + Namespace: releaseV1.Namespace, + Version: releaseV1.Version, Info: &release.Info{ - Status: release.Status(rel.Info.Status), - Notes: rel.Info.Notes, - Description: rel.Info.Description, + Status: release.Status(releaseV1.Info.Status), + Notes: releaseV1.Info.Notes, + Description: releaseV1.Info.Description, }, - Manifest: rel.Manifest, + Manifest: releaseV1.Manifest, Chart: release.Chart{ Metadata: &release.Metadata{ - Name: rel.Chart.Metadata.Name, - Version: rel.Chart.Metadata.Version, - AppVersion: rel.Chart.Metadata.AppVersion, + Name: releaseV1.Chart.Metadata.Name, + Version: releaseV1.Chart.Metadata.Version, + AppVersion: releaseV1.Chart.Metadata.AppVersion, }, }, - Labels: rel.Labels, + Labels: releaseV1.Labels, }, nil } @@ -94,12 +106,15 @@ func initRollbackClient(actionConfig *action.Configuration, rollbackOpts options rollbackClient.Version = rollbackOpts.Version } - rollbackClient.Wait = rollbackOpts.Wait + if rollbackOpts.Wait { + rollbackClient.WaitStrategy = kube.StatusWatcherStrategy + } else { + rollbackClient.WaitStrategy = kube.HookOnlyStrategy + } rollbackClient.WaitForJobs = rollbackOpts.WaitForJobs rollbackClient.CleanupOnFail = true // Sane default to clean up on failure - rollbackClient.Recreate = rollbackOpts.Recreate - rollbackClient.Force = rollbackOpts.Force - + rollbackClient.ForceReplace = rollbackOpts.Force + rollbackClient.ServerSideApply = "auto" // Set default values if not specified if rollbackOpts.Timeout == 0 { rollbackClient.Timeout = 5 * time.Minute // Sane default of 5 minutes diff --git a/pkg/libhelm/sdk/search_repo.go b/pkg/libhelm/sdk/search_repo.go index 2f36b3b73..dee1443d2 100644 --- a/pkg/libhelm/sdk/search_repo.go +++ b/pkg/libhelm/sdk/search_repo.go @@ -17,10 +17,10 @@ import ( "github.com/portainer/portainer/pkg/liboras" "github.com/rs/zerolog/log" "github.com/segmentio/encoding/json" - "helm.sh/helm/v3/pkg/chart" - "helm.sh/helm/v3/pkg/cli" - "helm.sh/helm/v3/pkg/getter" - "helm.sh/helm/v3/pkg/repo" + chart "helm.sh/helm/v4/pkg/chart/v2" + "helm.sh/helm/v4/pkg/cli" + "helm.sh/helm/v4/pkg/getter" + repo "helm.sh/helm/v4/pkg/repo/v1" "oras.land/oras-go/v2/registry" ) diff --git a/pkg/libhelm/sdk/show.go b/pkg/libhelm/sdk/show.go index 39fe2cfcd..0536ad67a 100644 --- a/pkg/libhelm/sdk/show.go +++ b/pkg/libhelm/sdk/show.go @@ -7,7 +7,7 @@ import ( "github.com/portainer/portainer/pkg/libhelm/cache" "github.com/portainer/portainer/pkg/libhelm/options" "github.com/rs/zerolog/log" - "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v4/pkg/action" ) var errRequiredShowOptions = errors.New("chart, output format and either repo or registry are required") @@ -107,7 +107,7 @@ func (hspm *HelmSDKPackageManager) Show(showOpts options.ShowOptions) ([]byte, e // initShowClient initializes the show client with the given options // and return the show client. func initShowClient(actionConfig *action.Configuration, showOpts options.ShowOptions) (*action.Show, error) { - showClient := action.NewShowWithConfig(action.ShowAll, actionConfig) + showClient := action.NewShow(action.ShowAll, actionConfig) err := configureChartPathOptions(&showClient.ChartPathOptions, showOpts.Version, showOpts.Repo, showOpts.Registry) if err != nil { return nil, fmt.Errorf("failed to configure chart path options: %w", err) diff --git a/pkg/libhelm/sdk/uninstall.go b/pkg/libhelm/sdk/uninstall.go index f8a509e75..144f0d69c 100644 --- a/pkg/libhelm/sdk/uninstall.go +++ b/pkg/libhelm/sdk/uninstall.go @@ -6,8 +6,9 @@ import ( "github.com/pkg/errors" "github.com/portainer/portainer/pkg/libhelm/options" "github.com/rs/zerolog/log" - "helm.sh/helm/v3/pkg/action" - "helm.sh/helm/v3/pkg/storage/driver" + "helm.sh/helm/v4/pkg/action" + "helm.sh/helm/v4/pkg/kube" + "helm.sh/helm/v4/pkg/storage/driver" ) // Uninstall implements the HelmPackageManager interface by using the Helm SDK to uninstall a release. @@ -37,7 +38,11 @@ func (hspm *HelmSDKPackageManager) Uninstall(uninstallOpts options.UninstallOpti uninstallClient := action.NewUninstall(actionConfig) // 'foreground' means the parent object remains in a "terminating" state until all of its children are deleted. This ensures that all dependent resources are completely removed before finalizing the deletion of the parent resource. uninstallClient.DeletionPropagation = "foreground" // "background" or "orphan" - uninstallClient.Wait = uninstallOpts.Wait + if uninstallOpts.Wait { + uninstallClient.WaitStrategy = kube.StatusWatcherStrategy + } else { + uninstallClient.WaitStrategy = kube.HookOnlyStrategy + } if uninstallOpts.Timeout == 0 { uninstallClient.Timeout = 15 * time.Minute } else { @@ -63,10 +68,19 @@ func (hspm *HelmSDKPackageManager) Uninstall(uninstallOpts options.UninstallOpti } if result != nil { + releaseV1, err := releaserToV1Release(result.Release) + if err != nil { + log.Error(). + Str("context", "HelmClient"). + Str("release", uninstallOpts.Name). + Err(err). + Msg("Failed to convert release to v1") + return errors.Wrap(err, "failed to convert release to v1") + } log.Debug(). Str("context", "HelmClient"). Str("release", uninstallOpts.Name). - Str("release_info", result.Release.Info.Description). + Str("release_info", releaseV1.Info.Description). Msg("Uninstall result details") } @@ -109,8 +123,18 @@ func (hspm *HelmSDKPackageManager) ForceRemoveRelease(uninstallOpts options.Unin // Delete each release version from storage for _, v := range versions { - if _, err := actionConfig.Releases.Delete(v.Name, v.Version); err != nil { - return errors.Wrapf(err, "failed to delete release version %d for force-remove", v.Version) + releaseV1, err := releaserToV1Release(v) + if err != nil { + log.Error(). + Str("context", "HelmClient"). + Str("release", uninstallOpts.Name). + Int("version", releaseV1.Version). + Err(err). + Msg("Failed to convert releaser version to v1 for force-remove, skipping deletion of this version") + continue + } + if _, err := actionConfig.Releases.Delete(releaseV1.Name, releaseV1.Version); err != nil { + return errors.Wrapf(err, "failed to delete release version %d for force-remove", releaseV1.Version) } } diff --git a/pkg/libhelm/sdk/upgrade.go b/pkg/libhelm/sdk/upgrade.go index 953a4cfad..455979a51 100644 --- a/pkg/libhelm/sdk/upgrade.go +++ b/pkg/libhelm/sdk/upgrade.go @@ -8,8 +8,8 @@ import ( "github.com/portainer/portainer/pkg/libhelm/options" "github.com/portainer/portainer/pkg/libhelm/release" "github.com/rs/zerolog/log" - "helm.sh/helm/v3/pkg/action" - "helm.sh/helm/v3/pkg/postrender" + "helm.sh/helm/v4/pkg/action" + "helm.sh/helm/v4/pkg/kube" ) // Upgrade implements the HelmPackageManager interface by using the Helm SDK to upgrade a chart. @@ -144,21 +144,32 @@ func (hspm *HelmSDKPackageManager) Upgrade(upgradeOpts options.InstallOptions) ( Msg("Failed to upgrade helm chart for helm release upgrade") return nil, errors.Wrap(err, "helm was not able to upgrade the chart for helm release upgrade") } + releaseV1, err := releaserToV1Release(helmRelease) + if err != nil { + log.Error(). + Str("context", "HelmClient"). + Str("chart", upgradeOpts.Chart). + Str("name", upgradeOpts.Name). + Str("namespace", upgradeOpts.Namespace). + Err(err). + Msg("Failed to convert helm release to v1 release for helm release upgrade") + return nil, errors.Wrap(err, "Failed to convert helm release to v1 release for helm release upgrade") + } return &release.Release{ - Name: helmRelease.Name, - Namespace: helmRelease.Namespace, + Name: releaseV1.Name, + Namespace: releaseV1.Namespace, Chart: release.Chart{ Metadata: &release.Metadata{ - Name: helmRelease.Chart.Metadata.Name, - Version: helmRelease.Chart.Metadata.Version, - AppVersion: helmRelease.Chart.Metadata.AppVersion, - Annotations: helmRelease.Chart.Metadata.Annotations, + Name: releaseV1.Chart.Metadata.Name, + Version: releaseV1.Chart.Metadata.Version, + AppVersion: releaseV1.Chart.Metadata.AppVersion, + Annotations: releaseV1.Chart.Metadata.Annotations, }, }, - Labels: helmRelease.Labels, - Version: helmRelease.Version, - Manifest: helmRelease.Manifest, + Labels: releaseV1.Labels, + Version: releaseV1.Version, + Manifest: releaseV1.Manifest, }, nil } @@ -167,10 +178,16 @@ func (hspm *HelmSDKPackageManager) Upgrade(upgradeOpts options.InstallOptions) ( func initUpgradeClient(actionConfig *action.Configuration, upgradeOpts options.InstallOptions) (*action.Upgrade, error) { upgradeClient := action.NewUpgrade(actionConfig) upgradeClient.DependencyUpdate = true - upgradeClient.Atomic = upgradeOpts.Atomic - upgradeClient.Wait = upgradeOpts.Wait + upgradeClient.RollbackOnFailure = upgradeOpts.Atomic upgradeClient.Version = upgradeOpts.Version - upgradeClient.DryRun = upgradeOpts.DryRun + if upgradeOpts.DryRun { + upgradeClient.DryRunStrategy = action.DryRunClient + } + if upgradeOpts.Wait { + upgradeClient.WaitStrategy = kube.StatusWatcherStrategy + } else { + upgradeClient.WaitStrategy = kube.HookOnlyStrategy + } upgradeClient.TakeOwnership = upgradeOpts.TakeOwnership // Equivalent to --take-ownership flag err := configureChartPathOptions(&upgradeClient.ChartPathOptions, upgradeOpts.Version, upgradeOpts.Repo, upgradeOpts.Registry) if err != nil { @@ -179,7 +196,7 @@ func initUpgradeClient(actionConfig *action.Configuration, upgradeOpts options.I // Set default values if not specified if upgradeOpts.Timeout == 0 { - if upgradeClient.Atomic { + if upgradeClient.RollbackOnFailure { upgradeClient.Timeout = 30 * time.Minute // the atomic flag significantly increases the upgrade time } else { upgradeClient.Timeout = 15 * time.Minute @@ -193,15 +210,8 @@ func initUpgradeClient(actionConfig *action.Configuration, upgradeOpts options.I upgradeClient.Namespace = upgradeOpts.Namespace } - switch { - case len(upgradeOpts.HelmAppLabels) > 0: + if len(upgradeOpts.HelmAppLabels) > 0 { upgradeClient.PostRenderer = &appLabelsPostRenderer{labels: upgradeOpts.HelmAppLabels} - case upgradeOpts.PostRenderer != "": - postRenderer, err := postrender.NewExec(upgradeOpts.PostRenderer) - if err != nil { - return nil, errors.Wrap(err, "failed to create post renderer") - } - upgradeClient.PostRenderer = postRenderer } return upgradeClient, nil diff --git a/pkg/libhelm/sdk/values.go b/pkg/libhelm/sdk/values.go index a79549d85..0bf903ba5 100644 --- a/pkg/libhelm/sdk/values.go +++ b/pkg/libhelm/sdk/values.go @@ -9,8 +9,8 @@ import ( "github.com/pkg/errors" "github.com/rs/zerolog/log" "go.yaml.in/yaml/v3" - "helm.sh/helm/v3/pkg/action" - "helm.sh/helm/v3/pkg/chartutil" + "helm.sh/helm/v4/pkg/action" + "helm.sh/helm/v4/pkg/chart/common" ) // GetHelmValuesFromFile reads the values file and parses it into a map[string]any @@ -49,9 +49,9 @@ func GetHelmValuesFromFile(valuesFile string) (map[string]any, error) { // parseValues parses YAML values data into a map func parseValues(data []byte) (map[string]any, error) { - // Use Helm's built-in chartutil.ReadValues which properly handles the conversion + // Use Helm's built-in common.ReadValues which properly handles the conversion // from map[interface{}]interface{} to map[string]interface{} - return chartutil.ReadValues(data) + return common.ReadValues(data) } // MergeValues merges two maps recursively, with values from the override map taking precedence diff --git a/pkg/libhelm/time/time.go b/pkg/libhelm/time/time.go deleted file mode 100644 index 5c94349fa..000000000 --- a/pkg/libhelm/time/time.go +++ /dev/null @@ -1,91 +0,0 @@ -/* -Copyright The Helm Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package time contains a wrapper for time.Time in the standard library and -// associated methods. This package mainly exists to workaround an issue in Go -// where the serializer doesn't omit an empty value for time: -// https://github.com/golang/go/issues/11939. As such, this can be removed if a -// proposal is ever accepted for Go -package time - -import ( - "bytes" - "time" -) - -// emptyString contains an empty JSON string value to be used as output -var emptyString = `""` - -// Time is a convenience wrapper around stdlib time, but with different -// marshalling and unmarshaling for zero values -type Time struct { - time.Time -} - -// Now returns the current time. It is a convenience wrapper around time.Now() -func Now() Time { - return Time{time.Now()} -} - -func (t Time) MarshalJSON() ([]byte, error) { - if t.IsZero() { - return []byte(emptyString), nil - } - - return t.Time.MarshalJSON() -} - -func (t *Time) UnmarshalJSON(b []byte) error { - if bytes.Equal(b, []byte("null")) { - return nil - } - // If it is empty, we don't have to set anything since time.Time is not a - // pointer and will be set to the zero value - if bytes.Equal([]byte(emptyString), b) { - return nil - } - - return t.Time.UnmarshalJSON(b) -} - -func Parse(layout, value string) (Time, error) { - t, err := time.Parse(layout, value) - return Time{Time: t}, err -} -func ParseInLocation(layout, value string, loc *time.Location) (Time, error) { - t, err := time.ParseInLocation(layout, value, loc) - return Time{Time: t}, err -} - -func Date(year int, month time.Month, day, hour, min, sec, nsec int, loc *time.Location) Time { - return Time{Time: time.Date(year, month, day, hour, min, sec, nsec, loc)} -} - -func Unix(sec int64, nsec int64) Time { return Time{Time: time.Unix(sec, nsec)} } - -func (t Time) Add(d time.Duration) Time { return Time{Time: t.Time.Add(d)} } -func (t Time) AddDate(years int, months int, days int) Time { - return Time{Time: t.Time.AddDate(years, months, days)} -} -func (t Time) After(u Time) bool { return t.Time.After(u.Time) } -func (t Time) Before(u Time) bool { return t.Time.Before(u.Time) } -func (t Time) Equal(u Time) bool { return t.Time.Equal(u.Time) } -func (t Time) In(loc *time.Location) Time { return Time{Time: t.Time.In(loc)} } -func (t Time) Local() Time { return Time{Time: t.Time.Local()} } -func (t Time) Round(d time.Duration) Time { return Time{Time: t.Time.Round(d)} } -func (t Time) Sub(u Time) time.Duration { return t.Time.Sub(u.Time) } -func (t Time) Truncate(d time.Duration) Time { return Time{Time: t.Time.Truncate(d)} } -func (t Time) UTC() Time { return Time{Time: t.Time.UTC()} } diff --git a/pkg/libhelm/time/time_test.go b/pkg/libhelm/time/time_test.go deleted file mode 100644 index 9de753f05..000000000 --- a/pkg/libhelm/time/time_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright The Helm Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package time - -import ( - "testing" - "time" - - "github.com/segmentio/encoding/json" -) - -var ( - testingTime, _ = Parse(time.RFC3339, "1977-09-02T22:04:05Z") - testingTimeString = `"1977-09-02T22:04:05Z"` -) - -func TestNonZeroValueMarshal(t *testing.T) { - res, err := json.Marshal(testingTime) - if err != nil { - t.Fatal(err) - } - if testingTimeString != string(res) { - t.Errorf("expected a marshaled value of %s, got %s", testingTimeString, res) - } -} - -func TestZeroValueMarshal(t *testing.T) { - res, err := json.Marshal(Time{}) - if err != nil { - t.Fatal(err) - } - if string(res) != emptyString { - t.Errorf("expected zero value to marshal to empty string, got %s", res) - } -} - -func TestNonZeroValueUnmarshal(t *testing.T) { - var myTime Time - err := json.Unmarshal([]byte(testingTimeString), &myTime) - if err != nil { - t.Fatal(err) - } - if !myTime.Equal(testingTime) { - t.Errorf("expected time to be equal to %v, got %v", testingTime, myTime) - } -} - -func TestEmptyStringUnmarshal(t *testing.T) { - var myTime Time - err := json.Unmarshal([]byte(emptyString), &myTime) - if err != nil { - t.Fatal(err) - } - if !myTime.IsZero() { - t.Errorf("expected time to be equal to zero value, got %v", myTime) - } -} - -func TestZeroValueUnmarshal(t *testing.T) { - // This test ensures that we can unmarshal any time value that was output - // with the current go default value of "0001-01-01T00:00:00Z" - var myTime Time - err := json.Unmarshal([]byte(`"0001-01-01T00:00:00Z"`), &myTime) - if err != nil { - t.Fatal(err) - } - if !myTime.IsZero() { - t.Errorf("expected time to be equal to zero value, got %v", myTime) - } -} diff --git a/pkg/libhelm/types/types.go b/pkg/libhelm/types/types.go index e4873d4de..59071c84a 100644 --- a/pkg/libhelm/types/types.go +++ b/pkg/libhelm/types/types.go @@ -3,8 +3,8 @@ package types import ( "github.com/portainer/portainer/pkg/libhelm/options" "github.com/portainer/portainer/pkg/libhelm/release" - "helm.sh/helm/v3/pkg/cli" - "helm.sh/helm/v3/pkg/repo" + "helm.sh/helm/v4/pkg/cli" + repo "helm.sh/helm/v4/pkg/repo/v1" ) // HelmPackageManager represents a service that interfaces with Helm diff --git a/pkg/libhelm/validate_repo.go b/pkg/libhelm/validate_repo.go index 087980962..a9d3a810a 100644 --- a/pkg/libhelm/validate_repo.go +++ b/pkg/libhelm/validate_repo.go @@ -8,9 +8,9 @@ import ( "strings" "github.com/portainer/portainer/pkg/libhelm/sdk" - "helm.sh/helm/v3/pkg/cli" - "helm.sh/helm/v3/pkg/getter" - "helm.sh/helm/v3/pkg/repo" + "helm.sh/helm/v4/pkg/cli" + "helm.sh/helm/v4/pkg/getter" + repo "helm.sh/helm/v4/pkg/repo/v1" ) func ValidateHelmRepositoryURL(repoUrl string, _ *http.Client) error {