feat: Add missingFileHandlerConfig.ignoreMissingGitBranch (#645)
This commit is contained in:
parent
60e024ee3b
commit
ec60ac815b
|
|
@ -236,6 +236,10 @@ releases:
|
|||
version: ~1.24.1 # the semver of the chart. range constraint is supported
|
||||
condition: vault.enabled # The values lookup key for filtering releases. Corresponds to the boolean value of `vault.enabled`, where `vault` is an arbitrary value
|
||||
missingFileHandler: Warn # set to either "Error" or "Warn". "Error" instructs helmfile to fail when unable to find a values or secrets file. When "Warn", it prints the file and continues.
|
||||
missingFileHandlerConfig:
|
||||
# Ignores missing git branch error so that the Debug/Info/Warn handler can treat a missing branch as non-error.
|
||||
# See https://github.com/helmfile/helmfile/issues/392
|
||||
ignoreMissingGitBranch: true
|
||||
# Values files used for rendering the chart
|
||||
values:
|
||||
# Value files passed via --values
|
||||
|
|
@ -400,6 +404,10 @@ environments:
|
|||
# Use "Warn", "Info", or "Debug" if you want helmfile to not fail when a values file is missing, while just leaving
|
||||
# a message about the missing file at the log-level.
|
||||
missingFileHandler: Error
|
||||
missingFileHandlerConfig:
|
||||
# Ignores missing git branch error so that the Debug/Info/Warn handler can treat a missing branch as non-error.
|
||||
# See https://github.com/helmfile/helmfile/issues/392
|
||||
ignoreMissingGitBranch: true
|
||||
# kubeContext to use for this environment
|
||||
kubeContext: kube-context
|
||||
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ func (c *StateCreator) loadEnvValues(st *HelmState, name string, failOnMissingEn
|
|||
if len(envSpec.Secrets) > 0 {
|
||||
var envSecretFiles []string
|
||||
for _, urlOrPath := range envSpec.Secrets {
|
||||
resolved, skipped, err := st.storage().resolveFile(envSpec.MissingFileHandler, "environment values", urlOrPath)
|
||||
resolved, skipped, err := st.storage().resolveFile(envSpec.MissingFileHandler, "environment values", urlOrPath, envSpec.MissingFileHandlerConfig.resolveFileOptions()...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,4 +13,6 @@ type EnvironmentSpec struct {
|
|||
// Use "Warn", "Info", or "Debug" if you want helmfile to not fail when a values file is missing, while just leaving
|
||||
// a message about the missing file at the log-level.
|
||||
MissingFileHandler *string `yaml:"missingFileHandler,omitempty"`
|
||||
// MissingFileHandlerConfig is composed of various settings for the MissingFileHandler
|
||||
MissingFileHandlerConfig MissingFileHandlerConfig `yaml:"missingFileHandlerConfig,omitempty"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,10 +82,19 @@ type ReleaseSetSpec struct {
|
|||
// non-existent path. The default behavior is to print a warning. Note the
|
||||
// differing default compared to other MissingFileHandlers.
|
||||
MissingFileHandler string `yaml:"missingFileHandler,omitempty"`
|
||||
// MissingFileHandlerConfig is composed of various settings for the MissingFileHandler
|
||||
MissingFileHandlerConfig MissingFileHandlerConfig `yaml:"missingFileHandlerConfig,omitempty"`
|
||||
|
||||
LockFile string `yaml:"lockFilePath,omitempty"`
|
||||
}
|
||||
|
||||
type MissingFileHandlerConfig struct {
|
||||
// IgnoreMissingGitBranch is set to true in order to let the missing file handler
|
||||
// treat missing git branch errors like `pathspec 'develop' did not match any file(s) known to git` safe
|
||||
// and ignored when the handler is set to Warn or Info.
|
||||
IgnoreMissingGitBranch bool `yaml:"ignoreMissingGitBranch,omitempty"`
|
||||
}
|
||||
|
||||
// helmStateAlias is helm state alias
|
||||
type helmStateAlias HelmState
|
||||
|
||||
|
|
@ -2721,13 +2730,19 @@ func (st *HelmState) removeFiles(files []string) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c MissingFileHandlerConfig) resolveFileOptions() []resolveFileOption {
|
||||
return []resolveFileOption{
|
||||
ignoreMissingGitBranch(c.IgnoreMissingGitBranch),
|
||||
}
|
||||
}
|
||||
|
||||
func (st *HelmState) generateTemporaryReleaseValuesFiles(release *ReleaseSpec, values []interface{}, missingFileHandler *string) ([]string, error) {
|
||||
generatedFiles := []string{}
|
||||
|
||||
for _, value := range values {
|
||||
switch typedValue := value.(type) {
|
||||
case string:
|
||||
paths, skip, err := st.storage().resolveFile(missingFileHandler, "values", typedValue)
|
||||
paths, skip, err := st.storage().resolveFile(missingFileHandler, "values", typedValue, st.MissingFileHandlerConfig.resolveFileOptions()...)
|
||||
if err != nil {
|
||||
return generatedFiles, err
|
||||
}
|
||||
|
|
@ -2828,7 +2843,7 @@ func (st *HelmState) generateSecretValuesFiles(helm helmexec.Interface, release
|
|||
|
||||
switch value := v.(type) {
|
||||
case string:
|
||||
paths, skip, err = st.storage().resolveFile(release.MissingFileHandler, "secrets", release.ValuesPathPrefix+value)
|
||||
paths, skip, err = st.storage().resolveFile(release.MissingFileHandler, "secrets", release.ValuesPathPrefix+value, st.MissingFileHandlerConfig.resolveFileOptions()...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -3282,7 +3297,7 @@ func (st *HelmState) LoadYAMLForEmbedding(release *ReleaseSpec, entries []interf
|
|||
case string:
|
||||
var values map[string]interface{}
|
||||
|
||||
paths, skip, err := st.storage().resolveFile(missingFileHandler, "values", pathPrefix+t)
|
||||
paths, skip, err := st.storage().resolveFile(missingFileHandler, "values", pathPrefix+t, st.MissingFileHandlerConfig.resolveFileOptions()...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"net/url"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
|
|
@ -30,17 +31,42 @@ func NewStorage(forFile string, logger *zap.SugaredLogger, fs *filesystem.FileSy
|
|||
}
|
||||
}
|
||||
|
||||
func (st *Storage) resolveFile(missingFileHandler *string, tpe, path string) ([]string, bool, error) {
|
||||
type resolveFileConfig struct {
|
||||
IgnoreMissingGitBranch bool
|
||||
}
|
||||
|
||||
type resolveFileOption func(*resolveFileConfig)
|
||||
|
||||
func ignoreMissingGitBranch(v bool) func(c *resolveFileConfig) {
|
||||
return func(c *resolveFileConfig) {
|
||||
c.IgnoreMissingGitBranch = v
|
||||
}
|
||||
}
|
||||
|
||||
func (st *Storage) resolveFile(missingFileHandler *string, tpe, path string, opts ...resolveFileOption) ([]string, bool, error) {
|
||||
title := fmt.Sprintf("%s file", tpe)
|
||||
|
||||
var files []string
|
||||
var err error
|
||||
var (
|
||||
files []string
|
||||
err error
|
||||
conf resolveFileConfig
|
||||
)
|
||||
|
||||
for _, o := range opts {
|
||||
o(&conf)
|
||||
}
|
||||
|
||||
if remote.IsRemote(path) {
|
||||
r := remote.NewRemote(st.logger, "", st.fs)
|
||||
|
||||
fetchedFilePath, err := r.Fetch(path, "values")
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
// https://github.com/helmfile/helmfile/issues/392
|
||||
if conf.IgnoreMissingGitBranch && strings.Contains(err.Error(), "' did not match any file(s) known to git") {
|
||||
st.logger.Debugf("Ignored missing git branch error: %v", err)
|
||||
} else {
|
||||
return nil, false, err
|
||||
}
|
||||
}
|
||||
|
||||
if st.fs.FileExistsAt(fetchedFilePath) {
|
||||
|
|
|
|||
|
|
@ -16,10 +16,12 @@ func TestStorage_resolveFile(t *testing.T) {
|
|||
missingFileHandler *string
|
||||
title string
|
||||
path string
|
||||
opts []resolveFileOption
|
||||
}
|
||||
|
||||
cacheDir := remote.CacheDir()
|
||||
infoHandler := MissingFileHandlerInfo
|
||||
warnHandler := MissingFileHandlerWarn
|
||||
errorHandler := MissingFileHandlerError
|
||||
|
||||
tests := []struct {
|
||||
|
|
@ -49,6 +51,55 @@ func TestStorage_resolveFile(t *testing.T) {
|
|||
wantSkipped: false,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "non existing branch in repo produce error",
|
||||
args: args{
|
||||
path: "git::https://github.com/helmfile/helmfile.git@examples/values/non-existing-file.yaml?ref=inexistent-branch-for-test",
|
||||
title: "values",
|
||||
missingFileHandler: &infoHandler,
|
||||
},
|
||||
wantSkipped: false,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "non existing branch in repo produce info when ignoreMissingGitBranch=true",
|
||||
args: args{
|
||||
path: "git::https://github.com/helmfile/helmfile.git@examples/values/non-existing-file.yaml?ref=inexistent-branch-for-test",
|
||||
title: "values",
|
||||
missingFileHandler: &infoHandler,
|
||||
opts: []resolveFileOption{
|
||||
ignoreMissingGitBranch(true),
|
||||
},
|
||||
},
|
||||
wantSkipped: true,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "non existing branch in repo produce warn when ignoreMissingGitBranch=true",
|
||||
args: args{
|
||||
path: "git::https://github.com/helmfile/helmfile.git@examples/values/non-existing-file.yaml?ref=inexistent-branch-for-test",
|
||||
title: "values",
|
||||
missingFileHandler: &warnHandler,
|
||||
opts: []resolveFileOption{
|
||||
ignoreMissingGitBranch(true),
|
||||
},
|
||||
},
|
||||
wantSkipped: true,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "non existing branch in repo produce error with error handler even if ignoreMissingGitBranch=true",
|
||||
args: args{
|
||||
path: "git::https://github.com/helmfile/helmfile.git@examples/values/non-existing-file.yaml?ref=inexistent-branch-for-test",
|
||||
title: "values",
|
||||
missingFileHandler: &errorHandler,
|
||||
opts: []resolveFileOption{
|
||||
ignoreMissingGitBranch(true),
|
||||
},
|
||||
},
|
||||
wantSkipped: false,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "existing remote value fetched",
|
||||
args: args{
|
||||
|
|
@ -75,7 +126,7 @@ func TestStorage_resolveFile(t *testing.T) {
|
|||
t.Run(tt.name, func(t *testing.T) {
|
||||
st := NewStorage(cacheDir, helmexec.NewLogger(io.Discard, "debug"), filesystem.DefaultFileSystem())
|
||||
|
||||
files, skipped, err := st.resolveFile(tt.args.missingFileHandler, tt.args.title, tt.args.path)
|
||||
files, skipped, err := st.resolveFile(tt.args.missingFileHandler, tt.args.title, tt.args.path, tt.args.opts...)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("resolveFile() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
|
|
|
|||
Loading…
Reference in New Issue