mirror of
https://github.com/helm/helm.git
synced 2026-08-05 07:30:46 +00:00
feat(template): introduce --validate
This feature flag allows `helm template` to be used against a live cluster. Some charts need CRDs to be applied to the cluster before calling `helm install`. This allows users to validate their templates will render with those resources set. Signed-off-by: Matthew Fisher <matt.fisher@microsoft.com>
This commit is contained in:
@@ -172,6 +172,7 @@ 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),
|
||||
|
||||
@@ -179,7 +180,6 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string
|
||||
newHomeCmd(out),
|
||||
newInitCmd(out),
|
||||
newPluginCmd(out),
|
||||
newTemplateCmd(out),
|
||||
newVersionCmd(out),
|
||||
|
||||
// Hidden documentation generator command: 'helm docs'
|
||||
|
||||
@@ -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 = `
|
||||
@@ -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]",
|
||||
@@ -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
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
@@ -70,6 +73,7 @@ type Install struct {
|
||||
ChartPathOptions
|
||||
ValueOptions
|
||||
|
||||
ClientOnly bool
|
||||
DryRun bool
|
||||
DisableHooks bool
|
||||
Replace bool
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
@@ -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 = ""
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user