diff --git a/go.mod b/go.mod index 0183199e..a0ce457b 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,7 @@ require ( k8s.io/apimachinery v0.22.2 k8s.io/cli-runtime v0.22.2 k8s.io/client-go v0.22.2 - k8s.io/helm v2.16.0+incompatible + k8s.io/helm v2.17.0+incompatible k8s.io/klog v1.0.0 sigs.k8s.io/controller-runtime v0.10.2 sigs.k8s.io/kind v0.10.0 diff --git a/go.sum b/go.sum index d347b92c..2b726958 100644 --- a/go.sum +++ b/go.sum @@ -1674,8 +1674,9 @@ k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8 k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/helm v2.16.0+incompatible h1:btXM7zx8MHBmnuO8KQH07rkw65tH2gYU+IMqz1xC++M= k8s.io/helm v2.16.0+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= +k8s.io/helm v2.17.0+incompatible h1:Bpn6o1wKLYqKM3+Osh8e+1/K2g/GsQJ4F4yNF2+deao= +k8s.io/helm v2.17.0+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.2.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= diff --git a/vendor/k8s.io/helm/pkg/chartutil/create.go b/vendor/k8s.io/helm/pkg/chartutil/create.go index 8bab7942..d8480f54 100644 --- a/vendor/k8s.io/helm/pkg/chartutil/create.go +++ b/vendor/k8s.io/helm/pkg/chartutil/create.go @@ -74,7 +74,7 @@ serviceAccount: create: true # The name of the service account to use. # If not set and create is true, a name is generated using the fullname template - name: + name: "" podSecurityContext: {} # fsGroup: 2000 diff --git a/vendor/k8s.io/helm/pkg/chartutil/requirements.go b/vendor/k8s.io/helm/pkg/chartutil/requirements.go index 4c971323..0bd16d2e 100644 --- a/vendor/k8s.io/helm/pkg/chartutil/requirements.go +++ b/vendor/k8s.io/helm/pkg/chartutil/requirements.go @@ -17,7 +17,9 @@ package chartutil import ( "errors" + "fmt" "log" + "regexp" "strings" "time" @@ -219,6 +221,9 @@ func ProcessRequirementsTags(reqs *Requirements, cvals Values) { } +// Validate alias names against this regexp +var aliasRegexp = regexp.MustCompile("^[a-zA-Z0-9-_]+$") + func getAliasDependency(charts []*chart.Chart, aliasChart *Dependency) *chart.Chart { var chartFound chart.Chart for _, existingChart := range charts { @@ -237,6 +242,11 @@ func getAliasDependency(charts []*chart.Chart, aliasChart *Dependency) *chart.Ch chartFound = *existingChart newMetadata := *existingChart.Metadata if aliasChart.Alias != "" { + // Make sure Alias is well-formed + if !aliasRegexp.MatchString(aliasChart.Alias) { + fmt.Printf("Invalid alias in dependency %q. Skipping.", aliasChart.Name) + continue + } newMetadata.Name = aliasChart.Alias } chartFound.Metadata = &newMetadata @@ -286,6 +296,9 @@ func doProcessRequirementsEnabled(c *chart.Chart, v *chart.Config, path string) chartDependencies = append(chartDependencies, chartDependency) } if req.Alias != "" { + if !aliasRegexp.MatchString(req.Alias) { + return fmt.Errorf("illegal alias name in %q", req.Name) + } req.Name = req.Alias } } @@ -396,7 +409,7 @@ func processImportValues(c *chart.Chart) error { if err != nil { return err } - b := cvals.AsMap() + b := make(map[string]interface{}, 0) // import values from each dependency if specified in import-values for _, r := range reqs.Dependencies { // only process raw requirement that is found in chart's dependencies (enabled) @@ -417,42 +430,34 @@ func processImportValues(c *chart.Chart) error { if len(r.ImportValues) > 0 { var outiv []interface{} for _, riv := range r.ImportValues { + nm := make(map[string]string, 0) switch iv := riv.(type) { case map[string]interface{}: - nm := map[string]string{ - "child": iv["child"].(string), - "parent": iv["parent"].(string), - } - outiv = append(outiv, nm) - s := name + "." + nm["child"] - // get child table - vv, err := cvals.Table(s) - if err != nil { - log.Printf("Warning: ImportValues missing table: %v", err) - continue - } - // create value map from child to be merged into parent - vm := pathToMap(nm["parent"], vv.AsMap()) - b = coalesceTables(b, vm, c.Metadata.Name) + nm["child"] = iv["child"].(string) + nm["parent"] = iv["parent"].(string) case string: - nm := map[string]string{ - "child": "exports." + iv, - "parent": ".", - } - outiv = append(outiv, nm) - s := name + "." + nm["child"] - vm, err := cvals.Table(s) - if err != nil { - log.Printf("Warning: ImportValues missing table: %v", err) - continue - } - b = coalesceTables(b, vm.AsMap(), c.Metadata.Name) + nm["child"] = "exports." + iv + nm["parent"] = "." } + + outiv = append(outiv, nm) + s := name + "." + nm["child"] + // get child table + vv, err := cvals.Table(s) + if err != nil { + log.Printf("Warning: ImportValues missing table: %v", err) + continue + } + // create value map from child to be merged into parent + vm := pathToMap(nm["parent"], vv.AsMap()) + b = coalesceTables(b, vm, c.Metadata.Name) + } // set our formatted import values r.ImportValues = outiv } } + b = coalesceTables(b, cvals, c.Metadata.Name) y, err := yaml.Marshal(b) if err != nil { return err diff --git a/vendor/k8s.io/helm/pkg/downloader/manager.go b/vendor/k8s.io/helm/pkg/downloader/manager.go index ce2e2ef0..38bb0a5a 100644 --- a/vendor/k8s.io/helm/pkg/downloader/manager.go +++ b/vendor/k8s.io/helm/pkg/downloader/manager.go @@ -457,7 +457,7 @@ func (m *Manager) getRepoNames(deps []*chartutil.Dependency) (map[string]string, if containsNonURL { errorMessage += ` Note that repositories must be URLs or aliases. For example, to refer to the stable -repository, use "https://kubernetes-charts.storage.googleapis.com/" or "@stable" instead of +repository, use "https://charts.helm.sh/stable" or "@stable" instead of "stable". Don't forget to add the repo, too ('helm repo add').` } return nil, errors.New(errorMessage) diff --git a/vendor/k8s.io/helm/pkg/engine/engine.go b/vendor/k8s.io/helm/pkg/engine/engine.go index b4b6475c..8c7d3611 100644 --- a/vendor/k8s.io/helm/pkg/engine/engine.go +++ b/vendor/k8s.io/helm/pkg/engine/engine.go @@ -26,11 +26,14 @@ import ( "text/template" "github.com/Masterminds/sprig" + "github.com/pkg/errors" "k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/proto/hapi/chart" ) +const recursionMaxNums = 1000 + // Engine is an implementation of 'cmd/tiller/environment'.Engine that uses Go templates. type Engine struct { // FuncMap contains the template functions that will be passed to each @@ -144,12 +147,23 @@ func (e *Engine) alterFuncMap(t *template.Template, referenceTpls map[string]ren funcMap[k] = v } + includedNames := make(map[string]int) + // Add the 'include' function here so we can close over t. funcMap["include"] = func(name string, data interface{}) (string, error) { buf := bytes.NewBuffer(nil) + if v, ok := includedNames[name]; ok { + if v > recursionMaxNums { + return "", errors.Wrapf(fmt.Errorf("unable to execute template"), "rendering template has a nested reference name: %s", name) + } + includedNames[name]++ + } else { + includedNames[name] = 1 + } if err := t.ExecuteTemplate(buf, name, data); err != nil { return "", err } + includedNames[name]-- return buf.String(), nil } diff --git a/vendor/k8s.io/helm/pkg/plugin/plugin.go b/vendor/k8s.io/helm/pkg/plugin/plugin.go index 07fcc700..27fbf808 100644 --- a/vendor/k8s.io/helm/pkg/plugin/plugin.go +++ b/vendor/k8s.io/helm/pkg/plugin/plugin.go @@ -16,14 +16,16 @@ limitations under the License. package plugin // import "k8s.io/helm/pkg/plugin" import ( + "fmt" "io/ioutil" "os" "path/filepath" "strings" - helm_env "k8s.io/helm/pkg/helm/environment" - "github.com/ghodss/yaml" + yaml2 "gopkg.in/yaml.v2" + + helm_env "k8s.io/helm/pkg/helm/environment" ) const pluginFileName = "plugin.yaml" @@ -32,10 +34,10 @@ const pluginFileName = "plugin.yaml" // charts from special sources type Downloaders struct { // Protocols are the list of schemes from the charts URL. - Protocols []string `json:"protocols"` + Protocols []string `json:"protocols" yaml:"protocols"` // Command is the executable path with which the plugin performs // the actual download for the corresponding Protocols - Command string `json:"command"` + Command string `json:"command" yaml:"command"` } // Metadata describes a plugin. @@ -43,16 +45,16 @@ type Downloaders struct { // This is the plugin equivalent of a chart.Metadata. type Metadata struct { // Name is the name of the plugin - Name string `json:"name"` + Name string `json:"name" yaml:"name"` // Version is a SemVer 2 version of the plugin. - Version string `json:"version"` + Version string `json:"version" yaml:"version"` // Usage is the single-line usage text shown in help - Usage string `json:"usage"` + Usage string `json:"usage" yaml:"usage"` // Description is a long description shown in places like `helm help` - Description string `json:"description"` + Description string `json:"description" yaml:"description"` // Command is the command, as a single string. // @@ -62,26 +64,26 @@ type Metadata struct { // // Note that command is not executed in a shell. To do so, we suggest // pointing the command to a shell script. - Command string `json:"command"` + Command string `json:"command" yaml:"command"` // IgnoreFlags ignores any flags passed in from Helm // // For example, if the plugin is invoked as `helm --debug myplugin`, if this // is false, `--debug` will be appended to `--command`. If this is true, // the `--debug` flag will be discarded. - IgnoreFlags bool `json:"ignoreFlags"` + IgnoreFlags bool `json:"ignoreFlags" yaml:"ignoreFlags,omitempty"` // UseTunnel indicates that this command needs a tunnel. // Setting this will cause a number of side effects, such as the // automatic setting of HELM_HOST. - UseTunnel bool `json:"useTunnel"` + UseTunnel bool `json:"useTunnel" yaml:"useTunnel,omitempty"` // Hooks are commands that will run on events. Hooks Hooks // Downloaders field is used if the plugin supply downloader mechanism // for special protocols. - Downloaders []Downloaders `json:"downloaders"` + Downloaders []Downloaders `json:"downloaders" yaml:"downloaders"` } // Plugin represents a plugin. @@ -119,12 +121,20 @@ func LoadDir(dirname string) (*Plugin, error) { } plug := &Plugin{Dir: dirname} + if err := validateMeta(data); err != nil { + return nil, err + } if err := yaml.Unmarshal(data, &plug.Metadata); err != nil { return nil, err } return plug, nil } +func validateMeta(data []byte) error { + // This is done ONLY for validation. We need to use ghodss/yaml for the actual parsing. + return yaml2.UnmarshalStrict(data, &Metadata{}) +} + // LoadAll loads all plugins found beneath the base directory. // // This scans only one directory level. @@ -141,13 +151,22 @@ func LoadAll(basedir string) ([]*Plugin, error) { return plugins, nil } + loaded := map[string]bool{} for _, yaml := range matches { dir := filepath.Dir(yaml) p, err := LoadDir(dir) + pname := p.Metadata.Name if err != nil { return plugins, err } + + if _, ok := loaded[pname]; ok { + fmt.Fprintf(os.Stderr, "A plugin named %q already exists. Skipping.", pname) + continue + } + plugins = append(plugins, p) + loaded[pname] = true } return plugins, nil } diff --git a/vendor/k8s.io/helm/pkg/repo/index.go b/vendor/k8s.io/helm/pkg/repo/index.go index 12f3308d..edeef99c 100644 --- a/vendor/k8s.io/helm/pkg/repo/index.go +++ b/vendor/k8s.io/helm/pkg/repo/index.go @@ -30,6 +30,7 @@ import ( "github.com/Masterminds/semver" "github.com/ghodss/yaml" + yaml2 "gopkg.in/yaml.v2" "k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/proto/hapi/chart" @@ -83,6 +84,17 @@ type IndexFile struct { PublicKeys []string `json:"publicKeys,omitempty"` } +// IndexValidation is used to validate the integrity of an index file +type IndexValidation struct { + // This is used ONLY for validation against chartmuseum's index files and + // is discarded after validation. + ServerInfo map[string]interface{} `yaml:"serverInfo,omitempty"` + APIVersion string `yaml:"apiVersion"` + Generated time.Time `yaml:"generated"` + Entries map[string]interface{} `yaml:"entries"` + PublicKeys []string `yaml:"publicKeys,omitempty"` +} + // NewIndexFile initializes an index. func NewIndexFile() *IndexFile { return &IndexFile{ @@ -283,9 +295,14 @@ func IndexDirectory(dir, baseURL string) (*IndexFile, error) { // This will fail if API Version is not set (ErrNoAPIVersion) or if the unmarshal fails. func loadIndex(data []byte) (*IndexFile, error) { i := &IndexFile{} + if err := validateIndex(data); err != nil { + return i, err + } + if err := yaml.Unmarshal(data, i); err != nil { return i, err } + i.SortEntries() if i.APIVersion == "" { // When we leave Beta, we should remove legacy support and just @@ -296,6 +313,16 @@ func loadIndex(data []byte) (*IndexFile, error) { return i, nil } +// validateIndex validates that the index is well-formed. +func validateIndex(data []byte) error { + // This is done ONLY for validation. We need to use ghodss/yaml for the actual parsing. + validation := &IndexValidation{} + if err := yaml2.UnmarshalStrict(data, validation); err != nil { + return err + } + return nil +} + // unversionedEntry represents a deprecated pre-Alpha.5 format. // // This will be removed prior to v2.0.0 diff --git a/vendor/k8s.io/helm/pkg/strvals/parser.go b/vendor/k8s.io/helm/pkg/strvals/parser.go index d0a647c6..41ee0a67 100644 --- a/vendor/k8s.io/helm/pkg/strvals/parser.go +++ b/vendor/k8s.io/helm/pkg/strvals/parser.go @@ -277,12 +277,20 @@ func (t *parser) listItem(list []interface{}, i int) ([]interface{}, error) { } case last == '[': // now we have a nested list. Read the index and handle. - i, err := t.keyIndex() + nextI, err := t.keyIndex() if err != nil { return list, fmt.Errorf("error parsing index: %s", err) } + var crtList []interface{} + if len(list) > i { + // If nested list already exists, take the value of list to next cycle. + existed := list[i] + if existed != nil { + crtList = list[i].([]interface{}) + } + } // Now we need to get the value after the ]. - list2, err := t.listItem(list, i) + list2, err := t.listItem(crtList, nextI) return setIndex(list, i, list2), err case last == '.': // We have a nested object. Send to t.key diff --git a/vendor/k8s.io/helm/pkg/version/version.go b/vendor/k8s.io/helm/pkg/version/version.go index d58be044..74accb40 100644 --- a/vendor/k8s.io/helm/pkg/version/version.go +++ b/vendor/k8s.io/helm/pkg/version/version.go @@ -26,7 +26,7 @@ var ( // Increment major number for new feature additions and behavioral changes. // Increment minor number for bug fixes and performance enhancements. // Increment patch number for critical fixes to existing releases. - Version = "v2.16" + Version = "v2.17" // BuildMetadata is extra build time data BuildMetadata = "unreleased" diff --git a/vendor/modules.txt b/vendor/modules.txt index 94f8d072..6f210ff5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -868,7 +868,7 @@ k8s.io/client-go/util/workqueue ## explicit; go 1.16 k8s.io/component-base/config k8s.io/component-base/config/v1alpha1 -# k8s.io/helm v2.16.0+incompatible +# k8s.io/helm v2.17.0+incompatible ## explicit k8s.io/helm/internal/third_party/dep/fs k8s.io/helm/pkg/chartutil