1
16
17 package exec
18
19 import (
20 "strings"
21 "testing"
22
23 "github.com/google/go-cmp/cmp"
24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25 "k8s.io/apimachinery/pkg/runtime"
26 "k8s.io/apimachinery/pkg/runtime/schema"
27 clientauthenticationv1 "k8s.io/client-go/pkg/apis/clientauthentication/v1"
28 clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
29 "k8s.io/client-go/rest"
30 )
31
32
33 type restInfo struct {
34 host string
35 tlsClientConfig rest.TLSClientConfig
36 proxyURL string
37 }
38
39 func TestLoadExecCredential(t *testing.T) {
40 t.Parallel()
41
42 tests := []struct {
43 name string
44 data []byte
45 wantExecCredential runtime.Object
46 wantRESTInfo restInfo
47 wantErrorPrefix string
48 }{
49 {
50 name: "v1 happy path",
51 data: marshal(t, clientauthenticationv1.SchemeGroupVersion, &clientauthenticationv1.ExecCredential{
52 Spec: clientauthenticationv1.ExecCredentialSpec{
53 Cluster: &clientauthenticationv1.Cluster{
54 Server: "https://some-server/some/path",
55 TLSServerName: "some-server-name",
56 InsecureSkipTLSVerify: true,
57 CertificateAuthorityData: []byte("some-ca-data"),
58 ProxyURL: "https://some-proxy-url:12345",
59 Config: runtime.RawExtension{
60 Raw: []byte(`{"apiVersion":"group/v1","kind":"PluginConfig","spec":{"names":["marshmallow","zelda"]}}`),
61 },
62 },
63 },
64 }),
65 wantExecCredential: &clientauthenticationv1.ExecCredential{
66 TypeMeta: metav1.TypeMeta{
67 Kind: "ExecCredential",
68 APIVersion: clientauthenticationv1.SchemeGroupVersion.String(),
69 },
70 Spec: clientauthenticationv1.ExecCredentialSpec{
71 Cluster: &clientauthenticationv1.Cluster{
72 Server: "https://some-server/some/path",
73 TLSServerName: "some-server-name",
74 InsecureSkipTLSVerify: true,
75 CertificateAuthorityData: []byte("some-ca-data"),
76 ProxyURL: "https://some-proxy-url:12345",
77 Config: runtime.RawExtension{
78 Raw: []byte(`{"apiVersion":"group/v1","kind":"PluginConfig","spec":{"names":["marshmallow","zelda"]}}`),
79 },
80 },
81 },
82 },
83 wantRESTInfo: restInfo{
84 host: "https://some-server/some/path",
85 tlsClientConfig: rest.TLSClientConfig{
86 Insecure: true,
87 ServerName: "some-server-name",
88 CAData: []byte("some-ca-data"),
89 },
90 proxyURL: "https://some-proxy-url:12345",
91 },
92 },
93 {
94 name: "v1beta1 happy path",
95 data: marshal(t, clientauthenticationv1beta1.SchemeGroupVersion, &clientauthenticationv1beta1.ExecCredential{
96 Spec: clientauthenticationv1beta1.ExecCredentialSpec{
97 Cluster: &clientauthenticationv1beta1.Cluster{
98 Server: "https://some-server/some/path",
99 TLSServerName: "some-server-name",
100 InsecureSkipTLSVerify: true,
101 CertificateAuthorityData: []byte("some-ca-data"),
102 ProxyURL: "https://some-proxy-url:12345",
103 Config: runtime.RawExtension{
104 Raw: []byte(`{"apiVersion":"group/v1","kind":"PluginConfig","spec":{"names":["marshmallow","zelda"]}}`),
105 },
106 },
107 },
108 }),
109 wantExecCredential: &clientauthenticationv1beta1.ExecCredential{
110 TypeMeta: metav1.TypeMeta{
111 Kind: "ExecCredential",
112 APIVersion: clientauthenticationv1beta1.SchemeGroupVersion.String(),
113 },
114 Spec: clientauthenticationv1beta1.ExecCredentialSpec{
115 Cluster: &clientauthenticationv1beta1.Cluster{
116 Server: "https://some-server/some/path",
117 TLSServerName: "some-server-name",
118 InsecureSkipTLSVerify: true,
119 CertificateAuthorityData: []byte("some-ca-data"),
120 ProxyURL: "https://some-proxy-url:12345",
121 Config: runtime.RawExtension{
122 Raw: []byte(`{"apiVersion":"group/v1","kind":"PluginConfig","spec":{"names":["marshmallow","zelda"]}}`),
123 },
124 },
125 },
126 },
127 wantRESTInfo: restInfo{
128 host: "https://some-server/some/path",
129 tlsClientConfig: rest.TLSClientConfig{
130 Insecure: true,
131 ServerName: "some-server-name",
132 CAData: []byte("some-ca-data"),
133 },
134 proxyURL: "https://some-proxy-url:12345",
135 },
136 },
137 {
138 name: "v1 nil config",
139 data: marshal(t, clientauthenticationv1.SchemeGroupVersion, &clientauthenticationv1.ExecCredential{
140 Spec: clientauthenticationv1.ExecCredentialSpec{
141 Cluster: &clientauthenticationv1.Cluster{
142 Server: "https://some-server/some/path",
143 TLSServerName: "some-server-name",
144 InsecureSkipTLSVerify: true,
145 CertificateAuthorityData: []byte("some-ca-data"),
146 ProxyURL: "https://some-proxy-url:12345",
147 },
148 },
149 }),
150 wantExecCredential: &clientauthenticationv1.ExecCredential{
151 TypeMeta: metav1.TypeMeta{
152 Kind: "ExecCredential",
153 APIVersion: clientauthenticationv1.SchemeGroupVersion.String(),
154 },
155 Spec: clientauthenticationv1.ExecCredentialSpec{
156 Cluster: &clientauthenticationv1.Cluster{
157 Server: "https://some-server/some/path",
158 TLSServerName: "some-server-name",
159 InsecureSkipTLSVerify: true,
160 CertificateAuthorityData: []byte("some-ca-data"),
161 ProxyURL: "https://some-proxy-url:12345",
162 },
163 },
164 },
165 wantRESTInfo: restInfo{
166 host: "https://some-server/some/path",
167 tlsClientConfig: rest.TLSClientConfig{
168 Insecure: true,
169 ServerName: "some-server-name",
170 CAData: []byte("some-ca-data"),
171 },
172 proxyURL: "https://some-proxy-url:12345",
173 },
174 },
175 {
176 name: "v1beta1 nil config",
177 data: marshal(t, clientauthenticationv1beta1.SchemeGroupVersion, &clientauthenticationv1beta1.ExecCredential{
178 Spec: clientauthenticationv1beta1.ExecCredentialSpec{
179 Cluster: &clientauthenticationv1beta1.Cluster{
180 Server: "https://some-server/some/path",
181 TLSServerName: "some-server-name",
182 InsecureSkipTLSVerify: true,
183 CertificateAuthorityData: []byte("some-ca-data"),
184 ProxyURL: "https://some-proxy-url:12345",
185 },
186 },
187 }),
188 wantExecCredential: &clientauthenticationv1beta1.ExecCredential{
189 TypeMeta: metav1.TypeMeta{
190 Kind: "ExecCredential",
191 APIVersion: clientauthenticationv1beta1.SchemeGroupVersion.String(),
192 },
193 Spec: clientauthenticationv1beta1.ExecCredentialSpec{
194 Cluster: &clientauthenticationv1beta1.Cluster{
195 Server: "https://some-server/some/path",
196 TLSServerName: "some-server-name",
197 InsecureSkipTLSVerify: true,
198 CertificateAuthorityData: []byte("some-ca-data"),
199 ProxyURL: "https://some-proxy-url:12345",
200 },
201 },
202 },
203 wantRESTInfo: restInfo{
204 host: "https://some-server/some/path",
205 tlsClientConfig: rest.TLSClientConfig{
206 Insecure: true,
207 ServerName: "some-server-name",
208 CAData: []byte("some-ca-data"),
209 },
210 proxyURL: "https://some-proxy-url:12345",
211 },
212 },
213 {
214 name: "v1 invalid cluster",
215 data: marshal(t, clientauthenticationv1.SchemeGroupVersion, &clientauthenticationv1.ExecCredential{
216 Spec: clientauthenticationv1.ExecCredentialSpec{
217 Cluster: &clientauthenticationv1.Cluster{
218 ProxyURL: "invalid- url\n",
219 },
220 },
221 }),
222 wantErrorPrefix: "cannot create rest.Config",
223 },
224 {
225 name: "v1beta1 invalid cluster",
226 data: marshal(t, clientauthenticationv1beta1.SchemeGroupVersion, &clientauthenticationv1beta1.ExecCredential{
227 Spec: clientauthenticationv1beta1.ExecCredentialSpec{
228 Cluster: &clientauthenticationv1beta1.Cluster{
229 ProxyURL: "invalid- url\n",
230 },
231 },
232 }),
233 wantErrorPrefix: "cannot create rest.Config",
234 },
235 {
236 name: "v1 nil cluster",
237 data: marshal(t, clientauthenticationv1.SchemeGroupVersion, &clientauthenticationv1.ExecCredential{}),
238 wantErrorPrefix: "ExecCredential does not contain cluster information",
239 },
240 {
241 name: "v1beta1 nil cluster",
242 data: marshal(t, clientauthenticationv1beta1.SchemeGroupVersion, &clientauthenticationv1beta1.ExecCredential{}),
243 wantErrorPrefix: "ExecCredential does not contain cluster information",
244 },
245 {
246 name: "invalid object kind",
247 data: marshal(t, metav1.SchemeGroupVersion, &metav1.Status{}),
248 wantErrorPrefix: "invalid group/kind: wanted ExecCredential.client.authentication.k8s.io, got Status",
249 },
250 {
251 name: "bad data",
252 data: []byte("bad data"),
253 wantErrorPrefix: "decode: ",
254 },
255 }
256 for _, test := range tests {
257 test := test
258 t.Run(test.name, func(t *testing.T) {
259 t.Parallel()
260
261 execCredential, restConfig, err := LoadExecCredential(test.data)
262 if test.wantErrorPrefix != "" {
263 if err == nil {
264 t.Error("wanted error, got success")
265 } else if !strings.HasPrefix(err.Error(), test.wantErrorPrefix) {
266 t.Errorf("wanted '%s', got '%s'", test.wantErrorPrefix, err.Error())
267 }
268 } else if err != nil {
269 t.Error(err)
270 } else {
271 if diff := cmp.Diff(test.wantExecCredential, execCredential); diff != "" {
272 t.Error(diff)
273 }
274
275 if diff := cmp.Diff(test.wantRESTInfo.host, restConfig.Host); diff != "" {
276 t.Error(diff)
277 }
278 if diff := cmp.Diff(test.wantRESTInfo.tlsClientConfig, restConfig.TLSClientConfig); diff != "" {
279 t.Error(diff)
280 }
281
282 proxyURL, err := restConfig.Proxy(nil)
283 if err != nil {
284 t.Fatal(err)
285 }
286 if diff := cmp.Diff(test.wantRESTInfo.proxyURL, proxyURL.String()); diff != "" {
287 t.Error(diff)
288 }
289 }
290 })
291 }
292 }
293
294 func marshal(t *testing.T, gv schema.GroupVersion, obj runtime.Object) []byte {
295 t.Helper()
296
297 data, err := runtime.Encode(codecs.LegacyCodec(gv), obj)
298 if err != nil {
299 t.Fatal(err)
300 }
301
302 return data
303 }
304
View as plain text