1
16
17 package auth
18
19 import (
20 "bytes"
21 "fmt"
22 "io"
23 "strings"
24 "testing"
25
26 authenticationv1 "k8s.io/api/authentication/v1"
27 authenticationv1alpha1 "k8s.io/api/authentication/v1alpha1"
28 authenticationv1beta1 "k8s.io/api/authentication/v1beta1"
29 corev1 "k8s.io/api/core/v1"
30 "k8s.io/apimachinery/pkg/api/errors"
31 "k8s.io/apimachinery/pkg/runtime"
32 "k8s.io/cli-runtime/pkg/printers"
33 authfake "k8s.io/client-go/kubernetes/fake"
34 core "k8s.io/client-go/testing"
35 cmdtesting "k8s.io/kubectl/pkg/cmd/testing"
36 "k8s.io/kubectl/pkg/scheme"
37 )
38
39 func TestWhoAmIRun(t *testing.T) {
40 tests := []struct {
41 name string
42 o *WhoAmIOptions
43 args []string
44 serverErr error
45 alphaDisabled bool
46 betaDisabled bool
47 stableDisabled bool
48
49 expectedError error
50 expectedBodyStrings []string
51 }{
52 {
53 name: "success test",
54 o: &WhoAmIOptions{
55 resourcePrinterFunc: printTableSelfSubjectAccessReview,
56 },
57 args: []string{},
58 expectedBodyStrings: []string{
59 `ATTRIBUTE VALUE`,
60 `Username jane.doe`,
61 `UID uniq-id`,
62 `Groups [students teachers]`,
63 `Extra: skills [reading learning]`,
64 `Extra: subjects [math sports]`,
65 ``,
66 },
67 },
68 {
69 name: "JSON test",
70 o: &WhoAmIOptions{
71 resourcePrinterFunc: printers.NewTypeSetter(scheme.Scheme).ToPrinter(&printers.JSONPrinter{}).PrintObj,
72 },
73 args: []string{},
74 expectedBodyStrings: []string{
75 `{
76 "kind": "SelfSubjectReview",
77 "apiVersion": "authentication.k8s.io/v1",
78 "metadata": {
79 "creationTimestamp": null
80 },
81 "status": {
82 "userInfo": {
83 "username": "jane.doe",
84 "uid": "uniq-id",
85 "groups": [
86 "students",
87 "teachers"
88 ],
89 "extra": {
90 "skills": [
91 "reading",
92 "learning"
93 ],
94 "subjects": [
95 "math",
96 "sports"
97 ]
98 }
99 }
100 }
101 }
102 `,
103 },
104 },
105 {
106 name: "success test no alpha",
107 o: &WhoAmIOptions{
108 resourcePrinterFunc: printTableSelfSubjectAccessReview,
109 },
110 args: []string{},
111 alphaDisabled: true,
112 expectedBodyStrings: []string{
113 `ATTRIBUTE VALUE`,
114 `Username jane.doe`,
115 `UID uniq-id`,
116 `Groups [students teachers]`,
117 `Extra: skills [reading learning]`,
118 `Extra: subjects [math sports]`,
119 ``,
120 },
121 },
122 {
123 name: "JSON test no alpha and stable",
124 o: &WhoAmIOptions{
125 resourcePrinterFunc: printers.NewTypeSetter(scheme.Scheme).ToPrinter(&printers.JSONPrinter{}).PrintObj,
126 },
127 args: []string{},
128 alphaDisabled: true,
129 stableDisabled: true,
130 expectedBodyStrings: []string{
131 `{
132 "kind": "SelfSubjectReview",
133 "apiVersion": "authentication.k8s.io/v1beta1",
134 "metadata": {
135 "creationTimestamp": null
136 },
137 "status": {
138 "userInfo": {
139 "username": "jane.doe",
140 "uid": "uniq-id",
141 "groups": [
142 "students",
143 "teachers"
144 ],
145 "extra": {
146 "skills": [
147 "reading",
148 "learning"
149 ],
150 "subjects": [
151 "math",
152 "sports"
153 ]
154 }
155 }
156 }
157 }
158 `,
159 },
160 },
161 {
162 name: "success test no beta",
163 o: &WhoAmIOptions{
164 resourcePrinterFunc: printTableSelfSubjectAccessReview,
165 },
166 args: []string{},
167 betaDisabled: true,
168 expectedBodyStrings: []string{
169 `ATTRIBUTE VALUE`,
170 `Username jane.doe`,
171 `UID uniq-id`,
172 `Groups [students teachers]`,
173 `Extra: skills [reading learning]`,
174 `Extra: subjects [math sports]`,
175 ``,
176 },
177 },
178 {
179 name: "JSON test no beta",
180 o: &WhoAmIOptions{
181 resourcePrinterFunc: printers.NewTypeSetter(scheme.Scheme).ToPrinter(&printers.JSONPrinter{}).PrintObj,
182 },
183 args: []string{},
184 betaDisabled: true,
185 expectedBodyStrings: []string{
186 `{
187 "kind": "SelfSubjectReview",
188 "apiVersion": "authentication.k8s.io/v1",
189 "metadata": {
190 "creationTimestamp": null
191 },
192 "status": {
193 "userInfo": {
194 "username": "jane.doe",
195 "uid": "uniq-id",
196 "groups": [
197 "students",
198 "teachers"
199 ],
200 "extra": {
201 "skills": [
202 "reading",
203 "learning"
204 ],
205 "subjects": [
206 "math",
207 "sports"
208 ]
209 }
210 }
211 }
212 }
213 `,
214 },
215 },
216 {
217 name: "all API disabled",
218 o: &WhoAmIOptions{
219 resourcePrinterFunc: printTableSelfSubjectAccessReview,
220 },
221 args: []string{},
222 betaDisabled: true,
223 alphaDisabled: true,
224 stableDisabled: true,
225 expectedError: notEnabledErr,
226 },
227 {
228 name: "Forbidden error",
229 o: &WhoAmIOptions{
230 resourcePrinterFunc: printTableSelfSubjectAccessReview,
231 },
232 args: []string{},
233 serverErr: errors.NewForbidden(
234 corev1.Resource("selfsubjectreviews"), "foo", fmt.Errorf("error"),
235 ),
236 expectedError: forbiddenErr,
237 expectedBodyStrings: []string{},
238 },
239 {
240 name: "NotFound error",
241 o: &WhoAmIOptions{
242 resourcePrinterFunc: printTableSelfSubjectAccessReview,
243 },
244 args: []string{},
245 serverErr: errors.NewNotFound(corev1.Resource("selfsubjectreviews"), "foo"),
246 expectedError: notEnabledErr,
247 expectedBodyStrings: []string{},
248 },
249 {
250 name: "Server error",
251 o: &WhoAmIOptions{
252 resourcePrinterFunc: printTableSelfSubjectAccessReview,
253 },
254 args: []string{},
255 serverErr: fmt.Errorf("a random server-side error"),
256 expectedError: fmt.Errorf("a random server-side error"),
257 expectedBodyStrings: []string{},
258 },
259 }
260
261 for _, test := range tests {
262 t.Run(test.name, func(t *testing.T) {
263 var b bytes.Buffer
264
265 test.o.Out = &b
266 test.o.ErrOut = io.Discard
267
268 tf := cmdtesting.NewTestFactory().WithNamespace("test")
269 defer tf.Cleanup()
270
271 fakeAuthClientSet := &authfake.Clientset{}
272
273 fakeAuthClientSet.AddReactor("create", "selfsubjectreviews",
274 func(action core.Action) (handled bool, ret runtime.Object, err error) {
275 if test.serverErr != nil {
276 return true, nil, test.serverErr
277 }
278
279 ui := authenticationv1.UserInfo{
280 Username: "jane.doe",
281 UID: "uniq-id",
282 Groups: []string{"students", "teachers"},
283 Extra: map[string]authenticationv1.ExtraValue{
284 "subjects": {"math", "sports"},
285 "skills": {"reading", "learning"},
286 },
287 }
288
289 switch action.GetResource().GroupVersion().String() {
290 case "authentication.k8s.io/v1alpha1":
291 if test.alphaDisabled {
292 return true, nil, errors.NewNotFound(corev1.Resource("selfsubjectreviews"), "foo")
293 }
294 res := &authenticationv1alpha1.SelfSubjectReview{
295 Status: authenticationv1alpha1.SelfSubjectReviewStatus{
296 UserInfo: ui,
297 },
298 }
299 return true, res, nil
300 case "authentication.k8s.io/v1beta1":
301 if test.betaDisabled {
302 return true, nil, errors.NewNotFound(corev1.Resource("selfsubjectreviews"), "foo")
303 }
304 res := &authenticationv1beta1.SelfSubjectReview{
305 Status: authenticationv1beta1.SelfSubjectReviewStatus{
306 UserInfo: ui,
307 },
308 }
309 return true, res, nil
310 case "authentication.k8s.io/v1":
311 if test.stableDisabled {
312 return true, nil, errors.NewNotFound(corev1.Resource("selfsubjectreviews"), "foo")
313 }
314 res := &authenticationv1.SelfSubjectReview{
315 Status: authenticationv1.SelfSubjectReviewStatus{
316 UserInfo: ui,
317 },
318 }
319 return true, res, nil
320 default:
321 return false, nil, fmt.Errorf("unknown API")
322 }
323 })
324 test.o.authV1beta1Client = fakeAuthClientSet.AuthenticationV1beta1()
325 test.o.authV1alpha1Client = fakeAuthClientSet.AuthenticationV1alpha1()
326 test.o.authV1Client = fakeAuthClientSet.AuthenticationV1()
327
328 err := test.o.Run()
329 switch {
330 case test.expectedError == nil && err == nil:
331
332 case err != nil && test.expectedError != nil && strings.Contains(err.Error(), test.expectedError.Error()):
333
334 default:
335 t.Errorf("%s: expected %v, got %v", test.name, test.expectedError, err)
336 return
337 }
338
339 res := b.String()
340 expectedBody := strings.Join(test.expectedBodyStrings, "\n")
341
342 if expectedBody != res {
343 t.Errorf("%s: expected \n%q, got \n%q", test.name, expectedBody, res)
344 }
345 })
346 }
347 }
348
View as plain text