diff --git a/pkg/action/lint.go b/pkg/action/lint.go index ca497f2b8..b15d4352f 100644 --- a/pkg/action/lint.go +++ b/pkg/action/lint.go @@ -59,7 +59,7 @@ func (l *Lint) Run(paths []string, vals map[string]interface{}) *LintResult { } result := &LintResult{} for _, path := range paths { - linter, err := lintChart(path, vals, l.Namespace, l.KubeVersion) + linter, err := lintChart(path, vals, l.Namespace, l.KubeVersion, l.Quiet) if err != nil { result.Errors = append(result.Errors, err) continue @@ -86,7 +86,7 @@ func HasWarningsOrErrors(result *LintResult) bool { return len(result.Errors) > 0 } -func lintChart(path string, vals map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion) (support.Linter, error) { +func lintChart(path string, vals map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion, quiet bool) (support.Linter, error) { var chartPath string linter := support.Linter{} @@ -125,5 +125,5 @@ func lintChart(path string, vals map[string]interface{}, namespace string, kubeV return linter, errors.Wrap(err, "unable to check Chart.yaml file in chart") } - return lint.AllWithKubeVersion(chartPath, vals, namespace, kubeVersion), nil + return lint.AllWithKubeVersion(chartPath, vals, namespace, kubeVersion, quiet), nil } diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 058cfa749..4a6a4f9f5 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -40,6 +40,8 @@ type Engine struct { Strict bool // In LintMode, some 'required' template values may be missing, so don't fail LintMode bool + // If quiet is enabled, suppress INFO messages + Quiet bool // optional provider of clients to talk to the Kubernetes API clientProvider *ClientProvider // EnableDNS tells the engine to allow DNS lookups when rendering templates @@ -145,7 +147,7 @@ func includeFun(t *template.Template, includedNames map[string]int) func(string, // As does 'tpl', so that nested calls to 'tpl' see the templates // defined by their enclosing contexts. -func tplFun(parent *template.Template, includedNames map[string]int, strict bool) func(string, interface{}) (string, error) { +func tplFun(parent *template.Template, includedNames map[string]int, strict bool, quiet bool) func(string, interface{}) (string, error) { return func(tpl string, vals interface{}) (string, error) { t, err := parent.Clone() if err != nil { @@ -165,7 +167,7 @@ func tplFun(parent *template.Template, includedNames map[string]int, strict bool // this lets any 'define's inside tpl be 'include'd. t.Funcs(template.FuncMap{ "include": includeFun(t, includedNames), - "tpl": tplFun(t, includedNames, strict), + "tpl": tplFun(t, includedNames, strict, quiet), }) // We need a .New template, as template text which is just blanks @@ -184,6 +186,11 @@ func tplFun(parent *template.Template, includedNames map[string]int, strict bool return "", errors.Wrapf(err, "error during tpl function execution for %q", tpl) } + // Supress INFO messages if quiet mode is enabled + if quiet { + return strings.ReplaceAll(buf.String(), "[INFO]", ""), nil + } + // See comment in renderWithReferences explaining the hack. return strings.ReplaceAll(buf.String(), "", ""), nil } @@ -196,22 +203,26 @@ func (e Engine) initFunMap(t *template.Template) { // Add the template-rendering functions here so we can close over t. funcMap["include"] = includeFun(t, includedNames) - funcMap["tpl"] = tplFun(t, includedNames, e.Strict) + funcMap["tpl"] = tplFun(t, includedNames, e.Strict, e.Quiet) // Add the `required` function here so we can use lintMode funcMap["required"] = func(warn string, val interface{}) (interface{}, error) { if val == nil { if e.LintMode { // Don't fail on missing required values when linting - log.Printf("[INFO] Missing required value: %s", warn) - return "", nil + if !e.Quiet { + log.Printf("[INFO] Missing required value: %s", warn) + } + return val, nil } return val, errors.Errorf(warnWrap(warn)) } else if _, ok := val.(string); ok { if val == "" { if e.LintMode { // Don't fail on missing required values when linting - log.Printf("[INFO] Missing required value: %s", warn) + if !e.Quiet { + log.Printf("[INFO] Missing required value: %s", warn) + } return "", nil } return val, errors.Errorf(warnWrap(warn)) @@ -224,7 +235,9 @@ func (e Engine) initFunMap(t *template.Template) { funcMap["fail"] = func(msg string) (string, error) { if e.LintMode { // Don't fail when linting - log.Printf("[INFO] Fail: %s", msg) + if !e.Quiet { // Check if --quiet flag is not set + log.Printf("[INFO] Fail: %s", msg) + } return "", nil } return "", errors.New(warnWrap(msg)) diff --git a/pkg/lint/lint.go b/pkg/lint/lint.go index c0e79f55b..9e7406235 100644 --- a/pkg/lint/lint.go +++ b/pkg/lint/lint.go @@ -25,19 +25,19 @@ import ( ) // All runs all of the available linters on the given base directory. -func All(basedir string, values map[string]interface{}, namespace string, _ bool) support.Linter { - return AllWithKubeVersion(basedir, values, namespace, nil) +func All(basedir string, values map[string]interface{}, namespace string, quiet bool) support.Linter { + return AllWithKubeVersion(basedir, values, namespace, nil, quiet) } // AllWithKubeVersion runs all the available linters on the given base directory, allowing to specify the kubernetes version. -func AllWithKubeVersion(basedir string, values map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion) support.Linter { +func AllWithKubeVersion(basedir string, values map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion, quiet bool) support.Linter { // Using abs path to get directory context chartDir, _ := filepath.Abs(basedir) linter := support.Linter{ChartDir: chartDir} rules.Chartfile(&linter) rules.ValuesWithOverrides(&linter, values) - rules.TemplatesWithKubeVersion(&linter, values, namespace, kubeVersion) + rules.TemplatesWithKubeVersion(&linter, values, namespace, kubeVersion, quiet) rules.Dependencies(&linter) return linter } diff --git a/pkg/lint/rules/template.go b/pkg/lint/rules/template.go index 661c7f963..69242e729 100644 --- a/pkg/lint/rules/template.go +++ b/pkg/lint/rules/template.go @@ -45,12 +45,12 @@ var ( ) // Templates lints the templates in the Linter. -func Templates(linter *support.Linter, values map[string]interface{}, namespace string, _ bool) { - TemplatesWithKubeVersion(linter, values, namespace, nil) +func Templates(linter *support.Linter, values map[string]interface{}, namespace string, quiet bool) { + TemplatesWithKubeVersion(linter, values, namespace, nil, quiet) } // TemplatesWithKubeVersion lints the templates in the Linter, allowing to specify the kubernetes version. -func TemplatesWithKubeVersion(linter *support.Linter, values map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion) { +func TemplatesWithKubeVersion(linter *support.Linter, values map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion, quiet bool) { fpath := "templates/" templatesPath := filepath.Join(linter.ChartDir, fpath) @@ -98,6 +98,7 @@ func TemplatesWithKubeVersion(linter *support.Linter, values map[string]interfac } var e engine.Engine e.LintMode = true + e.Quiet = quiet renderedContentMap, err := e.Render(chart, valuesToRender) renderOk := linter.RunLinterRule(support.ErrorSev, fpath, err)