github.com/latiif/helm@v2.15.0+incompatible/cmd/helm/init_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  	"io"
    22  	"io/ioutil"
    23  	"os"
    24  	"path/filepath"
    25  	"reflect"
    26  	"strings"
    27  	"testing"
    28  
    29  	"github.com/ghodss/yaml"
    30  
    31  	appsv1 "k8s.io/api/apps/v1"
    32  	v1 "k8s.io/api/core/v1"
    33  	apierrors "k8s.io/apimachinery/pkg/api/errors"
    34  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    35  	"k8s.io/apimachinery/pkg/runtime"
    36  	yamlutil "k8s.io/apimachinery/pkg/util/yaml"
    37  	"k8s.io/client-go/kubernetes/fake"
    38  	testcore "k8s.io/client-go/testing"
    39  
    40  	"k8s.io/helm/cmd/helm/installer"
    41  	"k8s.io/helm/pkg/helm/helmpath"
    42  )
    43  
    44  func TestInitCmd(t *testing.T) {
    45  	home, err := ioutil.TempDir("", "helm_home")
    46  	if err != nil {
    47  		t.Fatal(err)
    48  	}
    49  	defer os.RemoveAll(home)
    50  
    51  	var buf bytes.Buffer
    52  	fc := fake.NewSimpleClientset()
    53  	cmd := &initCmd{
    54  		out:        &buf,
    55  		home:       helmpath.Home(home),
    56  		kubeClient: fc,
    57  		namespace:  v1.NamespaceDefault,
    58  	}
    59  	if err := cmd.run(); err != nil {
    60  		t.Errorf("expected error: %v", err)
    61  	}
    62  	actions := fc.Actions()
    63  	if len(actions) != 2 {
    64  		t.Errorf("Expected 2 actions, got %d", len(actions))
    65  	}
    66  	if !actions[0].Matches("create", "deployments") {
    67  		t.Errorf("unexpected action: %v, expected create deployment", actions[0])
    68  	}
    69  	if !actions[1].Matches("create", "services") {
    70  		t.Errorf("unexpected action: %v, expected create service", actions[1])
    71  	}
    72  	expected := "Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster."
    73  	if !strings.Contains(buf.String(), expected) {
    74  		t.Errorf("expected %q, got %q", expected, buf.String())
    75  	}
    76  }
    77  
    78  func TestInitCmd_exists(t *testing.T) {
    79  	home, err := ioutil.TempDir("", "helm_home")
    80  	if err != nil {
    81  		t.Fatal(err)
    82  	}
    83  	defer os.RemoveAll(home)
    84  
    85  	var buf bytes.Buffer
    86  	fc := fake.NewSimpleClientset(&appsv1.Deployment{
    87  		ObjectMeta: metav1.ObjectMeta{
    88  			Namespace: v1.NamespaceDefault,
    89  			Name:      "tiller-deploy",
    90  		},
    91  	})
    92  	fc.PrependReactor("*", "*", func(action testcore.Action) (bool, runtime.Object, error) {
    93  		return true, nil, apierrors.NewAlreadyExists(v1.Resource("deployments"), "1")
    94  	})
    95  	cmd := &initCmd{
    96  		out:        &buf,
    97  		home:       helmpath.Home(home),
    98  		kubeClient: fc,
    99  		namespace:  v1.NamespaceDefault,
   100  	}
   101  	if err := cmd.run(); err != nil {
   102  		t.Errorf("expected error: %v", err)
   103  	}
   104  	expected := "Warning: Tiller is already installed in the cluster.\n" +
   105  		"(Use --client-only to suppress this message, or --upgrade to upgrade Tiller to the current version.)"
   106  	if !strings.Contains(buf.String(), expected) {
   107  		t.Errorf("expected %q, got %q", expected, buf.String())
   108  	}
   109  }
   110  
   111  func TestInitCmd_clientOnly(t *testing.T) {
   112  	home, err := ioutil.TempDir("", "helm_home")
   113  	if err != nil {
   114  		t.Fatal(err)
   115  	}
   116  	defer os.RemoveAll(home)
   117  
   118  	var buf bytes.Buffer
   119  	fc := fake.NewSimpleClientset()
   120  	cmd := &initCmd{
   121  		out:        &buf,
   122  		home:       helmpath.Home(home),
   123  		kubeClient: fc,
   124  		clientOnly: true,
   125  		namespace:  v1.NamespaceDefault,
   126  	}
   127  	if err := cmd.run(); err != nil {
   128  		t.Errorf("unexpected error: %v", err)
   129  	}
   130  	if len(fc.Actions()) != 0 {
   131  		t.Error("expected client call")
   132  	}
   133  	expected := "Not installing Tiller due to 'client-only' flag having been set"
   134  	if !strings.Contains(buf.String(), expected) {
   135  		t.Errorf("expected %q, got %q", expected, buf.String())
   136  	}
   137  }
   138  
   139  func TestInitCmd_dryRun(t *testing.T) {
   140  	// This is purely defensive in this case.
   141  	home, err := ioutil.TempDir("", "helm_home")
   142  	if err != nil {
   143  		t.Fatal(err)
   144  	}
   145  	cleanup := resetEnv()
   146  	defer func() {
   147  		os.Remove(home)
   148  		cleanup()
   149  	}()
   150  
   151  	settings.Debug = true
   152  
   153  	var buf bytes.Buffer
   154  	fc := fake.NewSimpleClientset()
   155  	cmd := &initCmd{
   156  		out:        &buf,
   157  		home:       helmpath.Home(home),
   158  		kubeClient: fc,
   159  		clientOnly: true,
   160  		dryRun:     true,
   161  		namespace:  v1.NamespaceDefault,
   162  	}
   163  	if err := cmd.run(); err != nil {
   164  		t.Fatal(err)
   165  	}
   166  	if got := len(fc.Actions()); got != 0 {
   167  		t.Errorf("expected no server calls, got %d", got)
   168  	}
   169  
   170  	docs := bytes.Split(buf.Bytes(), []byte("\n---"))
   171  	if got, want := len(docs), 2; got != want {
   172  		t.Fatalf("Expected document count of %d, got %d", want, got)
   173  	}
   174  	for _, doc := range docs {
   175  		var y map[string]interface{}
   176  		if err := yaml.Unmarshal(doc, &y); err != nil {
   177  			t.Errorf("Expected parseable YAML, got %q\n\t%s", doc, err)
   178  		}
   179  	}
   180  }
   181  
   182  func TestInitCmd_tlsOptions(t *testing.T) {
   183  	const testDir = "../../testdata"
   184  
   185  	// tls certificates in testDir
   186  	var (
   187  		testCaCertFile = filepath.Join(testDir, "ca.pem")
   188  		testCertFile   = filepath.Join(testDir, "crt.pem")
   189  		testKeyFile    = filepath.Join(testDir, "key.pem")
   190  	)
   191  
   192  	// these tests verify the effects of permuting the "--tls" and "--tls-verify" flags
   193  	// and the install options yieled as a result of (*initCmd).tlsOptions()
   194  	// during helm init.
   195  	var tests = []struct {
   196  		certFile string
   197  		keyFile  string
   198  		caFile   string
   199  		enable   bool
   200  		verify   bool
   201  		describe string
   202  	}{
   203  		{ // --tls and --tls-verify specified (--tls=true,--tls-verify=true)
   204  			certFile: testCertFile,
   205  			keyFile:  testKeyFile,
   206  			caFile:   testCaCertFile,
   207  			enable:   true,
   208  			verify:   true,
   209  			describe: "--tls and --tls-verify specified (--tls=true,--tls-verify=true)",
   210  		},
   211  		{ // --tls-verify implies --tls (--tls=false,--tls-verify=true)
   212  			certFile: testCertFile,
   213  			keyFile:  testKeyFile,
   214  			caFile:   testCaCertFile,
   215  			enable:   false,
   216  			verify:   true,
   217  			describe: "--tls-verify implies --tls (--tls=false,--tls-verify=true)",
   218  		},
   219  		{ // no --tls-verify (--tls=true,--tls-verify=false)
   220  			certFile: testCertFile,
   221  			keyFile:  testKeyFile,
   222  			caFile:   "",
   223  			enable:   true,
   224  			verify:   false,
   225  			describe: "no --tls-verify (--tls=true,--tls-verify=false)",
   226  		},
   227  		{ // tls is disabled (--tls=false,--tls-verify=false)
   228  			certFile: "",
   229  			keyFile:  "",
   230  			caFile:   "",
   231  			enable:   false,
   232  			verify:   false,
   233  			describe: "tls is disabled (--tls=false,--tls-verify=false)",
   234  		},
   235  	}
   236  
   237  	for _, tt := range tests {
   238  		// emulate tls file specific flags
   239  		tlsCaCertFile, tlsCertFile, tlsKeyFile = tt.caFile, tt.certFile, tt.keyFile
   240  
   241  		// emulate tls enable/verify flags
   242  		tlsEnable, tlsVerify = tt.enable, tt.verify
   243  
   244  		cmd := &initCmd{}
   245  		if err := cmd.tlsOptions(); err != nil {
   246  			t.Fatalf("unexpected error: %v", err)
   247  		}
   248  
   249  		// expected result options
   250  		expect := installer.Options{
   251  			TLSCaCertFile: tt.caFile,
   252  			TLSCertFile:   tt.certFile,
   253  			TLSKeyFile:    tt.keyFile,
   254  			VerifyTLS:     tt.verify,
   255  			EnableTLS:     tt.enable || tt.verify,
   256  		}
   257  
   258  		if !reflect.DeepEqual(cmd.opts, expect) {
   259  			t.Errorf("%s: got %#+v, want %#+v", tt.describe, cmd.opts, expect)
   260  		}
   261  	}
   262  }
   263  
   264  // TestInitCmd_output tests that init -o can be decoded
   265  func TestInitCmd_output(t *testing.T) {
   266  	// This is purely defensive in this case.
   267  	home, err := ioutil.TempDir("", "helm_home")
   268  	if err != nil {
   269  		t.Fatal(err)
   270  	}
   271  	dbg := settings.Debug
   272  	settings.Debug = true
   273  	defer func() {
   274  		os.Remove(home)
   275  		settings.Debug = dbg
   276  	}()
   277  	fc := fake.NewSimpleClientset()
   278  	tests := []string{"json", "yaml"}
   279  	for _, s := range tests {
   280  		var buf bytes.Buffer
   281  		cmd := &initCmd{
   282  			out:        &buf,
   283  			home:       helmpath.Home(home),
   284  			kubeClient: fc,
   285  			opts:       installer.Options{Output: installer.OutputFormat(s)},
   286  			namespace:  v1.NamespaceDefault,
   287  		}
   288  		if err := cmd.run(); err != nil {
   289  			t.Fatal(err)
   290  		}
   291  		if got := len(fc.Actions()); got != 0 {
   292  			t.Errorf("expected no server calls, got %d", got)
   293  		}
   294  
   295  		var obj interface{}
   296  		decoder := yamlutil.NewYAMLOrJSONDecoder(&buf, 4096)
   297  		for {
   298  			err := decoder.Decode(&obj)
   299  			if err != nil {
   300  				if err == io.EOF {
   301  					break
   302  				}
   303  				t.Errorf("error decoding init %s output %s %s", s, err, buf.String())
   304  			}
   305  		}
   306  	}
   307  }