// Values lints a chart's values.yaml file. func Values(linter *support.Linter) { vf := filepath.Join(linter.ChartDir, "values.yaml") fileExists := linter.RunLinterRule(support.InfoSev, validateValuesFileExistence(linter, vf)) if !fileExists { return } linter.RunLinterRule(support.ErrorSev, validateValuesFile(linter, vf)) }
// Chartfile runs a set of linter rules related to Chart.yaml file func Chartfile(linter *support.Linter) { chartFileName := "Chart.yaml" chartPath := filepath.Join(linter.ChartDir, chartFileName) linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartYamlNotDirectory(chartPath)) chartFile, err := chartutil.LoadChartfile(chartPath) validChartFile := linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartYamlFormat(err)) // Guard clause. Following linter rules require a parseable ChartFile if !validChartFile { return } linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartName(chartFile)) linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartNameDirMatch(linter.ChartDir, chartFile)) // Chart metadata linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartVersion(chartFile)) linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartEngine(chartFile)) linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartMaintainer(chartFile)) linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartSources(chartFile)) }
// Templates lints the templates in the Linter. func Templates(linter *support.Linter) { templatesPath := filepath.Join(linter.ChartDir, "templates") templatesDirExist := linter.RunLinterRule(support.WarningSev, validateTemplatesDir(templatesPath)) // Templates directory is optional for now if !templatesDirExist { return } // Load chart and parse templates, based on tiller/release_server chart, err := chartutil.Load(linter.ChartDir) chartLoaded := linter.RunLinterRule(support.ErrorSev, validateNoError(err)) if !chartLoaded { return } options := chartutil.ReleaseOptions{Name: "testRelease", Time: timeconv.Now(), Namespace: "testNamespace"} valuesToRender, err := chartutil.ToRenderValues(chart, chart.Values, options) if err != nil { // FIXME: This seems to generate a duplicate, but I can't find where the first // error is coming from. //linter.RunLinterRule(support.ErrorSev, err) return } renderedContentMap, err := engine.New().Render(chart, valuesToRender) renderOk := linter.RunLinterRule(support.ErrorSev, validateNoError(err)) if !renderOk { return } /* Iterate over all the templates to check: - It is a .yaml file - All the values in the template file is defined - {{}} include | quote - Generated content is a valid Yaml file - Metadata.Namespace is not set */ for _, template := range chart.Templates { fileName, preExecutedTemplate := template.Name, template.Data linter.RunLinterRule(support.ErrorSev, validateAllowedExtension(fileName)) // We only apply the following lint rules to yaml files if filepath.Ext(fileName) != ".yaml" { continue } // Check that all the templates have a matching value linter.RunLinterRule(support.WarningSev, validateNonMissingValues(fileName, templatesPath, valuesToRender, preExecutedTemplate)) linter.RunLinterRule(support.WarningSev, validateQuotes(fileName, string(preExecutedTemplate))) renderedContent := renderedContentMap[fileName] var yamlStruct K8sYamlStruct // Even though K8sYamlStruct only defines Metadata namespace, an error in any other // key will be raised as well err := yaml.Unmarshal([]byte(renderedContent), &yamlStruct) validYaml := linter.RunLinterRule(support.ErrorSev, validateYamlContent(fileName, err)) if !validYaml { continue } linter.RunLinterRule(support.ErrorSev, validateNoNamespace(fileName, yamlStruct)) } }