Skip to content

Commit

Permalink
add --remove-components to remove charts installed by zarf in other n…
Browse files Browse the repository at this point in the history
…amespaces
  • Loading branch information
jeff-mccoy committed Feb 8, 2022
1 parent 658237f commit 1132f19
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 9 deletions.
8 changes: 8 additions & 0 deletions cli/cmd/destroy.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"github.com/defenseunicorns/zarf/cli/internal/helm"
"os"
"regexp"

Expand All @@ -11,6 +12,7 @@ import (
)

var confirmDestroy bool
var removeComponents bool

var destroyCmd = &cobra.Command{
Use: "destroy",
Expand All @@ -31,6 +33,11 @@ var destroyCmd = &cobra.Command{
_ = os.Remove(script)
}
} else {
if removeComponents {
// The default behavior for charts installed outside the zarf namespace will be to leave them installed
helm.Destroy()
}

// If Zarf didn't deploy the cluster, only delete the ZarfNamespace
k8s.DeleteZarfNamespace()
}
Expand All @@ -41,5 +48,6 @@ func init() {
rootCmd.AddCommand(destroyCmd)

destroyCmd.Flags().BoolVar(&confirmDestroy, "confirm", false, "Confirm the destroy action")
destroyCmd.Flags().BoolVar(&removeComponents, "remove-components", false, "Also remove any installed components outside the zarf namespace")
_ = destroyCmd.MarkFlagRequired("confirm")
}
14 changes: 8 additions & 6 deletions cli/internal/helm/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
type ChartOptions struct {
BasePath string
Chart config.ZarfChart
ReleaseName string
ChartOverride *chart.Chart
ValueOverride map[string]interface{}
Images []string
Expand All @@ -40,6 +41,7 @@ func InstallOrUpgradeChart(options ChartOptions) {

var output *release.Release

options.ReleaseName = fmt.Sprintf("zarf-%s", options.Chart.Name)
actionConfig, err := createActionConfig(options.Chart.Namespace)

// Setup K8s connection
Expand All @@ -59,17 +61,17 @@ func InstallOrUpgradeChart(options ChartOptions) {
// On total failure try to rollback or uninstall
if histClient.Version > 1 {
spinner.Updatef("Performing chart rollback")
_ = rollbackChart(actionConfig, options.Chart.Name)
_ = rollbackChart(actionConfig, options.ReleaseName)
} else {
spinner.Updatef("Performing chart uninstall")
_, _ = uninstallChart(actionConfig, options.Chart.Name)
_, _ = uninstallChart(actionConfig, options.ReleaseName)
}
spinner.Errorf(nil, "Unable to complete helm chart install/upgrade")
break
}

spinner.Updatef("Checking for existing helm deployment")
if _, histErr := histClient.Run(options.Chart.Name); histErr == driver.ErrReleaseNotFound {
if _, histErr := histClient.Run(options.ReleaseName); histErr == driver.ErrReleaseNotFound {
// No prior release, try to install it
spinner.Updatef("Attempting chart installation")
output, err = installChart(actionConfig, options)
Expand Down Expand Up @@ -105,7 +107,7 @@ func GenerateChart(basePath string, manifest config.ZarfManifest, images []strin
// Generate a new chart
tmpChart := new(chart.Chart)
tmpChart.Metadata = new(chart.Metadata)
tmpChart.Metadata.Name = fmt.Sprintf("zarf-%s", manifest.Name)
tmpChart.Metadata.Name = fmt.Sprintf("raw-%s", manifest.Name)
// This is fun, increment forward in a semver-way using epoch so helm doesn't cry
tmpChart.Metadata.Version = fmt.Sprintf("0.1.%d", now.Unix())
tmpChart.Metadata.APIVersion = chart.APIVersionV1
Expand Down Expand Up @@ -159,7 +161,7 @@ func installChart(actionConfig *action.Configuration, options ChartOptions) (*re
client.SkipCRDs = false

// Must be unique per-namespace and < 53 characters. @todo: restrict helm loadedChart name to this
client.ReleaseName = options.Chart.Name
client.ReleaseName = options.ReleaseName

// Namespace must be specified
client.Namespace = options.Chart.Namespace
Expand Down Expand Up @@ -198,7 +200,7 @@ func upgradeChart(actionConfig *action.Configuration, options ChartOptions) (*re
}

// Perform the loadedChart upgrade
return client.Run(options.Chart.Name, loadedChart, chartValues)
return client.Run(options.ReleaseName, loadedChart, chartValues)
}

func rollbackChart(actionConfig *action.Configuration, name string) error {
Expand Down
54 changes: 54 additions & 0 deletions cli/internal/helm/destroy.go
Original file line number Diff line number Diff line change
@@ -1 +1,55 @@
package helm

import (
"github.com/defenseunicorns/zarf/cli/internal/message"
"helm.sh/helm/v3/pkg/action"
"regexp"
)

func Destroy() {
spinner := message.NewProgressSpinner("Searching for Zarf-installed charts")
defer spinner.Stop()

// Initially load the actionConfig without a namespace
actionConfig, err := createActionConfig("")
if err != nil {
// Don't fatal since this is a removal action
spinner.Errorf(err, "Unable to initialize the K8s client")
return
}

// Match a name that begins with "zarf-"
// Explanation: https://regex101.com/r/3yzKZy/1
zarfPrefix := regexp.MustCompile(`(?m)^zarf-`)

// Get a list of all releases in all namespaces
list := action.NewList(actionConfig)
list.All = true
list.AllNamespaces = true
// Uninstall in reverse order
list.ByDate = true
list.SortReverse = true
releases, err := list.Run()
if err != nil {
// Don't fatal since this is a removal action
spinner.Errorf(err, "Unable to get the list of installed charts")
}

// Iterate over all releases
for _, release := range releases {
// Filter on zarf releases
if zarfPrefix.MatchString(release.Name) {
spinner.Updatef("Uninstalling helm chart %s/%s", release.Namespace, release.Name)
// Establish a new actionConfig for the namespace
actionConfig, _ = createActionConfig(release.Namespace)
// Perform the uninstall
response, err := uninstallChart(actionConfig, release.Name)
message.Debug(response)
if err != nil {
// Don't fatal since this is a removal action
spinner.Errorf(err, "Unable to uninstall the chart")
}
}
}

}
6 changes: 3 additions & 3 deletions cli/internal/k8s/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,15 @@ func NewZarfTunnel() *Tunnel {
func (tunnel *Tunnel) Connect(target string, blocking bool) {
switch strings.ToUpper(target) {
case ZarfRegistry:
tunnel.resourceName = "docker-registry"
tunnel.resourceName = "zarf-docker-registry"
tunnel.localPort = PortRegistry
tunnel.remotePort = 5000
case ZarfLogging:
tunnel.resourceName = "loki-stack-grafana"
tunnel.resourceName = "zarf-loki-stack-grafana"
tunnel.localPort = PortLogging
tunnel.remotePort = 3000
case ZarfGit:
tunnel.resourceName = "gitea-http"
tunnel.resourceName = "zarf-gitea-http"
tunnel.localPort = PortGit
tunnel.remotePort = 3000
default:
Expand Down

0 comments on commit 1132f19

Please sign in to comment.