mirror of
https://github.com/helmfile/helmfile.git
synced 2026-10-06 20:27:20 +02:00
Support for createNamespace (#1226)
- createNamespace is a new attribute that can be added to helmDefaults or an individual release to enforce the creation of a release namespace during sync if the namespace does not exist. This leverages helm's (3.2+) --create-namespace flag for the install/upgrade command. If running helm < 3.2, the createNamespace attribute has no effect. Resolves #891 Resolves #1140
This commit is contained in:
+55
-9
@@ -6,6 +6,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -21,7 +22,7 @@ type decryptedSecret struct {
|
||||
|
||||
type execer struct {
|
||||
helmBinary string
|
||||
isHelm3 bool
|
||||
version Version
|
||||
runner Runner
|
||||
logger *zap.SugaredLogger
|
||||
kubeContext string
|
||||
@@ -47,25 +48,62 @@ func NewLogger(writer io.Writer, logLevel string) *zap.SugaredLogger {
|
||||
return zap.New(core).Sugar()
|
||||
}
|
||||
|
||||
func detectHelm3(helmBinary string, logger *zap.SugaredLogger, runner Runner) bool {
|
||||
// Support explicit opt-in via environment variable
|
||||
if os.Getenv("HELMFILE_HELM3") != "" {
|
||||
return true
|
||||
}
|
||||
func getHelmVersion(helmBinary string, logger *zap.SugaredLogger, runner Runner) Version {
|
||||
|
||||
// Autodetect from `helm verison`
|
||||
bytes, err := runner.Execute(helmBinary, []string{"version", "--client", "--short"}, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return strings.HasPrefix(string(bytes), "v3.")
|
||||
|
||||
if bytes == nil || len(bytes) == 0 {
|
||||
return Version{}
|
||||
}
|
||||
|
||||
re := regexp.MustCompile("v(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)")
|
||||
matches := re.FindStringSubmatch(string(bytes))
|
||||
|
||||
result := make(map[string]string)
|
||||
for i, name := range re.SubexpNames() {
|
||||
result[name] = matches[i]
|
||||
}
|
||||
|
||||
major, err := strconv.Atoi(result["major"])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
minor, err := strconv.Atoi(result["minor"])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
patch, err := strconv.Atoi(result["patch"])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Support explicit helm3 opt-in via environment variable
|
||||
if os.Getenv("HELMFILE_HELM3") != "" && major < 3 {
|
||||
return Version{
|
||||
Major: 3,
|
||||
Minor: 0,
|
||||
Patch: 0,
|
||||
}
|
||||
}
|
||||
|
||||
return Version{
|
||||
Major: major,
|
||||
Minor: minor,
|
||||
Patch: patch,
|
||||
}
|
||||
}
|
||||
|
||||
// New for running helm commands
|
||||
func New(helmBinary string, logger *zap.SugaredLogger, kubeContext string, runner Runner) *execer {
|
||||
return &execer{
|
||||
helmBinary: helmBinary,
|
||||
isHelm3: detectHelm3(helmBinary, logger, runner),
|
||||
version: getHelmVersion(helmBinary, logger, runner),
|
||||
logger: logger,
|
||||
kubeContext: kubeContext,
|
||||
runner: runner,
|
||||
@@ -349,5 +387,13 @@ func (helm *execer) write(out []byte) {
|
||||
}
|
||||
|
||||
func (helm *execer) IsHelm3() bool {
|
||||
return helm.isHelm3
|
||||
return helm.version.Major == 3
|
||||
}
|
||||
|
||||
func (helm *execer) GetVersion() Version {
|
||||
return helm.version
|
||||
}
|
||||
|
||||
func (helm *execer) IsVersionAtLeast(major int, minor int) bool {
|
||||
return helm.version.Major >= major && helm.version.Minor >= minor
|
||||
}
|
||||
|
||||
@@ -528,4 +528,45 @@ func Test_IsHelm3(t *testing.T) {
|
||||
if !helm.IsHelm3() {
|
||||
t.Error("helmexec.IsHelm3() - Failed to detect Helm 3")
|
||||
}
|
||||
|
||||
os.Setenv("HELMFILE_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")
|
||||
}
|
||||
os.Setenv("HELMFILE_HELM3", "")
|
||||
}
|
||||
|
||||
func Test_GetVersion(t *testing.T) {
|
||||
helm2Runner := mockRunner{output: []byte("Client: v2.16.1+ge13bc94\n")}
|
||||
helm := New("helm", NewLogger(os.Stdout, "info"), "dev", &helm2Runner)
|
||||
ver := helm.GetVersion()
|
||||
if ver.Major != 2 || ver.Minor != 16 || ver.Patch != 1 {
|
||||
t.Error(fmt.Sprintf("helmexec.GetVersion - did not detect correct Helm2 version; it was: %+v", ver))
|
||||
}
|
||||
|
||||
helm3Runner := mockRunner{output: []byte("v3.2.4+ge29ce2a\n")}
|
||||
helm = New("helm", NewLogger(os.Stdout, "info"), "dev", &helm3Runner)
|
||||
ver = helm.GetVersion()
|
||||
if ver.Major != 3 || ver.Minor != 2 || ver.Patch != 4 {
|
||||
t.Error(fmt.Sprintf("helmexec.GetVersion - did not detect correct Helm3 version; it was: %+v", ver))
|
||||
}
|
||||
}
|
||||
|
||||
func Test_IsVersionAtLeast(t *testing.T) {
|
||||
helm2Runner := mockRunner{output: []byte("Client: v2.16.1+ge13bc94\n")}
|
||||
helm := New("helm", NewLogger(os.Stdout, "info"), "dev", &helm2Runner)
|
||||
if !helm.IsVersionAtLeast(2, 1) {
|
||||
t.Error("helmexec.IsVersionAtLeast - 2.16.1 not atleast 2.1")
|
||||
}
|
||||
|
||||
if helm.IsVersionAtLeast(2, 19) {
|
||||
t.Error("helmexec.IsVersionAtLeast - 2.16.1 is atleast 2.19")
|
||||
}
|
||||
|
||||
if helm.IsVersionAtLeast(3, 2) {
|
||||
t.Error("helmexec.IsVersionAtLeast - 2.16.1 is atleast 3.2")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
package helmexec
|
||||
|
||||
// Version represents the version of helm
|
||||
type Version struct {
|
||||
Major int
|
||||
Minor int
|
||||
Patch int
|
||||
}
|
||||
|
||||
// Interface for executing helm commands
|
||||
type Interface interface {
|
||||
SetExtraArgs(args ...string)
|
||||
@@ -20,6 +27,8 @@ type Interface interface {
|
||||
List(context HelmContext, filter string, flags ...string) (string, error)
|
||||
DecryptSecret(context HelmContext, name string, flags ...string) (string, error)
|
||||
IsHelm3() bool
|
||||
GetVersion() Version
|
||||
IsVersionAtLeast(major int, minor int) bool
|
||||
}
|
||||
|
||||
type DependencyUpdater interface {
|
||||
|
||||
Reference in New Issue
Block a user