1
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