feat: use new helm version parse function (#760)
* feat: use new helm version parse function Signed-off-by: yxxhero <aiopsclub@163.com>
This commit is contained in:
		
							parent
							
								
									bfb94314be
								
							
						
					
					
						commit
						5e8a502b41
					
				|  | @ -12,6 +12,7 @@ import ( | ||||||
| 	"sync" | 	"sync" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Masterminds/semver/v3" | 	"github.com/Masterminds/semver/v3" | ||||||
|  | 	"github.com/helmfile/chartify" | ||||||
| 	"go.uber.org/zap" | 	"go.uber.org/zap" | ||||||
| 	"go.uber.org/zap/zapcore" | 	"go.uber.org/zap/zapcore" | ||||||
| 	"helm.sh/helm/v3/pkg/chart" | 	"helm.sh/helm/v3/pkg/chart" | ||||||
|  | @ -30,7 +31,7 @@ type decryptedSecret struct { | ||||||
| type execer struct { | type execer struct { | ||||||
| 	helmBinary           string | 	helmBinary           string | ||||||
| 	enableLiveOutput     bool | 	enableLiveOutput     bool | ||||||
| 	version              semver.Version | 	version              *semver.Version | ||||||
| 	runner               Runner | 	runner               Runner | ||||||
| 	logger               *zap.SugaredLogger | 	logger               *zap.SugaredLogger | ||||||
| 	kubeContext          string | 	kubeContext          string | ||||||
|  | @ -57,27 +58,30 @@ func NewLogger(writer io.Writer, logLevel string) *zap.SugaredLogger { | ||||||
| 	return zap.New(core).Sugar() | 	return zap.New(core).Sugar() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func parseHelmVersion(versionStr string) (semver.Version, error) { | func parseHelmVersion(versionStr string) (*semver.Version, error) { | ||||||
| 	if len(versionStr) == 0 { | 	if len(versionStr) == 0 { | ||||||
| 		return semver.Version{}, nil | 		return nil, fmt.Errorf("empty helm version") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	versionStr = strings.TrimLeft(versionStr, "Client: ") | 	v, err := chartify.FindSemVerInfo(versionStr) | ||||||
| 	versionStr = strings.TrimRight(versionStr, "\n") |  | ||||||
| 
 | 
 | ||||||
| 	ver, err := semver.NewVersion(versionStr) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return semver.Version{}, fmt.Errorf("error parsing helm version '%s'", versionStr) | 		return nil, fmt.Errorf("error find helm srmver version '%s': %w", versionStr, err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return *ver, nil | 	ver, err := semver.NewVersion(v) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("error parsing helm version '%s'", versionStr) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| func GetHelmVersion(helmBinary string, runner Runner) (semver.Version, error) { | 	return ver, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func GetHelmVersion(helmBinary string, runner Runner) (*semver.Version, error) { | ||||||
| 	// Autodetect from `helm version`
 | 	// Autodetect from `helm version`
 | ||||||
| 	outBytes, err := runner.Execute(helmBinary, []string{"version", "--client", "--short"}, nil, false) | 	outBytes, err := runner.Execute(helmBinary, []string{"version", "--client", "--short"}, nil, false) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return semver.Version{}, fmt.Errorf("error determining helm version: %w", err) | 		return nil, fmt.Errorf("error determining helm version: %w", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return parseHelmVersion(string(outBytes)) | 	return parseHelmVersion(string(outBytes)) | ||||||
|  | @ -152,7 +156,7 @@ func (helm *execer) AddRepo(name, repository, cafile, certfile, keyfile, usernam | ||||||
| 
 | 
 | ||||||
| 		// See https://github.com/helm/helm/pull/8777
 | 		// See https://github.com/helm/helm/pull/8777
 | ||||||
| 		if cons, err := semver.NewConstraint(">= 3.3.2"); err == nil { | 		if cons, err := semver.NewConstraint(">= 3.3.2"); err == nil { | ||||||
| 			if cons.Check(&helm.version) { | 			if cons.Check(helm.version) { | ||||||
| 				args = append(args, "--force-update") | 				args = append(args, "--force-update") | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
|  | @ -450,7 +454,7 @@ func (helm *execer) ChartPull(chart string, path string, flags ...string) error | ||||||
| 	var helmArgs []string | 	var helmArgs []string | ||||||
| 	helm.logger.Infof("Pulling %v", chart) | 	helm.logger.Infof("Pulling %v", chart) | ||||||
| 	helmVersionConstraint, _ := semver.NewConstraint(">= 3.7.0") | 	helmVersionConstraint, _ := semver.NewConstraint(">= 3.7.0") | ||||||
| 	if helmVersionConstraint.Check(&helm.version) { | 	if helmVersionConstraint.Check(helm.version) { | ||||||
| 		// in the 3.7.0 version, the chart pull has been replaced with helm pull
 | 		// in the 3.7.0 version, the chart pull has been replaced with helm pull
 | ||||||
| 		// https://github.com/helm/helm/releases/tag/v3.7.0
 | 		// https://github.com/helm/helm/releases/tag/v3.7.0
 | ||||||
| 		ociChartURL, ociChartTag := resolveOciChart(chart) | 		ociChartURL, ociChartTag := resolveOciChart(chart) | ||||||
|  | @ -465,7 +469,7 @@ func (helm *execer) ChartPull(chart string, path string, flags ...string) error | ||||||
| 
 | 
 | ||||||
| func (helm *execer) ChartExport(chart string, path string, flags ...string) error { | func (helm *execer) ChartExport(chart string, path string, flags ...string) error { | ||||||
| 	helmVersionConstraint, _ := semver.NewConstraint(">= 3.7.0") | 	helmVersionConstraint, _ := semver.NewConstraint(">= 3.7.0") | ||||||
| 	if helmVersionConstraint.Check(&helm.version) { | 	if helmVersionConstraint.Check(helm.version) { | ||||||
| 		// in the 3.7.0 version, the chart export has been removed
 | 		// in the 3.7.0 version, the chart export has been removed
 | ||||||
| 		// https://github.com/helm/helm/releases/tag/v3.7.0
 | 		// https://github.com/helm/helm/releases/tag/v3.7.0
 | ||||||
| 		return nil | 		return nil | ||||||
|  |  | ||||||
|  | @ -8,6 +8,7 @@ import ( | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"regexp" | 	"regexp" | ||||||
|  | 	"strings" | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Masterminds/semver/v3" | 	"github.com/Masterminds/semver/v3" | ||||||
|  | @ -27,6 +28,10 @@ func (mock *mockRunner) ExecuteStdIn(cmd string, args []string, env map[string]s | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (mock *mockRunner) Execute(cmd string, args []string, env map[string]string, enableLiveOutput bool) ([]byte, error) { | func (mock *mockRunner) Execute(cmd string, args []string, env map[string]string, enableLiveOutput bool) ([]byte, error) { | ||||||
|  | 	if len(mock.output) == 0 && strings.Join(args, " ") == "version --client --short" { | ||||||
|  | 		return []byte("v3.2.4+ge29ce2a"), nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return mock.output, mock.err | 	return mock.output, mock.err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -94,7 +99,7 @@ func Test_AddRepo_Helm_3_3_2(t *testing.T) { | ||||||
| 	logger := NewLogger(&buffer, "debug") | 	logger := NewLogger(&buffer, "debug") | ||||||
| 	helm := &execer{ | 	helm := &execer{ | ||||||
| 		helmBinary:  "helm", | 		helmBinary:  "helm", | ||||||
| 		version:     *semver.MustParse("3.3.2"), | 		version:     semver.MustParse("3.3.2"), | ||||||
| 		logger:      logger, | 		logger:      logger, | ||||||
| 		kubeContext: "dev", | 		kubeContext: "dev", | ||||||
| 		runner:      &mockRunner{}, | 		runner:      &mockRunner{}, | ||||||
|  | @ -737,7 +742,7 @@ exec: helm --kube-context dev pull oci://repo/helm-charts --version 0.14.0 --des | ||||||
| 			buffer.Reset() | 			buffer.Reset() | ||||||
| 			helm := &execer{ | 			helm := &execer{ | ||||||
| 				helmBinary:  tt.helmBin, | 				helmBinary:  tt.helmBin, | ||||||
| 				version:     *semver.MustParse(tt.helmVersion), | 				version:     semver.MustParse(tt.helmVersion), | ||||||
| 				logger:      logger, | 				logger:      logger, | ||||||
| 				kubeContext: "dev", | 				kubeContext: "dev", | ||||||
| 				runner:      &mockRunner{}, | 				runner:      &mockRunner{}, | ||||||
|  | @ -786,7 +791,7 @@ exec: helm --kube-context dev chart export chart --destination path1 --untar --u | ||||||
| 			buffer.Reset() | 			buffer.Reset() | ||||||
| 			helm := &execer{ | 			helm := &execer{ | ||||||
| 				helmBinary:  tt.helmBin, | 				helmBinary:  tt.helmBin, | ||||||
| 				version:     *semver.MustParse(tt.helmVersion), | 				version:     semver.MustParse(tt.helmVersion), | ||||||
| 				logger:      logger, | 				logger:      logger, | ||||||
| 				kubeContext: "dev", | 				kubeContext: "dev", | ||||||
| 				runner:      &mockRunner{}, | 				runner:      &mockRunner{}, | ||||||
|  | @ -975,7 +980,7 @@ func Test_ShowChart(t *testing.T) { | ||||||
| 	showChartRunner := mockRunner{output: []byte("name: my-chart\nversion: 3.2.0\n")} | 	showChartRunner := mockRunner{output: []byte("name: my-chart\nversion: 3.2.0\n")} | ||||||
| 	helm := &execer{ | 	helm := &execer{ | ||||||
| 		helmBinary:  "helm", | 		helmBinary:  "helm", | ||||||
| 		version:     *semver.MustParse("3.3.2"), | 		version:     semver.MustParse("3.3.2"), | ||||||
| 		logger:      NewLogger(os.Stdout, "info"), | 		logger:      NewLogger(os.Stdout, "info"), | ||||||
| 		kubeContext: "dev", | 		kubeContext: "dev", | ||||||
| 		runner:      &showChartRunner, | 		runner:      &showChartRunner, | ||||||
|  | @ -992,3 +997,55 @@ func Test_ShowChart(t *testing.T) { | ||||||
| 		t.Errorf("helmexec.ShowChart() - expected chart version was %s, received: %s", "3.2.0", metadata.Version) | 		t.Errorf("helmexec.ShowChart() - expected chart version was %s, received: %s", "3.2.0", metadata.Version) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func TestParseHelmVersion(t *testing.T) { | ||||||
|  | 	tests := []struct { | ||||||
|  | 		name    string | ||||||
|  | 		version string | ||||||
|  | 		want    *semver.Version | ||||||
|  | 		wantErr bool | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			name:    "helm 2", | ||||||
|  | 			version: "Client: v2.16.1+ge13bc94\n", | ||||||
|  | 			want:    semver.MustParse("v2.16.1+ge13bc94"), | ||||||
|  | 			wantErr: false, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:    "helm 3", | ||||||
|  | 			version: "Client: v3.2.4+ge29ce2a\n", | ||||||
|  | 			want:    semver.MustParse("v3.2.4+ge29ce2a"), | ||||||
|  | 			wantErr: false, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:    "helm 3 with os arch and build info", | ||||||
|  | 			version: "Client v3.7.1+7.el8+g8f33223\n", | ||||||
|  | 			want:    semver.MustParse("v3.7.1+7.el8"), | ||||||
|  | 			wantErr: false, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:    "empty version", | ||||||
|  | 			version: "", | ||||||
|  | 			want:    nil, | ||||||
|  | 			wantErr: true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:    "invalid version", | ||||||
|  | 			version: "oooooo", | ||||||
|  | 			want:    nil, | ||||||
|  | 			wantErr: true, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	for _, tt := range tests { | ||||||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||||||
|  | 			got, err := parseHelmVersion(tt.version) | ||||||
|  | 			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() = %v, want %v", got, tt.want) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue