Skip to content

support helm 3 using exec #151

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions cmd/helm3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package cmd

import (
"io/ioutil"
"os"
"os/exec"
"strconv"
)

func getRelease(release, namespace string) ([]byte, error) {
args := []string{"get", "manifest", release}
if namespace != "" {
args = append(args, "--namespace", namespace)
}
cmd := exec.Command(os.Getenv("HELM_BIN"), args...)
return cmd.Output()
}

func getHooks(release, namespace string) ([]byte, error) {
args := []string{"get", "hooks", release}
if namespace != "" {
args = append(args, "--namespace", namespace)
}
cmd := exec.Command(os.Getenv("HELM_BIN"), args...)
return cmd.Output()
}

func getRevision(release string, revision int, namespace string) ([]byte, error) {
args := []string{"get", "manifest", release, "--revision", strconv.Itoa(revision)}
if namespace != "" {
args = append(args, "--namespace", namespace)
}
cmd := exec.Command(os.Getenv("HELM_BIN"), args...)
return cmd.Output()
}

func getChart(release, namespace string) (string, error) {
args := []string{"get", release, "--template", "{{.Release.Chart.Name}}"}
if namespace != "" {
args = append(args, "--namespace", namespace)
}
cmd := exec.Command(os.Getenv("HELM_BIN"), args...)
out, err := cmd.Output()
if err != nil {
return "", err
}
return string(out), nil
}

func (d *diffCmd) template() ([]byte, error) {
flags := []string{}
if d.devel {
flags = append(flags, "--devel")
}
if d.noHooks {
flags = append(flags, "--no-hooks")
}
if d.chartVersion != "" {
flags = append(flags, "--version", d.chartVersion)
}
if d.namespace != "" {
flags = append(flags, "--namespace", d.namespace)
}
if !d.resetValues {
if d.reuseValues {
tmpfile, err := ioutil.TempFile("", "existing-values")
if err != nil {
return nil, err
}
defer os.Remove(tmpfile.Name())
flags = append(flags, "--values", tmpfile.Name())
}
for _, value := range d.values {
flags = append(flags, "--set", value)
}
for _, stringValue := range d.stringValues {
flags = append(flags, "--set-string", stringValue)
}
for _, valueFile := range d.valueFiles {
flags = append(flags, "--values", valueFile)
}
for _, fileValue := range d.fileValues {
flags = append(flags, "--set-file", fileValue)
}
}

args := []string{"template", d.release, d.chart}
args = append(args, flags...)
cmd := exec.Command(os.Getenv("HELM_BIN"), args...)
return cmd.Output()
}

func (d *diffCmd) existingValues(f *os.File) error {
cmd := exec.Command(os.Getenv("HELM_BIN"), "get", "values", d.release, "--all")
defer f.Close()
cmd.Stdout = f
return cmd.Run()
}
7 changes: 7 additions & 0 deletions cmd/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ const (
tlsCaCertDefault = "$HELM_HOME/ca.pem"
tlsCertDefault = "$HELM_HOME/cert.pem"
tlsKeyDefault = "$HELM_HOME/key.pem"

helm2TestSuccessHook = "test-success"
helm3TestHook = "test"
)

