From fd15dddb43bb62a74198174ef3d2f3d22aabcc94 Mon Sep 17 00:00:00 2001 From: Timofey Kirillov Date: Wed, 12 Oct 2022 15:39:07 +0300 Subject: [PATCH] fix(bundles): fix subcharts dependencies not published, and excess files published into the bundle * Only publish builtin helm chart files such as README.md, values.schema.json, LICENSE etc. * Do not publish arbitrary files from .helm dir, because these could contain custom secret-values and other unnecessary files * Do publish .helm/charts/CHART dir content in the case when CHART specified as a local dependency Signed-off-by: Timofey Kirillov --- pkg/deploy/helm/chart_extender/bundle.go | 32 ++++++++++ pkg/deploy/helm/chart_extender/werf_chart.go | 61 ++++++++++++++------ 2 files changed, 76 insertions(+), 17 deletions(-) diff --git a/pkg/deploy/helm/chart_extender/bundle.go b/pkg/deploy/helm/chart_extender/bundle.go index 04adca310a..3cdb9d78c8 100644 --- a/pkg/deploy/helm/chart_extender/bundle.go +++ b/pkg/deploy/helm/chart_extender/bundle.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "text/template" "helm.sh/helm/v3/pkg/chart" @@ -223,3 +224,34 @@ func readBundleJsonMap(path string) (map[string]string, error) { return res, nil } } + +var ( + AllowedBundleChartFiles = []string{ + "Chart.yaml", + "LICENSE", + "README.md", + "values.yaml", + "values.schema.json", + } + AllowedBundleChartDirs = []string{ + "charts/", + "crds/", + "templates/", + } +) + +func CheckBundlePathAllowed(path string) bool { + for _, p := range AllowedBundleChartFiles { + if p == path { + return true + } + } + + for _, d := range AllowedBundleChartDirs { + if strings.HasPrefix(path, d) { + return true + } + } + + return false +} diff --git a/pkg/deploy/helm/chart_extender/werf_chart.go b/pkg/deploy/helm/chart_extender/werf_chart.go index efba0c72ca..fd5d127756 100644 --- a/pkg/deploy/helm/chart_extender/werf_chart.go +++ b/pkg/deploy/helm/chart_extender/werf_chart.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "text/template" "github.com/mitchellh/copystructure" @@ -329,36 +330,47 @@ func (wc *WerfChart) CreateNewBundle(ctx context.Context, destDir, chartVersion } for _, f := range wc.HelmChart.Templates { - p := filepath.Join(destDir, f.Name) - dir := filepath.Dir(p) - - if err := os.MkdirAll(dir, os.ModePerm); err != nil { - return nil, fmt.Errorf("error creating dir %q: %w", dir, err) + if err := writeChartFile(ctx, destDir, f.Name, f.Data); err != nil { + return nil, fmt.Errorf("error writing chart template: %w", err) } + } - if err := ioutil.WriteFile(p, append(f.Data, []byte("\n")...), os.ModePerm); err != nil { - return nil, fmt.Errorf("unable to write %q: %w", p, err) + for _, f := range wc.HelmChart.Files { + if !CheckBundlePathAllowed(f.Name) { + continue + } + if err := writeChartFile(ctx, destDir, f.Name, f.Data); err != nil { + return nil, fmt.Errorf("error writing miscellaneous chart file: %w", err) } } - for _, f := range wc.HelmChart.Files { - p := filepath.Join(destDir, f.Name) - dir := filepath.Dir(p) + for _, dep := range wc.HelmChart.Metadata.Dependencies { + var depPath string - if err := os.MkdirAll(dir, os.ModePerm); err != nil { - return nil, fmt.Errorf("error creating dir %q: %w", dir, err) + switch { + case dep.Repository == "": + depPath = filepath.Join("charts", dep.Name) + case strings.HasPrefix(dep.Repository, "file://"): + depPath = strings.TrimPrefix(dep.Repository, "file://") + default: + continue } - if err := ioutil.WriteFile(p, append(f.Data, []byte("\n")...), os.ModePerm); err != nil { - return nil, fmt.Errorf("unable to write %q: %w", p, err) + for _, f := range wc.HelmChart.Raw { + if strings.HasPrefix(f.Name, depPath) { + if err := writeChartFile(ctx, destDir, f.Name, f.Data); err != nil { + return nil, fmt.Errorf("error writing subchart file: %w", err) + } + } } } if wc.HelmChart.Schema != nil { schemaFile := filepath.Join(destDir, "values.schema.json") - if data, err := json.Marshal(wc.HelmChart.Schema); err != nil { - return nil, fmt.Errorf("unable to prepare values.schema.json data: %w", err) - } else if err := ioutil.WriteFile(schemaFile, append(data, []byte("\n")...), os.ModePerm); err != nil { + if err := writeChartFile(ctx, destDir, "values.schema.json", wc.HelmChart.Schema); err != nil { + return nil, fmt.Errorf("error writing chart values schema: %w", err) + } + if err := ioutil.WriteFile(schemaFile, wc.HelmChart.Schema, os.ModePerm); err != nil { return nil, fmt.Errorf("unable to write %q: %w", schemaFile, err) } } @@ -380,3 +392,18 @@ func (wc *WerfChart) CreateNewBundle(ctx context.Context, destDir, chartVersion IgnoreInvalidAnnotationsAndLabels: wc.extraAnnotationsAndLabelsPostRenderer.IgnoreInvalidAnnotationsAndLabels, }) } + +func writeChartFile(ctx context.Context, destDir, fileName string, fileData []byte) error { + p := filepath.Join(destDir, fileName) + dir := filepath.Dir(p) + + logboek.Context(ctx).Debug().LogF("Writing chart file %q\n", p) + + if err := os.MkdirAll(dir, os.ModePerm); err != nil { + return fmt.Errorf("error creating dir %q: %w", dir, err) + } + if err := ioutil.WriteFile(p, fileData, os.ModePerm); err != nil { + return fmt.Errorf("unable to write %q: %w", p, err) + } + return nil +}