diff --git a/api/v1beta1/spec.go b/api/v1beta1/spec.go index f9d44fd4..17ac56a0 100644 --- a/api/v1beta1/spec.go +++ b/api/v1beta1/spec.go @@ -290,6 +290,9 @@ type HelmUpgradeOptions struct { // Recreate will (if true) recreate pods after a rollback. // +kubebuilder:default:=false + // + // Deprecated: This field is no longer supported + // // +optional Recreate bool `json:"recreate,omitempty"` diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 9241f874..dba06be0 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -21,12 +21,11 @@ limitations under the License. package v1beta1 import ( + apiv1beta1 "github.com/projectsveltos/libsveltos/api/v1beta1" corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" - - apiv1beta1 "github.com/projectsveltos/libsveltos/api/v1beta1" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. diff --git a/config/crd/bases/config.projectsveltos.io_clusterprofiles.yaml b/config/crd/bases/config.projectsveltos.io_clusterprofiles.yaml index c57f8380..ad586f21 100644 --- a/config/crd/bases/config.projectsveltos.io_clusterprofiles.yaml +++ b/config/crd/bases/config.projectsveltos.io_clusterprofiles.yaml @@ -412,8 +412,10 @@ spec: type: integer recreate: default: false - description: Recreate will (if true) recreate pods after - a rollback. + description: |- + Recreate will (if true) recreate pods after a rollback. + + Deprecated: This field is no longer supported type: boolean resetThenReuseValues: default: false diff --git a/config/crd/bases/config.projectsveltos.io_clusterpromotions.yaml b/config/crd/bases/config.projectsveltos.io_clusterpromotions.yaml index f70779a9..f68a8aeb 100644 --- a/config/crd/bases/config.projectsveltos.io_clusterpromotions.yaml +++ b/config/crd/bases/config.projectsveltos.io_clusterpromotions.yaml @@ -312,8 +312,10 @@ spec: type: integer recreate: default: false - description: Recreate will (if true) recreate pods - after a rollback. + description: |- + Recreate will (if true) recreate pods after a rollback. + + Deprecated: This field is no longer supported type: boolean resetThenReuseValues: default: false diff --git a/config/crd/bases/config.projectsveltos.io_clustersummaries.yaml b/config/crd/bases/config.projectsveltos.io_clustersummaries.yaml index 53580ecf..83abc8f1 100644 --- a/config/crd/bases/config.projectsveltos.io_clustersummaries.yaml +++ b/config/crd/bases/config.projectsveltos.io_clustersummaries.yaml @@ -449,8 +449,10 @@ spec: type: integer recreate: default: false - description: Recreate will (if true) recreate pods - after a rollback. + description: |- + Recreate will (if true) recreate pods after a rollback. + + Deprecated: This field is no longer supported type: boolean resetThenReuseValues: default: false diff --git a/config/crd/bases/config.projectsveltos.io_profiles.yaml b/config/crd/bases/config.projectsveltos.io_profiles.yaml index 36c52106..21a578d7 100644 --- a/config/crd/bases/config.projectsveltos.io_profiles.yaml +++ b/config/crd/bases/config.projectsveltos.io_profiles.yaml @@ -412,8 +412,10 @@ spec: type: integer recreate: default: false - description: Recreate will (if true) recreate pods after - a rollback. + description: |- + Recreate will (if true) recreate pods after a rollback. + + Deprecated: This field is no longer supported type: boolean resetThenReuseValues: default: false diff --git a/controllers/handlers_helm.go b/controllers/handlers_helm.go index bfdf6c47..804108b4 100644 --- a/controllers/handlers_helm.go +++ b/controllers/handlers_helm.go @@ -1,5 +1,5 @@ /* -Copyright 2022-24. projectsveltos.io. All rights reserved. +Copyright 2022-26. projectsveltos.io. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,11 +20,14 @@ import ( "bytes" "context" "crypto/sha256" + "crypto/tls" + "crypto/x509" "encoding/hex" "encoding/json" "fmt" "io" "math" + "net/http" "net/url" "os" "path" @@ -45,18 +48,21 @@ import ( "github.com/hexops/gotextdiff/myers" "github.com/hexops/gotextdiff/span" "github.com/pkg/errors" - "helm.sh/helm/v3/pkg/action" - "helm.sh/helm/v3/pkg/chart" - "helm.sh/helm/v3/pkg/chart/loader" - "helm.sh/helm/v3/pkg/chartutil" - "helm.sh/helm/v3/pkg/cli" - "helm.sh/helm/v3/pkg/downloader" - "helm.sh/helm/v3/pkg/getter" - "helm.sh/helm/v3/pkg/helmpath" - "helm.sh/helm/v3/pkg/registry" - "helm.sh/helm/v3/pkg/release" - "helm.sh/helm/v3/pkg/repo" - "helm.sh/helm/v3/pkg/storage/driver" + "helm.sh/helm/v4/pkg/action" + chartbase "helm.sh/helm/v4/pkg/chart" + "helm.sh/helm/v4/pkg/chart/common" + chart "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" + "helm.sh/helm/v4/pkg/helmpath" + "helm.sh/helm/v4/pkg/kube" + "helm.sh/helm/v4/pkg/registry" + releasecommon "helm.sh/helm/v4/pkg/release/common" + releasev1 "helm.sh/helm/v4/pkg/release/v1" + repo "helm.sh/helm/v4/pkg/repo/v1" + "helm.sh/helm/v4/pkg/storage/driver" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -68,7 +74,6 @@ import ( "k8s.io/client-go/dynamic" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/util/retry" - "k8s.io/klog/v2/textlogger" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/yaml" @@ -87,8 +92,7 @@ import ( ) var ( - storage = repo.File{} - helmLogger = textlogger.NewLogger(textlogger.NewConfig()) + storage = repo.File{} ) const ( @@ -708,7 +712,7 @@ func uninstallHelmCharts(ctx context.Context, c client.Client, clusterSummary *c return nil, err } - if currentRelease != nil && currentRelease.Status != string(release.StatusUninstalled) { + if currentRelease != nil && currentRelease.Status != string(releasecommon.StatusUninstalled) { err = doUninstallRelease(ctx, clusterSummary, instantiatedChart, kubeconfig, registryOptions, logger) if err != nil { if !errors.Is(err, driver.ErrReleaseNotFound) { @@ -1030,7 +1034,7 @@ func walkChartsAndDeploy(ctx context.Context, c client.Client, clusterSummary *c logger.V(logs.LogInfo).Info(fmt.Sprintf("release %s/%s (version %s) status: %s", currentRelease.ReleaseNamespace, currentRelease.ReleaseName, currentRelease.ChartVersion, currentRelease.Status)) } - if currentRelease.Status == release.StatusDeployed.String() { + if currentRelease.Status == releasecommon.StatusDeployed.String() { // Deployed chart is used for updating ClusterConfiguration. There is no ClusterConfiguration for mgmt cluster chartDeployed = append(chartDeployed, configv1beta1.Chart{ RepoURL: instantiatedChart.RepositoryURL, @@ -1127,8 +1131,6 @@ func determineChartOwnership(ctx context.Context, c client.Client, claimingHelmM if deployer.HasHigherOwnershipPriority(currentHelmManager.Spec.ClusterProfileSpec.Tier, claimingHelmManager.Spec.ClusterProfileSpec.Tier) { if claimingHelmManager.Spec.ClusterProfileSpec.SyncMode == configv1beta1.SyncModeDryRun { - // Since we are in DryRun mode do not reset the other ClusterSummary. It will still be managing - // the helm chart return true, nil } // New ClusterSummary is taking over managing this chart. So reset helmReleaseSummaries for this chart @@ -1138,13 +1140,11 @@ func determineChartOwnership(ctx context.Context, c client.Client, claimingHelmM if err != nil { return false, err } - // Reset Status of the ClusterSummary previously managing this resource err = requeueClusterSummary(ctx, libsveltosv1beta1.FeatureHelm, currentHelmManager, logger) if err != nil { return false, err } - // Set current ClusterSummary as the new manager chartManager.SetManagerForChart(claimingHelmManager, instantiatedChart) return true, nil @@ -1152,7 +1152,6 @@ func determineChartOwnership(ctx context.Context, c client.Client, claimingHelmM return false, nil } - // Nobody else is managing the chart return true, nil } @@ -1181,7 +1180,7 @@ func resetHelmReleaseSummaries(ctx context.Context, c client.Client, clusterSumm func handleInstall(ctx context.Context, clusterSummary *configv1beta1.ClusterSummary, mgmtResources map[string]*unstructured.Unstructured, currentChart *configv1beta1.HelmChart, kubeconfig string, registryOptions *registryClientOptions, isPullMode, templateOnly bool, logger logr.Logger, -) (*release.Release, *configv1beta1.ReleaseReport, error) { +) (*releasev1.Release, *configv1beta1.ReleaseReport, error) { logger.V(logs.LogDebug).Info("install helm release") @@ -1222,7 +1221,7 @@ func handleInstall(ctx context.Context, clusterSummary *configv1beta1.ClusterSum func handleUpgrade(ctx context.Context, clusterSummary *configv1beta1.ClusterSummary, mgmtResources map[string]*unstructured.Unstructured, currentChart *configv1beta1.HelmChart, currentRelease *releaseInfo, kubeconfig string, registryOptions *registryClientOptions, - logger logr.Logger) (*release.Release, *configv1beta1.ReleaseReport, error) { + logger logr.Logger) (*releasev1.Release, *configv1beta1.ReleaseReport, error) { var report *configv1beta1.ReleaseReport logger.V(logs.LogDebug).Info("upgrade helm release") @@ -1394,7 +1393,6 @@ func deployHelmChart(ctx context.Context, clusterSummary *configv1beta1.ClusterS } var report *configv1beta1.ReleaseReport - // In pull mode we cannot verify if shouldInstall(currentRelease, instantiatedChart) { _, report, err = handleInstall(ctx, clusterSummary, mgmtResources, instantiatedChart, kubeconfig, registryOptions, false, false, logger) @@ -1453,7 +1451,7 @@ func repoAddOrUpdate(settings *cli.EnvSettings, name, repoURL string, registryOp logger = logger.WithValues("repoURL", repoURL, "repoName", name) entry := &repo.Entry{Name: name, URL: repoURL, Username: registryOptions.username, Password: registryOptions.password, - InsecureSkipTLSverify: registryOptions.skipTLSVerify} + InsecureSkipTLSVerify: registryOptions.skipTLSVerify} chartRepo, err := repo.NewChartRepository(entry, getter.All(settings)) if err != nil { return err @@ -1500,7 +1498,7 @@ func getChartVersion(requestedChart *configv1beta1.HelmChart, chartRequested *ch func installRelease(ctx context.Context, clusterSummary *configv1beta1.ClusterSummary, settings *cli.EnvSettings, requestedChart *configv1beta1.HelmChart, kubeconfig string, registryOptions *registryClientOptions, values map[string]interface{}, mgmtResources map[string]*unstructured.Unstructured, templateOnly bool, logger logr.Logger, -) (*release.Release, error) { +) (*releasev1.Release, error) { if !isReferencingFluxSource(requestedChart) && requestedChart.ChartName == "" { return nil, fmt.Errorf("chart name can not be empty") @@ -1536,6 +1534,49 @@ func installRelease(ctx context.Context, clusterSummary *configv1beta1.ClusterSu return nil, err } + chartRequested, err := locateLoadAndValidateChart(chartName, settings, requestedChart, registryOptions, + installClient, logger) + if err != nil { + return nil, err + } + + if !templateOnly && clusterSummary.Spec.ClusterProfileSpec.SyncMode == configv1beta1.SyncModeDryRun { + installClient.DryRunStrategy = action.DryRunServer + } + + ctxWithTimeout, cancel := context.WithTimeout(ctx, getTimeoutValue(requestedChart.Options).Duration) + defer cancel() + + r, err := installClient.RunWithContext(ctxWithTimeout, chartRequested, values) + if err != nil { + logger.V(logs.LogInfo).Info(fmt.Sprintf("failed to install: %v", err)) + // This condition should never occur. A previous check ensures that only one + // ClusterProfile/Profile can manage a Helm Chart with a given name in a + // specific namespace within a managed cluster. If this code is reached, + // that check has already passed. Therefore, the "cannot re-use a name that + // is still in use" error should be impossible. + // There is no constant defined in the helm library but this is an error seen more than once. + if err.Error() == "cannot re-use a name that is still in use" { + _, err = upgradeRelease(ctx, clusterSummary, settings, requestedChart, kubeconfig, registryOptions, + values, mgmtResources, logger) + return nil, err + } + return nil, err + } + + logger.V(logs.LogDebug).Info("installing release done") + + rel, ok := r.(*releasev1.Release) + if !ok { + return nil, fmt.Errorf("unexpected release type %T", r) + } + return rel, nil +} + +func locateLoadAndValidateChart(chartName string, settings *cli.EnvSettings, requestedChart *configv1beta1.HelmChart, + registryOptions *registryClientOptions, installClient *action.Install, logger logr.Logger, +) (*chart.Chart, error) { + cp, err := installClient.LocateChart(chartName, settings) if err != nil { handleLocateChartError(settings, requestedChart, registryOptions, err, logger) @@ -1550,8 +1591,7 @@ func installRelease(ctx context.Context, clusterSummary *configv1beta1.ClusterSu requestedChart.ChartVersion = getChartVersion(requestedChart, chartRequested) - validInstallableChart := isChartInstallable(chartRequested) - if !validInstallableChart { + if !isChartInstallable(chartRequested) { return nil, fmt.Errorf("chart is not installable") } @@ -1567,38 +1607,16 @@ func installRelease(ctx context.Context, clusterSummary *configv1beta1.ClusterSu return nil, fmt.Errorf("%w: failed reloading chart after repo update", err) } - if clusterSummary.Spec.ClusterProfileSpec.SyncMode == configv1beta1.SyncModeDryRun { - installClient.DryRun = true - } - - ctxWithTimeout, cancel := context.WithTimeout(ctx, getTimeoutValue(requestedChart.Options).Duration) - defer cancel() - - r, err := installClient.RunWithContext(ctxWithTimeout, chartRequested, values) - if err != nil { - logger.V(logs.LogInfo).Info(fmt.Sprintf("failed to install: %v", err)) - // This condition should never occur. A previous check ensures that only one - // ClusterProfile/Profile can manage a Helm Chart with a given name in a - // specific namespace within a managed cluster. If this code is reached, - // that check has already passed. Therefore, the "cannot re-use a name that - // is still in use" error should be impossible. - // There is no constant defined in the helm library but this is an error seen more than once. - if err.Error() == "cannot re-use a name that is still in use" { - _, err = upgradeRelease(ctx, clusterSummary, settings, requestedChart, kubeconfig, registryOptions, - values, mgmtResources, logger) - return nil, err - } - return nil, err - } - - logger.V(logs.LogDebug).Info("installing release done") - - return r, nil + return chartRequested, nil } func checkDependencies(chartRequested *chart.Chart, installClient *action.Install, cp string, settings *cli.EnvSettings) error { if req := chartRequested.Metadata.Dependencies; req != nil { - err := action.CheckDependencies(chartRequested, req) + deps := make([]chartbase.Dependency, len(req)) + for i, d := range req { + deps[i] = d + } + err := action.CheckDependencies(chartRequested, deps) if err != nil { if installClient.DependencyUpdate { man := &downloader.Manager{ @@ -1643,8 +1661,6 @@ func uninstallRelease(ctx context.Context, clusterSummary *configv1beta1.Cluster } if !cluster.GetDeletionTimestamp().IsZero() { - // if cluster is marked for deletion, no need to worry about removing helm charts deployed - // there. return nil } @@ -1690,7 +1706,7 @@ func uninstallRelease(ctx context.Context, clusterSummary *configv1beta1.Cluster func upgradeRelease(ctx context.Context, clusterSummary *configv1beta1.ClusterSummary, settings *cli.EnvSettings, requestedChart *configv1beta1.HelmChart, kubeconfig string, registryOptions *registryClientOptions, values map[string]interface{}, - mgmtResources map[string]*unstructured.Unstructured, logger logr.Logger) (*release.Release, error) { + mgmtResources map[string]*unstructured.Unstructured, logger logr.Logger) (*releasev1.Release, error) { // No-op in DryRun mode if clusterSummary.Spec.ClusterProfileSpec.SyncMode == configv1beta1.SyncModeDryRun { @@ -1754,7 +1770,9 @@ func upgradeRelease(ctx context.Context, clusterSummary *configv1beta1.ClusterSu return nil, err } - err = upgradeCRDs(ctx, requestedChart, kubeconfig, chartRequested.CRDObjects(), logger) + crds := getCRDObjects(chartRequested) + + err = upgradeCRDs(ctx, requestedChart, kubeconfig, crds, logger) if err != nil { logger.V(logs.LogDebug).Info(fmt.Sprintf("failed to upgrade crds: %v", err)) return nil, err @@ -1770,7 +1788,11 @@ func upgradeRelease(ctx context.Context, clusterSummary *configv1beta1.ClusterSu logger.V(logs.LogDebug).Info("upgrading release done") - return helmRelease, nil + rel, ok := helmRelease.(*releasev1.Release) + if !ok { + return nil, fmt.Errorf("unexpected release type %T", helmRelease) + } + return rel, nil } func handleUpgradeError(ctx context.Context, err error, clusterSummary *configv1beta1.ClusterSummary, @@ -1785,7 +1807,7 @@ func handleUpgradeError(ctx context.Context, err error, clusterSummary *configv1 status := currentRelease.Info.Status if status.IsPending() || - status == release.StatusUninstalling || + status == releasecommon.StatusUninstalling || strings.Contains(err.Error(), "has no deployed releases") { logger.V(logs.LogInfo).Info(fmt.Sprintf("Release in %s state or inconsistent. Triggering recovery.", status)) @@ -1805,7 +1827,7 @@ func handleUpgradeError(ctx context.Context, err error, clusterSummary *configv1 func prepareChartAndDependencies( chartRequested *chart.Chart, requestedChart *configv1beta1.HelmChart, - chartPath string, // This is the 'chartName' path inside tmpDir + chartPath string, settings *cli.EnvSettings, registryOptions *registryClientOptions, logger logr.Logger, @@ -1822,8 +1844,11 @@ func prepareChartAndDependencies( return nil, fmt.Errorf("failed to get registry client: %w", err) } - // Check if dependencies are actually missing - if err := action.CheckDependencies(chartRequested, req); err != nil { + deps := make([]chartbase.Dependency, len(req)) + for i, d := range req { + deps[i] = d + } + if err := action.CheckDependencies(chartRequested, deps); err != nil { logger.V(logs.LogInfo).Info("Dependencies missing or out of date, attempting to fetch") man := &downloader.Manager{ @@ -1839,10 +1864,8 @@ func prepareChartAndDependencies( return nil, fmt.Errorf("failed to update dependencies: %w", err) } - // Reload from the directory where man.Update() just ran chartRequested, err = loader.Load(chartPath) if err != nil { - // Potential recovery: Use LoadDir which can be more forgiving with paths logger.V(logs.LogDebug).Info("standard loader failed, trying LoadDir", "err", err) chartRequested, err = loader.LoadDir(chartPath) if err != nil { @@ -1851,20 +1874,18 @@ func prepareChartAndDependencies( } } - // Sanitize the version to avoid "invalid semantic version" errors if chartRequested.Metadata.Version == "" || !isValidSemver(chartRequested.Metadata.Version) { logger.V(logs.LogInfo).Info("fixing invalid or empty chart version", "oldVersion", chartRequested.Metadata.Version) chartRequested.Metadata.Version = "0.1.0" } - // Keep the requestedChart object in sync with actual loaded metadata requestedChart.ChartVersion = chartRequested.Metadata.Version return chartRequested, nil } -func upgradeCRDsInFile(ctx context.Context, dr dynamic.ResourceInterface, chartFile *chart.File, +func upgradeCRDsInFile(ctx context.Context, dr dynamic.ResourceInterface, chartFile *common.File, logger logr.Logger) (int, error) { crds, err := deployer.GetUnstructured(chartFile.Data, logger) @@ -1920,7 +1941,6 @@ func upgradeCRDs(ctx context.Context, requestedChart *configv1beta1.HelmChart, k upgradedCRDs := 0 - // We do these one file at a time in the order they were read. for _, obj := range crds { tmpUpgradedCRDs, err := upgradeCRDsInFile(ctx, dr, obj.File, logger) if err != nil { @@ -1930,7 +1950,6 @@ func upgradeCRDs(ctx context.Context, requestedChart *configv1beta1.HelmChart, k upgradedCRDs += tmpUpgradedCRDs } - // Give time for the CRD to be recognized. if upgradedCRDs > 0 { const waitForCRDs = 30 time.Sleep(waitForCRDs * time.Second) @@ -1939,10 +1958,6 @@ func upgradeCRDs(ctx context.Context, requestedChart *configv1beta1.HelmChart, k return nil } -func debugf(format string, v ...interface{}) { - helmLogger.V(logs.LogDebug).Info(fmt.Sprintf(format, v...)) -} - func getRegistryClient(namespace string, registryOptions *registryClientOptions, enableClientCache bool, ) (*registry.Client, error) { @@ -1977,7 +1992,6 @@ func newDefaultRegistryClient(plainHTTP bool, settings *cli.EnvSettings, opts = append(opts, registry.ClientOptPlainHTTP()) } - // Create a new registry client registryClient, err := registry.NewClient(opts...) if err != nil { return nil, err @@ -1985,12 +1999,50 @@ func newDefaultRegistryClient(plainHTTP bool, settings *cli.EnvSettings, return registryClient, nil } +// newRegistryClientWithTLS creates a registry client configured with custom TLS settings. +// v4 CHANGE: registry.NewRegistryClientWithTLS was removed. We now build the TLS config +// manually and inject it via registry.ClientOptHTTPClient. func newRegistryClientWithTLS(certFile, keyFile, caFile string, insecureSkipTLSverify bool, settings *cli.EnvSettings) (*registry.Client, error) { - // Create a new registry client - registryClient, err := registry.NewRegistryClientWithTLS(os.Stderr, certFile, keyFile, caFile, insecureSkipTLSverify, - settings.RegistryConfig, settings.Debug) + tlsCfg := &tls.Config{ + InsecureSkipVerify: insecureSkipTLSverify, //nolint:gosec // the parameter is set by user + } + + if caFile != "" { + caPEM, err := os.ReadFile(caFile) + if err != nil { + return nil, fmt.Errorf("failed to read CA file %s: %w", caFile, err) + } + pool := x509.NewCertPool() + if !pool.AppendCertsFromPEM(caPEM) { + return nil, fmt.Errorf("failed to parse CA certificates from %s", caFile) + } + tlsCfg.RootCAs = pool + } + + if certFile != "" && keyFile != "" { + cert, err := tls.LoadX509KeyPair(certFile, keyFile) + if err != nil { + return nil, fmt.Errorf("failed to load client certificate/key: %w", err) + } + tlsCfg.Certificates = []tls.Certificate{cert} + } + + httpClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: tlsCfg, + }, + } + + opts := []registry.ClientOption{ + registry.ClientOptDebug(settings.Debug), + registry.ClientOptWriter(os.Stderr), + registry.ClientOptCredentialsFile(settings.RegistryConfig), + registry.ClientOptHTTPClient(httpClient), + } + + registryClient, err := registry.NewClient(opts...) if err != nil { return nil, err } @@ -2007,11 +2059,10 @@ func actionConfigInit(namespace, kubeconfig string, registryOptions *registryCli configFlags.Namespace = &namespace insecure := registryOptions.skipTLSVerify configFlags.Insecure = &insecure - // Use a 5m timeout timeout := "5m" configFlags.Timeout = &timeout - err := actionConfig.Init(configFlags, namespace, "secret", debugf) + err := actionConfig.Init(configFlags, namespace, "secret") if err != nil { return nil, err } @@ -2036,7 +2087,7 @@ func isChartInstallable(ch *chart.Chart) bool { } func getCurrentRelease(releaseName, releaseNamespace, kubeconfig string, registryOptions *registryClientOptions, - enableClientCache bool) (*release.Release, error) { + enableClientCache bool) (*releasev1.Release, error) { actionConfig, err := actionConfigInit(releaseNamespace, kubeconfig, registryOptions, enableClientCache) @@ -2045,7 +2096,18 @@ func getCurrentRelease(releaseName, releaseNamespace, kubeconfig string, registr } statusObject := action.NewStatus(actionConfig) - return statusObject.Run(releaseName) + r, err := statusObject.Run(releaseName) + if err != nil { + return nil, err + } + if r == nil { + return nil, nil + } + rel, ok := r.(*releasev1.Release) + if !ok { + return nil, fmt.Errorf("unexpected release type %T", r) + } + return rel, nil } func getReleaseInfo(releaseName, releaseNamespace, kubeconfig string, registryOptions *registryClientOptions, @@ -2071,7 +2133,7 @@ func getReleaseInfo(releaseName, releaseNamespace, kubeconfig string, registryOp var t metav1.Time if lastDeployed := currentRelease.Info.LastDeployed; !lastDeployed.IsZero() { - t = metav1.Time{Time: lastDeployed.Time} + t = metav1.Time{Time: lastDeployed} } element.Updated = t @@ -2087,23 +2149,23 @@ func recoverRelease(ctx context.Context, clusterSummary *configv1beta1.ClusterSu return err } - // 1. Check current status via Helm statusObject := action.NewStatus(actionConfig) - lastRelease, err := statusObject.Run(requestedChart.ReleaseName) + r, err := statusObject.Run(requestedChart.ReleaseName) if err != nil { if strings.Contains(err.Error(), "not found") { - return nil // Already gone + return nil } return err } + lastRelease, ok := r.(*releasev1.Release) + if !ok { + return fmt.Errorf("unexpected release type %T", r) + } status := lastRelease.Info.Status logger.V(logs.LogInfo).Info("Attempting recovery for stuck release", "status", status, "version", lastRelease.Version) - // 2. If stuck in Uninstalling or Pending, the standard 'uninstall' is likely hanging. - // We force recovery by deleting the Secret directly. - if status == release.StatusUninstalling || status.IsPending() { - // Helm secrets follow this naming convention + if status == releasecommon.StatusUninstalling || status.IsPending() { secretName := fmt.Sprintf("sh.helm.release.v1.%s.v%d", requestedChart.ReleaseName, lastRelease.Version) @@ -2119,8 +2181,6 @@ func recoverRelease(ctx context.Context, clusterSummary *configv1beta1.ClusterSu return err } - // Use the K8s client (ensure m.Client is available in your scope) - // This is the "Nuclear Option" that unblocks "cannot re-use a name" err = remoteClient.Delete(ctx, &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: secretName, @@ -2135,7 +2195,6 @@ func recoverRelease(ctx context.Context, clusterSummary *configv1beta1.ClusterSu return nil } - // 3. Fallback to standard uninstall if status is something else return uninstallRelease(ctx, clusterSummary, requestedChart.ReleaseName, requestedChart.ReleaseNamespace, kubeconfig, registryOptions, requestedChart, logger) } @@ -2148,11 +2207,8 @@ func shouldInstall(currentRelease *releaseInfo, requestedChart *configv1beta1.He return false } - // If the release was uninstalled with KeepHistory flag, this is the - // status seen at this point. Release should be installed in this state. - // Upgrade would fail if currentRelease != nil && - currentRelease.Status == release.StatusUninstalled.String() { + currentRelease.Status == releasecommon.StatusUninstalled.String() { return true } @@ -2164,7 +2220,7 @@ func shouldInstall(currentRelease *releaseInfo, requestedChart *configv1beta1.He } if currentRelease != nil && - currentRelease.Status == release.StatusDeployed.String() { + currentRelease.Status == releasecommon.StatusDeployed.String() { return false } @@ -2184,25 +2240,21 @@ func shouldUpgrade(ctx context.Context, currentRelease *releaseInfo, instantiate if clusterSummary.Spec.ClusterProfileSpec.SyncMode != configv1beta1.SyncModeContinuousWithDriftDetection { if clusterSummary.Spec.ClusterProfileSpec.SyncMode != configv1beta1.SyncModeDryRun { - // In DryRun mode, if values are different, report will be generated oldValueHash := getValueHashFromHelmChartSummary(instantiatedChart, clusterSummary) - // If Values configuration has changed, trigger an upgrade c := getManagementClusterClient() currentValueHash, err := getHelmChartValuesHash(ctx, c, instantiatedChart, clusterSummary, mgmtResources, logger) if err != nil { logger.V(logs.LogInfo).Info(fmt.Sprintf("failed to get current values hash: %v", err)) - currentValueHash = []byte("") // force upgrade + currentValueHash = []byte("") } if !reflect.DeepEqual(oldValueHash, currentValueHash) { return true } } - // With drift detection mode, there is reconciliation due to configuration drift even - // when version is same. So skip this check in SyncModeContinuousWithDriftDetection if currentRelease != nil { - if currentRelease.Status != release.StatusDeployed.String() { + if currentRelease.Status != releasecommon.StatusDeployed.String() { return true } @@ -2229,7 +2281,7 @@ func shouldUninstall(currentRelease *releaseInfo, requestedChart *configv1beta1. return false } - if currentRelease.Status == string(release.StatusUninstalled) { + if currentRelease.Status == string(releasecommon.StatusUninstalled) { return false } @@ -2245,9 +2297,8 @@ func shouldUninstall(currentRelease *releaseInfo, requestedChart *configv1beta1. func doInstallRelease(ctx context.Context, clusterSummary *configv1beta1.ClusterSummary, mgmtResources map[string]*unstructured.Unstructured, requestedChart *configv1beta1.HelmChart, kubeconfig string, registryOptions *registryClientOptions, templateOnly bool, logger logr.Logger, -) (*release.Release, error) { +) (*releasev1.Release, error) { - // No-op in DryRun mode if !templateOnly && clusterSummary.Spec.ClusterProfileSpec.SyncMode == configv1beta1.SyncModeDryRun { return nil, nil } @@ -2286,7 +2337,6 @@ func doUninstallRelease(ctx context.Context, clusterSummary *configv1beta1.Clust requestedChart *configv1beta1.HelmChart, kubeconfig string, registryOptions *registryClientOptions, logger logr.Logger) error { - // No-op in DryRun mode if clusterSummary.Spec.ClusterProfileSpec.SyncMode == configv1beta1.SyncModeDryRun { return nil } @@ -2304,9 +2354,8 @@ func doUninstallRelease(ctx context.Context, clusterSummary *configv1beta1.Clust // No action in DryRun mode. func doUpgradeRelease(ctx context.Context, clusterSummary *configv1beta1.ClusterSummary, mgmtResources map[string]*unstructured.Unstructured, requestedChart *configv1beta1.HelmChart, - kubeconfig string, registryOptions *registryClientOptions, logger logr.Logger) (*release.Release, error) { + kubeconfig string, registryOptions *registryClientOptions, logger logr.Logger) (*releasev1.Release, error) { - // No-op in DryRun mode if clusterSummary.Spec.ClusterProfileSpec.SyncMode == configv1beta1.SyncModeDryRun { return nil, nil } @@ -2340,7 +2389,6 @@ func doUpgradeRelease(ctx context.Context, clusterSummary *configv1beta1.Cluster func updateChartsInClusterConfiguration(ctx context.Context, c client.Client, clusterSummary *configv1beta1.ClusterSummary, chartDeployed []configv1beta1.Chart, logger logr.Logger) error { - // No-op in DryRun mode if clusterSummary.Spec.ClusterProfileSpec.SyncMode == configv1beta1.SyncModeDryRun { return nil } @@ -2359,7 +2407,7 @@ func updateChartsInClusterConfiguration(ctx context.Context, c client.Client, cl nil, chartDeployed) } -// undeployStaleReleases uninstalls all helm charts previously managed and not referenced anyomre +// undeployStaleReleases uninstalls all helm charts previously managed and not referenced anymore func undeployStaleReleases(ctx context.Context, c client.Client, clusterSummary *configv1beta1.ClusterSummary, kubeconfig string, mgmtResources map[string]*unstructured.Unstructured, logger logr.Logger, ) ([]configv1beta1.ReleaseReport, error) { @@ -2388,9 +2436,6 @@ func undeployStaleReleases(ctx context.Context, c client.Client, clusterSummary } if clusterSummary.Spec.ClusterProfileSpec.SyncMode != configv1beta1.SyncModeDryRun { - // If another ClusterSummary is queued to manage this chart in this cluster, do not uninstall. - // Let the other ClusterSummary take it over. - currentChart := &configv1beta1.HelmChart{ ReleaseNamespace: staleReleases[i].Namespace, ReleaseName: staleReleases[i].Name, @@ -2399,13 +2444,10 @@ func undeployStaleReleases(ctx context.Context, c client.Client, clusterSummary clusterSummary.Spec.ClusterNamespace, clusterSummary.Spec.ClusterName, clusterSummary.Spec.ClusterType, currentChart) if len(otherRegisteredClusterSummaries) > 1 { - // Immediately unregister so next inline ClusterSummary can take this over chartManager.UnregisterClusterSummaryForChart(clusterSummary, currentChart) err = requeueAllOtherClusterSummaries(ctx, c, clusterSummary.Spec.ClusterNamespace, otherRegisteredClusterSummaries, logger) if err != nil { - // TODO: Handle errors to prevent bad state. ClusterSummary no longer manage the chart, - // but no other ClusterSummary instance has been requeued. return nil, err } @@ -2427,13 +2469,9 @@ func undeployStaleReleases(ctx context.Context, c client.Client, clusterSummary return reports, nil } -// updateStatusForeferencedHelmReleases considers helm releases ClusterSummary currently +// updateStatusForReferencedHelmReleases considers helm releases ClusterSummary currently // references. For each of those helm releases, adds an entry in ClusterSummary.Status reporting // whether such helm release is managed by this ClusterSummary or not. -// This method also returns: -// - an error if any occurs -// - whether there is at least one helm release ClusterSummary is referencing, but currently not -// allowed to manage. // No action in DryRun mode. func updateStatusForReferencedHelmReleases(ctx context.Context, c client.Client, clusterSummary *configv1beta1.ClusterSummary, mgmtResources map[string]*unstructured.Unstructured, @@ -2446,7 +2484,7 @@ func updateStatusForReferencedHelmReleases(ctx context.Context, c client.Client, if len(clusterSummary.Spec.ClusterProfileSpec.HelmCharts) == 0 && len(clusterSummary.Status.HelmReleaseSummaries) == 0 { - // Nothing to do + return clusterSummary, false, nil } @@ -2479,7 +2517,6 @@ func updateStatusForReferencedHelmReleases(ctx context.Context, c client.Client, if err != nil { return err } - var canManage bool canManage, err = determineChartOwnership(ctx, c, clusterSummary, instantiatedChart, logger) if err != nil { @@ -2525,7 +2562,6 @@ func updateStatusForReferencedHelmReleases(ctx context.Context, c client.Client, } currentClusterSummary.Status.HelmReleaseSummaries = helmReleaseSummaries - return c.Status().Update(ctx, currentClusterSummary) }) return currentClusterSummary, conflict, err @@ -2674,7 +2710,7 @@ func updateClusterReportWithHelmReports(ctx context.Context, c client.Client, func getHelmChartInstantiatedValues(ctx context.Context, clusterSummary *configv1beta1.ClusterSummary, mgmtResources map[string]*unstructured.Unstructured, requestedChart *configv1beta1.HelmChart, - logger logr.Logger) (chartutil.Values, error) { + logger logr.Logger) (common.Values, error) { // Get management cluster resources once mgmtConfig := getManagementClusterConfig() @@ -2745,7 +2781,7 @@ func getHelmChartInstantiatedValues(ctx context.Context, clusterSummary *configv logger.V(logs.LogDebug).Info(fmt.Sprintf("Deploying helm charts with values %#v", result)) - return chartutil.Values(result), nil + return common.Values(result), nil } // getHelmChartValuesFrom return key-value pair from referenced ConfigMap/Secret. @@ -2808,10 +2844,14 @@ func collectResourcesFromManagedHelmChartsForDriftDetection(ctx context.Context, } statusObject := action.NewStatus(actionConfig) - results, err := statusObject.Run(instantiatedChart.ReleaseName) + rawResults, err := statusObject.Run(instantiatedChart.ReleaseName) if err != nil { return nil, err } + results, ok := rawResults.(*releasev1.Release) + if !ok { + return nil, fmt.Errorf("unexpected release type %T", rawResults) + } resources, err := collectHelmContent(results, install, false, logger) if err != nil { @@ -2834,152 +2874,152 @@ func collectResourcesFromManagedHelmChartsForDriftDetection(ctx context.Context, return helmResources, nil } -func isHookRelevantForPreInstall(hook *release.Hook) bool { +func isHookRelevantForPreInstall(hook *releasev1.Hook) bool { for _, event := range hook.Events { switch event { - case release.HookPreInstall: + case releasev1.HookPreInstall: return true - case release.HookTest, - release.HookPreUpgrade, - release.HookPreDelete, - release.HookPostDelete, - release.HookPreRollback, - release.HookPostRollback, - release.HookPostInstall, - release.HookPostUpgrade: + case releasev1.HookTest, + releasev1.HookPreUpgrade, + releasev1.HookPreDelete, + releasev1.HookPostDelete, + releasev1.HookPreRollback, + releasev1.HookPostRollback, + releasev1.HookPostInstall, + releasev1.HookPostUpgrade: return false } } return false } -func isHookRelevantForPreUpgrade(hook *release.Hook) bool { +func isHookRelevantForPreUpgrade(hook *releasev1.Hook) bool { for _, event := range hook.Events { switch event { - case release.HookPreUpgrade: + case releasev1.HookPreUpgrade: return true - case release.HookTest, - release.HookPreInstall, - release.HookPreDelete, - release.HookPostDelete, - release.HookPreRollback, - release.HookPostRollback, - release.HookPostInstall, - release.HookPostUpgrade: + case releasev1.HookTest, + releasev1.HookPreInstall, + releasev1.HookPreDelete, + releasev1.HookPostDelete, + releasev1.HookPreRollback, + releasev1.HookPostRollback, + releasev1.HookPostInstall, + releasev1.HookPostUpgrade: return false } } return false } -func isHookRelevantForPostInstall(hook *release.Hook) bool { +func isHookRelevantForPostInstall(hook *releasev1.Hook) bool { for _, event := range hook.Events { switch event { - case release.HookPostInstall: + case releasev1.HookPostInstall: return true - case release.HookTest, - release.HookPostUpgrade, - release.HookPreDelete, - release.HookPostDelete, - release.HookPreRollback, - release.HookPostRollback, - release.HookPreInstall, - release.HookPreUpgrade: + case releasev1.HookTest, + releasev1.HookPostUpgrade, + releasev1.HookPreDelete, + releasev1.HookPostDelete, + releasev1.HookPreRollback, + releasev1.HookPostRollback, + releasev1.HookPreInstall, + releasev1.HookPreUpgrade: return false } } return false } -func isHookRelevantForPostUpgrade(hook *release.Hook) bool { +func isHookRelevantForPostUpgrade(hook *releasev1.Hook) bool { for _, event := range hook.Events { switch event { - case release.HookPostUpgrade: + case releasev1.HookPostUpgrade: return true - case release.HookTest, - release.HookPostInstall, - release.HookPreDelete, - release.HookPostDelete, - release.HookPreRollback, - release.HookPostRollback, - release.HookPreInstall, - release.HookPreUpgrade: + case releasev1.HookTest, + releasev1.HookPostInstall, + releasev1.HookPreDelete, + releasev1.HookPostDelete, + releasev1.HookPreRollback, + releasev1.HookPostRollback, + releasev1.HookPreInstall, + releasev1.HookPreUpgrade: return false } } return false } -func isHookRelevantForPreRollback(hook *release.Hook) bool { +func isHookRelevantForPreRollback(hook *releasev1.Hook) bool { for _, event := range hook.Events { switch event { - case release.HookPreRollback: + case releasev1.HookPreRollback: return true - case release.HookTest, - release.HookPostInstall, - release.HookPostUpgrade, - release.HookPostDelete, - release.HookPreDelete, - release.HookPostRollback, - release.HookPreInstall, - release.HookPreUpgrade: + case releasev1.HookTest, + releasev1.HookPostInstall, + releasev1.HookPostUpgrade, + releasev1.HookPostDelete, + releasev1.HookPreDelete, + releasev1.HookPostRollback, + releasev1.HookPreInstall, + releasev1.HookPreUpgrade: return false } } return false } -func isHookRelevantForPostRollback(hook *release.Hook) bool { +func isHookRelevantForPostRollback(hook *releasev1.Hook) bool { for _, event := range hook.Events { switch event { - case release.HookPostRollback: + case releasev1.HookPostRollback: return true - case release.HookTest, - release.HookPreDelete, - release.HookPostInstall, - release.HookPostUpgrade, - release.HookPreRollback, - release.HookPostDelete, - release.HookPreInstall, - release.HookPreUpgrade: + case releasev1.HookTest, + releasev1.HookPreDelete, + releasev1.HookPostInstall, + releasev1.HookPostUpgrade, + releasev1.HookPreRollback, + releasev1.HookPostDelete, + releasev1.HookPreInstall, + releasev1.HookPreUpgrade: return false } } return false } -func isHookRelevantForPreDelete(hook *release.Hook) bool { +func isHookRelevantForPreDelete(hook *releasev1.Hook) bool { for _, event := range hook.Events { switch event { - case release.HookPreDelete: + case releasev1.HookPreDelete: return true - case release.HookTest, - release.HookPostInstall, - release.HookPostUpgrade, - release.HookPostDelete, - release.HookPreRollback, - release.HookPostRollback, - release.HookPreInstall, - release.HookPreUpgrade: + case releasev1.HookTest, + releasev1.HookPostInstall, + releasev1.HookPostUpgrade, + releasev1.HookPostDelete, + releasev1.HookPreRollback, + releasev1.HookPostRollback, + releasev1.HookPreInstall, + releasev1.HookPreUpgrade: return false } } return false } -func isHookRelevantForPostDelete(hook *release.Hook) bool { +func isHookRelevantForPostDelete(hook *releasev1.Hook) bool { for _, event := range hook.Events { switch event { - case release.HookPostDelete: + case releasev1.HookPostDelete: return true - case release.HookTest, - release.HookPreDelete, - release.HookPostInstall, - release.HookPostUpgrade, - release.HookPreRollback, - release.HookPostRollback, - release.HookPreInstall, - release.HookPreUpgrade: + case releasev1.HookTest, + releasev1.HookPreDelete, + releasev1.HookPostInstall, + releasev1.HookPostUpgrade, + releasev1.HookPreRollback, + releasev1.HookPostRollback, + releasev1.HookPreInstall, + releasev1.HookPreUpgrade: return false } } @@ -3008,7 +3048,7 @@ func hasHookDeleteAnnotation(obj *unstructured.Unstructured) bool { return exists } -func collectHelmContent(result *release.Release, helmActionVar helmAction, includeHookResources bool, +func collectHelmContent(result *releasev1.Release, helmActionVar helmAction, includeHookResources bool, logger logr.Logger) ([]*unstructured.Unstructured, error) { resources := make([]*unstructured.Unstructured, 0) @@ -3073,7 +3113,7 @@ func collectHelmContent(result *release.Release, helmActionVar helmAction, inclu return resources, nil } -func collectPreHooks(result *release.Release, helmActionVar helmAction, logger logr.Logger, +func collectPreHooks(result *releasev1.Release, helmActionVar helmAction, logger logr.Logger, ) ([]*unstructured.Unstructured, error) { resources := make([]*unstructured.Unstructured, 0) @@ -3110,7 +3150,7 @@ func collectPreHooks(result *release.Release, helmActionVar helmAction, logger l return resources, nil } -func collectPostHooks(result *release.Release, helmActionVar helmAction, logger logr.Logger, +func collectPostHooks(result *releasev1.Release, helmActionVar helmAction, logger logr.Logger, ) ([]*unstructured.Unstructured, error) { resources := make([]*unstructured.Unstructured, 0) @@ -3147,7 +3187,7 @@ func collectPostHooks(result *release.Release, helmActionVar helmAction, logger return resources, nil } -func collectHelmDeleteHooks(result *release.Release, logger logr.Logger) ([]*unstructured.Unstructured, error) { +func collectHelmDeleteHooks(result *releasev1.Release, logger logr.Logger) ([]*unstructured.Unstructured, error) { resources := make([]*unstructured.Unstructured, 0) // Parse pre delete hook manifests @@ -3494,14 +3534,6 @@ func getSubNotesValue(options *configv1beta1.HelmOptions) bool { return false } -func getRecreateValue(options *configv1beta1.HelmOptions) bool { - if options != nil { - return options.UpgradeOptions.Recreate - } - - return false -} - func getHelmInstallClient(ctx context.Context, requestedChart *configv1beta1.HelmChart, kubeconfig string, registryOptions *registryClientOptions, patches []libsveltosv1beta1.Patch, templateOnly bool, logger logr.Logger, ) (*action.Install, error) { @@ -3516,11 +3548,15 @@ func getHelmInstallClient(ctx context.Context, requestedChart *configv1beta1.Hel installClient.ReleaseName = requestedChart.ReleaseName installClient.Namespace = requestedChart.ReleaseNamespace installClient.Version = requestedChart.ChartVersion - installClient.Wait = getWaitHelmValue(requestedChart.Options) + if getWaitHelmValue(requestedChart.Options) { + installClient.WaitStrategy = kube.LegacyStrategy + } else { + installClient.WaitStrategy = kube.HookOnlyStrategy + } installClient.WaitForJobs = getWaitForJobsHelmValue(requestedChart.Options) installClient.CreateNamespace = getCreateNamespaceHelmValue(requestedChart.Options) installClient.SkipCRDs = getSkipCRDsHelmValue(requestedChart.Options) - installClient.Atomic = getAtomicHelmValue(requestedChart.Options) + installClient.RollbackOnFailure = getAtomicHelmValue(requestedChart.Options) installClient.DisableHooks = getDisableHooksHelmInstallValue(requestedChart.Options) installClient.DisableOpenAPIValidation = getDisableOpenAPIValidationValue(requestedChart.Options) installClient.Timeout = getTimeoutValue(requestedChart.Options).Duration @@ -3530,10 +3566,11 @@ func getHelmInstallClient(ctx context.Context, requestedChart *configv1beta1.Hel installClient.Description = getDescriptionValue(requestedChart.Options) installClient.PassCredentialsAll = getPassCredentialsToAllValue(requestedChart.Options) installClient.TakeOwnership = getTakeOwnershipHelmValue(requestedChart.Options, false) + installClient.ForceConflicts = true if actionConfig.RegistryClient != nil { installClient.SetRegistryClient(actionConfig.RegistryClient) } - installClient.InsecureSkipTLSverify = registryOptions.skipTLSVerify + installClient.InsecureSkipTLSVerify = registryOptions.skipTLSVerify installClient.PlainHTTP = registryOptions.plainHTTP installClient.CaFile = registryOptions.caPath @@ -3541,7 +3578,6 @@ func getHelmInstallClient(ctx context.Context, requestedChart *configv1beta1.Hel installClient.PostRenderer = &patcher.CustomPatchPostRenderer{Patches: patches} } - installClient.DryRun = false if templateOnly { currentVersion, err := k8s_utils.GetKubernetesVersion(ctx, getManagementClusterConfig(), logger) if err != nil { @@ -3549,10 +3585,9 @@ func getHelmInstallClient(ctx context.Context, requestedChart *configv1beta1.Hel } // We simply want to get list of resources that would be deployed. This is to prepare // what agent for a SveltosCluster in pull mode needs to deploy - installClient.DryRun = true - installClient.ClientOnly = true + installClient.DryRunStrategy = action.DryRunClient installClient.IncludeCRDs = true - installClient.KubeVersion, err = chartutil.ParseKubeVersion(currentVersion) + installClient.KubeVersion, err = common.ParseKubeVersion(currentVersion) if err != nil { return nil, err } @@ -3568,10 +3603,14 @@ func getHelmUpgradeClient(requestedChart *configv1beta1.HelmChart, actionConfig upgradeClient.Install = true upgradeClient.Namespace = requestedChart.ReleaseNamespace upgradeClient.Version = requestedChart.ChartVersion - upgradeClient.Wait = getWaitHelmValue(requestedChart.Options) + if getWaitHelmValue(requestedChart.Options) { + upgradeClient.WaitStrategy = kube.LegacyStrategy + } else { + upgradeClient.WaitStrategy = kube.HookOnlyStrategy + } upgradeClient.WaitForJobs = getWaitForJobsHelmValue(requestedChart.Options) upgradeClient.SkipCRDs = getSkipCRDsHelmValue(requestedChart.Options) - upgradeClient.Atomic = getAtomicHelmValue(requestedChart.Options) + upgradeClient.RollbackOnFailure = getAtomicHelmValue(requestedChart.Options) upgradeClient.DisableHooks = getDisableHooksHelmUpgradeValue(requestedChart.Options) upgradeClient.DisableOpenAPIValidation = getDisableOpenAPIValidationValue(requestedChart.Options) upgradeClient.Timeout = getTimeoutValue(requestedChart.Options).Duration @@ -3579,18 +3618,18 @@ func getHelmUpgradeClient(requestedChart *configv1beta1.HelmChart, actionConfig upgradeClient.ResetValues = getResetValues(requestedChart.Options) upgradeClient.ReuseValues = getReuseValues(requestedChart.Options) upgradeClient.ResetThenReuseValues = getResetThenReuseValues(requestedChart.Options) - upgradeClient.Force = getForceValue(requestedChart.Options) + upgradeClient.ForceReplace = getForceValue(requestedChart.Options) upgradeClient.Labels = getLabelsValue(requestedChart.Options) upgradeClient.Description = getDescriptionValue(requestedChart.Options) upgradeClient.MaxHistory = getMaxHistoryValue(requestedChart.Options) upgradeClient.CleanupOnFail = getCleanupOnFailValue(requestedChart.Options) upgradeClient.SubNotes = getSubNotesValue(requestedChart.Options) - upgradeClient.Recreate = getRecreateValue(requestedChart.Options) - upgradeClient.InsecureSkipTLSverify = registryOptions.skipTLSVerify + upgradeClient.InsecureSkipTLSVerify = registryOptions.skipTLSVerify upgradeClient.PlainHTTP = registryOptions.plainHTTP upgradeClient.CaFile = registryOptions.caPath upgradeClient.PassCredentialsAll = getPassCredentialsToAllValue(requestedChart.Options) upgradeClient.TakeOwnership = getTakeOwnershipHelmValue(requestedChart.Options, true) + upgradeClient.ForceConflicts = true if actionConfig.RegistryClient != nil { upgradeClient.SetRegistryClient(actionConfig.RegistryClient) @@ -3608,10 +3647,13 @@ func getHelmUninstallClient(requestedChart *configv1beta1.HelmChart, actionConfi uninstallClient := action.NewUninstall(actionConfig) uninstallClient.DryRun = false + uninstallClient.WaitStrategy = kube.HookOnlyStrategy if requestedChart != nil { uninstallClient.Timeout = getTimeoutValue(requestedChart.Options).Duration uninstallClient.Description = getDescriptionValue(requestedChart.Options) - uninstallClient.Wait = getWaitHelmValue(requestedChart.Options) + if getWaitHelmValue(requestedChart.Options) { + uninstallClient.WaitStrategy = kube.LegacyStrategy + } uninstallClient.DisableHooks = getDisableHooksHelmUninstallValue(requestedChart.Options) uninstallClient.KeepHistory = getKeepHistoryValue(requestedChart.Options) uninstallClient.DeletionPropagation = getDeletionPropagation(requestedChart.Options) @@ -3641,10 +3683,14 @@ func addExtraMetadata(ctx context.Context, requestedChart *configv1beta1.HelmCha } statusObject := action.NewStatus(actionConfig) - results, err := statusObject.Run(requestedChart.ReleaseName) + rawResults, err := statusObject.Run(requestedChart.ReleaseName) if err != nil { return err } + results, ok := rawResults.(*releasev1.Release) + if !ok { + return fmt.Errorf("unexpected release type %T", rawResults) + } resources, err := collectHelmContent(results, install, true, logger) if err != nil { @@ -4135,7 +4181,7 @@ func evaluateValuesDiff(ctx context.Context, currentValues map[string]interface{ return "", err } - var values chartutil.Values + var values common.Values values, err = getHelmChartInstantiatedValues(ctx, clusterSummary, mgmtResources, requestedChart, logger) if err != nil { return "", err @@ -4702,7 +4748,7 @@ func removeCachedData(settings *cli.EnvSettings, name, repoURL string, registryO logger = logger.WithValues("repoURL", repoURL, "repoName", name) entry := &repo.Entry{Name: name, URL: repoURL, Username: registryOptions.username, Password: registryOptions.password, - InsecureSkipTLSverify: registryOptions.skipTLSVerify} + InsecureSkipTLSVerify: registryOptions.skipTLSVerify} chartRepo, err := repo.NewChartRepository(entry, getter.All(settings)) if err != nil { logger.V(logs.LogInfo).Info(fmt.Sprintf("failed to get new chartRepository: %v", err)) @@ -4773,3 +4819,17 @@ func isValidSemver(v string) bool { _, err := semver.NewVersion(v) return err == nil } + +func getCRDObjects(ch *chart.Chart) []chart.CRD { + var crds []chart.CRD + for _, f := range ch.Files { + // Helm expects CRDs to be in the "crds/" directory + if strings.HasPrefix(f.Name, "crds/") { + crds = append(crds, chart.CRD{ + Name: f.Name, + File: f, + }) + } + } + return crds +} diff --git a/controllers/handlers_helm_test.go b/controllers/handlers_helm_test.go index 7c7092c6..6c8ade8b 100644 --- a/controllers/handlers_helm_test.go +++ b/controllers/handlers_helm_test.go @@ -30,7 +30,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "helm.sh/helm/v3/pkg/release" + releasecommon "helm.sh/helm/v4/pkg/release/common" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -95,7 +95,7 @@ var _ = Describe("HandlersHelm", func() { It("shouldInstall returns false when requested version does not match installed version", func() { currentRelease := &controllers.ReleaseInfo{ - Status: release.StatusDeployed.String(), + Status: releasecommon.StatusDeployed.String(), ChartVersion: "v2.5.0", } requestChart := &configv1beta1.HelmChart{ @@ -108,7 +108,7 @@ var _ = Describe("HandlersHelm", func() { It("shouldInstall returns false when requested version matches installed version", func() { currentRelease := &controllers.ReleaseInfo{ - Status: release.StatusDeployed.String(), + Status: releasecommon.StatusDeployed.String(), ChartVersion: "v2.5.3", } requestChart := &configv1beta1.HelmChart{ @@ -144,7 +144,7 @@ var _ = Describe("HandlersHelm", func() { It("shouldUninstall returns false when action is not Uninstall", func() { currentRelease := &controllers.ReleaseInfo{ - Status: release.StatusDeployed.String(), + Status: releasecommon.StatusDeployed.String(), ChartVersion: "v2.5.3", } requestChart := &configv1beta1.HelmChart{ @@ -156,7 +156,7 @@ var _ = Describe("HandlersHelm", func() { It("shouldUpgrade returns true when installed release is different than requested release", func() { currentRelease := &controllers.ReleaseInfo{ - Status: release.StatusDeployed.String(), + Status: releasecommon.StatusDeployed.String(), ChartVersion: "v2.5.0", } requestChart := &configv1beta1.HelmChart{ diff --git a/go.mod b/go.mod index 55112fa0..d660a8bd 100644 --- a/go.mod +++ b/go.mod @@ -18,13 +18,13 @@ require ( github.com/onsi/ginkgo/v2 v2.28.1 github.com/onsi/gomega v1.39.1 github.com/pkg/errors v0.9.1 - github.com/projectsveltos/libsveltos v1.6.0 + github.com/projectsveltos/libsveltos v1.6.1 github.com/prometheus/client_golang v1.23.2 github.com/robfig/cron v1.2.0 github.com/spf13/pflag v1.0.10 github.com/yuin/gopher-lua v1.1.1 golang.org/x/text v0.35.0 - helm.sh/helm/v3 v3.20.1 + helm.sh/helm/v4 v4.1.3 k8s.io/api v0.35.2 k8s.io/apiextensions-apiserver v0.35.2 k8s.io/apimachinery v0.35.2 @@ -49,38 +49,39 @@ require ( 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.3.0 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chai2010/gettext-go v1.0.3 // indirect - github.com/containerd/containerd v1.7.30 // indirect - github.com/containerd/errdefs v1.0.0 // indirect - github.com/containerd/log v0.1.0 // indirect - github.com/containerd/platforms v0.2.1 // indirect + github.com/cloudflare/circl v1.6.3 // indirect github.com/cyphar/filepath-securejoin v0.6.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/docker/docker-credential-helpers v0.8.2 // indirect + github.com/dylibso/observe-sdk/go v0.0.0-20240819160327-2d926c5d788a // indirect github.com/emicklei/go-restful/v3 v3.13.0 // 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/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fluxcd/cli-utils v0.37.2-flux.1 // indirect github.com/fluxcd/pkg/apis/acl v0.9.0 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-errors/errors v1.5.1 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.21.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.0 // indirect + github.com/go-openapi/swag v0.23.1 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gobuffalo/flect v1.0.3 // indirect github.com/gobwas/glob v0.2.3 // indirect + github.com/gofrs/flock v0.13.0 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/cel-go v0.27.0 // indirect github.com/google/gnostic-models v0.7.0 // indirect @@ -89,23 +90,21 @@ require ( github.com/google/uuid v1.6.0 // 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.3 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.8 // indirect github.com/huandu/xstrings v1.5.0 // indirect + github.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmoiron/sqlx v1.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect @@ -127,8 +126,8 @@ require ( github.com/projectsveltos/lua-utils/glua-sprig v0.0.0-20251212200258-2b3cdcb7c0f5 // indirect github.com/projectsveltos/lua-utils/glua-strings v0.0.0-20251212200258-2b3cdcb7c0f5 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.66.1 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rubenv/sql-migrate v1.8.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect @@ -137,35 +136,37 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/cast v1.10.0 // indirect github.com/spf13/cobra v1.10.2 // indirect + github.com/tetratelabs/wabin v0.0.0-20230304001439-f6f874872834 // indirect + github.com/tetratelabs/wazero v1.11.0 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.2.0 // indirect github.com/zeebo/blake3 v0.2.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 // indirect go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 // indirect go.opentelemetry.io/otel/metric v1.40.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/trace v1.40.0 // indirect - go.opentelemetry.io/proto/otlp v1.5.0 // indirect + go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.48.0 // indirect golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect golang.org/x/mod v0.33.0 // indirect golang.org/x/net v0.50.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect golang.org/x/sync v0.20.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/term v0.40.0 // indirect golang.org/x/time v0.12.0 // indirect golang.org/x/tools v0.42.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect - google.golang.org/grpc v1.72.3 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect + google.golang.org/grpc v1.78.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index cd77ea1c..243ad85e 100644 --- a/go.sum +++ b/go.sum @@ -22,6 +22,8 @@ github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= +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/TwiN/go-color v1.4.1 h1:mqG0P/KBgHKVqmtL5ye7K0/Gr4l6hTksPgTgMk3mUzc= github.com/TwiN/go-color v1.4.1/go.mod h1:WcPf/jtiW95WBIsEeY1Lc/b8aaWoiqQpu5cf8WFxu+s= github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= @@ -34,20 +36,14 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v1.0.3 h1:9liNh8t+u26xl5ddmWLmsOsdNLwkdRTg5AG+JnTiM80= github.com/chai2010/gettext-go v1.0.3/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= -github.com/containerd/containerd v1.7.30 h1:/2vezDpLDVGGmkUXmlNPLCCNKHJ5BbC5tJB5JNzQhqE= -github.com/containerd/containerd v1.7.30/go.mod h1:fek494vwJClULlTpExsmOyKCMUAbuVjlFsJQc4/j44M= -github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= -github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= -github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= -github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= -github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= +github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= +github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= github.com/coredns/caddy v1.1.1 h1:2eYKZT7i6yxIfGP3qLJoJ7HAsDJqYB+X68g4NYjSrE0= github.com/coredns/caddy v1.1.1/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= github.com/coredns/corefile-migration v1.0.30 h1:ljZNPGgna+4yKv81gfkvkgLEWdtz0NjBR1glaiPI140= @@ -82,18 +78,24 @@ github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= +github.com/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/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -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.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= +github.com/evanphx/json-patch v5.9.0+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/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/fluxcd/cli-utils v0.37.2-flux.1 h1:tQ588ghtRN+E+kHq415FddfqA9v4brn/1WWgrP6rQR0= +github.com/fluxcd/cli-utils v0.37.2-flux.1/go.mod h1:LcWSu1NYET8d8U7O326RhEm5JkQXCMK6ITu4G1CT02c= github.com/fluxcd/pkg/apis/acl v0.9.0 h1:wBpgsKT+jcyZEcM//OmZr9RiF8klL3ebrDp2u2ThsnA= github.com/fluxcd/pkg/apis/acl v0.9.0/go.mod h1:TttNS+gocsGLwnvmgVi3/Yscwqrjc17+vhgYfqkfrV4= github.com/fluxcd/pkg/apis/meta v1.26.0 h1:dxP1FfBpTCYso6odzRcltVnnRuBb2VyhhgV0VX9YbUE= @@ -133,12 +135,12 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.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/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.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +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.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= @@ -149,6 +151,8 @@ 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/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +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/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= @@ -175,17 +179,12 @@ 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.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 h1:X+2YciYSxvMQK0UZ7sg45ZVabVZBeBuvMkmuI2V3Fak= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7/go.mod h1:lW34nIZuQ8UDPdkon5fmfp2l3+ZkQ2me/+oecHYLOII= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48= github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw= github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGNJAg1dcN2Fpfw= @@ -196,6 +195,8 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= 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-20250417193237-f615e6bd150b h1:ogbOPx86mIhFy764gGkqnkFC8m5PJA7sPzlk9ppLVQA= +github.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= @@ -224,8 +225,8 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= -github.com/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/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= @@ -270,8 +271,6 @@ 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/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/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -279,8 +278,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= -github.com/projectsveltos/libsveltos v1.6.0 h1:O6Rd5K+HsmyxKS/YVlXywGaLriNmU/T6MkhEFziaIjY= -github.com/projectsveltos/libsveltos v1.6.0/go.mod h1:Wi/ICx8bv1SGBuzIu6ZFEJAosauY3jA/wbIe1SCvnEs= +github.com/projectsveltos/libsveltos v1.6.1 h1:+NRYGDWONyUfjX0/LKFtPwvK/eQhO/jz1yvcPBj2lVA= +github.com/projectsveltos/libsveltos v1.6.1/go.mod h1:Wi/ICx8bv1SGBuzIu6ZFEJAosauY3jA/wbIe1SCvnEs= github.com/projectsveltos/lua-utils/glua-json v0.0.0-20251212200258-2b3cdcb7c0f5 h1:khnc+994UszxZYu69J+R5FKiLA/Nk1JQj0EYAkwTWz0= github.com/projectsveltos/lua-utils/glua-json v0.0.0-20251212200258-2b3cdcb7c0f5/go.mod h1:yVL8KQFa9tmcxgwl9nwIMtKgtmIVC1zaFRSCfOwYvPY= github.com/projectsveltos/lua-utils/glua-runes v0.0.0-20251212200258-2b3cdcb7c0f5 h1:YbsebwRwTRhV8QacvEAdFqxcxHdeu7JTVtsBovbkgos= @@ -293,10 +292,12 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -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.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= +github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos= +github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= 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= @@ -343,6 +344,10 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO 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/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -366,50 +371,50 @@ github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/bridges/prometheus v0.57.0 h1:UW0+QyeyBVhn+COBec3nGhfnFe5lwB0ic1JBVjzhk0w= -go.opentelemetry.io/contrib/bridges/prometheus v0.57.0/go.mod h1:ppciCHRLsyCio54qbzQv0E4Jyth/fLWDTJYfvWpcSVk= -go.opentelemetry.io/contrib/exporters/autoexport v0.57.0 h1:jmTVJ86dP60C01K3slFQa2NQ/Aoi7zA+wy7vMOKD9H4= -go.opentelemetry.io/contrib/exporters/autoexport v0.57.0/go.mod h1:EJBheUMttD/lABFyLXhce47Wr6DPWYReCzaZiXadH7g= -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/contrib/bridges/prometheus v0.65.0 h1:I/7S/yWobR3QHFLqHsJ8QOndoiFsj1VgHpQiq43KlUI= +go.opentelemetry.io/contrib/bridges/prometheus v0.65.0/go.mod h1:jPF6gn3y1E+nozCAEQj3c6NZ8KY+tvAgSVfvoOJUFac= +go.opentelemetry.io/contrib/exporters/autoexport v0.65.0 h1:2gApdml7SznX9szEKFjKjM4qGcGSvAybYLBY319XG3g= +go.opentelemetry.io/contrib/exporters/autoexport v0.65.0/go.mod h1:0QqAGlbHXhmPYACG3n5hNzO5DnEqqtg4VcK5pr22RI0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0= go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 h1:WzNab7hOOLzdDF/EoWCt4glhrbMPVMOO5JYTmpz36Ls= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0/go.mod h1:hKvJwTzJdp90Vh7p6q/9PAOd55dI6WA6sWj62a/JvSs= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0 h1:S+LdBGiQXtJdowoJoQPEtI52syEP/JYBUpjO49EQhV8= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0/go.mod h1:5KXybFvPGds3QinJWQT7pmXf+TN5YIa7CNYObWRkj50= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 h1:j7ZSD+5yn+lo3sGV69nW04rRR0jhYnBwjuX3r0HvnK0= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0/go.mod h1:WXbYJTUaZXAbYd8lbgGuvih0yuCfOFC5RJoYnoLcGz8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0 h1:t/Qur3vKSkUCcDVaSumWF2PKHt85pc7fRvFuoVT8qFU= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0/go.mod h1:Rl61tySSdcOJWoEgYZVtmnKdA0GeKrSqkHC1t+91CH8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 h1:cMyu9O88joYEaI47CnQkxO1XZdpoTF9fEnW2duIddhw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0/go.mod h1:6Am3rn7P9TVVeXYG+wtcGE7IE1tsQ+bP3AuWcKt/gOI= -go.opentelemetry.io/otel/exporters/prometheus v0.54.0 h1:rFwzp68QMgtzu9PgP3jm9XaMICI6TsofWWPcBDKwlsU= -go.opentelemetry.io/otel/exporters/prometheus v0.54.0/go.mod h1:QyjcV9qDP6VeK5qPyKETvNjmaaEc7+gqjh4SS0ZYzDU= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.8.0 h1:CHXNXwfKWfzS65yrlB2PVds1IBZcdsX8Vepy9of0iRU= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.8.0/go.mod h1:zKU4zUgKiaRxrdovSS2amdM5gOc59slmo/zJwGX+YBg= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.32.0 h1:SZmDnHcgp3zwlPBS2JX2urGYe/jBKEIT6ZedHRUyCz8= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.32.0/go.mod h1:fdWW0HtZJ7+jNpTKUR0GpMEDP69nR8YBJQxNiVCE3jk= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0 h1:cC2yDI3IQd0Udsux7Qmq8ToKAx1XCilTQECZ0KDZyTw= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0/go.mod h1:2PD5Ex6z8CFzDbTdOlwyNIUywRr1DN0ospafJM1wJ+s= -go.opentelemetry.io/otel/log v0.8.0 h1:egZ8vV5atrUWUbnSsHn6vB8R21G2wrKqNiDt3iWertk= -go.opentelemetry.io/otel/log v0.8.0/go.mod h1:M9qvDdUTRCopJcGRKg57+JSQ9LgLBrwwfC32epk5NX8= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.16.0 h1:ZVg+kCXxd9LtAaQNKBxAvJ5NpMf7LpvEr4MIZqb0TMQ= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.16.0/go.mod h1:hh0tMeZ75CCXrHd9OXRYxTlCAdxcXioWHFIpYw2rZu8= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.16.0 h1:djrxvDxAe44mJUrKataUbOhCKhR3F8QCyWucO16hTQs= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.16.0/go.mod h1:dt3nxpQEiSoKvfTVxp3TUg5fHPLhKtbcnN3Z1I1ePD0= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.40.0 h1:NOyNnS19BF2SUDApbOKbDtWZ0IK7b8FJ2uAGdIWOGb0= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.40.0/go.mod h1:VL6EgVikRLcJa9ftukrHu/ZkkhFBSo1lzvdBC9CF1ss= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.40.0 h1:9y5sHvAxWzft1WQ4BwqcvA+IFVUJ1Ya75mSAUnFEVwE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.40.0/go.mod h1:eQqT90eR3X5Dbs1g9YSM30RavwLF725Ris5/XSXWvqE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0/go.mod h1:bTdK1nhqF76qiPoCCdyFIV+N/sRHYXYCTQc+3VCi3MI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 h1:DvJDOPmSWQHWywQS6lKL+pb8s3gBLOZUtw4N+mavW1I= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0/go.mod h1:EtekO9DEJb4/jRyN4v4Qjc2yA7AtfCBuz2FynRUWTXs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 h1:wVZXIWjQSeSmMoxF74LzAnpVQOAFDo3pPji9Y4SOFKc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0/go.mod h1:khvBS2IggMFNwZK/6lEeHg/W57h/IX6J4URh57fuI40= +go.opentelemetry.io/otel/exporters/prometheus v0.62.0 h1:krvC4JMfIOVdEuNPTtQ0ZjCiXrybhv+uOHMfHRmnvVo= +go.opentelemetry.io/otel/exporters/prometheus v0.62.0/go.mod h1:fgOE6FM/swEnsVQCqCnbOfRV4tOnWPg7bVeo4izBuhQ= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.16.0 h1:ivlbaajBWJqhcCPniDqDJmRwj4lc6sRT+dCAVKNmxlQ= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.16.0/go.mod h1:u/G56dEKDDwXNCVLsbSrllB2o8pbtFLUC4HpR66r2dc= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.40.0 h1:ZrPRak/kS4xI3AVXy8F7pipuDXmDsrO8Lg+yQjBLjw0= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.40.0/go.mod h1:3y6kQCWztq6hyW8Z9YxQDDm0Je9AJoFar2G0yDcmhRk= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.40.0 h1:MzfofMZN8ulNqobCmCAVbqVL5syHw+eB2qPRkCMA/fQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.40.0/go.mod h1:E73G9UFtKRXrxhBsHtG00TB5WxX57lpsQzogDkqBTz8= +go.opentelemetry.io/otel/log v0.16.0 h1:DeuBPqCi6pQwtCK0pO4fvMB5eBq6sNxEnuTs88pjsN4= +go.opentelemetry.io/otel/log v0.16.0/go.mod h1:rWsmqNVTLIA8UnwYVOItjyEZDbKIkMxdQunsIhpUMes= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= -go.opentelemetry.io/otel/sdk/log v0.8.0 h1:zg7GUYXqxk1jnGF/dTdLPrK06xJdrXgqgFLnI4Crxvs= -go.opentelemetry.io/otel/sdk/log v0.8.0/go.mod h1:50iXr0UVwQrYS45KbruFrEt4LvAdCaWWgIrsN3ZQggo= +go.opentelemetry.io/otel/sdk/log v0.16.0 h1:e/b4bdlQwC5fnGtG3dlXUrNOnP7c8YLVSpSfEBIkTnI= +go.opentelemetry.io/otel/sdk/log v0.16.0/go.mod h1:JKfP3T6ycy7QEuv3Hj8oKDy7KItrEkus8XJE6EoSzw4= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= -go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= +go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= +go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -435,8 +440,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= @@ -469,14 +474,16 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= -google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.72.3 h1:6sysal2a4j9trATt+J/TSSEA/Q45ZrXzNh5zy4NMWuA= -google.golang.org/grpc v1.72.3/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 h1:merA0rdPeUV3YIIfHHcH4qBkiQAc1nfCKSI7lB4cV2M= +google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409/go.mod h1:fl8J1IvUjCilwZzQowmw2b7HQB2eAuYBabMXzWurF+I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= +google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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= @@ -491,8 +498,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= -helm.sh/helm/v3 v3.20.1 h1:T8PodUaH1UwNvE+imUA2mIKjJItY8g7CVvLVP5g4NzI= -helm.sh/helm/v3 v3.20.1/go.mod h1:Fl1kBaWCpkUrM6IYXPjQ3bdZQfFrogKArqptvueZ6Ww= +helm.sh/helm/v4 v4.1.3 h1:Abfmb+oJUtxoaXDyB2Jhw1zRk3hT6aFfHta+AXb8Lno= +helm.sh/helm/v4 v4.1.3/go.mod h1:5dSo8rRgn3OTkDAc/k0Ipw5/Q+BlqKIKZwa0XwSiINI= k8s.io/api v0.35.2 h1:tW7mWc2RpxW7HS4CoRXhtYHSzme1PN1UjGHJ1bdrtdw= k8s.io/api v0.35.2/go.mod h1:7AJfqGoAZcwSFhOjcGM7WV05QxMMgUaChNfLTXDRE60= k8s.io/apiextensions-apiserver v0.35.2 h1:iyStXHoJZsUXPh/nFAsjC29rjJWdSgUmG1XpApE29c0= diff --git a/manifest/manifest.yaml b/manifest/manifest.yaml index 0115b750..477f9682 100644 --- a/manifest/manifest.yaml +++ b/manifest/manifest.yaml @@ -721,8 +721,10 @@ spec: type: integer recreate: default: false - description: Recreate will (if true) recreate pods after - a rollback. + description: |- + Recreate will (if true) recreate pods after a rollback. + + Deprecated: This field is no longer supported type: boolean resetThenReuseValues: default: false @@ -2362,8 +2364,10 @@ spec: type: integer recreate: default: false - description: Recreate will (if true) recreate pods - after a rollback. + description: |- + Recreate will (if true) recreate pods after a rollback. + + Deprecated: This field is no longer supported type: boolean resetThenReuseValues: default: false @@ -4578,8 +4582,10 @@ spec: type: integer recreate: default: false - description: Recreate will (if true) recreate pods - after a rollback. + description: |- + Recreate will (if true) recreate pods after a rollback. + + Deprecated: This field is no longer supported type: boolean resetThenReuseValues: default: false @@ -6243,8 +6249,10 @@ spec: type: integer recreate: default: false - description: Recreate will (if true) recreate pods after - a rollback. + description: |- + Recreate will (if true) recreate pods after a rollback. + + Deprecated: This field is no longer supported type: boolean resetThenReuseValues: default: false