Drop Helm v2 support (#613)

Resolves #589

Signed-off-by: xiaomudk <xiaomudk@gmail.com>
This commit is contained in:
xiaomudk
2023-01-17 09:24:47 +09:00
committed by GitHub
parent 1f134d931f
commit c4eb62388b
40 changed files with 458 additions and 1594 deletions
+3 -36
View File
@@ -2,43 +2,10 @@ package helmexec
import (
"io"
"os"
"path/filepath"
)
type HelmContext struct {
Tillerless bool
TillerNamespace string
HistoryMax int
WorkerIndex int
Writer io.Writer
}
func (context *HelmContext) GetTillerlessArgs(helm *execer) []string {
if context.Tillerless && !helm.IsHelm3() {
if context.TillerNamespace != "" {
return []string{"tiller", "run", context.TillerNamespace, "--", helm.helmBinary}
}
return []string{"tiller", "run", "--", helm.helmBinary}
}
return []string{}
}
func (context *HelmContext) getTillerlessEnv() map[string]string {
if context.Tillerless {
result := map[string]string{
"HELM_TILLER_SILENT": "true",
// Changing the TILLER port doesn't really work: https://github.com/helm/helm/issues/3159
// So this is not used for the moment.
// "HELM_TILLER_PORT": strconv.Itoa(44134 + context.WorkerIndex),
}
if config := os.Getenv("KUBECONFIG"); config != "" {
absConfig, err := filepath.Abs(config)
if err == nil {
result["KUBECONFIG"] = absConfig
}
}
return result
}
return map[string]string{}
HistoryMax int
WorkerIndex int
Writer io.Writer
}
-100
View File
@@ -1,100 +0,0 @@
package helmexec
import (
"os"
"path/filepath"
"testing"
"github.com/Masterminds/semver/v3"
"github.com/stretchr/testify/require"
)
// TestGetTillerlessArgs tests the GetTillerlessArgs function
func TestGetTillerlessArgs(t *testing.T) {
helmBinary := "helm"
tests := []struct {
tillerless bool
helmMajorVersion string
tillerNamespace string
expected []string
}{
{
tillerless: true,
helmMajorVersion: "2.0.0",
expected: []string{"tiller", "run", "--", helmBinary},
},
{
tillerless: true,
helmMajorVersion: "2.0.0",
tillerNamespace: "test-namespace",
expected: []string{"tiller", "run", "test-namespace", "--", helmBinary},
},
{
tillerless: false,
helmMajorVersion: "2.0.0",
expected: []string{},
},
{
tillerless: true,
helmMajorVersion: "3.0.0",
expected: []string{},
},
}
for _, test := range tests {
hc := &HelmContext{
Tillerless: test.tillerless,
TillerNamespace: test.tillerNamespace,
}
sr, _ := semver.NewVersion(test.helmMajorVersion)
he := &execer{
helmBinary: helmBinary,
version: *sr,
}
require.Equalf(t, test.expected, hc.GetTillerlessArgs(he), "expected result %s, received result %s", test.expected, hc.GetTillerlessArgs(he))
}
}
func pwd() string {
pwd, _ := os.Getwd()
return pwd
}
// TestGetTillerlessEnv tests the getTillerlessEnv function
func TestGetTillerlessEnv(t *testing.T) {
kubeconfigEnv := "KUBECONFIG"
tests := []struct {
tillerless bool
kubeconfig string
expected map[string]string
}{
{
tillerless: true,
kubeconfig: "",
expected: map[string]string{"HELM_TILLER_SILENT": "true"},
},
{
tillerless: true,
kubeconfig: "abc",
expected: map[string]string{"HELM_TILLER_SILENT": "true", kubeconfigEnv: filepath.Join(pwd(), "abc")},
},
{
tillerless: true,
kubeconfig: "/path/to/kubeconfig",
expected: map[string]string{"HELM_TILLER_SILENT": "true", kubeconfigEnv: "/path/to/kubeconfig"},
},
{
tillerless: false,
expected: map[string]string{},
},
}
for _, test := range tests {
hc := &HelmContext{
Tillerless: test.tillerless,
}
t.Setenv(kubeconfigEnv, test.kubeconfig)
result := hc.getTillerlessEnv()
require.Equalf(t, test.expected, result, "expected result %s, received result %s", test.expected, result)
}
}
+20 -40
View File
@@ -248,14 +248,10 @@ func (helm *execer) UpdateDeps(chart string) error {
func (helm *execer) SyncRelease(context HelmContext, name, chart string, flags ...string) error {
helm.logger.Infof("Upgrading release=%v, chart=%v", name, redactedURL(chart))
preArgs := context.GetTillerlessArgs(helm)
env := context.getTillerlessEnv()
preArgs := make([]string, 0)
env := make(map[string]string)
if helm.IsHelm3() {
flags = append(flags, "--history-max", strconv.Itoa(context.HistoryMax))
} else {
env["HELM_TILLER_HISTORY_MAX"] = strconv.Itoa(context.HistoryMax)
}
flags = append(flags, "--history-max", strconv.Itoa(context.HistoryMax))
out, err := helm.exec(append(append(preArgs, "upgrade", "--install", name, chart), flags...), env, nil)
helm.write(nil, out)
@@ -264,8 +260,8 @@ func (helm *execer) SyncRelease(context HelmContext, name, chart string, flags .
func (helm *execer) ReleaseStatus(context HelmContext, name string, flags ...string) error {
helm.logger.Infof("Getting status %v", name)
preArgs := context.GetTillerlessArgs(helm)
env := context.getTillerlessEnv()
preArgs := make([]string, 0)
env := make(map[string]string)
out, err := helm.exec(append(append(preArgs, "status", name), flags...), env, nil)
helm.write(nil, out)
return err
@@ -273,14 +269,9 @@ func (helm *execer) ReleaseStatus(context HelmContext, name string, flags ...str
func (helm *execer) List(context HelmContext, filter string, flags ...string) (string, error) {
helm.logger.Infof("Listing releases matching %v", filter)
preArgs := context.GetTillerlessArgs(helm)
env := context.getTillerlessEnv()
var args []string
if helm.IsHelm3() {
args = []string{"list", "--filter", filter}
} else {
args = []string{"list", filter}
}
preArgs := make([]string, 0)
env := make(map[string]string)
args := []string{"list", "--filter", filter}
enableLiveOutput := false
out, err := helm.exec(append(append(preArgs, args...), flags...), env, &enableLiveOutput)
@@ -290,11 +281,9 @@ func (helm *execer) List(context HelmContext, filter string, flags ...string) (s
// of the release to exist.
//
// This fixes it by removing the header from the v3 output, so that the output is formatted the same as that of v2.
if helm.IsHelm3() {
lines := strings.Split(string(out), "\n")
lines = lines[1:]
out = []byte(strings.Join(lines, "\n"))
}
lines := strings.Split(string(out), "\n")
lines = lines[1:]
out = []byte(strings.Join(lines, "\n"))
helm.write(nil, out)
return string(out), err
}
@@ -320,8 +309,8 @@ func (helm *execer) DecryptSecret(context HelmContext, name string, flags ...str
helm.decryptedSecretMutex.Unlock()
helm.logger.Infof("Decrypting secret %v", absPath)
preArgs := context.GetTillerlessArgs(helm)
env := context.getTillerlessEnv()
preArgs := make([]string, 0)
env := make(map[string]string)
settings := cli.New()
pluginVersion, err := GetPluginVersion("secrets", settings.PluginsDirectory)
if err != nil {
@@ -389,12 +378,7 @@ func (helm *execer) DecryptSecret(context HelmContext, name string, flags ...str
func (helm *execer) TemplateRelease(name string, chart string, flags ...string) error {
helm.logger.Infof("Templating release=%v, chart=%v", name, redactedURL(chart))
var args []string
if helm.IsHelm3() {
args = []string{"template", name, chart}
} else {
args = []string{"template", chart, "--name", name}
}
args := []string{"template", name, chart}
out, err := helm.exec(append(args, flags...), map[string]string{}, nil)
@@ -431,8 +415,8 @@ func (helm *execer) DiffRelease(context HelmContext, name, chart string, suppres
} else {
helm.logger.Infof("Comparing release=%v, chart=%v", name, redactedURL(chart))
}
preArgs := context.GetTillerlessArgs(helm)
env := context.getTillerlessEnv()
preArgs := make([]string, 0)
env := make(map[string]string)
var overrideEnableLiveOutput *bool = nil
if suppressDiff {
enableLiveOutput := false
@@ -511,8 +495,8 @@ func (helm *execer) ChartExport(chart string, path string, flags ...string) erro
func (helm *execer) DeleteRelease(context HelmContext, name string, flags ...string) error {
helm.logger.Infof("Deleting %v", name)
preArgs := context.GetTillerlessArgs(helm)
env := context.getTillerlessEnv()
preArgs := make([]string, 0)
env := make(map[string]string)
out, err := helm.exec(append(append(preArgs, "delete", name), flags...), env, nil)
helm.write(nil, out)
return err
@@ -520,8 +504,8 @@ func (helm *execer) DeleteRelease(context HelmContext, name string, flags ...str
func (helm *execer) TestRelease(context HelmContext, name string, flags ...string) error {
helm.logger.Infof("Testing %v", name)
preArgs := context.GetTillerlessArgs(helm)
env := context.getTillerlessEnv()
preArgs := make([]string, 0)
env := make(map[string]string)
args := []string{"test", name}
out, err := helm.exec(append(append(preArgs, args...), flags...), env, nil)
helm.write(nil, out)
@@ -634,10 +618,6 @@ func resolveOciChart(ociChart string) (ociChartURL, ociChartTag string) {
}
func (helm *execer) ShowChart(chartPath string) (chart.Metadata, error) {
if !helm.IsHelm3() {
// show chart command isn't supported in helm2
return chart.Metadata{}, fmt.Errorf("helm show isn't supported in helm2")
}
var helmArgs = []string{"show", "chart", chartPath}
out, error := helm.exec(helmArgs, map[string]string{}, nil)
if error != nil {
+6 -72
View File
@@ -5,7 +5,6 @@ import (
"fmt"
"io"
"os"
"path"
"path/filepath"
"reflect"
"regexp"
@@ -277,7 +276,7 @@ func Test_SyncRelease(t *testing.T) {
helm := MockExecer(logger, "dev")
err := helm.SyncRelease(HelmContext{}, "release", "chart", "--timeout 10", "--wait", "--wait-for-jobs")
expected := `Upgrading release=release, chart=chart
exec: helm --kube-context dev upgrade --install release chart --timeout 10 --wait --wait-for-jobs
exec: helm --kube-context dev upgrade --install release chart --timeout 10 --wait --wait-for-jobs --history-max 0
`
if err != nil {
t.Errorf("unexpected error: %v", err)
@@ -289,7 +288,7 @@ exec: helm --kube-context dev upgrade --install release chart --timeout 10 --wai
buffer.Reset()
err = helm.SyncRelease(HelmContext{}, "release", "chart")
expected = `Upgrading release=release, chart=chart
exec: helm --kube-context dev upgrade --install release chart
exec: helm --kube-context dev upgrade --install release chart --history-max 0
`
if err != nil {
t.Errorf("unexpected error: %v", err)
@@ -301,24 +300,7 @@ exec: helm --kube-context dev upgrade --install release chart
buffer.Reset()
err = helm.SyncRelease(HelmContext{}, "release", "https://example_user:example_password@repo.example.com/chart.tgz")
expected = `Upgrading release=release, chart=https://example_user:xxxxx@repo.example.com/chart.tgz
exec: helm --kube-context dev upgrade --install release https://example_user:example_password@repo.example.com/chart.tgz
`
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected {
t.Errorf("helmexec.SyncRelease()\nactual = %v\nexpect = %v", buffer.String(), expected)
}
}
func Test_SyncReleaseTillerless(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev")
err := helm.SyncRelease(HelmContext{Tillerless: true, TillerNamespace: "foo"}, "release", "chart",
"--timeout 10", "--wait", "--wait-for-jobs")
expected := `Upgrading release=release, chart=chart
exec: helm --kube-context dev tiller run foo -- helm upgrade --install release chart --timeout 10 --wait --wait-for-jobs
exec: helm --kube-context dev upgrade --install release https://example_user:example_password@repo.example.com/chart.tgz --history-max 0
`
if err != nil {
t.Errorf("unexpected error: %v", err)
@@ -548,22 +530,6 @@ exec: helm --kube-context dev diff upgrade --allow-unreleased release https://ex
}
}
func Test_DiffReleaseTillerless(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev")
err := helm.DiffRelease(HelmContext{Tillerless: true}, "release", "chart", false, "--timeout 10", "--wait", "--wait-for-jobs")
expected := `Comparing release=release, chart=chart
exec: helm --kube-context dev tiller run -- helm diff upgrade --allow-unreleased release chart --timeout 10 --wait --wait-for-jobs
`
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected {
t.Errorf("helmexec.DiffRelease()\nactual = %v\nexpect = %v", buffer.String(), expected)
}
}
func Test_DeleteRelease(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
@@ -887,31 +853,6 @@ func Test_LogLevels(t *testing.T) {
}
}
func Test_getTillerlessEnv(t *testing.T) {
context := HelmContext{Tillerless: true, TillerNamespace: "foo", WorkerIndex: 1}
os.Unsetenv("KUBECONFIG")
actual := context.getTillerlessEnv()
if val, found := actual["HELM_TILLER_SILENT"]; !found || val != "true" {
t.Errorf("getTillerlessEnv() HELM_TILLER_SILENT\nactual = %s\nexpect = true", val)
}
// This feature is disabled until it is fixed in helm
/*if val, found := actual["HELM_TILLER_PORT"]; !found || val != "44135" {
t.Errorf("getTillerlessEnv() HELM_TILLER_PORT\nactual = %s\nexpect = 44135", val)
}*/
if val, found := actual["KUBECONFIG"]; found {
t.Errorf("getTillerlessEnv() KUBECONFIG\nactual = %s\nexpect = nil", val)
}
t.Setenv("KUBECONFIG", "toto")
actual = context.getTillerlessEnv()
cwd, _ := os.Getwd()
expected := path.Join(cwd, "toto")
if val, found := actual["KUBECONFIG"]; !found || val != expected {
t.Errorf("getTillerlessEnv() KUBECONFIG\nactual = %s\nexpect = %s", val, expected)
}
}
func Test_mergeEnv(t *testing.T) {
actual := env2map(mergeEnv([]string{"A=1", "B=c=d", "E=2"}, map[string]string{"B": "3", "F": "4"}))
expected := map[string]string{"A": "1", "B": "3", "E": "2", "F": "4"}
@@ -926,7 +867,7 @@ func Test_Template(t *testing.T) {
helm := MockExecer(logger, "dev")
err := helm.TemplateRelease("release", "path/to/chart", "--values", "file.yml")
expected := `Templating release=release, chart=path/to/chart
exec: helm --kube-context dev template path/to/chart --name release --values file.yml
exec: helm --kube-context dev template release path/to/chart --values file.yml
`
if err != nil {
t.Errorf("unexpected error: %v", err)
@@ -938,7 +879,7 @@ exec: helm --kube-context dev template path/to/chart --name release --values fil
buffer.Reset()
err = helm.TemplateRelease("release", "https://example_user:example_password@repo.example.com/chart.tgz", "--values", "file.yml")
expected = `Templating release=release, chart=https://example_user:xxxxx@repo.example.com/chart.tgz
exec: helm --kube-context dev template https://example_user:example_password@repo.example.com/chart.tgz --name release --values file.yml
exec: helm --kube-context dev template release https://example_user:example_password@repo.example.com/chart.tgz --values file.yml
`
if err != nil {
t.Errorf("unexpected error: %v", err)
@@ -1064,15 +1005,8 @@ func Test_resolveOciChart(t *testing.T) {
}
func Test_ShowChart(t *testing.T) {
helm2Runner := mockRunner{output: []byte("Client: v2.16.1+ge13bc94\n")}
helm := New("helm", false, NewLogger(os.Stdout, "info"), "dev", &helm2Runner)
_, err := helm.ShowChart("fake-chart")
if err == nil {
t.Error("helmexec.ShowChart() - helm show isn't supported in helm2")
}
showChartRunner := mockRunner{output: []byte("name: my-chart\nversion: 3.2.0\n")}
helm = &execer{
helm := &execer{
helmBinary: "helm",
version: *semver.MustParse("3.3.2"),
logger: NewLogger(os.Stdout, "info"),