lint: lint all documents in a multi-doc yaml file

Signed-off-by: Nandor Kracser <bonifaido@gmail.com>
pull/8862/head
Nandor Kracser 4 years ago
parent 6ca989e777
commit dfb5a5e8cc
No known key found for this signature in database
GPG Key ID: 7A4C93C7D6B80413

@ -20,6 +20,7 @@ import (
"bufio"
"bytes"
"fmt"
"io"
"os"
"path"
"path/filepath"
@ -27,7 +28,7 @@ import (
"strings"
"github.com/pkg/errors"
"sigs.k8s.io/yaml"
"k8s.io/apimachinery/pkg/util/yaml"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/chartutil"
@ -117,20 +118,30 @@ func Templates(linter *support.Linter, values map[string]interface{}, namespace
renderedContent := renderedContentMap[path.Join(chart.Name(), fileName)]
if strings.TrimSpace(renderedContent) != "" {
linter.RunLinterRule(support.WarningSev, fpath, validateTopIndentLevel(renderedContent))
var yamlStruct K8sYamlStruct
// Even though K8sYamlStruct only defines a few fields, an error in any other
// key will be raised as well
err := yaml.Unmarshal([]byte(renderedContent), &yamlStruct)
if (K8sYamlStruct{}) == yamlStruct {
continue
decoder := yaml.NewYAMLOrJSONDecoder(strings.NewReader(renderedContent), 4096)
// Lint all resources if the file contains multiple documents separated by ---
for {
// Even though K8sYamlStruct only defines a few fields, an error in any other
// key will be raised as well
var yamlStruct *K8sYamlStruct
err := decoder.Decode(&yamlStruct)
if err == io.EOF {
break
}
// If YAML linting fails, we sill progress. So we don't capture the returned state
// on this linter run.
linter.RunLinterRule(support.ErrorSev, fpath, validateYamlContent(err))
if yamlStruct != nil {
linter.RunLinterRule(support.ErrorSev, fpath, validateMetadataName(yamlStruct))
linter.RunLinterRule(support.ErrorSev, fpath, validateNoDeprecations(yamlStruct))
linter.RunLinterRule(support.ErrorSev, fpath, validateMatchSelector(yamlStruct, renderedContent))
}
}
// If YAML linting fails, we sill progress. So we don't capture the returned state
// on this linter run.
linter.RunLinterRule(support.ErrorSev, fpath, validateYamlContent(err))
linter.RunLinterRule(support.ErrorSev, fpath, validateMetadataName(&yamlStruct))
linter.RunLinterRule(support.ErrorSev, fpath, validateNoDeprecations(&yamlStruct))
linter.RunLinterRule(support.ErrorSev, fpath, validateMatchSelector(&yamlStruct, renderedContent))
}
}
}

@ -107,6 +107,20 @@ func TestV3Fail(t *testing.T) {
}
}
func TestMultiTemplateFail(t *testing.T) {
linter := support.Linter{ChartDir: "./testdata/multi-template-fail"}
Templates(&linter, values, namespace, strict)
res := linter.Messages
if len(res) != 1 {
t.Fatalf("Expected 1 error, got %d, %v", len(res), res)
}
if !strings.Contains(res[0].Err.Error(), "object name does not conform to Kubernetes naming requirements") {
t.Errorf("Unexpected error: %s", res[0].Err)
}
}
func TestValidateMetadataName(t *testing.T) {
names := map[string]bool{
"": false,

@ -0,0 +1,21 @@
apiVersion: v2
name: multi-template-fail
description: A Helm chart for Kubernetes
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: 1.16.0

@ -0,0 +1,13 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: game-config
data:
game.properties: cheat
---
apiVersion: v1
kind: ConfigMap
metadata:
name: -this:name-is-not_valid$
data:
game.properties: empty
Loading…
Cancel
Save