github.com/oam-dev/kubevela@v1.9.11/pkg/addon/push_test.go (about)

     1  /*
     2  Copyright 2022 The KubeVela 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 addon
    18  
    19  import (
    20  	"context"
    21  	"crypto/rand"
    22  	"crypto/tls"
    23  	"net/http"
    24  	"net/http/httptest"
    25  	"os"
    26  
    27  	. "github.com/onsi/ginkgo/v2"
    28  	. "github.com/onsi/gomega"
    29  	"k8s.io/helm/pkg/tlsutil"
    30  )
    31  
    32  var _ = Describe("Addon push command", func() {
    33  	var (
    34  		testTarballPath    = "testdata/charts/sample-1.0.1.tgz"
    35  		testServerCertPath = "testdata/tls/server.crt"
    36  		testServerKeyPath  = "testdata/tls/server.key"
    37  		testServerCAPath   = "testdata/tls/server_ca.crt"
    38  		testClientCAPath   = "testdata/tls/client_ca.crt"
    39  		testClientCertPath = "testdata/tls/client.crt"
    40  		testClientKeyPath  = "testdata/tls/client.key"
    41  	)
    42  	var (
    43  		statusCode int
    44  		body       string
    45  		tmp        string
    46  	)
    47  	var p *PushCmd
    48  	var ts *httptest.Server
    49  	var err error
    50  	var ds RegistryDataStore
    51  
    52  	setArgsAndRun := func(args []string) error {
    53  		p = &PushCmd{}
    54  		p.Client = k8sClient
    55  		p.Out = os.Stdout
    56  		p.ChartName = args[0]
    57  		p.RepoName = args[1]
    58  		p.SetFieldsFromEnv()
    59  		return p.Push(context.TODO())
    60  	}
    61  
    62  	AfterEach(func() {
    63  		ts.Close()
    64  		_ = os.RemoveAll(tmp)
    65  		err = ds.DeleteRegistry(context.TODO(), "helm-push-test")
    66  		Expect(err).To(Succeed())
    67  	})
    68  
    69  	Context("plain old HTTP Server", func() {
    70  		BeforeEach(func() {
    71  			statusCode = 201
    72  			body = "{\"success\": true}"
    73  			ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    74  				w.WriteHeader(statusCode)
    75  				w.Write([]byte(body))
    76  			}))
    77  
    78  			// Create new Helm home w/ test repo
    79  			tmp, err = os.MkdirTemp("", "helm-push-test")
    80  			Expect(err).To(Succeed())
    81  
    82  			// Add our helm repo to addon registry
    83  			ds = NewRegistryDataStore(k8sClient)
    84  			err = ds.AddRegistry(context.TODO(), Registry{
    85  				Name: "helm-push-test",
    86  				Helm: &HelmSource{
    87  					URL: ts.URL,
    88  				},
    89  			})
    90  			Expect(err).To(Succeed())
    91  
    92  			_ = os.Setenv("HELM_REPO_USERNAME", "myuser")
    93  			_ = os.Setenv("HELM_REPO_PASSWORD", "mypass")
    94  			_ = os.Setenv("HELM_REPO_CONTEXT_PATH", "/x/y/z")
    95  		})
    96  
    97  		It("Not enough args", func() {
    98  			err = setArgsAndRun([]string{"", ""})
    99  			Expect(err).ShouldNot(Succeed(), "expecting error with missing args, instead got nil")
   100  		})
   101  
   102  		It("Bad chart path", func() {
   103  			args := []string{"/this/this/not/a/chart", "helm-push-test"}
   104  			err = setArgsAndRun(args)
   105  			Expect(err).ShouldNot(Succeed(), "expecting error with bad chart path, instead got nil")
   106  		})
   107  
   108  		It("Bad repo name", func() {
   109  			args := []string{testTarballPath, "this-is-not-a-valid-repo"}
   110  			err = setArgsAndRun(args)
   111  			Expect(err).ShouldNot(Succeed(), "expecting error with bad repo name, instead got nil")
   112  		})
   113  
   114  		It("Valid tar, repo name", func() {
   115  			args := []string{testTarballPath, "helm-push-test"}
   116  			err = setArgsAndRun(args)
   117  			Expect(err).Should(Succeed())
   118  		})
   119  
   120  		It("Valid tar, repo URL", func() {
   121  			args := []string{testTarballPath, ts.URL}
   122  			err = setArgsAndRun(args)
   123  			Expect(err).Should(Succeed())
   124  		})
   125  
   126  		It("Trigger 409, already exists", func() {
   127  			statusCode = 409
   128  			body = "{\"error\": \"package already exists\"}"
   129  			args := []string{testTarballPath, "helm-push-test"}
   130  			err = setArgsAndRun(args)
   131  			Expect(err).ShouldNot(Succeed(), "expecting error with 409, instead got nil")
   132  		})
   133  
   134  		It("Unable to parse JSON response body", func() {
   135  			statusCode = 500
   136  			body = "duiasnhioasd"
   137  			args := []string{testTarballPath, "helm-push-test"}
   138  			err = setArgsAndRun(args)
   139  			Expect(err).ShouldNot(Succeed(), "expecting error with bad response body, instead got nil")
   140  		})
   141  	})
   142  
   143  	Context("TLS Enabled Server", func() {
   144  		BeforeEach(func() {
   145  			statusCode = 201
   146  			body = "{\"success\": true}"
   147  			ts = httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   148  				w.WriteHeader(statusCode)
   149  				_, _ = w.Write([]byte(body))
   150  			}))
   151  			serverCert, err := tls.LoadX509KeyPair(testServerCertPath, testServerKeyPath)
   152  			Expect(err).To(Succeed(), "failed to load certificate and key")
   153  
   154  			clientCaCertPool, err := tlsutil.CertPoolFromFile(testClientCAPath)
   155  			Expect(err).To(Succeed(), "load server CA file failed")
   156  
   157  			ts.TLS = &tls.Config{
   158  				ClientCAs:    clientCaCertPool,
   159  				ClientAuth:   tls.RequireAndVerifyClientCert,
   160  				Certificates: []tls.Certificate{serverCert},
   161  				Rand:         rand.Reader,
   162  			}
   163  			ts.StartTLS()
   164  
   165  			// Create new Helm home w/ test repo
   166  			tmp, err = os.MkdirTemp("", "helm-push-test")
   167  			Expect(err).To(Succeed())
   168  
   169  			// Add our helm repo to addon registry
   170  			ds = NewRegistryDataStore(k8sClient)
   171  			err = ds.AddRegistry(context.TODO(), Registry{
   172  				Name: "helm-push-test",
   173  				Helm: &HelmSource{
   174  					URL: ts.URL,
   175  				},
   176  			})
   177  			Expect(err).To(Succeed())
   178  
   179  			_ = os.Setenv("HELM_REPO_USERNAME", "myuser")
   180  			_ = os.Setenv("HELM_REPO_PASSWORD", "mypass")
   181  			_ = os.Setenv("HELM_REPO_CONTEXT_PATH", "/x/y/z")
   182  		})
   183  
   184  		It("no cert provided", func() {
   185  			_ = os.Unsetenv("HELM_REPO_CA_FILE")
   186  			_ = os.Unsetenv("HELM_REPO_CERT_FILE")
   187  			_ = os.Unsetenv("HELM_REPO_KEY_FILE")
   188  			args := []string{testTarballPath, "helm-push-test"}
   189  			err = setArgsAndRun(args)
   190  			Expect(err).ShouldNot(Succeed(), "expected non nil error but got nil when run cmd without certificate option")
   191  		})
   192  
   193  		It("with cert", func() {
   194  			_ = os.Setenv("HELM_REPO_CA_FILE", testServerCAPath)
   195  			_ = os.Setenv("HELM_REPO_CERT_FILE", testClientCertPath)
   196  			_ = os.Setenv("HELM_REPO_KEY_FILE", testClientKeyPath)
   197  			args := []string{testTarballPath, "helm-push-test"}
   198  			err = setArgsAndRun(args)
   199  			Expect(err).Should(Succeed())
   200  		})
   201  	})
   202  })