fix: helm chart referenced by http URL (#695)
We unintentionally broke this since #593. Fixes #675 Fixes #687
This commit is contained in:
		
							parent
							
								
									e0d0a1cf7f
								
							
						
					
					
						commit
						7dec948950
					
				|  | @ -1025,6 +1025,57 @@ x: | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func TestVisitDesiredStatesWithReleasesFiltered_RemoteTgzAsChart(t *testing.T) { | ||||||
|  | 	testcases := []struct { | ||||||
|  | 		expr, env, expected string | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			expected: "https://github.com/arangodb/kube-arangodb/releases/download/0.3.11/kube-arangodb-crd.tgz", | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	for i := range testcases { | ||||||
|  | 		testcase := testcases[i] | ||||||
|  | 		t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) { | ||||||
|  | 			files := map[string]string{ | ||||||
|  | 				"/path/to/helmfile.yaml": ` | ||||||
|  | releases: | ||||||
|  |   - name: arangodb-crd | ||||||
|  |     chart: https://github.com/arangodb/kube-arangodb/releases/download/0.3.11/kube-arangodb-crd.tgz
 | ||||||
|  | `, | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			actual := []state.ReleaseSpec{} | ||||||
|  | 
 | ||||||
|  | 			collectReleases := func(st *state.HelmState, helm helmexec.Interface) []error { | ||||||
|  | 				for _, r := range st.Releases { | ||||||
|  | 					actual = append(actual, r) | ||||||
|  | 				} | ||||||
|  | 				return []error{} | ||||||
|  | 			} | ||||||
|  | 			app := appWithFs(&App{ | ||||||
|  | 				KubeContext: "default", | ||||||
|  | 				Logger:      helmexec.NewLogger(os.Stderr, "debug"), | ||||||
|  | 				Reverse:     false, | ||||||
|  | 				Namespace:   "", | ||||||
|  | 				Selectors:   []string{}, | ||||||
|  | 				Env:         "default", | ||||||
|  | 			}, files) | ||||||
|  | 			err := app.VisitDesiredStatesWithReleasesFiltered( | ||||||
|  | 				"helmfile.yaml", collectReleases, | ||||||
|  | 			) | ||||||
|  | 			if err != nil { | ||||||
|  | 				t.Fatalf("unexpected error: %v", err) | ||||||
|  | 			} | ||||||
|  | 			if len(actual) != 1 { | ||||||
|  | 				t.Errorf("unexpected number of processed releases: expected=1, got=%d", len(actual)) | ||||||
|  | 			} | ||||||
|  | 			if actual[0].Chart != testcase.expected { | ||||||
|  | 				t.Errorf("unexpected chart: expected=%s, got=%s", testcase.expected, actual[0].Chart) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func TestLoadDesiredStateFromYaml_DuplicateReleaseName(t *testing.T) { | func TestLoadDesiredStateFromYaml_DuplicateReleaseName(t *testing.T) { | ||||||
| 	yamlFile := "example/path/to/yaml/file" | 	yamlFile := "example/path/to/yaml/file" | ||||||
| 	yamlContent := []byte(`releases: | 	yamlContent := []byte(`releases: | ||||||
|  |  | ||||||
|  | @ -128,21 +128,6 @@ func (d *ResolvedDependencies) Get(chart, versionConstraint string) (string, err | ||||||
| 	return "", fmt.Errorf("no resolved dependency found for \"%s\"", chart) | 	return "", fmt.Errorf("no resolved dependency found for \"%s\"", chart) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func resolveRemoteChart(repoAndChart string) (string, string, bool) { |  | ||||||
| 	parts := strings.Split(repoAndChart, "/") |  | ||||||
| 	if isLocalChart(repoAndChart) { |  | ||||||
| 		return "", "", false |  | ||||||
| 	} |  | ||||||
| 	if len(parts) != 2 { |  | ||||||
| 		panic(fmt.Sprintf("unsupported format of chart name: %s", repoAndChart)) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	repo := parts[0] |  | ||||||
| 	chart := parts[1] |  | ||||||
| 
 |  | ||||||
| 	return repo, chart, true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (st *HelmState) mergeLockedDependencies() (*HelmState, error) { | func (st *HelmState) mergeLockedDependencies() (*HelmState, error) { | ||||||
| 	filename, unresolved, err := getUnresolvedDependenciess(st) | 	filename, unresolved, err := getUnresolvedDependenciess(st) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  |  | ||||||
|  | @ -1073,17 +1073,6 @@ func normalizeChart(basePath, chart string) string { | ||||||
| 	} | 	} | ||||||
| 	return filepath.Join(basePath, chart) | 	return filepath.Join(basePath, chart) | ||||||
| } | } | ||||||
| 
 |  | ||||||
| func isLocalChart(chart string) bool { |  | ||||||
| 	regex, _ := regexp.Compile("^[.]?./") |  | ||||||
| 	matched := regex.MatchString(chart) |  | ||||||
| 	if matched { |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return chart == "" || chart[0] == '/' || len(strings.Split(chart, "/")) != 2 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func pathExists(chart string) bool { | func pathExists(chart string) bool { | ||||||
| 	_, err := os.Stat(chart) | 	_, err := os.Stat(chart) | ||||||
| 	return err == nil | 	return err == nil | ||||||
|  |  | ||||||
|  | @ -0,0 +1,40 @@ | ||||||
|  | package state | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"regexp" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func isLocalChart(chart string) bool { | ||||||
|  | 	regex, _ := regexp.Compile("^[.]?./") | ||||||
|  | 	matched := regex.MatchString(chart) | ||||||
|  | 	if matched { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	uriLike := strings.Index(chart, "://") > -1 | ||||||
|  | 	if uriLike { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return chart == "" || | ||||||
|  | 		chart[0] == '/' || | ||||||
|  | 		strings.Index(chart, "/") == -1 || | ||||||
|  | 		len(strings.Split(chart, "/")) != 2 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func resolveRemoteChart(repoAndChart string) (string, string, bool) { | ||||||
|  | 	if isLocalChart(repoAndChart) { | ||||||
|  | 		return "", "", false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	parts := strings.Split(repoAndChart, "/") | ||||||
|  | 	if len(parts) != 2 { | ||||||
|  | 		return "", "", false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	repo := parts[0] | ||||||
|  | 	chart := parts[1] | ||||||
|  | 
 | ||||||
|  | 	return repo, chart, true | ||||||
|  | } | ||||||
|  | @ -0,0 +1,113 @@ | ||||||
|  | package state | ||||||
|  | 
 | ||||||
|  | import "testing" | ||||||
|  | 
 | ||||||
|  | func TestIsLocalChart(t *testing.T) { | ||||||
|  | 	testcases := []struct { | ||||||
|  | 		input    string | ||||||
|  | 		expected bool | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			input:    "mychart", | ||||||
|  | 			expected: true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			input:    "stable/mysql", | ||||||
|  | 			expected: false, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			input:    "./charts/myapp", | ||||||
|  | 			expected: true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			input:    "charts/mysubsystem/myapp", | ||||||
|  | 			expected: true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			input:    "./charts/mysubsystem/myapp", | ||||||
|  | 			expected: true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			// Regression test case for:
 | ||||||
|  | 			// * https://github.com/roboll/helmfile/issues/675
 | ||||||
|  | 			// * https://github.com/roboll/helmfile/issues/687
 | ||||||
|  | 			input:    "https://github.com/arangodb/kube-arangodb/releases/download/0.3.11/kube-arangodb-crd.tgz", | ||||||
|  | 			expected: false, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			input:    "https://example.com/bar.tgz", | ||||||
|  | 			expected: false, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for i := range testcases { | ||||||
|  | 		testcase := testcases[i] | ||||||
|  | 
 | ||||||
|  | 		actual := isLocalChart(testcase.input) | ||||||
|  | 
 | ||||||
|  | 		if testcase.expected != actual { | ||||||
|  | 			t.Errorf("unexpected result: isLocalChart(\"%s\"): expected=%v, got=%v", testcase.input, testcase.expected, actual) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestResolveRemortChart(t *testing.T) { | ||||||
|  | 	testcases := []struct { | ||||||
|  | 		input  string | ||||||
|  | 		repo   string | ||||||
|  | 		chart  string | ||||||
|  | 		remote bool | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			input:  "mychart", | ||||||
|  | 			remote: false, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			input:  "stable/mysql", | ||||||
|  | 			repo:   "stable", | ||||||
|  | 			chart:  "mysql", | ||||||
|  | 			remote: true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			input:  "./charts/myapp", | ||||||
|  | 			remote: false, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			input:  "charts/mysubsystem/myapp", | ||||||
|  | 			remote: false, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			input:  "./charts/mysubsystem/myapp", | ||||||
|  | 			remote: false, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			// Regression test case for:
 | ||||||
|  | 			// * https://github.com/roboll/helmfile/issues/675
 | ||||||
|  | 			// * https://github.com/roboll/helmfile/issues/687
 | ||||||
|  | 			input:  "https://github.com/arangodb/kube-arangodb/releases/download/0.3.11/kube-arangodb-crd.tgz", | ||||||
|  | 			remote: false, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			input:  "https://example.com/bar.tgz", | ||||||
|  | 			remote: false, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for i := range testcases { | ||||||
|  | 		testcase := testcases[i] | ||||||
|  | 
 | ||||||
|  | 		repo, chart, actual := resolveRemoteChart(testcase.input) | ||||||
|  | 
 | ||||||
|  | 		if testcase.remote != actual { | ||||||
|  | 			t.Fatalf("unexpected result: reolveRemoteChart(\"%s\"): expected=%v, got=%v", testcase.input, testcase.remote, actual) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if testcase.repo != repo { | ||||||
|  | 			t.Errorf("unexpected repo: %s: expected=%v, got=%v", testcase.input, testcase.repo, repo) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if testcase.chart != chart { | ||||||
|  | 			t.Errorf("unexpected chart: %s: expected=%v, got=%v", testcase.input, testcase.chart, chart) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue