Skip to content

Commit

Permalink
chore: add logger to zarf destroy (#3162)
Browse files Browse the repository at this point in the history
Signed-off-by: Kit Patella <[email protected]>
  • Loading branch information
mkcp authored Oct 30, 2024
1 parent 96c5afa commit d8bf303
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 9 deletions.
10 changes: 8 additions & 2 deletions src/cmd/destroy.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/zarf-dev/zarf/src/config/lang"
"github.com/zarf-dev/zarf/src/internal/packager/helm"
"github.com/zarf-dev/zarf/src/pkg/cluster"
"github.com/zarf-dev/zarf/src/pkg/logger"
"github.com/zarf-dev/zarf/src/pkg/message"
"github.com/zarf-dev/zarf/src/pkg/utils/exec"

Expand All @@ -33,7 +34,9 @@ var destroyCmd = &cobra.Command{
// TODO(mkcp): refactor and de-nest this function.
RunE: func(cmd *cobra.Command, _ []string) error {
ctx := cmd.Context()
timeoutCtx, cancel := context.WithTimeout(cmd.Context(), cluster.DefaultTimeout)
l := logger.From(ctx)

timeoutCtx, cancel := context.WithTimeout(ctx, cluster.DefaultTimeout)
defer cancel()
c, err := cluster.NewClusterWithWait(timeoutCtx)
if err != nil {
Expand All @@ -46,6 +49,7 @@ var destroyCmd = &cobra.Command{
state, err := c.LoadZarfState(ctx)
if err != nil {
message.WarnErr(err, err.Error())
l.Warn(err.Error())
}

// If Zarf deployed the cluster, burn it all down
Expand All @@ -68,6 +72,7 @@ var destroyCmd = &cobra.Command{
err := exec.CmdWithPrint(script)
if errors.Is(err, os.ErrPermission) {
message.Warnf(lang.CmdDestroyErrScriptPermissionDenied, script)
l.Warn("received 'permission denied' when trying to execute script. Please double-check you have the correct kube-context.", "script", script)

// Don't remove scripts we can't execute so the user can try to manually run
continue
Expand All @@ -79,11 +84,12 @@ var destroyCmd = &cobra.Command{
err = os.Remove(script)
if err != nil {
message.WarnErr(err, fmt.Sprintf("Unable to remove script. script=%s", script))
l.Warn("unable to remove script", "script", script, "error", err.Error())
}
}
} else {
// Perform chart uninstallation
helm.Destroy(removeComponents)
helm.Destroy(ctx, removeComponents)

// If Zarf didn't deploy the cluster, only delete the ZarfNamespace
if err := c.DeleteZarfNamespace(ctx); err != nil {
Expand Down
4 changes: 3 additions & 1 deletion src/internal/packager/helm/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"context"
"errors"
"fmt"
"github.com/zarf-dev/zarf/src/pkg/logger"
"time"

"github.com/Masterminds/semver/v3"
Expand Down Expand Up @@ -213,12 +214,13 @@ func (h *Helm) TemplateChart(ctx context.Context) (manifest string, chartValues
}

// RemoveChart removes a chart from the cluster.
func (h *Helm) RemoveChart(namespace string, name string, spinner *message.Spinner) error {
func (h *Helm) RemoveChart(ctx context.Context, namespace string, name string, spinner *message.Spinner) error {
// Establish a new actionConfig for the namespace.
_ = h.createActionConfig(namespace, spinner)
// Perform the uninstall.
response, err := h.uninstallChart(name)
message.Debug(response)
logger.From(ctx).Debug("chart uninstalled", "response", response)
return err
}

Expand Down
15 changes: 13 additions & 2 deletions src/internal/packager/helm/destroy.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@
package helm

import (
"context"
"regexp"
"time"

"github.com/zarf-dev/zarf/src/pkg/cluster"
"github.com/zarf-dev/zarf/src/pkg/logger"
"github.com/zarf-dev/zarf/src/pkg/message"
"helm.sh/helm/v3/pkg/action"
)

// Destroy removes ZarfInitPackage charts from the cluster and optionally all Zarf-installed charts.
func Destroy(purgeAllZarfInstallations bool) {
func Destroy(ctx context.Context, purgeAllZarfInstallations bool) {
start := time.Now()
l := logger.From(ctx)
spinner := message.NewProgressSpinner("Removing Zarf-installed charts")
defer spinner.Stop()
l.Info("removing Zarf-installed charts")

h := Helm{}

Expand All @@ -24,6 +30,7 @@ func Destroy(purgeAllZarfInstallations bool) {
if err != nil {
// Don't fatal since this is a removal action
spinner.Errorf(err, "Unable to initialize the K8s client")
l.Error("unable to initialize the K8s client", "error", err.Error())
return
}

Expand All @@ -42,6 +49,7 @@ func Destroy(purgeAllZarfInstallations bool) {
if err != nil {
// Don't fatal since this is a removal action
spinner.Errorf(err, "Unable to get the list of installed charts")
l.Error("unable to get the list of installed charts", "error", err.Error())
}

// Iterate over all releases
Expand All @@ -53,12 +61,15 @@ func Destroy(purgeAllZarfInstallations bool) {
// Filter on zarf releases
if zarfPrefix.MatchString(release.Name) {
spinner.Updatef("Uninstalling helm chart %s/%s", release.Namespace, release.Name)
if err = h.RemoveChart(release.Namespace, release.Name, spinner); err != nil {
l.Info("uninstalling helm chart", "namespace", release.Namespace, "name", release.Name)
if err = h.RemoveChart(ctx, release.Namespace, release.Name, spinner); err != nil {
// Don't fatal since this is a removal action
spinner.Errorf(err, "Unable to uninstall the chart")
l.Error("unable to uninstall the chart", "error", err.Error())
}
}
}

spinner.Success()
l.Debug("done uninstalling charts", "duration", time.Since(start))
}
2 changes: 2 additions & 0 deletions src/pkg/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type Cluster struct {

// NewClusterWithWait creates a new Cluster instance and waits for the given timeout for the cluster to be ready.
func NewClusterWithWait(ctx context.Context) (*Cluster, error) {
start := time.Now()
l := logger.From(ctx)
spinner := message.NewProgressSpinner("Waiting for cluster connection")
defer spinner.Stop()
Expand Down Expand Up @@ -74,6 +75,7 @@ func NewClusterWithWait(ctx context.Context) (*Cluster, error) {
}

spinner.Success()
l.Debug("done waiting for cluster, connected", "duration", time.Since(start))

return c, nil
}
Expand Down
6 changes: 6 additions & 0 deletions src/pkg/cluster/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@ import (
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/zarf-dev/zarf/src/pkg/logger"
"github.com/zarf-dev/zarf/src/pkg/message"
)

// DeleteZarfNamespace deletes the Zarf namespace from the connected cluster.
func (c *Cluster) DeleteZarfNamespace(ctx context.Context) error {
start := time.Now()
l := logger.From(ctx)
spinner := message.NewProgressSpinner("Deleting the zarf namespace from this cluster")
defer spinner.Stop()
l.Info("deleting the zarf namespace from this cluster")

err := c.Clientset.CoreV1().Namespaces().Delete(ctx, ZarfNamespaceName, metav1.DeleteOptions{})
if kerrors.IsNotFound(err) {
Expand All @@ -42,6 +46,8 @@ func (c *Cluster) DeleteZarfNamespace(ctx context.Context) error {
if err != nil {
return err
}

l.Debug("done deleting the zarf namespace from this cluster", "duration", time.Since(start))
return nil
}

Expand Down
10 changes: 7 additions & 3 deletions src/pkg/cluster/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/defenseunicorns/pkg/helpers/v2"
"github.com/zarf-dev/zarf/src/config"
"github.com/zarf-dev/zarf/src/config/lang"
"github.com/zarf-dev/zarf/src/pkg/logger"
"github.com/zarf-dev/zarf/src/pkg/message"
"github.com/zarf-dev/zarf/src/pkg/pki"
"github.com/zarf-dev/zarf/src/types"
Expand Down Expand Up @@ -205,7 +206,7 @@ func (c *Cluster) LoadZarfState(ctx context.Context) (*types.ZarfState, error) {
if err != nil {
return nil, fmt.Errorf("%w: %w", stateErr, err)
}
c.debugPrintZarfState(state)
c.debugPrintZarfState(ctx, state)
return state, nil
}

Expand All @@ -230,10 +231,11 @@ func (c *Cluster) sanitizeZarfState(state *types.ZarfState) *types.ZarfState {
return state
}

func (c *Cluster) debugPrintZarfState(state *types.ZarfState) {
func (c *Cluster) debugPrintZarfState(ctx context.Context, state *types.ZarfState) {
if state == nil {
return
}

// this is a shallow copy, nested pointers WILL NOT be copied
oldState := *state
sanitized := c.sanitizeZarfState(&oldState)
Expand All @@ -242,11 +244,13 @@ func (c *Cluster) debugPrintZarfState(state *types.ZarfState) {
return
}
message.Debugf("ZarfState - %s", string(b))

logger.From(ctx).Debug("cluster.debugPrintZarfState", "state", sanitized)
}

// SaveZarfState takes a given state and persists it to the Zarf/zarf-state secret.
func (c *Cluster) SaveZarfState(ctx context.Context, state *types.ZarfState) error {
c.debugPrintZarfState(state)
c.debugPrintZarfState(ctx, state)

data, err := json.Marshal(&state)
if err != nil {
Expand Down
12 changes: 12 additions & 0 deletions src/pkg/cluster/zarf.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"errors"
"fmt"
"strings"
"time"

autoscalingV2 "k8s.io/api/autoscaling/v2"
corev1 "k8s.io/api/core/v1"
Expand All @@ -19,6 +20,7 @@ import (
"github.com/zarf-dev/zarf/src/api/v1alpha1"
"github.com/zarf-dev/zarf/src/config"
"github.com/zarf-dev/zarf/src/internal/gitea"
"github.com/zarf-dev/zarf/src/pkg/logger"
"github.com/zarf-dev/zarf/src/pkg/message"
"github.com/zarf-dev/zarf/src/types"
)
Expand Down Expand Up @@ -133,41 +135,51 @@ func (c *Cluster) DeleteDeployedPackage(ctx context.Context, packageName string)

// StripZarfLabelsAndSecretsFromNamespaces removes metadata and secrets from existing namespaces no longer manged by Zarf.
func (c *Cluster) StripZarfLabelsAndSecretsFromNamespaces(ctx context.Context) {
start := time.Now()
l := logger.From(ctx)
spinner := message.NewProgressSpinner("Removing zarf metadata & secrets from existing namespaces not managed by Zarf")
defer spinner.Stop()
l.Info("removing zarf metadata & secrets from existing namespaces not managed by Zarf")

deleteOptions := metav1.DeleteOptions{}
listOptions := metav1.ListOptions{
LabelSelector: ZarfManagedByLabel + "=zarf",
}

// TODO(mkcp): Remove unnecessary nesting w/ else
namespaceList, err := c.Clientset.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
if err != nil {
spinner.Errorf(err, "Unable to get k8s namespaces")
l.Error("unable to get k8s namespaces", "error", err)
} else {
for _, namespace := range namespaceList.Items {
if _, ok := namespace.Labels[AgentLabel]; ok {
spinner.Updatef("Removing Zarf Agent label for namespace %s", namespace.Name)
l.Info("removing Zarf Agent label", "namespace", namespace.Name)
delete(namespace.Labels, AgentLabel)
namespaceCopy := namespace
_, err := c.Clientset.CoreV1().Namespaces().Update(ctx, &namespaceCopy, metav1.UpdateOptions{})
if err != nil {
// This is not a hard failure, but we should log it
spinner.Errorf(err, "Unable to update the namespace labels for %s", namespace.Name)
l.Warn("unable to update the namespace labels", "namespace", namespace.Name, "error", err)
}
}

spinner.Updatef("Removing Zarf secrets for namespace %s", namespace.Name)
l.Info("removing Zarf secrets", "namespace", namespace.Name)
err := c.Clientset.CoreV1().
Secrets(namespace.Name).
DeleteCollection(ctx, deleteOptions, listOptions)
if err != nil {
spinner.Errorf(err, "Unable to delete secrets from namespace %s", namespace.Name)
l.Error("unable to delete secrets", "namespace", namespace.Name, "error", err)
}
}
}

spinner.Success()
l.Debug("done stripping zarf labels and secrets from namespaces", "duration", time.Since(start))
}

// RecordPackageDeployment saves metadata about a package that has been deployed to the cluster.
Expand Down
2 changes: 1 addition & 1 deletion src/pkg/packager/remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ func (p *Packager) removeComponent(ctx context.Context, deployedPackage *types.D
spinner.Updatef("Uninstalling chart '%s' from the '%s' component", chart.ChartName, deployedComponent.Name)

helmCfg := helm.NewClusterOnly(p.cfg, p.variableConfig, p.state, p.cluster)
if err := helmCfg.RemoveChart(chart.Namespace, chart.ChartName, spinner); err != nil {
if err := helmCfg.RemoveChart(ctx, chart.Namespace, chart.ChartName, spinner); err != nil {
if !errors.Is(err, driver.ErrReleaseNotFound) {
onFailure()
return deployedPackage, fmt.Errorf("unable to uninstall the helm chart %s in the namespace %s: %w",
Expand Down

0 comments on commit d8bf303

Please sign in to comment.