var (
Expand All @@ -24,6 +27,10 @@ var (
DefaultHelmHome = filepath.Join(homedir.HomeDir(), ".helm")
)

func isHelm3() bool {
return os.Getenv("TILLER_HOST") == ""
}

func addCommonCmdOptions(f *flag.FlagSet) {
settings.AddFlagsTLS(f)
settings.InitTLS(f)
Expand Down
51 changes: 50 additions & 1 deletion cmd/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ func releaseCmd() *cobra.Command {
}

diff.releases = args[0:]
if isHelm3() {
return diff.differentiateHelm3()
}
if diff.client == nil {
diff.client = createHelmClient()
}
Expand All @@ -73,11 +76,57 @@ func releaseCmd() *cobra.Command {
releaseCmd.Flags().BoolVar(&diff.includeTests, "include-tests", false, "enable the diffing of the helm test hooks")
releaseCmd.SuggestionsMinimumDistance = 1

addCommonCmdOptions(releaseCmd.Flags())
if !isHelm3() {
addCommonCmdOptions(releaseCmd.Flags())
}

return releaseCmd
}

func (d *release) differentiateHelm3() error {
namespace := os.Getenv("HELM_NAMESPACE")
excludes := []string{helm3TestHook, helm2TestSuccessHook}
if d.includeTests {
excludes = []string{}
}
releaseResponse1, err := getRelease(d.releases[0], namespace)
if err != nil {
return err
}
releaseChart1, err := getChart(d.releases[0], namespace)
if err != nil {
return err
}

releaseResponse2, err := getRelease(d.releases[1], namespace)
if err != nil {
return err
}
releaseChart2, err := getChart(d.releases[1], namespace)
if err != nil {
return err
}

if releaseChart1 == releaseChart2 {
seenAnyChanges := diff.Releases(
manifest.Parse(string(releaseResponse1), namespace, excludes...),
manifest.Parse(string(releaseResponse2), namespace, excludes...),
d.suppressedKinds,
d.outputContext,
os.Stdout)

if d.detailedExitCode && seenAnyChanges {
return Error{
error: errors.New("identified at least one change, exiting with non-zero exit code (detailed-exitcode parameter enabled)"),
Code: 2,
}
}
} else {
fmt.Printf("Error : Incomparable Releases \n Unable to compare releases from two different charts \"%s\", \"%s\". \n try helm diff release --help to know more \n", releaseChart1, releaseChart2)
}
return nil
}

func (d *release) differentiate() error {

releaseResponse1, err := d.client.ReleaseContent(d.releases[0])
Expand Down
72 changes: 71 additions & 1 deletion cmd/revision.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ func revisionCmd() *cobra.Command {

diff.release = args[0]
diff.revisions = args[1:]
if isHelm3() {
return diff.differentiateHelm3()
}
if diff.client == nil {
diff.client = createHelmClient()
}
Expand All @@ -83,11 +86,78 @@ func revisionCmd() *cobra.Command {
revisionCmd.Flags().BoolVar(&diff.includeTests, "include-tests", false, "enable the diffing of the helm test hooks")
revisionCmd.SuggestionsMinimumDistance = 1

addCommonCmdOptions(revisionCmd.Flags())
if !isHelm3() {
addCommonCmdOptions(revisionCmd.Flags())
}

return revisionCmd
}

func (d *revision) differentiateHelm3() error {
namespace := os.Getenv("HELM_NAMESPACE")
excludes := []string{helm3TestHook, helm2TestSuccessHook}
if d.includeTests {
excludes = []string{}
}
switch len(d.revisions) {
case 1:
releaseResponse, err := getRelease(d.release, namespace)

if err != nil {
return err
}

revision, _ := strconv.Atoi(d.revisions[0])
revisionResponse, err := getRevision(d.release, revision, namespace)
if err != nil {
return err
}

diff.Manifests(
manifest.Parse(string(revisionResponse), namespace, excludes...),
manifest.Parse(string(releaseResponse), namespace, excludes...),
d.suppressedKinds,
d.outputContext,
os.Stdout)

case 2:
revision1, _ := strconv.Atoi(d.revisions[0])
revision2, _ := strconv.Atoi(d.revisions[1])
if revision1 > revision2 {
revision1, revision2 = revision2, revision1
}

revisionResponse1, err := getRevision(d.release, revision1, namespace)
if err != nil {
return prettyError(err)
}

revisionResponse2, err := getRevision(d.release, revision2, namespace)
if err != nil {
return prettyError(err)
}

seenAnyChanges := diff.Manifests(
manifest.Parse(string(revisionResponse1), namespace, excludes...),
manifest.Parse(string(revisionResponse2), namespace, excludes...),
d.suppressedKinds,
d.outputContext,
os.Stdout)

if d.detailedExitCode && seenAnyChanges {
return Error{
error: errors.New("identified at least one change, exiting with non-zero exit code (detailed-exitcode parameter enabled)"),
Code: 2,
}
}

default:
return errors.New("Invalid Arguments")
}

return nil
}

func (d *revision) differentiate() error {

switch len(d.revisions) {
Expand Down
46 changes: 45 additions & 1 deletion cmd/rollback.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ func rollbackCmd() *cobra.Command {
diff.release = args[0]
diff.revisions = args[1:]

if isHelm3() {
return diff.backcastHelm3()
}

if diff.client == nil {
diff.client = createHelmClient()
}
Expand All @@ -74,11 +78,51 @@ func rollbackCmd() *cobra.Command {
rollbackCmd.Flags().BoolVar(&diff.includeTests, "include-tests", false, "enable the diffing of the helm test hooks")
rollbackCmd.SuggestionsMinimumDistance = 1

addCommonCmdOptions(rollbackCmd.Flags())
if !isHelm3() {
addCommonCmdOptions(rollbackCmd.Flags())
}

return rollbackCmd
}

func (d *rollback) backcastHelm3() error {
namespace := os.Getenv("HELM_NAMESPACE")
excludes := []string{helm3TestHook, helm2TestSuccessHook}
if d.includeTests {
excludes = []string{}
}
// get manifest of the latest release
releaseResponse, err := getRelease(d.release, namespace)

if err != nil {
return err
}

// get manifest of the release to rollback
revision, _ := strconv.Atoi(d.revisions[0])
revisionResponse, err := getRevision(d.release, revision, namespace)
if err != nil {
return err
}

// create a diff between the current manifest and the version of the manifest that a user is intended to rollback
seenAnyChanges := diff.Manifests(
manifest.Parse(string(releaseResponse), namespace, excludes...),
manifest.Parse(string(revisionResponse), namespace, excludes...),
d.suppressedKinds,
d.outputContext,
os.Stdout)

if d.detailedExitCode && seenAnyChanges {
return Error{
error: errors.New("identified at least one change, exiting with non-zero exit code (detailed-exitcode parameter enabled)"),
Code: 2,
}
}

return nil
}

func (d *rollback) backcast() error {

// get manifest of the latest release
Expand Down
Loading