github.com/umeshredd/helm@v3.0.0-alpha.1+incompatible/pkg/action/lint.go (about)

     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  	"io/ioutil"
    21  	"os"
    22  	"path/filepath"
    23  	"strings"
    24  
    25  	"github.com/pkg/errors"
    26  
    27  	"helm.sh/helm/pkg/chartutil"
    28  	"helm.sh/helm/pkg/lint"
    29  	"helm.sh/helm/pkg/lint/support"
    30  )
    31  
    32  var errLintNoChart = errors.New("no chart found for linting (missing Chart.yaml)")
    33  
    34  // Lint is the action for checking that the semantics of a chart are well-formed.
    35  //
    36  // It provides the implementation of 'helm lint'.
    37  type Lint struct {
    38  	ValueOptions
    39  
    40  	Strict    bool
    41  	Namespace string
    42  }
    43  
    44  type LintResult struct {
    45  	TotalChartsLinted int
    46  	Messages          []support.Message
    47  	Errors            []error
    48  }
    49  
    50  // NewLint creates a new Lint object with the given configuration.
    51  func NewLint() *Lint {
    52  	return &Lint{}
    53  }
    54  
    55  // Run executes 'helm Lint' against the given chart.
    56  func (l *Lint) Run(paths []string) *LintResult {
    57  	lowestTolerance := support.ErrorSev
    58  	if l.Strict {
    59  		lowestTolerance = support.WarningSev
    60  	}
    61  
    62  	result := &LintResult{}
    63  	for _, path := range paths {
    64  		if linter, err := lintChart(path, l.ValueOptions.rawValues, l.Namespace, l.Strict); err != nil {
    65  			if err == errLintNoChart {
    66  				result.Errors = append(result.Errors, err)
    67  			}
    68  		} else {
    69  			result.Messages = append(result.Messages, linter.Messages...)
    70  			result.TotalChartsLinted++
    71  			if linter.HighestSeverity >= lowestTolerance {
    72  				result.Errors = append(result.Errors, err)
    73  			}
    74  		}
    75  	}
    76  	return result
    77  }
    78  
    79  func lintChart(path string, vals map[string]interface{}, namespace string, strict bool) (support.Linter, error) {
    80  	var chartPath string
    81  	linter := support.Linter{}
    82  
    83  	if strings.HasSuffix(path, ".tgz") {
    84  		tempDir, err := ioutil.TempDir("", "helm-lint")
    85  		if err != nil {
    86  			return linter, err
    87  		}
    88  		defer os.RemoveAll(tempDir)
    89  
    90  		file, err := os.Open(path)
    91  		if err != nil {
    92  			return linter, err
    93  		}
    94  		defer file.Close()
    95  
    96  		if err = chartutil.Expand(tempDir, file); err != nil {
    97  			return linter, err
    98  		}
    99  
   100  		lastHyphenIndex := strings.LastIndex(filepath.Base(path), "-")
   101  		if lastHyphenIndex <= 0 {
   102  			return linter, errors.Errorf("unable to parse chart archive %q, missing '-'", filepath.Base(path))
   103  		}
   104  		base := filepath.Base(path)[:lastHyphenIndex]
   105  		chartPath = filepath.Join(tempDir, base)
   106  	} else {
   107  		chartPath = path
   108  	}
   109  
   110  	// Guard: Error out of this is not a chart.
   111  	if _, err := os.Stat(filepath.Join(chartPath, "Chart.yaml")); err != nil {
   112  		return linter, errLintNoChart
   113  	}
   114  
   115  	return lint.All(chartPath, vals, namespace, strict), nil
   116  }