...

Source file src/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/kubectl_test.go

Documentation: sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane

     1  /*
     2  Copyright 2021 The Kubernetes 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 controlplane_test
    18  
    19  import (
    20  	"io"
    21  
    22  	. "github.com/onsi/ginkgo/v2"
    23  	. "github.com/onsi/gomega"
    24  	. "github.com/onsi/gomega/gstruct"
    25  	"k8s.io/client-go/rest"
    26  	"k8s.io/client-go/tools/clientcmd"
    27  	ccapi "k8s.io/client-go/tools/clientcmd/api"
    28  
    29  	. "sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane"
    30  )
    31  
    32  var _ = Describe("Kubectl", func() {
    33  	It("runs kubectl", func() {
    34  		k := &KubeCtl{Path: "bash"}
    35  		args := []string{"-c", "echo 'something'"}
    36  		stdout, stderr, err := k.Run(args...)
    37  		Expect(err).NotTo(HaveOccurred())
    38  		Expect(stdout).To(ContainSubstring("something"))
    39  		bytes, err := io.ReadAll(stderr)
    40  		Expect(err).NotTo(HaveOccurred())
    41  		Expect(bytes).To(BeEmpty())
    42  	})
    43  
    44  	Context("when the command returns a non-zero exit code", func() {
    45  		It("returns an error", func() {
    46  			k := &KubeCtl{Path: "bash"}
    47  			args := []string{
    48  				"-c", "echo 'this is StdErr' >&2; echo 'but this is StdOut' >&1; exit 66",
    49  			}
    50  
    51  			stdout, stderr, err := k.Run(args...)
    52  
    53  			Expect(err).To(MatchError(ContainSubstring("exit status 66")))
    54  
    55  			Expect(stdout).To(ContainSubstring("but this is StdOut"))
    56  			Expect(stderr).To(ContainSubstring("this is StdErr"))
    57  		})
    58  	})
    59  })
    60  
    61  var _ = Describe("KubeConfigFromREST", func() {
    62  	var (
    63  		restCfg *rest.Config
    64  		rawCfg  []byte
    65  		cfg     *ccapi.Config
    66  	)
    67  
    68  	BeforeEach(func() {
    69  		restCfg = &rest.Config{
    70  			Host:    "https://some-host:8675",
    71  			APIPath: "/some-prefix",
    72  			TLSClientConfig: rest.TLSClientConfig{
    73  				CertData: []byte("cert"),
    74  				KeyData:  []byte("key"),
    75  				CAData:   []byte("ca-cert"),
    76  			},
    77  			BearerToken: "some-tok",
    78  			Username:    "some-user",
    79  			Password:    "some-password",
    80  		}
    81  	})
    82  
    83  	JustBeforeEach(func() {
    84  		var err error
    85  		rawCfg, err = KubeConfigFromREST(restCfg)
    86  		Expect(err).NotTo(HaveOccurred(), "should be able to convert & serialize the kubeconfig")
    87  
    88  		cfg, err = clientcmd.Load(rawCfg)
    89  		Expect(err).NotTo(HaveOccurred(), "should be able to deserialize the generated kubeconfig")
    90  	})
    91  
    92  	It("should set up a context, and set it as the current one", func() {
    93  		By("checking that the current context exists")
    94  		Expect(cfg.CurrentContext).NotTo(BeEmpty(), "should have a current context")
    95  		Expect(cfg.Contexts).To(HaveKeyWithValue(cfg.CurrentContext, Not(BeNil())), "the current context should exist as a context")
    96  
    97  		By("checking that it points to valid info")
    98  		currCtx := cfg.Contexts[cfg.CurrentContext]
    99  		Expect(currCtx).To(PointTo(MatchFields(IgnoreExtras, Fields{
   100  			"Cluster":  Not(BeEmpty()),
   101  			"AuthInfo": Not(BeEmpty()),
   102  		})))
   103  
   104  		Expect(cfg.Clusters).To(HaveKeyWithValue(currCtx.Cluster, Not(BeNil())), "should point to a cluster")
   105  		Expect(cfg.AuthInfos).To(HaveKeyWithValue(currCtx.AuthInfo, Not(BeNil())), "should point to a user")
   106  	})
   107  
   108  	Context("when no TLS is enabled", func() {
   109  		BeforeEach(func() {
   110  			restCfg.Host = "http://some-host:8675"
   111  			restCfg.TLSClientConfig = rest.TLSClientConfig{}
   112  		})
   113  
   114  		It("should use http in the server url", func() {
   115  			cluster := cfg.Clusters[cfg.Contexts[cfg.CurrentContext].Cluster]
   116  			Expect(cluster.Server).To(HavePrefix("http://"))
   117  		})
   118  	})
   119  
   120  	It("configure the current context to point to the given REST config's server, with CA data", func() {
   121  		cluster := cfg.Clusters[cfg.Contexts[cfg.CurrentContext].Cluster]
   122  		Expect(cluster).To(PointTo(MatchFields(IgnoreExtras, Fields{
   123  			"Server":                   Equal("https://some-host:8675/some-prefix"),
   124  			"CertificateAuthorityData": Equal([]byte("ca-cert")),
   125  		})))
   126  	})
   127  
   128  	It("should copy all non-plugin auth info over", func() {
   129  		user := cfg.AuthInfos[cfg.Contexts[cfg.CurrentContext].AuthInfo]
   130  		Expect(user).To(PointTo(MatchFields(IgnoreExtras, Fields{
   131  			"ClientCertificateData": Equal([]byte("cert")),
   132  			"ClientKeyData":         Equal([]byte("key")),
   133  			"Token":                 Equal("some-tok"),
   134  			"Username":              Equal("some-user"),
   135  			"Password":              Equal("some-password"),
   136  		})))
   137  	})
   138  })
   139  

View as plain text