Introduce DISABLE_INSECURE_FEATURES to disable insecure command executions (#1)
* introduce DISABLE_INSECURE_FEATURES to disable insecure executions Signed-off-by: Quan TRAN <account@itscaro.me> * disable remote sources when DISABLE_INSECURE_FEATURES is set to "true" Signed-off-by: Quan TRAN <account@itscaro.me> * refactor envvar package Signed-off-by: Quan TRAN <account@itscaro.me> * (test) fix test fixtures Signed-off-by: Quan TRAN <account@itscaro.me> * use absolute path to avoid unit test failure Signed-off-by: Quan TRAN <account@itscaro.me> * Fix conflicts Co-authored-by: Yusuke Kuoka <ykuoka@gmail.com>
This commit is contained in:
parent
789af92c09
commit
577f54af7a
|
|
@ -667,13 +667,12 @@ func (a *App) visitStateFiles(fileOrDir string, opts LoadOpts, do func(string, s
|
|||
|
||||
a.Logger.Debugf("processing file \"%s\" in directory \"%s\"", file, dir)
|
||||
|
||||
err := a.within(dir, func() error {
|
||||
absd, err := a.abs(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return do(file, absd)
|
||||
absd, errAbsDir := a.abs(dir)
|
||||
if errAbsDir != nil {
|
||||
return errAbsDir
|
||||
}
|
||||
err := a.within(absd, func() error {
|
||||
return do(file, dir)
|
||||
})
|
||||
if err != nil {
|
||||
return appError(fmt.Sprintf("in %s/%s", dir, file), err)
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -292,6 +293,7 @@ NAME CHART VERSION
|
|||
external-secrets incubator/raw
|
||||
my-release incubator/raw
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -343,6 +345,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -418,6 +421,7 @@ UPDATED RELEASES:
|
|||
NAME CHART VERSION
|
||||
external-secrets incubator/raw 3.1.0
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -465,6 +469,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -551,6 +556,7 @@ kubernetes-external-secrets incubator/raw
|
|||
external-secrets incubator/raw
|
||||
my-release incubator/raw
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -599,6 +605,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -680,6 +687,7 @@ NAME CHART VERSION
|
|||
external-secrets incubator/raw
|
||||
my-release incubator/raw
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -733,6 +741,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -826,6 +835,7 @@ my-release incubator/raw
|
|||
DELETED RELEASES:
|
||||
NAME
|
||||
kubernetes-external-secrets
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -877,6 +887,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -960,6 +971,7 @@ NAME CHART VERSION
|
|||
external-secrets incubator/raw
|
||||
my-release incubator/raw
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -998,6 +1010,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -1060,6 +1073,7 @@ second-pass rendering result of "helmfile.yaml.part.0":
|
|||
merged environment: &{default map[] map[]}
|
||||
0 release(s) matching app=test_non_existent found in helmfile.yaml
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -213,6 +213,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -294,6 +295,7 @@ NAME CHART VERSION
|
|||
external-secrets incubator/raw
|
||||
my-release incubator/raw
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -345,6 +347,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -420,6 +423,7 @@ UPDATED RELEASES:
|
|||
NAME CHART VERSION
|
||||
external-secrets incubator/raw 3.1.0
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -467,6 +471,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -553,6 +558,7 @@ kubernetes-external-secrets incubator/raw
|
|||
external-secrets incubator/raw
|
||||
my-release incubator/raw
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -601,6 +607,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -682,6 +689,7 @@ NAME CHART VERSION
|
|||
external-secrets incubator/raw
|
||||
my-release incubator/raw
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -735,6 +743,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -828,6 +837,7 @@ my-release incubator/raw
|
|||
DELETED RELEASES:
|
||||
NAME
|
||||
kubernetes-external-secrets
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -879,6 +889,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -962,6 +973,7 @@ NAME CHART VERSION
|
|||
external-secrets incubator/raw
|
||||
my-release incubator/raw
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -1006,6 +1018,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -1084,6 +1097,7 @@ serviceC my/chart
|
|||
serviceB my/chart
|
||||
serviceA my/chart
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -1122,6 +1136,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -1184,6 +1199,7 @@ second-pass rendering result of "helmfile.yaml.part.0":
|
|||
merged environment: &{default map[] map[]}
|
||||
0 release(s) matching app=test_non_existent found in helmfile.yaml
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -286,6 +287,7 @@ NAME CHART VERSION
|
|||
external-secrets incubator/raw
|
||||
my-release incubator/raw
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -328,6 +330,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -414,6 +417,7 @@ kubernetes-external-secrets incubator/raw
|
|||
external-secrets incubator/raw
|
||||
my-release incubator/raw
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -452,6 +456,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -530,6 +535,7 @@ serviceC my/chart
|
|||
serviceB my/chart
|
||||
serviceA my/chart
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -580,6 +586,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -673,6 +680,7 @@ my-release incubator/raw
|
|||
DELETED RELEASES:
|
||||
NAME
|
||||
kubernetes-external-secrets
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -721,6 +729,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -804,6 +813,7 @@ NAME CHART VERSION
|
|||
external-secrets incubator/raw
|
||||
my-release incubator/raw
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -842,6 +852,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -904,6 +915,7 @@ second-pass rendering result of "helmfile.yaml.part.0":
|
|||
merged environment: &{default map[] map[]}
|
||||
0 release(s) matching app=test_non_existent found in helmfile.yaml
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/helmfile/helmfile/pkg/envvar"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/remote"
|
||||
"github.com/helmfile/helmfile/pkg/testutil"
|
||||
|
|
@ -636,8 +637,8 @@ releases:
|
|||
{label: "name=doesnotexists", expectedReleases: []string{"zipkin", "prometheus", "grafana", "bar", "bar", "grafana", "postgresql"}, expectErr: false},
|
||||
}
|
||||
|
||||
os.Setenv(ExperimentalEnvVar, ExperimentalSelectorExplicit)
|
||||
defer os.Unsetenv(ExperimentalEnvVar)
|
||||
os.Setenv(envvar.Experimental, ExperimentalSelectorExplicit)
|
||||
defer os.Unsetenv(envvar.Experimental)
|
||||
|
||||
runFilterSubHelmFilesTests(desiredTestcases, files, t, "2nd EmbeddedSelectors")
|
||||
|
||||
|
|
@ -686,8 +687,8 @@ releases:
|
|||
{label: "name!=grafana", expectedReleases: []string{"grafana", "zipkin", "mongodb"}, expectErr: false},
|
||||
}
|
||||
|
||||
os.Setenv(ExperimentalEnvVar, ExperimentalSelectorExplicit)
|
||||
defer os.Unsetenv(ExperimentalEnvVar)
|
||||
os.Setenv(envvar.Experimental, ExperimentalSelectorExplicit)
|
||||
defer os.Unsetenv(envvar.Experimental)
|
||||
|
||||
runFilterSubHelmFilesTests(desiredTestcases, files, t, "2nd 3leveldeep")
|
||||
|
||||
|
|
@ -748,8 +749,8 @@ releases:
|
|||
{label: "select!=foo", expectedReleases: []string{"grafana", "prometheus", "zipkin", "prometheus", "zipkin", "mongodb"}, expectErr: false},
|
||||
}
|
||||
|
||||
os.Setenv(ExperimentalEnvVar, ExperimentalSelectorExplicit)
|
||||
defer os.Unsetenv(ExperimentalEnvVar)
|
||||
os.Setenv(envvar.Experimental, ExperimentalSelectorExplicit)
|
||||
defer os.Unsetenv(envvar.Experimental)
|
||||
|
||||
runFilterSubHelmFilesTests(desiredTestcases, files, t, "2nd inherits")
|
||||
|
||||
|
|
@ -867,7 +868,7 @@ tillerNs: INLINE_TILLER_NS_2
|
|||
Namespace: "",
|
||||
Selectors: []string{},
|
||||
Env: "default",
|
||||
FileOrDir: "helmfile.yaml",
|
||||
FileOrDir: "/path/to/helmfile.yaml",
|
||||
}, files)
|
||||
|
||||
expectNoCallsToHelm(app)
|
||||
|
|
@ -2871,6 +2872,7 @@ backend-v1 4 Fri Nov 1 08:40:07 2019 DEPLOYED backend-3.1.0 3.1.0
|
|||
{Name: "frontend-v1", Flags: []string{}},
|
||||
},
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -3049,6 +3051,7 @@ DELETED RELEASES:
|
|||
NAME
|
||||
frontend-v1
|
||||
backend-v1
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
//
|
||||
|
|
@ -3114,6 +3117,7 @@ releases:
|
|||
deleted: []exectest.Release{},
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -3172,6 +3176,7 @@ baz stable/mychart3
|
|||
bar stable/mychart2
|
||||
foo stable/mychart1
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
//
|
||||
|
|
@ -3218,6 +3223,7 @@ baz 4 Fri Nov 1 08:40:07 2019 DEPLOYED mychart3-3.1.0 3.1.0 defau
|
|||
deleted: []exectest.Release{},
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -3280,6 +3286,7 @@ baz stable/mychart3 3.1.0
|
|||
bar stable/mychart2 3.1.0
|
||||
foo stable/mychart1
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
//
|
||||
|
|
@ -3326,6 +3333,7 @@ baz 4 Fri Nov 1 08:40:07 2019 DEPLOYED mychart3-3.1.0 3.1.0 defau
|
|||
deleted: []exectest.Release{},
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -3388,6 +3396,7 @@ baz stable/mychart3 3.1.0
|
|||
bar stable/mychart2 3.1.0
|
||||
foo stable/mychart1
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
//
|
||||
|
|
@ -3594,6 +3603,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -3653,6 +3663,7 @@ NAME CHART VERSION
|
|||
foo stable/mychart1
|
||||
bar stable/mychart2
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
//
|
||||
|
|
@ -3911,6 +3922,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -3992,6 +4004,7 @@ NAME CHART VERSION
|
|||
external-secrets incubator/raw
|
||||
my-release incubator/raw
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
|
@ -4038,6 +4051,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -4101,6 +4115,7 @@ merged environment: &{default map[] map[]}
|
|||
2 release(s) matching app=test found in helmfile.yaml
|
||||
|
||||
err: release "default/default/external-secrets" depends on "default/kube-system/kubernetes-external-secrets" which does not match the selectors. Please add a selector like "--selector name=kubernetes-external-secrets", or indicate whether to skip (--skip-needs) or include (--include-needs) these dependencies
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
|
@ -4140,6 +4155,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -4202,6 +4218,7 @@ second-pass rendering result of "helmfile.yaml.part.0":
|
|||
merged environment: &{default map[] map[]}
|
||||
0 release(s) matching app=test_non_existent found in helmfile.yaml
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
//
|
||||
|
|
@ -4233,6 +4250,7 @@ releases:
|
|||
concurrency: 1,
|
||||
error: `in ./helmfile.yaml: release "default//foo" depends on "default/ns1/bar" which does not match the selectors. Please add a selector like "--selector name=bar", or indicate whether to skip (--skip-needs) or include (--include-needs) these dependencies`,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -4268,6 +4286,7 @@ merged environment: &{default map[] map[]}
|
|||
1 release(s) matching name=foo found in helmfile.yaml
|
||||
|
||||
err: release "default//foo" depends on "default/ns1/bar" which does not match the selectors. Please add a selector like "--selector name=bar", or indicate whether to skip (--skip-needs) or include (--include-needs) these dependencies
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
|
@ -4295,6 +4314,7 @@ releases:
|
|||
concurrency: 1,
|
||||
error: "in ./helmfile.yaml: release(s) \"default//foo\" depend(s) on an undefined release \"default/ns1/bar\". Perhaps you made a typo in \"needs\" or forgot defining a release named \"bar\" with appropriate \"namespace\" and \"kubeContext\"?",
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -4330,6 +4350,7 @@ merged environment: &{default map[] map[]}
|
|||
2 release(s) found in helmfile.yaml
|
||||
|
||||
err: release(s) "default//foo" depend(s) on an undefined release "default/ns1/bar". Perhaps you made a typo in "needs" or forgot defining a release named "bar" with appropriate "namespace" and "kubeContext"?
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
|
@ -4361,6 +4382,7 @@ releases:
|
|||
concurrency: 1,
|
||||
error: "in ./helmfile.yaml: found 2 duplicate releases with ID \"default//foo\"",
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -4402,6 +4424,7 @@ second-pass rendering result of "helmfile.yaml.part.0":
|
|||
|
||||
merged environment: &{default map[] map[]}
|
||||
err: found 2 duplicate releases with ID "default//foo"
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
|
@ -4560,6 +4583,7 @@ releases:
|
|||
"/path/to/charts/example/Chart.yaml": `foo: FOO`,
|
||||
},
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -4591,6 +4615,7 @@ merged environment: &{default map[] map[]}
|
|||
There are no repositories defined in your helmfile.yaml.
|
||||
This means helmfile cannot update your dependencies or create a lock file.
|
||||
See https://github.com/roboll/helmfile/issues/878 for more information.
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
charts: []string{"/path/to/charts/example"},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,20 +3,21 @@ package app
|
|||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/envvar"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultHelmfile = "helmfile.yaml"
|
||||
DeprecatedHelmfile = "charts.yaml"
|
||||
DefaultHelmfileDirectory = "helmfile.d"
|
||||
ExperimentalEnvVar = "HELMFILE_EXPERIMENTAL" // environment variable for experimental features, expecting "true" lower case
|
||||
ExperimentalSelectorExplicit = "explicit-selector-inheritance" // value to remove default selector inheritance to sub-helmfiles and use the explicit one
|
||||
)
|
||||
|
||||
func experimentalModeEnabled() bool {
|
||||
return os.Getenv(ExperimentalEnvVar) == "true"
|
||||
return os.Getenv(envvar.Experimental) == "true"
|
||||
}
|
||||
|
||||
func isExplicitSelectorInheritanceEnabled() bool {
|
||||
return experimentalModeEnabled() || strings.Contains(os.Getenv(ExperimentalEnvVar), ExperimentalSelectorExplicit)
|
||||
return experimentalModeEnabled() || strings.Contains(os.Getenv(envvar.Experimental), ExperimentalSelectorExplicit)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,49 +5,50 @@ import (
|
|||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/envvar"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestIsExplicitSelectorInheritanceEnabled tests the isExplicitSelectorInheritanceEnabled function
|
||||
func TestIsExplicitSelectorInheritanceEnabled(t *testing.T) {
|
||||
//env var ExperimentalEnvVar is not set
|
||||
require.Empty(t, os.Getenv(ExperimentalEnvVar))
|
||||
require.Empty(t, os.Getenv(envvar.Experimental))
|
||||
require.False(t, isExplicitSelectorInheritanceEnabled())
|
||||
|
||||
//check for env var ExperimentalEnvVar set to true
|
||||
os.Setenv(ExperimentalEnvVar, "true")
|
||||
os.Setenv(envvar.Experimental, "true")
|
||||
require.True(t, isExplicitSelectorInheritanceEnabled())
|
||||
|
||||
//check for env var ExperimentalEnvVar set to anything
|
||||
os.Setenv(ExperimentalEnvVar, "anything")
|
||||
os.Setenv(envvar.Experimental, "anything")
|
||||
require.False(t, isExplicitSelectorInheritanceEnabled())
|
||||
|
||||
//check for env var ExperimentalEnvVar set to ExperimentalSelectorExplicit
|
||||
os.Setenv(ExperimentalEnvVar, ExperimentalSelectorExplicit)
|
||||
os.Setenv(envvar.Experimental, ExperimentalSelectorExplicit)
|
||||
require.True(t, isExplicitSelectorInheritanceEnabled())
|
||||
|
||||
// check for env var ExperimentalEnvVar set to a string that contains ExperimentalSelectorExplicit and ExperimentalEnvVar set to true
|
||||
os.Setenv(ExperimentalEnvVar, fmt.Sprintf("%s-%s-%s", "a", ExperimentalSelectorExplicit, "b"))
|
||||
os.Setenv(envvar.Experimental, fmt.Sprintf("%s-%s-%s", "a", ExperimentalSelectorExplicit, "b"))
|
||||
require.True(t, isExplicitSelectorInheritanceEnabled())
|
||||
|
||||
// reset env var
|
||||
defer os.Unsetenv(ExperimentalEnvVar)
|
||||
defer os.Unsetenv(envvar.Experimental)
|
||||
}
|
||||
|
||||
// TestExperimentalModeEnabled tests the experimentalModeEnabled function
|
||||
func TestExperimentalModeEnabled(t *testing.T) {
|
||||
//env var ExperimentalEnvVar is not set
|
||||
require.Empty(t, os.Getenv(ExperimentalEnvVar))
|
||||
require.Empty(t, os.Getenv(envvar.Experimental))
|
||||
require.False(t, experimentalModeEnabled())
|
||||
|
||||
//check for env var ExperimentalEnvVar set to anything
|
||||
os.Setenv(ExperimentalEnvVar, "anything")
|
||||
os.Setenv(envvar.Experimental, "anything")
|
||||
require.False(t, experimentalModeEnabled())
|
||||
|
||||
//check for env var ExperimentalEnvVar set to true
|
||||
os.Setenv(ExperimentalEnvVar, "true")
|
||||
os.Setenv(envvar.Experimental, "true")
|
||||
require.True(t, experimentalModeEnabled())
|
||||
|
||||
// reset env var
|
||||
defer os.Unsetenv(ExperimentalEnvVar)
|
||||
defer os.Unsetenv(envvar.Experimental)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ anotherbackend 4 Fri Nov 1 08:40:07 2019 DEPLOYED anotherbackend-3.1.0
|
|||
{Name: "logging", Flags: []string{}},
|
||||
},
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -441,6 +442,7 @@ servicemesh
|
|||
database
|
||||
front-proxy
|
||||
logging
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -487,6 +489,7 @@ anotherbackend 4 Fri Nov 1 08:40:07 2019 DEPLOYED anotherbackend-3.1.0
|
|||
{Name: "logging", Flags: []string{}},
|
||||
},
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -621,6 +624,7 @@ release "logging" processed
|
|||
DELETED RELEASES:
|
||||
NAME
|
||||
logging
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -642,6 +646,7 @@ logging
|
|||
{Name: "frontend-v1", Flags: []string{}},
|
||||
},
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -690,6 +695,7 @@ DELETED RELEASES:
|
|||
NAME
|
||||
frontend-v1
|
||||
backend-v1
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -712,6 +718,7 @@ backend-v1
|
|||
{Name: "frontend-v1", Flags: []string{}},
|
||||
},
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -760,6 +767,7 @@ DELETED RELEASES:
|
|||
NAME
|
||||
frontend-v1
|
||||
backend-v1
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -321,6 +321,7 @@ anotherbackend 4 Fri Nov 1 08:40:07 2019 DEPLOYED anotherbackend-3.1.0
|
|||
{Name: "logging", Flags: []string{}},
|
||||
},
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -481,6 +482,7 @@ servicemesh
|
|||
database
|
||||
front-proxy
|
||||
logging
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -527,6 +529,7 @@ anotherbackend 4 Fri Nov 1 08:40:07 2019 DEPLOYED anotherbackend-3.1.0
|
|||
{Name: "logging", Flags: []string{}},
|
||||
},
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -661,6 +664,7 @@ release "logging" processed
|
|||
DELETED RELEASES:
|
||||
NAME
|
||||
logging
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -682,6 +686,7 @@ logging
|
|||
{Name: "frontend-v1", Flags: []string{}},
|
||||
},
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -730,6 +735,7 @@ DELETED RELEASES:
|
|||
NAME
|
||||
frontend-v1
|
||||
backend-v1
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
@ -752,6 +758,7 @@ backend-v1
|
|||
{Name: "frontend-v1", Flags: []string{}},
|
||||
},
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -800,6 +807,7 @@ DELETED RELEASES:
|
|||
NAME
|
||||
frontend-v1
|
||||
backend-v1
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ backend-v1 4 Fri Nov 1 08:40:07 2019 DEPLOYED backend-3.1.0 3.1.0
|
|||
upgraded: []exectest.Release{},
|
||||
deleted: []exectest.Release{},
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -263,6 +264,7 @@ Affected releases are:
|
|||
logging (charts/fluent-bit) UPDATED
|
||||
servicemesh (charts/istio) UPDATED
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
//
|
||||
|
|
@ -328,6 +330,7 @@ releases:
|
|||
deleted: []exectest.Release{},
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -369,6 +372,7 @@ Affected releases are:
|
|||
baz (mychart3) UPDATED
|
||||
foo (mychart1) UPDATED
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
//
|
||||
|
|
@ -567,6 +571,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -611,6 +616,7 @@ Affected releases are:
|
|||
bar (mychart2) UPDATED
|
||||
foo (mychart1) UPDATED
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
|
@ -639,6 +645,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -679,6 +686,7 @@ Affected releases are:
|
|||
bar (mychart2) UPDATED
|
||||
foo (mychart1) UPDATED
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
//
|
||||
|
|
@ -924,6 +932,7 @@ releases:
|
|||
concurrency: 1,
|
||||
error: "Identified at least one change",
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -990,6 +999,7 @@ Affected releases are:
|
|||
external-secrets (incubator/raw) UPDATED
|
||||
my-release (incubator/raw) UPDATED
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
|
@ -1033,6 +1043,7 @@ releases:
|
|||
concurrency: 1,
|
||||
error: `in ./helmfile.yaml: release "default/external-secrets" depends on "kube-system/kubernetes-external-secrets" which does not match the selectors. Please add a selector like "--selector name=kubernetes-external-secrets", or indicate whether to skip (--skip-needs) or include (--include-needs) these dependencies`,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -1096,6 +1107,7 @@ merged environment: &{default map[] map[]}
|
|||
2 release(s) matching app=test found in helmfile.yaml
|
||||
|
||||
err: release "default/external-secrets" depends on "kube-system/kubernetes-external-secrets" which does not match the selectors. Please add a selector like "--selector name=kubernetes-external-secrets", or indicate whether to skip (--skip-needs) or include (--include-needs) these dependencies
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
|
@ -1136,6 +1148,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -1198,6 +1211,7 @@ second-pass rendering result of "helmfile.yaml.part.0":
|
|||
merged environment: &{default map[] map[]}
|
||||
0 release(s) matching app=test_non_existent found in helmfile.yaml
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
//
|
||||
|
|
@ -1229,6 +1243,7 @@ releases:
|
|||
concurrency: 1,
|
||||
error: `in ./helmfile.yaml: release(s) "foo" depend(s) on an undefined release "bar". Perhaps you made a typo in "needs" or forgot defining a release named "bar" with appropriate "namespace" and "kubeContext"?`,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -1264,6 +1279,7 @@ merged environment: &{default map[] map[]}
|
|||
2 release(s) found in helmfile.yaml
|
||||
|
||||
err: release(s) "foo" depend(s) on an undefined release "bar". Perhaps you made a typo in "needs" or forgot defining a release named "bar" with appropriate "namespace" and "kubeContext"?
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,6 +247,7 @@ backend-v1 4 Fri Nov 1 08:40:07 2019 DEPLOYED backend-3.1.0 3.1.0
|
|||
upgraded: []exectest.Release{},
|
||||
deleted: []exectest.Release{},
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -382,6 +383,7 @@ Affected releases are:
|
|||
logging (charts/fluent-bit) UPDATED
|
||||
servicemesh (charts/istio) UPDATED
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
//
|
||||
|
|
@ -447,6 +449,7 @@ releases:
|
|||
deleted: []exectest.Release{},
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -488,6 +491,7 @@ Affected releases are:
|
|||
baz (mychart3) UPDATED
|
||||
foo (mychart1) UPDATED
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
//
|
||||
|
|
@ -686,6 +690,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -730,6 +735,7 @@ Affected releases are:
|
|||
bar (mychart2) UPDATED
|
||||
foo (mychart1) UPDATED
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
|
@ -758,6 +764,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -798,6 +805,7 @@ Affected releases are:
|
|||
bar (mychart2) UPDATED
|
||||
foo (mychart1) UPDATED
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
//
|
||||
|
|
@ -1043,6 +1051,7 @@ releases:
|
|||
concurrency: 1,
|
||||
error: "Identified at least one change",
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -1109,6 +1118,7 @@ Affected releases are:
|
|||
external-secrets (incubator/raw) UPDATED
|
||||
my-release (incubator/raw) UPDATED
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
|
@ -1152,6 +1162,7 @@ releases:
|
|||
concurrency: 1,
|
||||
error: `in ./helmfile.yaml: release "default/default/external-secrets" depends on "default/kube-system/kubernetes-external-secrets" which does not match the selectors. Please add a selector like "--selector name=kubernetes-external-secrets", or indicate whether to skip (--skip-needs) or include (--include-needs) these dependencies`,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -1215,6 +1226,7 @@ merged environment: &{default map[] map[]}
|
|||
2 release(s) matching app=test found in helmfile.yaml
|
||||
|
||||
err: release "default/default/external-secrets" depends on "default/kube-system/kubernetes-external-secrets" which does not match the selectors. Please add a selector like "--selector name=kubernetes-external-secrets", or indicate whether to skip (--skip-needs) or include (--include-needs) these dependencies
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
|
@ -1255,6 +1267,7 @@ releases:
|
|||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -1317,6 +1330,7 @@ second-pass rendering result of "helmfile.yaml.part.0":
|
|||
merged environment: &{default map[] map[]}
|
||||
0 release(s) matching app=test_non_existent found in helmfile.yaml
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
//
|
||||
|
|
@ -1349,6 +1363,7 @@ releases:
|
|||
concurrency: 1,
|
||||
error: `in ./helmfile.yaml: release "default//foo" depends on "default//bar" which does not match the selectors. Please add a selector like "--selector name=bar", or indicate whether to skip (--skip-needs) or include (--include-needs) these dependencies`,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -1382,6 +1397,7 @@ merged environment: &{default map[] map[]}
|
|||
1 release(s) matching name=foo found in helmfile.yaml
|
||||
|
||||
err: release "default//foo" depends on "default//bar" which does not match the selectors. Please add a selector like "--selector name=bar", or indicate whether to skip (--skip-needs) or include (--include-needs) these dependencies
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
|
@ -1410,6 +1426,7 @@ releases:
|
|||
concurrency: 1,
|
||||
error: `in ./helmfile.yaml: release(s) "default//foo" depend(s) on an undefined release "default//bar". Perhaps you made a typo in "needs" or forgot defining a release named "bar" with appropriate "namespace" and "kubeContext"?`,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -1445,6 +1462,7 @@ merged environment: &{default map[] map[]}
|
|||
2 release(s) found in helmfile.yaml
|
||||
|
||||
err: release(s) "default//foo" depend(s) on an undefined release "default//bar". Perhaps you made a typo in "needs" or forgot defining a release named "bar" with appropriate "namespace" and "kubeContext"?
|
||||
changing working directory back to "/path/to"
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -63,3 +64,4 @@ UPDATED RELEASES:
|
|||
NAME CHART VERSION
|
||||
foo incubator/raw
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -41,3 +42,4 @@ second-pass rendering result of "helmfile.yaml.part.0":
|
|||
merged environment: &{default map[] map[]}
|
||||
0 release(s) matching app=foo found in helmfile.yaml
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
processing file "helmfile.yaml" in directory "."
|
||||
changing working directory to "/path/to"
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
|
|
@ -67,3 +68,4 @@ UPDATED RELEASES:
|
|||
NAME CHART VERSION
|
||||
foo incubator/raw
|
||||
|
||||
changing working directory back to "/path/to"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
package envvar
|
||||
|
||||
const DisableInsecureFeatures = "HELMFILE_DISABLE_INSECURE_FEATURES"
|
||||
const SkipInsecureTemplateFunctions = "HELMFILE_SKIP_INSECURE_TEMPLATE_FUNCTIONS"
|
||||
const Experimental = "HELMFILE_EXPERIMENTAL" // environment variable for experimental features, expecting "true" lower case
|
||||
const Environment = "HELMFILE_ENVIRONMENT"
|
||||
const TempDir = "HELMFILE_TEMPDIR"
|
||||
const Helm3 = "HELMFILE_HELM3"
|
||||
|
|
@ -12,6 +12,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/helmfile/helmfile/pkg/envvar"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
|
@ -65,7 +66,7 @@ func parseHelmVersion(versionStr string) (semver.Version, error) {
|
|||
}
|
||||
|
||||
// Support explicit helm3 opt-in via environment variable
|
||||
if os.Getenv("HELMFILE_HELM3") != "" && ver.Major() < 3 {
|
||||
if os.Getenv(envvar.Helm3) != "" && ver.Major() < 3 {
|
||||
return *semver.MustParse("v3.0.0"), nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/helmfile/helmfile/pkg/envvar"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"go.uber.org/zap"
|
||||
|
|
@ -794,13 +795,13 @@ func Test_IsHelm3(t *testing.T) {
|
|||
t.Error("helmexec.IsHelm3() - Failed to detect Helm 3")
|
||||
}
|
||||
|
||||
os.Setenv("HELMFILE_HELM3", "1")
|
||||
os.Setenv(envvar.Helm3, "1")
|
||||
helm2Runner = mockRunner{output: []byte("Client: v2.16.0+ge13bc94\n")}
|
||||
helm = New("helm", NewLogger(os.Stdout, "info"), "dev", &helm2Runner)
|
||||
if !helm.IsHelm3() {
|
||||
t.Error("helmexec.IsHelm3() - Helm3 not detected when HELMFILE_HELM3 is set")
|
||||
t.Errorf("helmexec.IsHelm3() - Helm3 not detected when %s is set", envvar.Helm3)
|
||||
}
|
||||
os.Setenv("HELMFILE_HELM3", "")
|
||||
os.Setenv(envvar.Helm3, "")
|
||||
}
|
||||
|
||||
func Test_GetVersion(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -7,15 +7,23 @@ import (
|
|||
neturl "net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/go-getter"
|
||||
"github.com/hashicorp/go-getter/helper/url"
|
||||
"github.com/helmfile/helmfile/pkg/envvar"
|
||||
"go.uber.org/multierr"
|
||||
"go.uber.org/zap"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
var disableInsecureFeatures bool
|
||||
|
||||
func init() {
|
||||
disableInsecureFeatures, _ = strconv.ParseBool(os.Getenv(envvar.DisableInsecureFeatures))
|
||||
}
|
||||
|
||||
func CacheDir() string {
|
||||
dir, err := os.UserCacheDir()
|
||||
if err != nil {
|
||||
|
|
@ -279,6 +287,9 @@ func (g *GoGetter) Get(wd, src, dst string) error {
|
|||
}
|
||||
|
||||
func NewRemote(logger *zap.SugaredLogger, homeDir string, readFile func(string) ([]byte, error), dirExists func(string) bool, fileExists func(string) bool) *Remote {
|
||||
if disableInsecureFeatures {
|
||||
panic("Remote sources are disabled due to 'DISABLE_INSECURE_FEATURES'")
|
||||
}
|
||||
remote := &Remote{
|
||||
Logger: logger,
|
||||
Home: homeDir,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/helmfile/helmfile/pkg/envvar"
|
||||
"k8s.io/apimachinery/pkg/util/rand"
|
||||
)
|
||||
|
||||
|
|
@ -32,7 +33,7 @@ func tempValuesFilePath(release *ReleaseSpec, data interface{}) (*string, error)
|
|||
panic(err)
|
||||
}
|
||||
|
||||
workDir := os.Getenv("HELMFILE_TEMPDIR")
|
||||
workDir := os.Getenv(envvar.TempDir)
|
||||
if workDir == "" {
|
||||
workDir, err = os.MkdirTemp(os.TempDir(), "helmfile")
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -8,16 +8,38 @@ import (
|
|||
"os/exec"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/helmfile/helmfile/pkg/envvar"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
type Values = map[string]interface{}
|
||||
|
||||
var DisableInsecureFeaturesErr = DisableInsecureFeaturesError{envvar.DisableInsecureFeatures + " is active, insecure function calls are disabled"}
|
||||
|
||||
type DisableInsecureFeaturesError struct {
|
||||
err string
|
||||
}
|
||||
|
||||
func (e DisableInsecureFeaturesError) Error() string {
|
||||
return e.err
|
||||
}
|
||||
|
||||
var (
|
||||
disableInsecureFeatures bool
|
||||
skipInsecureTemplateFunctions bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
disableInsecureFeatures, _ = strconv.ParseBool(os.Getenv(envvar.DisableInsecureFeatures))
|
||||
skipInsecureTemplateFunctions, _ = strconv.ParseBool(os.Getenv(envvar.SkipInsecureTemplateFunctions))
|
||||
}
|
||||
|
||||
func (c *Context) createFuncMap() template.FuncMap {
|
||||
funcMap := template.FuncMap{
|
||||
"envExec": c.EnvExec,
|
||||
|
|
@ -36,7 +58,7 @@ func (c *Context) createFuncMap() template.FuncMap {
|
|||
"fetchSecretValue": fetchSecretValue,
|
||||
"expandSecretRefs": fetchSecretValues,
|
||||
}
|
||||
if c.preRender {
|
||||
if c.preRender || skipInsecureTemplateFunctions {
|
||||
// disable potential side-effect template calls
|
||||
funcMap["exec"] = func(string, []interface{}, ...string) (string, error) {
|
||||
return "", nil
|
||||
|
|
@ -48,6 +70,15 @@ func (c *Context) createFuncMap() template.FuncMap {
|
|||
return "", nil
|
||||
}
|
||||
}
|
||||
if disableInsecureFeatures {
|
||||
// disable insecure functions
|
||||
funcMap["exec"] = func(string, []interface{}, ...string) (string, error) {
|
||||
return "", DisableInsecureFeaturesErr
|
||||
}
|
||||
funcMap["readFile"] = func(string) (string, error) {
|
||||
return "", DisableInsecureFeaturesErr
|
||||
}
|
||||
}
|
||||
|
||||
return funcMap
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,57 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCreateFuncMap(t *testing.T) {
|
||||
currentVal := disableInsecureFeatures
|
||||
|
||||
{
|
||||
disableInsecureFeatures = false
|
||||
ctx := &Context{basePath: "."}
|
||||
funcMaps := ctx.createFuncMap()
|
||||
args := make([]interface{}, 0)
|
||||
outputExec, _ := funcMaps["exec"].(func(command string, args []interface{}, inputs ...string) (string, error))("ls", args)
|
||||
require.Contains(t, outputExec, "context.go")
|
||||
}
|
||||
|
||||
disableInsecureFeatures = currentVal
|
||||
}
|
||||
|
||||
func TestCreateFuncMap_DisabledInsecureFeatures(t *testing.T) {
|
||||
currentVal := disableInsecureFeatures
|
||||
|
||||
{
|
||||
disableInsecureFeatures = true
|
||||
ctx := &Context{basePath: "."}
|
||||
funcMaps := ctx.createFuncMap()
|
||||
args := make([]interface{}, 0)
|
||||
_, err1 := funcMaps["exec"].(func(command string, args []interface{}, inputs ...string) (string, error))("ls", args)
|
||||
require.ErrorIs(t, err1, DisableInsecureFeaturesErr)
|
||||
_, err2 := funcMaps["readFile"].(func(filename string) (string, error))("context_funcs_test.go")
|
||||
require.ErrorIs(t, err2, DisableInsecureFeaturesErr)
|
||||
}
|
||||
|
||||
disableInsecureFeatures = currentVal
|
||||
}
|
||||
|
||||
func TestCreateFuncMap_SkipInsecureTemplateFunctions(t *testing.T) {
|
||||
currentVal := skipInsecureTemplateFunctions
|
||||
|
||||
{
|
||||
skipInsecureTemplateFunctions = true
|
||||
ctx := &Context{basePath: "."}
|
||||
funcMaps := ctx.createFuncMap()
|
||||
args := make([]interface{}, 0)
|
||||
actual1, err1 := funcMaps["exec"].(func(command string, args []interface{}, inputs ...string) (string, error))("ls", args)
|
||||
require.Equal(t, "", actual1)
|
||||
require.ErrorIs(t, err1, nil)
|
||||
actual2, err2 := funcMaps["readFile"].(func(filename string) (string, error))("context_funcs_test.go")
|
||||
require.Equal(t, "", actual2)
|
||||
require.ErrorIs(t, err2, nil)
|
||||
}
|
||||
|
||||
skipInsecureTemplateFunctions = currentVal
|
||||
}
|
||||
|
||||
func TestReadFile(t *testing.T) {
|
||||
expected := `foo:
|
||||
bar: BAR
|
||||
|
|
|
|||
Loading…
Reference in New Issue