github.com/defensepoint-snyk-test/helm-new@v0.0.0-20211130153739-c57ea64d6603/cmd/helm/helm_test.go (about)

     1  /*
     2  Copyright The Helm Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"io"
    23  	"io/ioutil"
    24  	"os"
    25  	"path/filepath"
    26  	"regexp"
    27  	"strings"
    28  	"testing"
    29  
    30  	"github.com/spf13/cobra"
    31  
    32  	"k8s.io/client-go/util/homedir"
    33  	"k8s.io/helm/pkg/helm"
    34  	"k8s.io/helm/pkg/helm/environment"
    35  	"k8s.io/helm/pkg/helm/helmpath"
    36  	"k8s.io/helm/pkg/proto/hapi/release"
    37  	"k8s.io/helm/pkg/repo"
    38  )
    39  
    40  // releaseCmd is a command that works with a FakeClient
    41  type releaseCmd func(c *helm.FakeClient, out io.Writer) *cobra.Command
    42  
    43  // runReleaseCases runs a set of release cases through the given releaseCmd.
    44  func runReleaseCases(t *testing.T, tests []releaseCase, rcmd releaseCmd) {
    45  	var buf bytes.Buffer
    46  	for _, tt := range tests {
    47  		t.Run(tt.name, func(t *testing.T) {
    48  			c := &helm.FakeClient{
    49  				Rels:      tt.rels,
    50  				Responses: tt.responses,
    51  			}
    52  			cmd := rcmd(c, &buf)
    53  			cmd.ParseFlags(tt.flags)
    54  			err := cmd.RunE(cmd, tt.args)
    55  			if (err != nil) != tt.err {
    56  				t.Errorf("expected error, got '%v'", err)
    57  			}
    58  			re := regexp.MustCompile(tt.expected)
    59  			if !re.Match(buf.Bytes()) {
    60  				t.Errorf("expected\n%q\ngot\n%q", tt.expected, buf.String())
    61  			}
    62  			buf.Reset()
    63  		})
    64  	}
    65  }
    66  
    67  // releaseCase describes a test case that works with releases.
    68  type releaseCase struct {
    69  	name  string
    70  	args  []string
    71  	flags []string
    72  	// expected is the string to be matched. This supports regular expressions.
    73  	expected string
    74  	err      bool
    75  	resp     *release.Release
    76  	// Rels are the available releases at the start of the test.
    77  	rels      []*release.Release
    78  	responses map[string]release.TestRun_Status
    79  }
    80  
    81  // tempHelmHome sets up a Helm Home in a temp dir.
    82  //
    83  // This does not clean up the directory. You must do that yourself.
    84  // You  must also set helmHome yourself.
    85  func tempHelmHome(t *testing.T) (helmpath.Home, error) {
    86  	oldhome := settings.Home
    87  	dir, err := ioutil.TempDir("", "helm_home-")
    88  	if err != nil {
    89  		return helmpath.Home("n/"), err
    90  	}
    91  
    92  	settings.Home = helmpath.Home(dir)
    93  	if err := ensureTestHome(settings.Home, t); err != nil {
    94  		return helmpath.Home("n/"), err
    95  	}
    96  	settings.Home = oldhome
    97  	return helmpath.Home(dir), nil
    98  }
    99  
   100  // ensureTestHome creates a home directory like ensureHome, but without remote references.
   101  //
   102  // t is used only for logging.
   103  func ensureTestHome(home helmpath.Home, t *testing.T) error {
   104  	configDirectories := []string{home.String(), home.Repository(), home.Cache(), home.LocalRepository(), home.Plugins(), home.Starters()}
   105  	for _, p := range configDirectories {
   106  		if fi, err := os.Stat(p); err != nil {
   107  			if err := os.MkdirAll(p, 0755); err != nil {
   108  				return fmt.Errorf("Could not create %s: %s", p, err)
   109  			}
   110  		} else if !fi.IsDir() {
   111  			return fmt.Errorf("%s must be a directory", p)
   112  		}
   113  	}
   114  
   115  	repoFile := home.RepositoryFile()
   116  	if fi, err := os.Stat(repoFile); err != nil {
   117  		rf := repo.NewRepoFile()
   118  		rf.Add(&repo.Entry{
   119  			Name:  "charts",
   120  			URL:   "http://example.com/foo",
   121  			Cache: "charts-index.yaml",
   122  		}, &repo.Entry{
   123  			Name:  "local",
   124  			URL:   "http://localhost.com:7743/foo",
   125  			Cache: "local-index.yaml",
   126  		})
   127  		if err := rf.WriteFile(repoFile, 0644); err != nil {
   128  			return err
   129  		}
   130  	} else if fi.IsDir() {
   131  		return fmt.Errorf("%s must be a file, not a directory", repoFile)
   132  	}
   133  	if r, err := repo.LoadRepositoriesFile(repoFile); err == repo.ErrRepoOutOfDate {
   134  		t.Log("Updating repository file format...")
   135  		if err := r.WriteFile(repoFile, 0644); err != nil {
   136  			return err
   137  		}
   138  	}
   139  
   140  	localRepoIndexFile := home.LocalRepository(localRepositoryIndexFile)
   141  	if fi, err := os.Stat(localRepoIndexFile); err != nil {
   142  		i := repo.NewIndexFile()
   143  		if err := i.WriteFile(localRepoIndexFile, 0644); err != nil {
   144  			return err
   145  		}
   146  
   147  		//TODO: take this out and replace with helm update functionality
   148  		os.Symlink(localRepoIndexFile, home.CacheIndex("local"))
   149  	} else if fi.IsDir() {
   150  		return fmt.Errorf("%s must be a file, not a directory", localRepoIndexFile)
   151  	}
   152  
   153  	t.Logf("$HELM_HOME has been configured at %s.\n", settings.Home.String())
   154  	return nil
   155  
   156  }
   157  
   158  func TestRootCmd(t *testing.T) {
   159  	cleanup := resetEnv()
   160  	defer cleanup()
   161  
   162  	tests := []struct {
   163  		name   string
   164  		args   []string
   165  		envars map[string]string
   166  		home   string
   167  	}{
   168  		{
   169  			name: "defaults",
   170  			args: []string{"home"},
   171  			home: filepath.Join(homedir.HomeDir(), ".helm"),
   172  		},
   173  		{
   174  			name: "with --home set",
   175  			args: []string{"--home", "/foo"},
   176  			home: "/foo",
   177  		},
   178  		{
   179  			name: "subcommands with --home set",
   180  			args: []string{"home", "--home", "/foo"},
   181  			home: "/foo",
   182  		},
   183  		{
   184  			name:   "with $HELM_HOME set",
   185  			args:   []string{"home"},
   186  			envars: map[string]string{"HELM_HOME": "/bar"},
   187  			home:   "/bar",
   188  		},
   189  		{
   190  			name:   "subcommands with $HELM_HOME set",
   191  			args:   []string{"home"},
   192  			envars: map[string]string{"HELM_HOME": "/bar"},
   193  			home:   "/bar",
   194  		},
   195  		{
   196  			name:   "with $HELM_HOME and --home set",
   197  			args:   []string{"home", "--home", "/foo"},
   198  			envars: map[string]string{"HELM_HOME": "/bar"},
   199  			home:   "/foo",
   200  		},
   201  	}
   202  
   203  	// ensure not set locally
   204  	os.Unsetenv("HELM_HOME")
   205  
   206  	for _, tt := range tests {
   207  		t.Run(tt.name, func(t *testing.T) {
   208  			defer os.Unsetenv("HELM_HOME")
   209  
   210  			for k, v := range tt.envars {
   211  				os.Setenv(k, v)
   212  			}
   213  
   214  			cmd := newRootCmd(tt.args)
   215  			cmd.SetOutput(ioutil.Discard)
   216  			cmd.SetArgs(tt.args)
   217  			cmd.Run = func(*cobra.Command, []string) {}
   218  			if err := cmd.Execute(); err != nil {
   219  				t.Errorf("unexpected error: %s", err)
   220  			}
   221  
   222  			if settings.Home.String() != tt.home {
   223  				t.Errorf("expected home %q, got %q", tt.home, settings.Home)
   224  			}
   225  			homeFlag := cmd.Flag("home").Value.String()
   226  			homeFlag = os.ExpandEnv(homeFlag)
   227  			if homeFlag != tt.home {
   228  				t.Errorf("expected home %q, got %q", tt.home, homeFlag)
   229  			}
   230  		})
   231  	}
   232  }
   233  
   234  func TestTLSFlags(t *testing.T) {
   235  	cleanup := resetEnv()
   236  	defer cleanup()
   237  
   238  	homePath := os.Getenv("HELM_HOME")
   239  	if homePath == "" {
   240  		homePath = filepath.Join(homedir.HomeDir(), ".helm")
   241  	}
   242  
   243  	home := helmpath.Home(homePath)
   244  
   245  	tests := []struct {
   246  		name     string
   247  		args     []string
   248  		envars   map[string]string
   249  		settings environment.EnvSettings
   250  	}{
   251  		{
   252  			name: "defaults",
   253  			args: []string{"version", "-c"},
   254  			settings: environment.EnvSettings{
   255  				TillerHost:              "",
   256  				TillerConnectionTimeout: 300,
   257  				TillerNamespace:         "kube-system",
   258  				Home:                    home,
   259  				Debug:                   false,
   260  				KubeContext:             "",
   261  				KubeConfig:              "",
   262  				TLSEnable:               false,
   263  				TLSVerify:               false,
   264  				TLSServerName:           "",
   265  				TLSCaCertFile:           home.TLSCaCert(),
   266  				TLSCertFile:             home.TLSCert(),
   267  				TLSKeyFile:              home.TLSKey(),
   268  			},
   269  		},
   270  		{
   271  			name: "tls enable",
   272  			args: []string{"version", "-c", "--tls"},
   273  			settings: environment.EnvSettings{
   274  				TillerHost:              "",
   275  				TillerConnectionTimeout: 300,
   276  				TillerNamespace:         "kube-system",
   277  				Home:                    home,
   278  				Debug:                   false,
   279  				KubeContext:             "",
   280  				KubeConfig:              "",
   281  				TLSEnable:               true,
   282  				TLSVerify:               false,
   283  				TLSServerName:           "",
   284  				TLSCaCertFile:           home.TLSCaCert(),
   285  				TLSCertFile:             home.TLSCert(),
   286  				TLSKeyFile:              home.TLSKey(),
   287  			},
   288  		},
   289  		{
   290  			name: "tls verify",
   291  			args: []string{"version", "-c", "--tls-verify"},
   292  			settings: environment.EnvSettings{
   293  				TillerHost:              "",
   294  				TillerConnectionTimeout: 300,
   295  				TillerNamespace:         "kube-system",
   296  				Home:                    home,
   297  				Debug:                   false,
   298  				KubeContext:             "",
   299  				KubeConfig:              "",
   300  				TLSEnable:               false,
   301  				TLSVerify:               true,
   302  				TLSServerName:           "",
   303  				TLSCaCertFile:           home.TLSCaCert(),
   304  				TLSCertFile:             home.TLSCert(),
   305  				TLSKeyFile:              home.TLSKey(),
   306  			},
   307  		},
   308  		{
   309  			name: "tls servername",
   310  			args: []string{"version", "-c", "--tls-hostname=foo"},
   311  			settings: environment.EnvSettings{
   312  				TillerHost:              "",
   313  				TillerConnectionTimeout: 300,
   314  				TillerNamespace:         "kube-system",
   315  				Home:                    home,
   316  				Debug:                   false,
   317  				KubeContext:             "",
   318  				KubeConfig:              "",
   319  				TLSEnable:               false,
   320  				TLSVerify:               false,
   321  				TLSServerName:           "foo",
   322  				TLSCaCertFile:           home.TLSCaCert(),
   323  				TLSCertFile:             home.TLSCert(),
   324  				TLSKeyFile:              home.TLSKey(),
   325  			},
   326  		},
   327  		{
   328  			name: "tls cacert",
   329  			args: []string{"version", "-c", "--tls-ca-cert=/foo"},
   330  			settings: environment.EnvSettings{
   331  				TillerHost:              "",
   332  				TillerConnectionTimeout: 300,
   333  				TillerNamespace:         "kube-system",
   334  				Home:                    home,
   335  				Debug:                   false,
   336  				KubeContext:             "",
   337  				KubeConfig:              "",
   338  				TLSEnable:               false,
   339  				TLSVerify:               false,
   340  				TLSServerName:           "",
   341  				TLSCaCertFile:           "/foo",
   342  				TLSCertFile:             home.TLSCert(),
   343  				TLSKeyFile:              home.TLSKey(),
   344  			},
   345  		},
   346  		{
   347  			name: "tls cert",
   348  			args: []string{"version", "-c", "--tls-cert=/foo"},
   349  			settings: environment.EnvSettings{
   350  				TillerHost:              "",
   351  				TillerConnectionTimeout: 300,
   352  				TillerNamespace:         "kube-system",
   353  				Home:                    home,
   354  				Debug:                   false,
   355  				KubeContext:             "",
   356  				KubeConfig:              "",
   357  				TLSEnable:               false,
   358  				TLSVerify:               false,
   359  				TLSServerName:           "",
   360  				TLSCaCertFile:           home.TLSCaCert(),
   361  				TLSCertFile:             "/foo",
   362  				TLSKeyFile:              home.TLSKey(),
   363  			},
   364  		},
   365  		{
   366  			name: "tls key",
   367  			args: []string{"version", "-c", "--tls-key=/foo"},
   368  			settings: environment.EnvSettings{
   369  				TillerHost:              "",
   370  				TillerConnectionTimeout: 300,
   371  				TillerNamespace:         "kube-system",
   372  				Home:                    home,
   373  				Debug:                   false,
   374  				KubeContext:             "",
   375  				KubeConfig:              "",
   376  				TLSEnable:               false,
   377  				TLSVerify:               false,
   378  				TLSServerName:           "",
   379  				TLSCaCertFile:           home.TLSCaCert(),
   380  				TLSCertFile:             home.TLSCert(),
   381  				TLSKeyFile:              "/foo",
   382  			},
   383  		},
   384  		{
   385  			name:   "tls enable envvar",
   386  			args:   []string{"version", "-c"},
   387  			envars: map[string]string{"HELM_TLS_ENABLE": "true"},
   388  			settings: environment.EnvSettings{
   389  				TillerHost:              "",
   390  				TillerConnectionTimeout: 300,
   391  				TillerNamespace:         "kube-system",
   392  				Home:                    home,
   393  				Debug:                   false,
   394  				KubeContext:             "",
   395  				KubeConfig:              "",
   396  				TLSEnable:               true,
   397  				TLSVerify:               false,
   398  				TLSServerName:           "",
   399  				TLSCaCertFile:           home.TLSCaCert(),
   400  				TLSCertFile:             home.TLSCert(),
   401  				TLSKeyFile:              home.TLSKey(),
   402  			},
   403  		},
   404  		{
   405  			name:   "tls verify envvar",
   406  			args:   []string{"version", "-c"},
   407  			envars: map[string]string{"HELM_TLS_VERIFY": "true"},
   408  			settings: environment.EnvSettings{
   409  				TillerHost:              "",
   410  				TillerConnectionTimeout: 300,
   411  				TillerNamespace:         "kube-system",
   412  				Home:                    home,
   413  				Debug:                   false,
   414  				KubeContext:             "",
   415  				KubeConfig:              "",
   416  				TLSEnable:               false,
   417  				TLSVerify:               true,
   418  				TLSServerName:           "",
   419  				TLSCaCertFile:           home.TLSCaCert(),
   420  				TLSCertFile:             home.TLSCert(),
   421  				TLSKeyFile:              home.TLSKey(),
   422  			},
   423  		},
   424  		{
   425  			name:   "tls servername envvar",
   426  			args:   []string{"version", "-c"},
   427  			envars: map[string]string{"HELM_TLS_HOSTNAME": "foo"},
   428  			settings: environment.EnvSettings{
   429  				TillerHost:              "",
   430  				TillerConnectionTimeout: 300,
   431  				TillerNamespace:         "kube-system",
   432  				Home:                    home,
   433  				Debug:                   false,
   434  				KubeContext:             "",
   435  				KubeConfig:              "",
   436  				TLSEnable:               false,
   437  				TLSVerify:               false,
   438  				TLSServerName:           "foo",
   439  				TLSCaCertFile:           home.TLSCaCert(),
   440  				TLSCertFile:             home.TLSCert(),
   441  				TLSKeyFile:              home.TLSKey(),
   442  			},
   443  		},
   444  		{
   445  			name:   "tls cacert envvar",
   446  			args:   []string{"version", "-c"},
   447  			envars: map[string]string{"HELM_TLS_CA_CERT": "/foo"},
   448  			settings: environment.EnvSettings{
   449  				TillerHost:              "",
   450  				TillerConnectionTimeout: 300,
   451  				TillerNamespace:         "kube-system",
   452  				Home:                    home,
   453  				Debug:                   false,
   454  				KubeContext:             "",
   455  				KubeConfig:              "",
   456  				TLSEnable:               false,
   457  				TLSVerify:               false,
   458  				TLSServerName:           "",
   459  				TLSCaCertFile:           "/foo",
   460  				TLSCertFile:             home.TLSCert(),
   461  				TLSKeyFile:              home.TLSKey(),
   462  			},
   463  		},
   464  		{
   465  			name:   "tls cert envvar",
   466  			args:   []string{"version", "-c"},
   467  			envars: map[string]string{"HELM_TLS_CERT": "/foo"},
   468  			settings: environment.EnvSettings{
   469  				TillerHost:              "",
   470  				TillerConnectionTimeout: 300,
   471  				TillerNamespace:         "kube-system",
   472  				Home:                    home,
   473  				Debug:                   false,
   474  				KubeContext:             "",
   475  				KubeConfig:              "",
   476  				TLSEnable:               false,
   477  				TLSVerify:               false,
   478  				TLSServerName:           "",
   479  				TLSCaCertFile:           home.TLSCaCert(),
   480  				TLSCertFile:             "/foo",
   481  				TLSKeyFile:              home.TLSKey(),
   482  			},
   483  		},
   484  		{
   485  			name:   "tls key envvar",
   486  			args:   []string{"version", "-c"},
   487  			envars: map[string]string{"HELM_TLS_KEY": "/foo"},
   488  			settings: environment.EnvSettings{
   489  				TillerHost:              "",
   490  				TillerConnectionTimeout: 300,
   491  				TillerNamespace:         "kube-system",
   492  				Home:                    home,
   493  				Debug:                   false,
   494  				KubeContext:             "",
   495  				KubeConfig:              "",
   496  				TLSEnable:               false,
   497  				TLSVerify:               false,
   498  				TLSServerName:           "",
   499  				TLSCaCertFile:           home.TLSCaCert(),
   500  				TLSCertFile:             home.TLSCert(),
   501  				TLSKeyFile:              "/foo",
   502  			},
   503  		},
   504  	}
   505  
   506  	// ensure not set locally
   507  	tlsEnvvars := []string{
   508  		"HELM_TLS_HOSTNAME",
   509  		"HELM_TLS_CA_CERT",
   510  		"HELM_TLS_CERT",
   511  		"HELM_TLS_KEY",
   512  		"HELM_TLS_VERIFY",
   513  		"HELM_TLS_ENABLE",
   514  	}
   515  
   516  	for i := range tlsEnvvars {
   517  		os.Unsetenv(tlsEnvvars[i])
   518  	}
   519  
   520  	for _, tt := range tests {
   521  		t.Run(tt.name, func(t *testing.T) {
   522  
   523  			for k, v := range tt.envars {
   524  				os.Setenv(k, v)
   525  				defer os.Unsetenv(k)
   526  			}
   527  
   528  			cmd := newRootCmd(tt.args)
   529  			cmd.SetOutput(ioutil.Discard)
   530  			cmd.SetArgs(tt.args)
   531  			cmd.Run = func(*cobra.Command, []string) {}
   532  			if err := cmd.Execute(); err != nil {
   533  				t.Errorf("unexpected error: %s", err)
   534  			}
   535  
   536  			if settings != tt.settings {
   537  				t.Errorf("expected settings %v, got %v", tt.settings, settings)
   538  			}
   539  		})
   540  	}
   541  }
   542  
   543  func resetEnv() func() {
   544  	origSettings := settings
   545  	origEnv := os.Environ()
   546  	return func() {
   547  		settings = origSettings
   548  		for _, pair := range origEnv {
   549  			kv := strings.SplitN(pair, "=", 2)
   550  			os.Setenv(kv[0], kv[1])
   551  		}
   552  	}
   553  }