Skip to content

Commit

Permalink
feat(bundles): support custom secret values files when publishing bundle
Browse files Browse the repository at this point in the history
werf bundle publish --secret-values .helm/custom-secret-values.yaml — will merge .helm/secret-values.yaml with .helm/custom-values.yaml and embed resulting secret-values.yaml into the bundle.

Signed-off-by: Timofey Kirillov <timofey.kirillov@flant.com>
  • Loading branch information
distorhead committed Feb 28, 2023
1 parent 18e958d commit 5290e33
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 57 deletions.
17 changes: 4 additions & 13 deletions cmd/werf/bundle/export/export.go
Expand Up @@ -11,7 +11,6 @@ import (
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/cli/values"
"helm.sh/helm/v3/pkg/getter"

"github.com/werf/logboek"
"github.com/werf/werf/cmd/werf/common"
Expand Down Expand Up @@ -367,22 +366,14 @@ func runExport(ctx context.Context, imagesToProcess build.ImagesToProcess) error
SubchartExtenderFactoryFunc: func() chart.ChartExtender { return chart_extender.NewWerfSubchart() },
}

valueOpts := &values.Options{
chartVersion := fmt.Sprintf("0.0.0-%d", time.Now().Unix())

if _, err := wc.CreateNewBundle(ctx, cmdData.Destination, chartVersion, &values.Options{
ValueFiles: common.GetValues(&commonCmdData),
StringValues: common.GetSetString(&commonCmdData),
Values: common.GetSet(&commonCmdData),
FileValues: common.GetSetFile(&commonCmdData),
}

chartVersion := fmt.Sprintf("0.0.0-%d", time.Now().Unix())

p := getter.All(helm_v3.Settings)
vals, err := valueOpts.MergeValues(p, wc)
if err != nil {
return err
}

if _, err := wc.CreateNewBundle(ctx, cmdData.Destination, chartVersion, vals); err != nil {
}); err != nil {
return fmt.Errorf("unable to create bundle: %w", err)
}

Expand Down
39 changes: 22 additions & 17 deletions cmd/werf/bundle/publish/publish.go
Expand Up @@ -13,7 +13,6 @@ import (
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/cli/values"
"helm.sh/helm/v3/pkg/getter"

"github.com/werf/logboek"
"github.com/werf/werf/cmd/werf/common"
Expand All @@ -23,6 +22,7 @@ import (
"github.com/werf/werf/pkg/deploy/helm/chart_extender"
"github.com/werf/werf/pkg/deploy/helm/chart_extender/helpers"
"github.com/werf/werf/pkg/deploy/helm/command_helpers"
"github.com/werf/werf/pkg/deploy/secrets_manager"
"github.com/werf/werf/pkg/git_repo"
"github.com/werf/werf/pkg/git_repo/gitdata"
"github.com/werf/werf/pkg/image"
Expand Down Expand Up @@ -111,8 +111,11 @@ func NewCmd(ctx context.Context) *cobra.Command {
common.SetupSetString(&commonCmdData, cmd)
common.SetupSetFile(&commonCmdData, cmd)
common.SetupValues(&commonCmdData, cmd)
common.SetupSecretValues(&commonCmdData, cmd)
common.SetupIgnoreSecretKey(&commonCmdData, cmd)

commonCmdData.SetupDisableDefaultValues(cmd)
commonCmdData.SetupDisableDefaultSecretValues(cmd)
commonCmdData.SetupSkipDependenciesRepoRefresh(cmd)

common.SetupSaveBuildReport(&commonCmdData, cmd)
Expand Down Expand Up @@ -334,13 +337,23 @@ func runPublish(ctx context.Context, imagesToProcess build.ImagesToProcess) erro
return err
}

wc := chart_extender.NewWerfChart(ctx, giterminismManager, nil, chartDir, helm_v3.Settings, helmRegistryClient, chart_extender.WerfChartOptions{
secretsManager := secrets_manager.NewSecretsManager(secrets_manager.SecretsManagerOptions{
DisableSecretsDecryption: *commonCmdData.IgnoreSecretKey,
})

// FIXME(1.3): compatibility mode with older 1.2 versions, which do not require WERF_SECRET_KEY in the 'werf bundle publish' command
if err := secretsManager.AllowMissedSecretKeyMode(giterminismManager.ProjectDir()); err != nil {
return err
}

wc := chart_extender.NewWerfChart(ctx, giterminismManager, secretsManager, chartDir, helm_v3.Settings, helmRegistryClient, chart_extender.WerfChartOptions{
BuildChartDependenciesOpts: command_helpers.BuildChartDependenciesOptions{SkipUpdate: *commonCmdData.SkipDependenciesRepoRefresh},
SecretValueFiles: common.GetSecretValues(&commonCmdData),
ExtraAnnotations: userExtraAnnotations,
ExtraLabels: userExtraLabels,
IgnoreInvalidAnnotationsAndLabels: true,
DisableDefaultValues: *commonCmdData.DisableDefaultValues,
DisableDefaultSecretValues: true,
DisableDefaultSecretValues: *commonCmdData.DisableDefaultSecretValues,
})

if err := wc.SetEnv(*commonCmdData.Environment); err != nil {
Expand Down Expand Up @@ -377,13 +390,6 @@ func runPublish(ctx context.Context, imagesToProcess build.ImagesToProcess) erro
SubchartExtenderFactoryFunc: func() chart.ChartExtender { return chart_extender.NewWerfSubchart() },
}

valueOpts := &values.Options{
ValueFiles: *commonCmdData.Values,
StringValues: *commonCmdData.SetString,
Values: *commonCmdData.Set,
FileValues: *commonCmdData.SetFile,
}

sv, err := bundles.BundleTagToChartVersion(ctx, cmdData.Tag, time.Now())
if err != nil {
return fmt.Errorf("unable to set chart version from bundle tag %q: %w", cmdData.Tag, err)
Expand All @@ -393,13 +399,12 @@ func runPublish(ctx context.Context, imagesToProcess build.ImagesToProcess) erro
bundleTmpDir := filepath.Join(werf.GetServiceDir(), "tmp", "bundles", uuid.NewV4().String())
defer os.RemoveAll(bundleTmpDir)

p := getter.All(helm_v3.Settings)
vals, err := valueOpts.MergeValues(p, wc)
if err != nil {
return err
}

bundle, err := wc.CreateNewBundle(ctx, bundleTmpDir, chartVersion, vals)
bundle, err := wc.CreateNewBundle(ctx, bundleTmpDir, chartVersion, &values.Options{
ValueFiles: *commonCmdData.Values,
StringValues: *commonCmdData.SetString,
Values: *commonCmdData.Set,
FileValues: *commonCmdData.SetFile,
})
if err != nil {
return fmt.Errorf("unable to create bundle: %w", err)
}
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions pkg/deploy/helm/chart_extender/bundle.go
Expand Up @@ -146,9 +146,9 @@ func (bundle *Bundle) MakeValues(inputVals map[string]interface{}) (map[string]i
chartutil.CoalesceTables(vals, bundle.ServiceValues)

if debugSecretValues() {
debugPrintValues(bundle.ChartExtenderContext, "secret", bundle.SecretsRuntimeData.DecodedSecretValues)
debugPrintValues(bundle.ChartExtenderContext, "secret", bundle.SecretsRuntimeData.DecryptedSecretValues)
}
chartutil.CoalesceTables(vals, bundle.SecretsRuntimeData.DecodedSecretValues)
chartutil.CoalesceTables(vals, bundle.SecretsRuntimeData.DecryptedSecretValues)

debugPrintValues(bundle.ChartExtenderContext, "input", inputVals)
chartutil.CoalesceTables(vals, inputVals)
Expand Down
Expand Up @@ -37,11 +37,11 @@ func SetupWerfSecretFile(secretsRuntimeData *secrets.SecretsRuntimeData, funcMap
return "", fmt.Errorf("expected relative secret file path, given path %v", secretRelativePath)
}

decodedData, ok := secretsRuntimeData.DecodedSecretFilesData[secretRelativePath]
decodedData, ok := secretsRuntimeData.DecryptedSecretFilesData[secretRelativePath]

if !ok {
var secretFiles []string
for key := range secretsRuntimeData.DecodedSecretFilesData {
for key := range secretsRuntimeData.DecryptedSecretFilesData {
secretFiles = append(secretFiles, key)
}

Expand Down
Expand Up @@ -6,6 +6,7 @@ import (
"io/ioutil"

"helm.sh/helm/v3/pkg/chart"
"sigs.k8s.io/yaml"

"github.com/werf/werf/pkg/deploy/secrets_manager"
"github.com/werf/werf/pkg/giterminism_manager"
Expand All @@ -14,14 +15,14 @@ import (
)

type SecretsRuntimeData struct {
DecodedSecretValues map[string]interface{}
DecodedSecretFilesData map[string]string
SecretValuesToMask []string
DecryptedSecretValues map[string]interface{}
DecryptedSecretFilesData map[string]string
SecretValuesToMask []string
}

func NewSecretsRuntimeData() *SecretsRuntimeData {
return &SecretsRuntimeData{
DecodedSecretFilesData: make(map[string]string),
DecryptedSecretFilesData: make(map[string]string),
}
}

Expand Down Expand Up @@ -51,14 +52,12 @@ func (secretsRuntimeData *SecretsRuntimeData) DecodeAndLoadSecrets(ctx context.C
if err != nil {
return fmt.Errorf("unable to read custom secret values file %q from local filesystem: %w", customSecretValuesFileName, err)
}

file.Data = data
} else {
data, err := opts.GiterminismManager.FileReader().ReadChartFile(ctx, customSecretValuesFileName)
if err != nil {
return fmt.Errorf("unable to read custom secret values file %q: %w", customSecretValuesFileName, err)
}

file.Data = data
}

Expand All @@ -68,7 +67,7 @@ func (secretsRuntimeData *SecretsRuntimeData) DecodeAndLoadSecrets(ctx context.C
var encoder *secret.YamlEncoder
if len(secretDirFiles)+len(loadedSecretValuesFiles) > 0 {
if enc, err := secretsManager.GetYamlEncoder(ctx, secretsWorkingDir); err != nil {
return err
return fmt.Errorf("error getting secrets yaml encoder: %w", err)
} else {
encoder = enc
}
Expand All @@ -78,8 +77,8 @@ func (secretsRuntimeData *SecretsRuntimeData) DecodeAndLoadSecrets(ctx context.C
if data, err := LoadChartSecretDirFilesData(chartDir, secretDirFiles, encoder); err != nil {
return fmt.Errorf("error loading secret files data: %w", err)
} else {
secretsRuntimeData.DecodedSecretFilesData = data
for _, fileData := range secretsRuntimeData.DecodedSecretFilesData {
secretsRuntimeData.DecryptedSecretFilesData = data
for _, fileData := range secretsRuntimeData.DecryptedSecretFilesData {
secretsRuntimeData.SecretValuesToMask = append(secretsRuntimeData.SecretValuesToMask, fileData)
}
}
Expand All @@ -89,10 +88,42 @@ func (secretsRuntimeData *SecretsRuntimeData) DecodeAndLoadSecrets(ctx context.C
if values, err := LoadChartSecretValueFiles(chartDir, loadedSecretValuesFiles, encoder); err != nil {
return fmt.Errorf("error loading secret value files: %w", err)
} else {
secretsRuntimeData.DecodedSecretValues = values
secretsRuntimeData.DecryptedSecretValues = values
secretsRuntimeData.SecretValuesToMask = append(secretsRuntimeData.SecretValuesToMask, secretvalues.ExtractSecretValuesFromMap(values)...)
}
}

return nil
}

func (secretsRuntimeData *SecretsRuntimeData) GetEncodedSecretValues(ctx context.Context, secretsManager *secrets_manager.SecretsManager, secretsWorkingDir string) (map[string]interface{}, error) {
if len(secretsRuntimeData.DecryptedSecretValues) == 0 {
return nil, nil
}

// FIXME: secrets encoder should receive interface{} raw data instead of []byte yaml data

var encoder *secret.YamlEncoder
if enc, err := secretsManager.GetYamlEncoder(ctx, secretsWorkingDir); err != nil {
return nil, fmt.Errorf("error getting secrets yaml encoder: %w", err)
} else {
encoder = enc
}

decryptedSecretsData, err := yaml.Marshal(secretsRuntimeData.DecryptedSecretValues)
if err != nil {
return nil, fmt.Errorf("unable to marshal decrypted secrets yaml: %w", err)
}

encryptedSecretsData, err := encoder.EncryptYamlData(decryptedSecretsData)
if err != nil {
return nil, fmt.Errorf("unable to encrypt secrets data: %w", err)
}

var encryptedData map[string]interface{}
if err := yaml.Unmarshal(encryptedSecretsData, &encryptedData); err != nil {
return nil, fmt.Errorf("unable to unmarshal encrypted secrets data: %w", err)
}

return encryptedData, nil
}

0 comments on commit 5290e33

Please sign in to comment.