fix: panic when using helm v3.3 (#1427) (#1428)

This commit is contained in:
Anatoly Rugalev 2020-08-24 02:57:17 +03:00 committed by GitHub
parent a9aa7af572
commit 90a41222e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 28 deletions

View File

@ -48,40 +48,28 @@ func NewLogger(writer io.Writer, logLevel string) *zap.SugaredLogger {
return zap.New(core).Sugar()
}
func getHelmVersion(helmBinary string, logger *zap.SugaredLogger, runner Runner) Version {
// versionRegex matches versions like v1.1.1 and v1.1
var versionRegex = regexp.MustCompile("v(?P<major>\\d+)\\.(?P<minor>\\d+)(?:\\.(?P<patch>\\d+))?")
// Autodetect from `helm verison`
bytes, err := runner.Execute(helmBinary, []string{"version", "--client", "--short"}, nil)
if err != nil {
panic(err)
func parseHelmVersion(versionStr string) (Version, error) {
if len(versionStr) == 0 {
return Version{}, nil
}
if bytes == nil || len(bytes) == 0 {
return Version{}
matches := versionRegex.FindStringSubmatch(versionStr)
if len(matches) == 0 {
return Version{}, fmt.Errorf("error parsing helm verion '%s'", versionStr)
}
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() {
for i, name := range versionRegex.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)
}
// We ignore errors because regex matches only integers
// If any of the parts does not exist - default "0" will be used
major, _ := strconv.Atoi(result["major"])
minor, _ := strconv.Atoi(result["minor"])
patch, _ := strconv.Atoi(result["patch"])
// Support explicit helm3 opt-in via environment variable
if os.Getenv("HELMFILE_HELM3") != "" && major < 3 {
@ -89,21 +77,37 @@ func getHelmVersion(helmBinary string, logger *zap.SugaredLogger, runner Runner)
Major: 3,
Minor: 0,
Patch: 0,
}
}, nil
}
return Version{
Major: major,
Minor: minor,
Patch: patch,
}, nil
}
func getHelmVersion(helmBinary string, runner Runner) (Version, error) {
// Autodetect from `helm verison`
bytes, err := runner.Execute(helmBinary, []string{"version", "--client", "--short"}, nil)
if err != nil {
return Version{}, fmt.Errorf("error determining helm version: %w", err)
}
return parseHelmVersion(string(bytes))
}
// New for running helm commands
func New(helmBinary string, logger *zap.SugaredLogger, kubeContext string, runner Runner) *execer {
// TODO: proper error handling
version, err := getHelmVersion(helmBinary, runner)
if err != nil {
panic(err)
}
return &execer{
helmBinary: helmBinary,
version: getHelmVersion(helmBinary, logger, runner),
version: version,
logger: logger,
kubeContext: kubeContext,
runner: runner,

View File

@ -570,3 +570,50 @@ func Test_IsVersionAtLeast(t *testing.T) {
}
}
func Test_parseHelmVersion(t *testing.T) {
tests := []struct {
ver string
want Version
wantErr bool
}{
{
ver: "v1.2.3",
want: Version{
Major: 1,
Minor: 2,
Patch: 3,
},
wantErr: false,
},
{
ver: "v1.2",
want: Version{
Major: 1,
Minor: 2,
Patch: 0,
},
wantErr: false,
},
{
ver: "v1",
wantErr: true,
},
{
ver: "1.1.1",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.ver, func(t *testing.T) {
got, err := parseHelmVersion(tt.ver)
if (err != nil) != tt.wantErr {
t.Errorf("parseHelmVersion() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("parseHelmVersion() got = %v, want %v", got, tt.want)
}
})
}
}