feat(template): Allow template to connect to the cluster if the user so requests.

Signed-off-by: Sergio Morales <sergio@cornershopapp.com>
pull/8379/head
Sergio Morales 5 years ago
parent 97774ee13c
commit 08b27ad74e
No known key found for this signature in database
GPG Key ID: D58EBB258D258A01

@ -43,6 +43,10 @@ import (
// FeatureGateOCI is the feature gate for checking if `helm chart` and `helm registry` commands should work
const FeatureGateOCI = gates.Gate("HELM_EXPERIMENTAL_OCI")
// UnsafeTemplateLiveConn handles unsafe-template-live-conn arg as env var
// to simplify the integration with third party tools and plugins.
const UnsafeTemplateLiveConn = gates.Gate("HELM_UNSAFE_TEMPLATE_LIVE_CONN")
var settings = cli.New()
func init() {

@ -45,6 +45,7 @@ faked locally. Additionally, none of the server-side testing of chart validity
func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
var validate bool
var includeCrds bool
var unsafeTemplateLiveConn bool
client := action.NewInstall(cfg)
valueOpts := &values.Options{}
var extraAPIs []string
@ -59,6 +60,7 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
return compInstall(args, toComplete, client)
},
RunE: func(_ *cobra.Command, args []string) error {
client.UnsafeTemplateLiveConn = unsafeTemplateLiveConn || UnsafeTemplateLiveConn.IsEnabled()
client.DryRun = true
client.ReleaseName = "RELEASE-NAME"
client.Replace = true // Skip the name check
@ -147,6 +149,7 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
f.BoolVar(&client.IsUpgrade, "is-upgrade", false, "set .Release.IsUpgrade instead of .Release.IsInstall")
f.StringArrayVarP(&extraAPIs, "api-versions", "a", []string{}, "Kubernetes api versions used for Capabilities.APIVersions")
f.BoolVar(&client.UseReleaseName, "release-name", false, "use release name in the output-dir path.")
f.BoolVar(&unsafeTemplateLiveConn, "unsafe-template-live-conn", false, "enables the connection to the cluster. It is considered unsafe use under your own risk.")
bindPostRenderFlag(cmd, &client.PostRenderer)
return cmd

@ -97,7 +97,7 @@ type Configuration struct {
// renderResources renders the templates in a chart
//
// TODO: This function is badly in need of a refactor.
func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, releaseName, outputDir string, subNotes, useReleaseName, includeCrds bool, pr postrender.PostRenderer, dryRun bool) ([]*release.Hook, *bytes.Buffer, string, error) {
func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, releaseName, outputDir string, subNotes, useReleaseName, includeCrds bool, pr postrender.PostRenderer, dryRun bool, unsafeTemplateLiveConn bool) ([]*release.Hook, *bytes.Buffer, string, error) {
hs := []*release.Hook{}
b := bytes.NewBuffer(nil)
@ -119,15 +119,34 @@ func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values
// It will break in interesting and exotic ways because other data (e.g. discovery)
// is mocked. It is not up to the template author to decide when the user wants to
// connect to the cluster. So when the user says to dry run, respect the user's
// wishes and do not connect to the cluster.
if !dryRun && c.RESTClientGetter != nil {
// wishes and do not connect to the cluster
// When the user uses `helm template --unsafe-template-live-conn` we understand that wants
// to use a live cluster connection.
if unsafeTemplateLiveConn && c.RESTClientGetter != nil {
rest, err := c.RESTClientGetter.ToRESTConfig()
if err != nil {
return hs, b, "", err
}
files, err2 = engine.RenderWithClient(ch, values, rest)
} else {
files, err2 = engine.Render(ch, values)
}
if err2 != nil {
return hs, b, "", err2
}
// When templateLive is false then `helm template` was not invoked.
if len(files) == 0 {
if !dryRun && c.RESTClientGetter != nil {
rest, err := c.RESTClientGetter.ToRESTConfig()
if err != nil {
return hs, b, "", err
}
files, err2 = engine.RenderWithClient(ch, values, rest)
} else {
files, err2 = engine.Render(ch, values)
}
}
if err2 != nil {

@ -100,6 +100,8 @@ type Install struct {
// OutputDir/<ReleaseName>
UseReleaseName bool
PostRenderer postrender.PostRenderer
// Handle case when user wants to retrieve date from the cluster during template
UnsafeTemplateLiveConn bool
}
// ChartPathOptions captures common options used for controlling chart paths
@ -236,7 +238,7 @@ func (i *Install) Run(chrt *chart.Chart, vals map[string]interface{}) (*release.
rel := i.createRelease(chrt, vals)
var manifestDoc *bytes.Buffer
rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.SubNotes, i.UseReleaseName, i.IncludeCRDs, i.PostRenderer, i.DryRun)
rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.SubNotes, i.UseReleaseName, i.IncludeCRDs, i.PostRenderer, i.DryRun, i.UnsafeTemplateLiveConn)
// Even for errors, attach this if available
if manifestDoc != nil {
rel.Manifest = manifestDoc.String()

@ -217,7 +217,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[strin
return nil, nil, err
}
hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", u.SubNotes, false, false, u.PostRenderer, u.DryRun)
hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", u.SubNotes, false, false, u.PostRenderer, u.DryRun, false)
if err != nil {
return nil, nil, err
}

Loading…
Cancel
Save