Skip to content

Commit

Permalink
Merge pull request helm#6049 from bacongobbler/helm-template-schema-v…
Browse files Browse the repository at this point in the history
…alidation

feat(template): introduce --validate
  • Loading branch information
Matthew Fisher authored Jul 23, 2019
2 parents 7ddd3f4 + 7de9124 commit 97e7461
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 27 deletions.
2 changes: 1 addition & 1 deletion cmd/helm/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,14 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string
newReleaseTestCmd(actionConfig, out),
newRollbackCmd(actionConfig, out),
newStatusCmd(actionConfig, out),
newTemplateCmd(actionConfig, out),
newUninstallCmd(actionConfig, out),
newUpgradeCmd(actionConfig, out),

newCompletionCmd(out),
newHomeCmd(out),
newInitCmd(out),
newPluginCmd(out),
newTemplateCmd(out),
newVersionCmd(out),

// Hidden documentation generator command: 'helm docs'
Expand Down
32 changes: 8 additions & 24 deletions cmd/helm/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,12 @@ package main
import (
"fmt"
"io"
"io/ioutil"
"strings"

"github.com/spf13/cobra"
"github.com/spf13/pflag"

"helm.sh/helm/cmd/helm/require"
"helm.sh/helm/pkg/action"
"helm.sh/helm/pkg/chartutil"
kubefake "helm.sh/helm/pkg/kube/fake"
"helm.sh/helm/pkg/storage"
"helm.sh/helm/pkg/storage/driver"
)

const templateDesc = `
Expand All @@ -42,18 +36,9 @@ of the server-side testing of chart validity (e.g. whether an API is supported)
is done.
`

func newTemplateCmd(out io.Writer) *cobra.Command {
customConfig := &action.Configuration{
// Add mock objects in here so it doesn't use Kube API server
Releases: storage.Init(driver.NewMemory()),
KubeClient: &kubefake.PrintingKubeClient{Out: ioutil.Discard},
Capabilities: chartutil.DefaultCapabilities,
Log: func(format string, v ...interface{}) {
fmt.Fprintf(out, format, v...)
},
}

client := action.NewInstall(customConfig)
func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
var validate bool
client := action.NewInstall(cfg)

cmd := &cobra.Command{
Use: "template [NAME] [CHART]",
Expand All @@ -64,6 +49,7 @@ func newTemplateCmd(out io.Writer) *cobra.Command {
client.DryRun = true
client.ReleaseName = "RELEASE-NAME"
client.Replace = true // Skip the name check
client.ClientOnly = !validate
rel, err := runInstall(args, client, out)
if err != nil {
return err
Expand All @@ -73,12 +59,10 @@ func newTemplateCmd(out io.Writer) *cobra.Command {
},
}

addInstallFlags(cmd.Flags(), client)
addTemplateFlags(cmd.Flags(), client)
f := cmd.Flags()
addInstallFlags(f, client)
f.StringVar(&client.OutputDir, "output-dir", "", "writes the executed templates to files in output-dir instead of stdout")
f.BoolVar(&validate, "validate", false, "establish a connection to Kubernetes for schema validation")

return cmd
}

func addTemplateFlags(f *pflag.FlagSet, client *action.Install) {
f.StringVar(&client.OutputDir, "output-dir", "", "writes the executed templates to files in output-dir instead of stdout")
}
12 changes: 12 additions & 0 deletions pkg/action/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ import (
"helm.sh/helm/pkg/engine"
"helm.sh/helm/pkg/getter"
"helm.sh/helm/pkg/hooks"
kubefake "helm.sh/helm/pkg/kube/fake"
"helm.sh/helm/pkg/release"
"helm.sh/helm/pkg/releaseutil"
"helm.sh/helm/pkg/repo"
"helm.sh/helm/pkg/storage"
"helm.sh/helm/pkg/storage/driver"
"helm.sh/helm/pkg/strvals"
"helm.sh/helm/pkg/version"
)
Expand All @@ -70,6 +73,7 @@ type Install struct {
ChartPathOptions
ValueOptions

ClientOnly bool
DryRun bool
DisableHooks bool
Replace bool
Expand Down Expand Up @@ -119,6 +123,14 @@ func (i *Install) Run(chrt *chart.Chart) (*release.Release, error) {
return nil, err
}

if i.ClientOnly {
// Add mock objects in here so it doesn't use Kube API server
// NOTE(bacongobbler): used for `helm template`
i.cfg.Capabilities = chartutil.DefaultCapabilities
i.cfg.KubeClient = &kubefake.PrintingKubeClient{Out: ioutil.Discard}
i.cfg.Releases = storage.Init(driver.NewMemory())
}

// Make sure if Atomic is set, that wait is set as well. This makes it so
// the user doesn't have to specify both
i.Wait = i.Wait || i.Atomic
Expand Down
15 changes: 13 additions & 2 deletions pkg/action/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ import (
"github.com/stretchr/testify/assert"

"helm.sh/helm/internal/test"
"helm.sh/helm/pkg/chartutil"
kubefake "helm.sh/helm/pkg/kube/fake"
"helm.sh/helm/pkg/release"
"helm.sh/helm/pkg/storage/driver"
kubefake "helm.sh/helm/pkg/kube/fake"
)

type nameTemplateTestCase struct {
Expand Down Expand Up @@ -74,6 +75,16 @@ func TestInstallRelease(t *testing.T) {
is.Equal(rel.Info.Description, "Install complete")
}

func TestInstallReleaseClientOnly(t *testing.T) {
is := assert.New(t)
instAction := installAction(t)
instAction.ClientOnly = true
instAction.Run(buildChart()) // disregard output

is.Equal(instAction.cfg.Capabilities, chartutil.DefaultCapabilities)
is.Equal(instAction.cfg.KubeClient, &kubefake.PrintingKubeClient{Out: ioutil.Discard})
}

func TestInstallRelease_NoName(t *testing.T) {
instAction := installAction(t)
instAction.ReleaseName = ""
Expand Down Expand Up @@ -278,7 +289,7 @@ func TestInstallRelease_Atomic(t *testing.T) {
is.Error(err)
is.Equal(err, driver.ErrReleaseNotFound)
})

t.Run("atomic uninstall fails", func(t *testing.T) {
instAction := installAction(t)
instAction.ReleaseName = "come-fail-away-with-me"
Expand Down

0 comments on commit 97e7461

Please sign in to comment.