github.com/aaronmell/helm@v3.0.0-beta.2+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  	Strict    bool
    39  	Namespace string
    40  }
    41  
    42  type LintResult struct {
    43  	TotalChartsLinted int
    44  	Messages          []support.Message
    45  	Errors            []error
    46  }
    47  
    48  // NewLint creates a new Lint object with the given configuration.
    49  func NewLint() *Lint {
    50  	return &Lint{}
    51  }
    52  
    53  // Run executes 'helm Lint' against the given chart.
    54  func (l *Lint) Run(paths []string, vals map[string]interface{}) *LintResult {
    55  	lowestTolerance := support.ErrorSev
    56  	if l.Strict {
    57  		lowestTolerance = support.WarningSev
    58  	}
    59  
    60  	result := &LintResult{}
    61  	for _, path := range paths {
    62  		linter, err := lintChart(path, vals, l.Namespace, l.Strict)
    63  		if err != nil {
    64  			if err == errLintNoChart {
    65  				result.Errors = append(result.Errors, err)
    66  			}
    67  			if linter.HighestSeverity >= lowestTolerance {
    68  				result.Errors = append(result.Errors, err)
    69  			}
    70  		} else {
    71  			result.Messages = append(result.Messages, linter.Messages...)
    72  			result.TotalChartsLinted++
    73  			for _, msg := range linter.Messages {
    74  				if msg.Severity == support.ErrorSev {
    75  					result.Errors = append(result.Errors, msg.Err)
    76  					result.Messages = append(result.Messages, msg)
    77  				}
    78  			}
    79  		}
    80  	}
    81  	return result
    82  }
    83  
    84  func lintChart(path string, vals map[string]interface{}, namespace string, strict bool) (support.Linter, error) {
    85  	var chartPath string
    86  	linter := support.Linter{}
    87  	currentVals := make(map[string]interface{}, len(vals))
    88  	for key, value := range vals {
    89  		currentVals[key] = value
    90  	}
    91  
    92  	if strings.HasSuffix(path, ".tgz") {
    93  		tempDir, err := ioutil.TempDir("", "helm-lint")
    94  		if err != nil {
    95  			return linter, err
    96  		}
    97  		defer os.RemoveAll(tempDir)
    98  
    99  		file, err := os.Open(path)
   100  		if err != nil {
   101  			return linter, err
   102  		}
   103  		defer file.Close()
   104  
   105  		if err = chartutil.Expand(tempDir, file); err != nil {
   106  			return linter, err
   107  		}
   108  
   109  		lastHyphenIndex := strings.LastIndex(filepath.Base(path), "-")
   110  		if lastHyphenIndex <= 0 {
   111  			return linter, errors.Errorf("unable to parse chart archive %q, missing '-'", filepath.Base(path))
   112  		}
   113  		base := filepath.Base(path)[:lastHyphenIndex]
   114  		chartPath = filepath.Join(tempDir, base)
   115  	} else {
   116  		chartPath = path
   117  	}
   118  
   119  	// Guard: Error out of this is not a chart.
   120  	if _, err := os.Stat(filepath.Join(chartPath, "Chart.yaml")); err != nil {
   121  		return linter, errLintNoChart
   122  	}
   123  
   124  	return lint.All(chartPath, currentVals, namespace, strict), nil
   125  }