...

Source file src/helm.sh/helm/v3/pkg/action/lint.go

Documentation: helm.sh/helm/v3/pkg/action

     1  /*
     2  Copyright The Helm Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package action
    18  
    19  import (
    20  	"os"
    21  	"path/filepath"
    22  	"strings"
    23  
    24  	"github.com/pkg/errors"
    25  
    26  	"helm.sh/helm/v3/pkg/chartutil"
    27  	"helm.sh/helm/v3/pkg/lint"
    28  	"helm.sh/helm/v3/pkg/lint/support"
    29  )
    30  
    31  // Lint is the action for checking that the semantics of a chart are well-formed.
    32  //
    33  // It provides the implementation of 'helm lint'.
    34  type Lint struct {
    35  	Strict        bool
    36  	Namespace     string
    37  	WithSubcharts bool
    38  	Quiet         bool
    39  	KubeVersion   *chartutil.KubeVersion
    40  }
    41  
    42  // LintResult is the result of Lint
    43  type LintResult struct {
    44  	TotalChartsLinted int
    45  	Messages          []support.Message
    46  	Errors            []error
    47  }
    48  
    49  // NewLint creates a new Lint object with the given configuration.
    50  func NewLint() *Lint {
    51  	return &Lint{}
    52  }
    53  
    54  // Run executes 'helm Lint' against the given chart.
    55  func (l *Lint) Run(paths []string, vals map[string]interface{}) *LintResult {
    56  	lowestTolerance := support.ErrorSev
    57  	if l.Strict {
    58  		lowestTolerance = support.WarningSev
    59  	}
    60  	result := &LintResult{}
    61  	for _, path := range paths {
    62  		linter, err := lintChart(path, vals, l.Namespace, l.KubeVersion)
    63  		if err != nil {
    64  			result.Errors = append(result.Errors, err)
    65  			continue
    66  		}
    67  
    68  		result.Messages = append(result.Messages, linter.Messages...)
    69  		result.TotalChartsLinted++
    70  		for _, msg := range linter.Messages {
    71  			if msg.Severity >= lowestTolerance {
    72  				result.Errors = append(result.Errors, msg.Err)
    73  			}
    74  		}
    75  	}
    76  	return result
    77  }
    78  
    79  // HasWarningsOrErrors checks is LintResult has any warnings or errors
    80  func HasWarningsOrErrors(result *LintResult) bool {
    81  	for _, msg := range result.Messages {
    82  		if msg.Severity > support.InfoSev {
    83  			return true
    84  		}
    85  	}
    86  	return len(result.Errors) > 0
    87  }
    88  
    89  func lintChart(path string, vals map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion) (support.Linter, error) {
    90  	var chartPath string
    91  	linter := support.Linter{}
    92  
    93  	if strings.HasSuffix(path, ".tgz") || strings.HasSuffix(path, ".tar.gz") {
    94  		tempDir, err := os.MkdirTemp("", "helm-lint")
    95  		if err != nil {
    96  			return linter, errors.Wrap(err, "unable to create temp dir to extract tarball")
    97  		}
    98  		defer os.RemoveAll(tempDir)
    99  
   100  		file, err := os.Open(path)
   101  		if err != nil {
   102  			return linter, errors.Wrap(err, "unable to open tarball")
   103  		}
   104  		defer file.Close()
   105  
   106  		if err = chartutil.Expand(tempDir, file); err != nil {
   107  			return linter, errors.Wrap(err, "unable to extract tarball")
   108  		}
   109  
   110  		files, err := os.ReadDir(tempDir)
   111  		if err != nil {
   112  			return linter, errors.Wrapf(err, "unable to read temporary output directory %s", tempDir)
   113  		}
   114  		if !files[0].IsDir() {
   115  			return linter, errors.Errorf("unexpected file %s in temporary output directory %s", files[0].Name(), tempDir)
   116  		}
   117  
   118  		chartPath = filepath.Join(tempDir, files[0].Name())
   119  	} else {
   120  		chartPath = path
   121  	}
   122  
   123  	// Guard: Error out if this is not a chart.
   124  	if _, err := os.Stat(filepath.Join(chartPath, "Chart.yaml")); err != nil {
   125  		return linter, errors.Wrap(err, "unable to check Chart.yaml file in chart")
   126  	}
   127  
   128  	return lint.AllWithKubeVersion(chartPath, vals, namespace, kubeVersion), nil
   129  }
   130  

View as plain text