mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-02-02 10:35:08 -05:00
cli: ask user to confirm cert-manager upgrades
This commit is contained in:
parent
e7c7e35f51
commit
075a0e0ad6
@ -109,8 +109,8 @@ func (u *Upgrader) GetCurrentImage(ctx context.Context) (*unstructured.Unstructu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpgradeHelmServices upgrade helm services.
|
// UpgradeHelmServices upgrade helm services.
|
||||||
func (u *Upgrader) UpgradeHelmServices(ctx context.Context, config *config.Config, timeout time.Duration) error {
|
func (u *Upgrader) UpgradeHelmServices(ctx context.Context, config *config.Config, timeout time.Duration, allowDestructive bool) error {
|
||||||
return u.helmClient.Upgrade(ctx, config, timeout)
|
return u.helmClient.Upgrade(ctx, config, timeout, allowDestructive)
|
||||||
}
|
}
|
||||||
|
|
||||||
// KubernetesVersion returns the version of Kubernetes the Constellation is currently running on.
|
// KubernetesVersion returns the version of Kubernetes the Constellation is currently running on.
|
||||||
@ -234,7 +234,7 @@ func (u *stableClient) kubernetesVersion() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type helmInterface interface {
|
type helmInterface interface {
|
||||||
Upgrade(ctx context.Context, config *config.Config, timeout time.Duration) error
|
Upgrade(ctx context.Context, config *config.Config, timeout time.Duration, allowDestructive bool) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type debugLog interface {
|
type debugLog interface {
|
||||||
|
@ -8,10 +8,12 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
||||||
|
"github.com/edgelesssys/constellation/v2/cli/internal/helm"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/image"
|
"github.com/edgelesssys/constellation/v2/cli/internal/image"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/config"
|
"github.com/edgelesssys/constellation/v2/internal/config"
|
||||||
@ -30,6 +32,7 @@ func newUpgradeExecuteCmd() *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().Bool("helm", false, "Execute helm upgrade. This feature is still in development an may change without anounncement. Upgrades all helm charts deployed during constellation-init.")
|
cmd.Flags().Bool("helm", false, "Execute helm upgrade. This feature is still in development an may change without anounncement. Upgrades all helm charts deployed during constellation-init.")
|
||||||
|
cmd.Flags().BoolP("yes", "y", false, "Run upgrades without further confirmation. WARNING: might delete your resources in case you are using cert-manager in your cluster. Please read the docs.")
|
||||||
cmd.Flags().Duration("timeout", 3*time.Minute, "Change helm upgrade timeout. This feature is still in development an may change without anounncement. Might be useful for slow connections or big clusters.")
|
cmd.Flags().Duration("timeout", 3*time.Minute, "Change helm upgrade timeout. This feature is still in development an may change without anounncement. Might be useful for slow connections or big clusters.")
|
||||||
if err := cmd.Flags().MarkHidden("helm"); err != nil {
|
if err := cmd.Flags().MarkHidden("helm"); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -59,27 +62,35 @@ func runUpgradeExecute(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func upgradeExecute(cmd *cobra.Command, imageFetcher imageFetcher, upgrader cloudUpgrader, fileHandler file.Handler) error {
|
func upgradeExecute(cmd *cobra.Command, imageFetcher imageFetcher, upgrader cloudUpgrader, fileHandler file.Handler) error {
|
||||||
configPath, err := cmd.Flags().GetString("config")
|
flags, err := parseUpgradeExecuteFlags(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("parsing flags: %w", err)
|
||||||
}
|
}
|
||||||
conf, err := config.New(fileHandler, configPath)
|
conf, err := config.New(fileHandler, flags.configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return displayConfigValidationErrors(cmd.ErrOrStderr(), err)
|
return displayConfigValidationErrors(cmd.ErrOrStderr(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
helm, err := cmd.Flags().GetBool("helm")
|
if flags.helmFlag {
|
||||||
if err != nil {
|
err = upgrader.UpgradeHelmServices(cmd.Context(), conf, flags.upgradeTimeout, helm.DenyDestructive)
|
||||||
return err
|
if errors.Is(err, helm.ErrConfirmationMissing) {
|
||||||
}
|
if !flags.yes {
|
||||||
if helm {
|
cmd.PrintErrln("WARNING: Upgrading cert-manager will destroy all custom resources you have manually created that are based on the current version of cert-manager.")
|
||||||
timeout, err := cmd.Flags().GetDuration("timeout")
|
ok, askErr := askToConfirm(cmd, "Do you want to upgrade cert-manager anyway?")
|
||||||
if err != nil {
|
if askErr != nil {
|
||||||
return err
|
return fmt.Errorf("asking for confirmation: %w", err)
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
cmd.Println("Aborting upgrade.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = upgrader.UpgradeHelmServices(cmd.Context(), conf, flags.upgradeTimeout, helm.AllowDestructive)
|
||||||
}
|
}
|
||||||
if err := upgrader.UpgradeHelmServices(cmd.Context(), conf, timeout); err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("upgrading helm: %w", err)
|
return fmt.Errorf("upgrading helm: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,9 +107,39 @@ func upgradeExecute(cmd *cobra.Command, imageFetcher imageFetcher, upgrader clou
|
|||||||
return upgrader.Upgrade(cmd.Context(), imageReference, conf.Upgrade.Image, conf.Upgrade.Measurements)
|
return upgrader.Upgrade(cmd.Context(), imageReference, conf.Upgrade.Image, conf.Upgrade.Measurements)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseUpgradeExecuteFlags(cmd *cobra.Command) (upgradeExecuteFlags, error) {
|
||||||
|
configPath, err := cmd.Flags().GetString("config")
|
||||||
|
if err != nil {
|
||||||
|
return upgradeExecuteFlags{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
helmFlag, err := cmd.Flags().GetBool("helm")
|
||||||
|
if err != nil {
|
||||||
|
return upgradeExecuteFlags{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
yes, err := cmd.Flags().GetBool("yes")
|
||||||
|
if err != nil {
|
||||||
|
return upgradeExecuteFlags{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout, err := cmd.Flags().GetDuration("timeout")
|
||||||
|
if err != nil {
|
||||||
|
return upgradeExecuteFlags{}, err
|
||||||
|
}
|
||||||
|
return upgradeExecuteFlags{configPath: configPath, helmFlag: helmFlag, yes: yes, upgradeTimeout: timeout}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type upgradeExecuteFlags struct {
|
||||||
|
configPath string
|
||||||
|
helmFlag bool
|
||||||
|
yes bool
|
||||||
|
upgradeTimeout time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
type cloudUpgrader interface {
|
type cloudUpgrader interface {
|
||||||
Upgrade(ctx context.Context, imageReference, imageVersion string, measurements measurements.M) error
|
Upgrade(ctx context.Context, imageReference, imageVersion string, measurements measurements.M) error
|
||||||
UpgradeHelmServices(ctx context.Context, config *config.Config, timeout time.Duration) error
|
UpgradeHelmServices(ctx context.Context, config *config.Config, timeout time.Duration, allowDestructive bool) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type imageFetcher interface {
|
type imageFetcher interface {
|
||||||
|
@ -75,7 +75,7 @@ func (u stubUpgrader) Upgrade(context.Context, string, string, measurements.M) e
|
|||||||
return u.err
|
return u.err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u stubUpgrader) UpgradeHelmServices(ctx context.Context, config *config.Config, timeout time.Duration) error {
|
func (u stubUpgrader) UpgradeHelmServices(ctx context.Context, config *config.Config, timeout time.Duration, allowDestructive bool) error {
|
||||||
return u.helmErr
|
return u.helmErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,21 +16,31 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/deploy/helm"
|
"github.com/edgelesssys/constellation/v2/internal/deploy/helm"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"golang.org/x/mod/semver"
|
"golang.org/x/mod/semver"
|
||||||
"helm.sh/helm/v3/pkg/action"
|
"helm.sh/helm/v3/pkg/action"
|
||||||
"helm.sh/helm/v3/pkg/chart"
|
"helm.sh/helm/v3/pkg/chart"
|
||||||
"helm.sh/helm/v3/pkg/cli"
|
"helm.sh/helm/v3/pkg/cli"
|
||||||
|
"helm.sh/helm/v3/pkg/release"
|
||||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// AllowDestructive is a named bool to signal that destructive actions have been confirmed by the user.
|
||||||
|
AllowDestructive = true
|
||||||
|
// DenyDestructive is a named bool to signal that destructive actions have not been confirmed by the user yet.
|
||||||
|
DenyDestructive = false
|
||||||
|
)
|
||||||
|
|
||||||
// Client handles interaction with helm.
|
// Client handles interaction with helm.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
config *action.Configuration
|
config *action.Configuration
|
||||||
kubectl crdClient
|
kubectl crdClient
|
||||||
fs file.Handler
|
fs file.Handler
|
||||||
|
actions actionWrapper
|
||||||
log debugLog
|
log debugLog
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,26 +65,26 @@ func NewClient(client crdClient, kubeConfigPath, helmNamespace string, log debug
|
|||||||
return nil, fmt.Errorf("initializing kubectl: %w", err)
|
return nil, fmt.Errorf("initializing kubectl: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Client{config: actionConfig, kubectl: client, fs: fileHandler, log: log}, nil
|
return &Client{kubectl: client, fs: fileHandler, actions: actions{config: actionConfig}, log: log}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upgrade runs a helm-upgrade on all deployments that are managed via Helm.
|
// Upgrade runs a helm-upgrade on all deployments that are managed via Helm.
|
||||||
// If the CLI receives an interrupt signal it will cancel the context.
|
// If the CLI receives an interrupt signal it will cancel the context.
|
||||||
// Canceling the context will prompt helm to abort and roll back the ongoing upgrade.
|
// Canceling the context will prompt helm to abort and roll back the ongoing upgrade.
|
||||||
func (c *Client) Upgrade(ctx context.Context, config *config.Config, timeout time.Duration) error {
|
func (c *Client) Upgrade(ctx context.Context, config *config.Config, timeout time.Duration, allowDestructive bool) error {
|
||||||
if err := c.upgradeRelease(ctx, timeout, ciliumPath, ciliumReleaseName, false); err != nil {
|
if err := c.upgradeRelease(ctx, timeout, ciliumPath, ciliumReleaseName, false, allowDestructive); err != nil {
|
||||||
return fmt.Errorf("upgrading cilium: %w", err)
|
return fmt.Errorf("upgrading cilium: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.upgradeRelease(ctx, timeout, certManagerPath, certManagerReleaseName, false); err != nil {
|
if err := c.upgradeRelease(ctx, timeout, certManagerPath, certManagerReleaseName, false, allowDestructive); err != nil {
|
||||||
return fmt.Errorf("upgrading cert-manager: %w", err)
|
return fmt.Errorf("upgrading cert-manager: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.upgradeRelease(ctx, timeout, conOperatorsPath, conOperatorsReleaseName, true); err != nil {
|
if err := c.upgradeRelease(ctx, timeout, conOperatorsPath, conOperatorsReleaseName, true, allowDestructive); err != nil {
|
||||||
return fmt.Errorf("upgrading constellation operators: %w", err)
|
return fmt.Errorf("upgrading constellation operators: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.upgradeRelease(ctx, timeout, conServicesPath, conServicesReleaseName, false); err != nil {
|
if err := c.upgradeRelease(ctx, timeout, conServicesPath, conServicesReleaseName, false, allowDestructive); err != nil {
|
||||||
return fmt.Errorf("upgrading constellation-services: %w", err)
|
return fmt.Errorf("upgrading constellation-services: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,9 +93,7 @@ func (c *Client) Upgrade(ctx context.Context, config *config.Config, timeout tim
|
|||||||
|
|
||||||
// currentVersion returns the version of the currently installed helm release.
|
// currentVersion returns the version of the currently installed helm release.
|
||||||
func (c *Client) currentVersion(release string) (string, error) {
|
func (c *Client) currentVersion(release string) (string, error) {
|
||||||
client := action.NewList(c.config)
|
rel, err := c.actions.listAction(release)
|
||||||
client.Filter = release
|
|
||||||
rel, err := client.Run()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -104,8 +112,11 @@ func (c *Client) currentVersion(release string) (string, error) {
|
|||||||
return rel[0].Chart.Metadata.Version, nil
|
return rel[0].Chart.Metadata.Version, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrConfirmationMissing signals that an action requires user confirmation.
|
||||||
|
var ErrConfirmationMissing = errors.New("action requires user confirmation")
|
||||||
|
|
||||||
func (c *Client) upgradeRelease(
|
func (c *Client) upgradeRelease(
|
||||||
ctx context.Context, timeout time.Duration, chartPath, releaseName string, hasCRDs bool,
|
ctx context.Context, timeout time.Duration, chartPath, releaseName string, hasCRDs bool, allowDestructive bool,
|
||||||
) error {
|
) error {
|
||||||
chart, err := loadChartsDir(helmFS, chartPath)
|
chart, err := loadChartsDir(helmFS, chartPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -126,6 +137,10 @@ func (c *Client) upgradeRelease(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if releaseName == certManagerReleaseName && !allowDestructive {
|
||||||
|
return ErrConfirmationMissing
|
||||||
|
}
|
||||||
|
|
||||||
if hasCRDs {
|
if hasCRDs {
|
||||||
if err := c.updateCRDs(ctx, chart); err != nil {
|
if err := c.updateCRDs(ctx, chart); err != nil {
|
||||||
return fmt.Errorf("updating CRDs: %w", err)
|
return fmt.Errorf("updating CRDs: %w", err)
|
||||||
@ -137,13 +152,9 @@ func (c *Client) upgradeRelease(
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.log.Debugf("Upgrading %s from %s to %s", releaseName, currentVersion, chart.Metadata.Version)
|
c.log.Debugf("Upgrading %s from %s to %s", releaseName, currentVersion, chart.Metadata.Version)
|
||||||
action := action.NewUpgrade(c.config)
|
err = c.actions.upgradeAction(ctx, releaseName, chart, values, timeout)
|
||||||
action.Atomic = true
|
if err != nil {
|
||||||
action.Namespace = constants.HelmNamespace
|
return err
|
||||||
action.ReuseValues = false
|
|
||||||
action.Timeout = timeout
|
|
||||||
if _, err := action.RunWithContext(ctx, releaseName, chart, values); err != nil {
|
|
||||||
return fmt.Errorf("upgrading %s: %w", releaseName, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -159,9 +170,9 @@ func (c *Client) prepareValues(chart *chart.Chart, releaseName string) (map[stri
|
|||||||
if releaseName == certManagerReleaseName {
|
if releaseName == certManagerReleaseName {
|
||||||
chart.Values["installCRDs"] = true
|
chart.Values["installCRDs"] = true
|
||||||
}
|
}
|
||||||
values, err := c.GetValues(releaseName)
|
values, err := c.actions.getValues(releaseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("getting values: %w", err)
|
return nil, fmt.Errorf("getting values for %s: %w", releaseName, err)
|
||||||
}
|
}
|
||||||
return helm.MergeMaps(chart.Values, values), nil
|
return helm.MergeMaps(chart.Values, values), nil
|
||||||
}
|
}
|
||||||
@ -230,3 +241,40 @@ type crdClient interface {
|
|||||||
GetCRDs(ctx context.Context) ([]apiextensionsv1.CustomResourceDefinition, error)
|
GetCRDs(ctx context.Context) ([]apiextensionsv1.CustomResourceDefinition, error)
|
||||||
GetCRs(ctx context.Context, gvr schema.GroupVersionResource) ([]unstructured.Unstructured, error)
|
GetCRs(ctx context.Context, gvr schema.GroupVersionResource) ([]unstructured.Unstructured, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type actionWrapper interface {
|
||||||
|
listAction(release string) ([]*release.Release, error)
|
||||||
|
getValues(release string) (map[string]any, error)
|
||||||
|
upgradeAction(ctx context.Context, releaseName string, chart *chart.Chart, values map[string]any, timeout time.Duration) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type actions struct {
|
||||||
|
config *action.Configuration
|
||||||
|
}
|
||||||
|
|
||||||
|
// listAction execute a List action by wrapping helm's action package.
|
||||||
|
// It creates the action, runs it at returns results and errors.
|
||||||
|
func (a actions) listAction(release string) ([]*release.Release, error) {
|
||||||
|
action := action.NewList(a.config)
|
||||||
|
action.Filter = release
|
||||||
|
return action.Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a actions) getValues(release string) (map[string]any, error) {
|
||||||
|
client := action.NewGetValues(a.config)
|
||||||
|
// Version corresponds to the releases revision. Specifying a Version <= 0 yields the latest release.
|
||||||
|
client.Version = 0
|
||||||
|
return client.Run(release)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a actions) upgradeAction(ctx context.Context, releaseName string, chart *chart.Chart, values map[string]any, timeout time.Duration) error {
|
||||||
|
action := action.NewUpgrade(a.config)
|
||||||
|
action.Atomic = true
|
||||||
|
action.Namespace = constants.HelmNamespace
|
||||||
|
action.ReuseValues = false
|
||||||
|
action.Timeout = timeout
|
||||||
|
if _, err := action.RunWithContext(ctx, releaseName, chart, values); err != nil {
|
||||||
|
return fmt.Errorf("upgrading %s: %w", releaseName, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -7,9 +7,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
package helm
|
package helm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"helm.sh/helm/v3/pkg/chart"
|
||||||
|
"helm.sh/helm/v3/pkg/release"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestIsUpgrade(t *testing.T) {
|
func TestIsUpgrade(t *testing.T) {
|
||||||
@ -77,3 +82,47 @@ func TestIsUpgrade(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUpgradeRelease(t *testing.T) {
|
||||||
|
testCases := map[string]struct {
|
||||||
|
allowDestructive bool
|
||||||
|
wantError bool
|
||||||
|
}{
|
||||||
|
"allow": {
|
||||||
|
allowDestructive: true,
|
||||||
|
},
|
||||||
|
"deny": {
|
||||||
|
allowDestructive: false,
|
||||||
|
wantError: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, tc := range testCases {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
client := Client{kubectl: nil, actions: &stubActionWrapper{}, log: logger.NewTest(t)}
|
||||||
|
err := client.upgradeRelease(context.Background(), 0, certManagerPath, certManagerReleaseName, false, tc.allowDestructive)
|
||||||
|
if tc.wantError {
|
||||||
|
assert.ErrorIs(err, ErrConfirmationMissing)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert.NoError(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type stubActionWrapper struct{}
|
||||||
|
|
||||||
|
// listAction returns a list of len 1 with a release that has only it's version set.
|
||||||
|
func (a *stubActionWrapper) listAction(_ string) ([]*release.Release, error) {
|
||||||
|
return []*release.Release{{Chart: &chart.Chart{Metadata: &chart.Metadata{Version: "1.0.0"}}}}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *stubActionWrapper) getValues(release string) (map[string]any, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *stubActionWrapper) upgradeAction(ctx context.Context, releaseName string, chart *chart.Chart, values map[string]any, timeout time.Duration) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user