Skip to content

Commit

Permalink
Merge pull request #90 from Praqma/feature/destroy
Browse files Browse the repository at this point in the history
adding destroy support. Fixes #88
  • Loading branch information
Sami Alajrami committed Sep 27, 2018
2 parents f1dab5c + 6931094 commit e179188
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 66 deletions.
24 changes: 20 additions & 4 deletions decision_maker.go
Expand Up @@ -26,6 +26,12 @@ func makePlan(s *state) *plan {
// decide makes a decision about what commands (actions) need to be executed
// to make a release section of the desired state come true.
func decide(r *release, s *state) {
if destroy {
if ok, rs := helmReleaseExists(r, ""); ok {
deleteRelease(r, rs)
return
}
}

// check for deletion
if !r.Enabled {
Expand Down Expand Up @@ -102,7 +108,7 @@ func installRelease(r *release) {

cmd := command{
Cmd: "bash",
Args: []string{"-c", "helm install " + r.Chart + " -n " + r.Name + " --namespace " + r.Namespace + getValuesFiles(r) + " --version " + r.Version + getSetValues(r) + getWait(r) + getDesiredTillerNamespaceFlag(r) + getTLSFlags(r) + getTimeout(r) + getNoHooks(r) + getDryRunFlags()},
Args: []string{"-c", "helm install " + r.Chart + " -n " + r.Name + " --namespace " + r.Namespace + getValuesFiles(r) + " --version " + r.Version + getSetValues(r) + getSetStringValues(r) + getWait(r) + getDesiredTillerNamespaceFlag(r) + getTLSFlags(r) + getTimeout(r) + getNoHooks(r) + getDryRunFlags()},
Description: "installing release [ " + r.Name + " ] in namespace [[ " + r.Namespace + " ]] using Tiller in [ " + getDesiredTillerNamespace(r) + " ]",
}
outcome.addCommand(cmd, r.Priority, r)
Expand Down Expand Up @@ -219,7 +225,7 @@ func diffRelease(r *release) string {

cmd := command{
Cmd: "bash",
Args: []string{"-c", "helm diff " + colorFlag + "upgrade " + r.Name + " " + r.Chart + getValuesFiles(r) + " --version " + r.Version + " " + getSetValues(r) + getWait(r) + getDesiredTillerNamespaceFlag(r) + getTLSFlags(r) + getTimeout(r) + getNoHooks(r)},
Args: []string{"-c", "helm diff " + colorFlag + "upgrade " + r.Name + " " + r.Chart + getValuesFiles(r) + " --version " + r.Version + " " + getSetValues(r) + getSetStringValues(r) + getWait(r) + getDesiredTillerNamespaceFlag(r) + getTLSFlags(r) + getTimeout(r) + getNoHooks(r)},
Description: "upgrading release [ " + r.Name + " ] using Tiller in [ " + getDesiredTillerNamespace(r) + " ]",
}

Expand All @@ -236,7 +242,7 @@ func diffRelease(r *release) string {
func upgradeRelease(r *release) {
cmd := command{
Cmd: "bash",
Args: []string{"-c", "helm upgrade " + r.Name + " " + r.Chart + getValuesFiles(r) + " --version " + r.Version + " --force " + getSetValues(r) + getWait(r) + getDesiredTillerNamespaceFlag(r) + getTLSFlags(r) + getTimeout(r) + getNoHooks(r) + getDryRunFlags()},
Args: []string{"-c", "helm upgrade " + r.Name + " " + r.Chart + getValuesFiles(r) + " --version " + r.Version + " --force " + getSetValues(r) + getSetStringValues(r) + getWait(r) + getDesiredTillerNamespaceFlag(r) + getTLSFlags(r) + getTimeout(r) + getNoHooks(r) + getDryRunFlags()},
Description: "upgrading release [ " + r.Name + " ] using Tiller in [ " + getDesiredTillerNamespace(r) + " ]",
}

Expand All @@ -256,7 +262,7 @@ func reInstallRelease(r *release, rs releaseState) {

installCmd := command{
Cmd: "bash",
Args: []string{"-c", "helm install " + r.Chart + " --version " + r.Version + " -n " + r.Name + " --namespace " + r.Namespace + getValuesFiles(r) + getSetValues(r) + getWait(r) + getDesiredTillerNamespaceFlag(r) + getTLSFlags(r) + getTimeout(r) + getNoHooks(r) + getDryRunFlags()},
Args: []string{"-c", "helm install " + r.Chart + " --version " + r.Version + " -n " + r.Name + " --namespace " + r.Namespace + getValuesFiles(r) + getSetValues(r) + getSetStringValues(r) + getWait(r) + getDesiredTillerNamespaceFlag(r) + getTLSFlags(r) + getTimeout(r) + getNoHooks(r) + getDryRunFlags()},
Description: "installing release [ " + r.Name + " ] in namespace [[ " + r.Namespace + " ]] using Tiller in [ " + getDesiredTillerNamespace(r) + " ]",
}
outcome.addCommand(installCmd, r.Priority, r)
Expand Down Expand Up @@ -345,6 +351,16 @@ func getSetValues(r *release) string {
return result
}

// getSetStringValues returns --set-string params to be used with helm install/upgrade commands
func getSetStringValues(r *release) string {
result := ""
for k, v := range r.SetString {
value := substituteEnv(v)
result = result + " --set-string " + k + "=\"" + strings.Replace(value, ",", "\\,", -1) + "\""
}
return result
}

// getWait returns a partial helm command containing the helm wait flag (--wait) if the wait flag for the release was set to true
// Otherwise, retruns an empty string
func getWait(r *release) string {
Expand Down
86 changes: 47 additions & 39 deletions docs/desired_state_specification.md

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions example.toml
@@ -1,4 +1,4 @@
# version: v1.5.0
# version: v1.6.2
# metadata -- add as many key/value pairs as you want
[metadata]
org = "example.com"
Expand Down Expand Up @@ -74,8 +74,10 @@
protected = true
priority= -3
wait = true
[apps.jenkins.set] # values to override values from values.yaml with values from env vars or directly entered-- useful for passing secrets to charts
[apps.jenkins.setString] # values to override values from values.yaml with values from env vars or directly entered-- useful for passing secrets to charts
AdminPassword="$JENKINS_PASSWORD" # $JENKINS_PASSWORD must exist in the environment
MyLongIntVar="1234567890"
[apps.jenkins.set]
AdminUser="admin"


Expand Down
3 changes: 3 additions & 0 deletions example.yaml
Expand Up @@ -73,6 +73,9 @@ apps:
set: # values to override values from values.yaml with values from env vars-- useful for passing secrets to charts
AdminPassword: "$JENKINS_PASSWORD" # $JENKINS_PASSWORD must exist in the environment
AdminUser: "admin"
setString:
MyLongIntVar: "1234567890"


# artifactory will be deployed using the Tiller in the kube-system namespace
artifactory:
Expand Down
10 changes: 5 additions & 5 deletions init.go
Expand Up @@ -43,6 +43,7 @@ func init() {
flag.BoolVar(&apply, "apply", false, "apply the plan directly")
flag.BoolVar(&debug, "debug", false, "show the execution logs")
flag.BoolVar(&dryRun, "dry-run", false, "apply the dry-run option for helm commands.")
flag.BoolVar(&destroy, "destroy", false, "delete all deployed releases. Purge delete is used if the purge option is set to true for the releases.")
flag.BoolVar(&v, "v", false, "show the version")
flag.BoolVar(&verbose, "verbose", false, "show verbose execution logs")
flag.BoolVar(&noBanner, "no-banner", false, "don't show the banner")
Expand Down Expand Up @@ -71,6 +72,10 @@ func init() {
logError("ERROR: --apply and --dry-run can't be used together.")
}

if destroy && apply {
logError("ERROR: --destroy and --apply can't be used together.")
}

helmVersion = strings.TrimSpace(strings.SplitN(getHelmClientVersion(), ": ", 2)[1])
kubectlVersion = strings.TrimSpace(strings.SplitN(getKubectlClientVersion(), ": ", 2)[1])

Expand Down Expand Up @@ -128,11 +133,6 @@ func init() {
}
}

// print all env variables
// for _, pair := range os.Environ() {
// fmt.Println(pair)
// }

// read the TOML/YAML desired state file
var fileState state
for _, f := range files {
Expand Down
8 changes: 6 additions & 2 deletions main.go
Expand Up @@ -32,12 +32,13 @@ var checkCleanup bool
var skipValidation bool
var applyLabels bool
var keepUntrackedReleases bool
var appVersion = "v1.6.1"
var appVersion = "v1.6.2"
var helmVersion string
var kubectlVersion string
var pwd string
var relativeDir string
var dryRun bool
var destroy bool

func main() {
// set the kubecontext to be used Or create it if it does not exist
Expand Down Expand Up @@ -81,6 +82,9 @@ func main() {
}

log.Println("INFO: checking what I need to do for your charts ... ")
if destroy {
log.Println("WARN: --destroy is enabled. Your releases will be deleted!")
}

p := makePlan(&s)
if !keepUntrackedReleases {
Expand All @@ -91,7 +95,7 @@ func main() {
p.printPlan()
p.sendPlanToSlack()

if apply || dryRun {
if apply || dryRun || destroy {
p.execPlan()
}

Expand Down
37 changes: 24 additions & 13 deletions release.go
Expand Up @@ -5,28 +5,31 @@ import (
"log"
"os"
"strings"

version "github.com/hashicorp/go-version"
)

// release type representing Helm releases which are described in the desired state
type release struct {
Name string
Description string
Namespace string
Enabled bool
Chart string
Version string
Name string `yaml:"name"`
Description string `yaml:"description"`
Namespace string `yaml:"namespace"`
Enabled bool `yaml:"enabled"`
Chart string `yaml:"chart"`
Version string `yaml:"version"`
ValuesFile string `yaml:"valuesFile"`
ValuesFiles []string `yaml:"valuesFiles"`
SecretFile string `yaml:"secretFile"`
SecretFiles []string `yaml:"secretFiles"`
Purge bool
Test bool
Protected bool
Wait bool
Priority int
TillerNamespace string
Purge bool `yaml:"purge"`
Test bool `yaml:"test"`
Protected bool `yaml:"protected"`
Wait bool `yaml:"wait"`
Priority int `yaml:"priority"`
TillerNamespace string `yaml:"tillerNamespace"`
Set map[string]string
NoHooks bool
SetString map[string]string `yaml:"setString"`
NoHooks bool `yaml:"noHooks"`
Timeout int
}

Expand Down Expand Up @@ -105,6 +108,14 @@ func validateRelease(appLabel string, r *release, names map[string]map[string]bo
names[r.Name]["kube-system"] = true
}

if len(r.SetString) > 0 {
v1, _ := version.NewVersion(helmVersion)
setStringConstraint, _ := version.NewConstraint(">=2.9.0")
if !setStringConstraint.Check(v1) {
return false, "you are using setString in your desired state, but your helm client does not support it. You need helm v2.9.0 or above for this feature."
}
}

return true, ""
}

Expand Down
2 changes: 1 addition & 1 deletion test_files/dockerfile
Expand Up @@ -3,7 +3,7 @@
FROM golang:1.10-alpine3.7 as builder

ENV KUBE_VERSION v1.8.2
ENV HELM_VERSION v2.7.0
ENV HELM_VERSION v2.10.0

RUN apk add --update --no-cache ca-certificates git \
&& apk add --update -t deps curl tar gzip make bash \
Expand Down

0 comments on commit e179188

Please sign in to comment.