2022-09-05 03:06:08 -04:00
|
|
|
/*
|
|
|
|
Copyright (c) Edgeless Systems GmbH
|
|
|
|
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
*/
|
|
|
|
|
2022-08-12 04:20:19 -04:00
|
|
|
package helm
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"embed"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io/fs"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/edgelesssys/constellation/internal/cloud/cloudprovider"
|
|
|
|
"github.com/edgelesssys/constellation/internal/deploy/helm"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"helm.sh/helm/pkg/ignore"
|
|
|
|
"helm.sh/helm/v3/pkg/chart"
|
|
|
|
"helm.sh/helm/v3/pkg/chart/loader"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Run `go generate` to deterministically create the patched Helm deployment for cilium
|
|
|
|
//go:generate ./generateCilium.sh
|
|
|
|
|
|
|
|
//go:embed all:charts/cilium/*
|
|
|
|
var HelmFS embed.FS
|
|
|
|
|
|
|
|
type ChartLoader struct{}
|
|
|
|
|
|
|
|
func (i *ChartLoader) Load(csp string) ([]byte, error) {
|
|
|
|
ciliumDeployment, err := i.loadCilium(csp)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
deployments := helm.Deployments{Cilium: ciliumDeployment}
|
|
|
|
depl, err := json.Marshal(deployments)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return depl, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i *ChartLoader) loadCilium(csp string) (helm.Deployment, error) {
|
|
|
|
chart, err := loadChartsDir(HelmFS, "charts/cilium")
|
|
|
|
if err != nil {
|
|
|
|
return helm.Deployment{}, err
|
|
|
|
}
|
|
|
|
var ciliumVals map[string]interface{}
|
2022-08-24 03:45:02 -04:00
|
|
|
switch cloudprovider.FromString(csp) {
|
|
|
|
case cloudprovider.GCP:
|
2022-08-12 04:20:19 -04:00
|
|
|
ciliumVals = gcpVals
|
2022-08-24 03:45:02 -04:00
|
|
|
case cloudprovider.Azure:
|
2022-08-12 04:20:19 -04:00
|
|
|
ciliumVals = azureVals
|
2022-08-24 03:45:02 -04:00
|
|
|
case cloudprovider.QEMU:
|
2022-08-12 04:20:19 -04:00
|
|
|
ciliumVals = qemuVals
|
|
|
|
default:
|
|
|
|
return helm.Deployment{}, fmt.Errorf("unknown csp: %s", csp)
|
|
|
|
}
|
|
|
|
return helm.Deployment{Chart: chart, Values: ciliumVals}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// taken from loader.LoadDir from the helm go module
|
|
|
|
// loadChartsDir loads from a directory.
|
|
|
|
//
|
|
|
|
// This loads charts only from directories.
|
|
|
|
func loadChartsDir(efs embed.FS, dir string) (*chart.Chart, error) {
|
|
|
|
utf8bom := []byte{0xEF, 0xBB, 0xBF}
|
|
|
|
// Just used for errors.
|
|
|
|
c := &chart.Chart{}
|
|
|
|
|
|
|
|
rules := ignore.Empty()
|
|
|
|
ifile, err := efs.ReadFile(filepath.Join(dir, ignore.HelmIgnore))
|
|
|
|
if err == nil {
|
|
|
|
r, err := ignore.Parse(bytes.NewReader(ifile))
|
|
|
|
if err != nil {
|
|
|
|
return c, err
|
|
|
|
}
|
|
|
|
rules = r
|
|
|
|
}
|
|
|
|
rules.AddDefaults()
|
|
|
|
|
|
|
|
files := []*loader.BufferedFile{}
|
|
|
|
|
|
|
|
walk := func(path string, d fs.DirEntry, err error) error {
|
|
|
|
n := strings.TrimPrefix(path, dir)
|
|
|
|
if n == "" {
|
|
|
|
// No need to process top level. Avoid bug with helmignore .* matching
|
|
|
|
// empty names. See issue https://github.com/kubernetes/helm/issues/1776.
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Normalize to / since it will also work on Windows
|
|
|
|
n = filepath.ToSlash(n)
|
|
|
|
|
|
|
|
// Check input err
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
fi, err := d.Info()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if d.IsDir() {
|
|
|
|
// Directory-based ignore rules should involve skipping the entire
|
|
|
|
// contents of that directory.
|
|
|
|
if rules.Ignore(n, fi) {
|
|
|
|
return filepath.SkipDir
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// If a .helmignore file matches, skip this file.
|
|
|
|
if rules.Ignore(n, fi) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Irregular files include devices, sockets, and other uses of files that
|
|
|
|
// are not regular files. In Go they have a file mode type bit set.
|
|
|
|
// See https://golang.org/pkg/os/#FileMode for examples.
|
|
|
|
if !fi.Mode().IsRegular() {
|
|
|
|
return fmt.Errorf("cannot load irregular file %s as it has file mode type bits set", path)
|
|
|
|
}
|
|
|
|
|
|
|
|
data, err := efs.ReadFile(path)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "error reading %s", n)
|
|
|
|
}
|
|
|
|
|
|
|
|
data = bytes.TrimPrefix(data, utf8bom)
|
|
|
|
n = strings.TrimPrefix(n, "/")
|
|
|
|
|
|
|
|
files = append(files, &loader.BufferedFile{Name: n, Data: data})
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := fs.WalkDir(efs, dir, walk); err != nil {
|
|
|
|
return c, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return loader.LoadFiles(files)
|
|
|
|
}
|