-
Notifications
You must be signed in to change notification settings - Fork 281
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #22 from aananthraj/feature/revision-diff
feature Implementation: Diff between Revisions #6
- Loading branch information
Showing
4 changed files
with
231 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package cmd | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"os" | ||
"strconv" | ||
|
||
"github.com/databus23/helm-diff/diff" | ||
"github.com/databus23/helm-diff/manifest" | ||
"github.com/spf13/cobra" | ||
"k8s.io/helm/pkg/helm" | ||
) | ||
|
||
type revision struct { | ||
release string | ||
client helm.Interface | ||
suppressedKinds []string | ||
revisions []string | ||
} | ||
|
||
const revisionCmdLongUsage = ` | ||
This command compares the manifests details of a named release. | ||
It can be used to compare the manifests of | ||
- lastest REVISION with specified REVISION | ||
$ helm diff revision [flags] RELEASE REVISION1 | ||
Example: | ||
$ helm diff revision my-release 2 | ||
- REVISION1 with REVISION2 | ||
$ helm diff revision [flags] RELEASE REVISION1 REVISION2 | ||
Example: | ||
$ helm diff revision my-release 2 3 | ||
` | ||
|
||
func revisionCmd() *cobra.Command { | ||
diff := revision{} | ||
revisionCmd := &cobra.Command{ | ||
Use: "revision [flags] RELEASE REVISION1 [REVISION2]", | ||
Short: "Shows diff between revision's manifests", | ||
Long: revisionCmdLongUsage, | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
if v, _ := cmd.Flags().GetBool("version"); v { | ||
fmt.Println(Version) | ||
return nil | ||
} | ||
|
||
switch { | ||
case len(args) < 2: | ||
return errors.New("Too few arguments to Command \"revision\".\nMinimum 2 arguments required: release name, revision") | ||
case len(args) > 3: | ||
return errors.New("Too many arguments to Command \"revision\".\nMaximum 3 arguments allowed: release name, revision1, revision2") | ||
} | ||
|
||
if q, _ := cmd.Flags().GetBool("suppress-secrets"); q { | ||
diff.suppressedKinds = append(diff.suppressedKinds, "Secret") | ||
} | ||
|
||
diff.release = args[0] | ||
diff.revisions = args[1:] | ||
if diff.client == nil { | ||
diff.client = helm.NewClient(helm.Host(os.Getenv("TILLER_HOST")), helm.ConnectTimeout(int64(30))) | ||
} | ||
return diff.differentiate() | ||
}, | ||
} | ||
|
||
revisionCmd.Flags().BoolP("suppress-secrets", "q", false, "suppress secrets in the output") | ||
revisionCmd.Flags().StringArrayVar(&diff.suppressedKinds, "suppress", []string{}, "allows suppression of the values listed in the diff output") | ||
revisionCmd.SuggestionsMinimumDistance = 1 | ||
return revisionCmd | ||
} | ||
|
||
func (d *revision) differentiate() error { | ||
|
||
switch len(d.revisions) { | ||
case 1: | ||
releaseResponse, err := d.client.ReleaseContent(d.release) | ||
|
||
if err != nil { | ||
return prettyError(err) | ||
} | ||
|
||
revision, _ := strconv.Atoi(d.revisions[0]) | ||
revisionResponse, err := d.client.ReleaseContent(d.release, helm.ContentReleaseVersion(int32(revision))) | ||
if err != nil { | ||
return prettyError(err) | ||
} | ||
|
||
diff.DiffManifests(manifest.Parse(revisionResponse.Release.Manifest), manifest.Parse(releaseResponse.Release.Manifest), d.suppressedKinds, 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 := d.client.ReleaseContent(d.release, helm.ContentReleaseVersion(int32(revision1))) | ||
if err != nil { | ||
return prettyError(err) | ||
} | ||
|
||
revisionResponse2, err := d.client.ReleaseContent(d.release, helm.ContentReleaseVersion(int32(revision2))) | ||
if err != nil { | ||
return prettyError(err) | ||
} | ||
|
||
diff.DiffManifests(manifest.Parse(revisionResponse1.Release.Manifest), manifest.Parse(revisionResponse2.Release.Manifest), d.suppressedKinds, os.Stdout) | ||
|
||
default: | ||
return errors.New("Invalid Arguments") | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"strconv" | ||
|
||
"github.com/databus23/helm-diff/diff" | ||
"github.com/databus23/helm-diff/manifest" | ||
"github.com/spf13/cobra" | ||
"k8s.io/helm/pkg/helm" | ||
) | ||
|
||
type rollback struct { | ||
release string | ||
client helm.Interface | ||
suppressedKinds []string | ||
revisions []string | ||
} | ||
|
||
const rollbackCmdLongUsage = ` | ||
This command compares the laset manifests details of a named release | ||
with specific revision values to rollback. | ||
It forecasts/visualizes changes, that a helm rollback could perform. | ||
` | ||
|
||
func rollbackCmd() *cobra.Command { | ||
diff := rollback{} | ||
rollbackCmd := &cobra.Command{ | ||
Use: "rollback [flags] [RELEASE] [REVISION]", | ||
Short: "Show a diff explaining what a helm rollback could perform", | ||
Long: rollbackCmdLongUsage, | ||
Example: " helm diff rollback my-release 2", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
if v, _ := cmd.Flags().GetBool("version"); v { | ||
fmt.Println(Version) | ||
return nil | ||
} | ||
|
||
if err := checkArgsLength(len(args), "release name", "revision number"); err != nil { | ||
return err | ||
} | ||
|
||
if q, _ := cmd.Flags().GetBool("suppress-secrets"); q { | ||
diff.suppressedKinds = append(diff.suppressedKinds, "Secret") | ||
} | ||
|
||
diff.release = args[0] | ||
diff.revisions = args[1:] | ||
|
||
if diff.client == nil { | ||
diff.client = helm.NewClient(helm.Host(os.Getenv("TILLER_HOST")), helm.ConnectTimeout(int64(30))) | ||
} | ||
|
||
return diff.backcast() | ||
}, | ||
} | ||
|
||
rollbackCmd.Flags().BoolP("suppress-secrets", "q", false, "suppress secrets in the output") | ||
rollbackCmd.Flags().StringArrayVar(&diff.suppressedKinds, "suppress", []string{}, "allows suppression of the values listed in the diff output") | ||
rollbackCmd.SuggestionsMinimumDistance = 1 | ||
return rollbackCmd | ||
} | ||
|
||
func (d *rollback) backcast() error { | ||
|
||
// get manifest of the latest release | ||
releaseResponse, err := d.client.ReleaseContent(d.release) | ||
|
||
if err != nil { | ||
return prettyError(err) | ||
} | ||
|
||
// get manifest of the release to rollback | ||
revision, _ := strconv.Atoi(d.revisions[0]) | ||
revisionResponse, err := d.client.ReleaseContent(d.release, helm.ContentReleaseVersion(int32(revision))) | ||
if err != nil { | ||
return prettyError(err) | ||
} | ||
|
||
// create a diff between the current manifest and the version of the manifest that a user is intended to rollback | ||
diff.DiffManifests(manifest.Parse(releaseResponse.Release.Manifest), manifest.Parse(revisionResponse.Release.Manifest), d.suppressedKinds, os.Stdout) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,41 @@ | ||
package cmd | ||
|
||
import "github.com/spf13/cobra" | ||
import ( | ||
"github.com/mgutz/ansi" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func New() *cobra.Command { | ||
|
||
chartCommand := newChartCommand() | ||
|
||
cmd := &cobra.Command{ | ||
Use: "diff", | ||
Short: "Show manifest differences", | ||
//Alias root command to chart subcommand | ||
Args: chartCommand.Args, | ||
// parse the flags and check for actions like suppress-secrets, no-colors | ||
PersistentPreRun: func(cmd *cobra.Command, args []string) { | ||
if nc, _ := cmd.Flags().GetBool("no-color"); nc { | ||
ansi.DisableColors(true) | ||
} | ||
}, | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
cmd.Println(`Command "helm diff" is deprecated, use "helm diff upgrade" instead`) | ||
return chartCommand.RunE(cmd, args) | ||
}, | ||
} | ||
|
||
chartCommand := newChartCommand() | ||
cmd.AddCommand(newVersionCmd(), chartCommand) | ||
//Alias root command to chart subcommand | ||
cmd.Args = chartCommand.Args | ||
// add no-color as global flag | ||
cmd.PersistentFlags().Bool("no-color", false, "remove colors from the output") | ||
// add flagset from chartCommand | ||
cmd.Flags().AddFlagSet(chartCommand.Flags()) | ||
cmd.RunE = func(cmd *cobra.Command, args []string) error { | ||
cmd.Println(`Command "helm diff" is deprecated, use "helm diff upgrade" instead`) | ||
return chartCommand.RunE(cmd, args) | ||
} | ||
cmd.AddCommand(newVersionCmd(), chartCommand) | ||
// add subcommands | ||
cmd.AddCommand( | ||
revisionCmd(), | ||
rollbackCmd(), | ||
) | ||
cmd.SetHelpCommand(&cobra.Command{}) // Disable the help command | ||
|
||
return cmd | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters