@@ -17,7 +17,9 @@ import (
1717 corev1 "k8s.io/api/core/v1"
1818 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1919 "sigs.k8s.io/controller-runtime/pkg/client"
20+ "sigs.k8s.io/controller-runtime/pkg/client/fake"
2021
22+ grpcContext "github.com/nginx/nginx-gateway-fabric/v2/internal/controller/nginx/agent/grpc/context"
2123 "github.com/nginx/nginx-gateway-fabric/v2/internal/framework/controller"
2224)
2325
@@ -67,6 +69,7 @@ func (m *mockClient) List(_ context.Context, obj client.ObjectList, _ ...client.
6769 Namespace : m .podNamespace ,
6870 Labels : labels ,
6971 },
72+ Status : corev1.PodStatus {Phase : corev1 .PodRunning },
7073 },
7174 }
7275
@@ -204,38 +207,6 @@ func TestInterceptor(t *testing.T) {
204207 expErrCode : codes .Unauthenticated ,
205208 expErrMsg : "must be of the format" ,
206209 },
207- {
208- name : "mismatched namespace in username" ,
209- md : validMetadata ,
210- peer : validPeerData ,
211- username : "system:serviceaccount:invalid:gateway-nginx" ,
212- appName : "gateway-nginx" ,
213- podNamespace : "default" ,
214- authenticated : true ,
215- expErrCode : codes .Unauthenticated ,
216- expErrMsg : "does not match namespace" ,
217- },
218- {
219- name : "mismatched name in username" ,
220- md : validMetadata ,
221- peer : validPeerData ,
222- username : "system:serviceaccount:default:invalid" ,
223- appName : "gateway-nginx" ,
224- podNamespace : "default" ,
225- authenticated : true ,
226- expErrCode : codes .Unauthenticated ,
227- expErrMsg : "does not match service account name" ,
228- },
229- {
230- name : "missing app name label" ,
231- md : validMetadata ,
232- peer : validPeerData ,
233- username : "system:serviceaccount:default:gateway-nginx" ,
234- podNamespace : "default" ,
235- authenticated : true ,
236- expErrCode : codes .Unauthenticated ,
237- expErrMsg : "could not get app name" ,
238- },
239210 }
240211
241212 streamHandler := func (_ any , _ grpc.ServerStream ) error {
@@ -261,7 +232,7 @@ func TestInterceptor(t *testing.T) {
261232 }
262233 cs := NewContextSetter (mockK8sClient , "ngf-audience" )
263234
264- ctx := context . Background ()
235+ ctx := t . Context ()
265236 if test .md != nil {
266237 peerCtx := context .Background ()
267238 if test .peer != nil {
@@ -290,3 +261,147 @@ func TestInterceptor(t *testing.T) {
290261 })
291262 }
292263}
264+
265+ type patchClient struct {
266+ client.Client
267+ }
268+
269+ func (p * patchClient ) Create (_ context.Context , obj client.Object , _ ... client.CreateOption ) error {
270+ tr , ok := obj .(* authv1.TokenReview )
271+ if ok {
272+ tr .Status .Authenticated = true
273+ tr .Status .User .Username = "system:serviceaccount:default:gateway-nginx"
274+ }
275+ return nil
276+ }
277+
278+ func TestValidateToken_PodListOptions (t * testing.T ) {
279+ t .Parallel ()
280+
281+ testCases := []struct {
282+ pod * corev1.Pod
283+ gi * grpcContext.GrpcInfo
284+ name string
285+ shouldErr bool
286+ }{
287+ {
288+ name : "all match" ,
289+ pod : & corev1.Pod {
290+ ObjectMeta : metav1.ObjectMeta {
291+ Name : "nginx-pod" ,
292+ Namespace : "default" ,
293+ Labels : map [string ]string {
294+ controller .AppNameLabel : "gateway-nginx" ,
295+ },
296+ },
297+ Status : corev1.PodStatus {PodIP : "1.2.3.4" , Phase : corev1 .PodRunning },
298+ },
299+ gi : & grpcContext.GrpcInfo {Token : "dummy-token" , IPAddress : "1.2.3.4" },
300+ shouldErr : false ,
301+ },
302+ {
303+ name : "ip matches, namespace does not" ,
304+ pod : & corev1.Pod {
305+ ObjectMeta : metav1.ObjectMeta {
306+ Name : "nginx-pod" ,
307+ Namespace : "other-namespace" ,
308+ Labels : map [string ]string {
309+ controller .AppNameLabel : "gateway-nginx" ,
310+ },
311+ },
312+ Status : corev1.PodStatus {PodIP : "1.2.3.4" , Phase : corev1 .PodRunning },
313+ },
314+ gi : & grpcContext.GrpcInfo {Token : "dummy-token" , IPAddress : "1.2.3.4" },
315+ shouldErr : true ,
316+ },
317+ {
318+ name : "ip matches, label value does not match" ,
319+ pod : & corev1.Pod {
320+ ObjectMeta : metav1.ObjectMeta {
321+ Name : "nginx-pod" ,
322+ Namespace : "default" ,
323+ Labels : map [string ]string {
324+ controller .AppNameLabel : "not-gateway-nginx" ,
325+ },
326+ },
327+ Status : corev1.PodStatus {PodIP : "1.2.3.4" , Phase : corev1 .PodRunning },
328+ },
329+ gi : & grpcContext.GrpcInfo {Token : "dummy-token" , IPAddress : "1.2.3.4" },
330+ shouldErr : true ,
331+ },
332+ {
333+ name : "ip matches, label does not exist" ,
334+ pod : & corev1.Pod {
335+ ObjectMeta : metav1.ObjectMeta {
336+ Name : "nginx-pod" ,
337+ Namespace : "default" ,
338+ Labels : map [string ]string {},
339+ },
340+ Status : corev1.PodStatus {PodIP : "1.2.3.4" , Phase : corev1 .PodRunning },
341+ },
342+ gi : & grpcContext.GrpcInfo {Token : "dummy-token" , IPAddress : "1.2.3.4" },
343+ shouldErr : true ,
344+ },
345+ {
346+ name : "ip does not match" ,
347+ pod : & corev1.Pod {
348+ ObjectMeta : metav1.ObjectMeta {
349+ Name : "nginx-pod" ,
350+ Namespace : "default" ,
351+ Labels : map [string ]string {
352+ controller .AppNameLabel : "gateway-nginx" ,
353+ },
354+ },
355+ Status : corev1.PodStatus {PodIP : "1.2.3.4" , Phase : corev1 .PodRunning },
356+ },
357+ gi : & grpcContext.GrpcInfo {Token : "dummy-token" , IPAddress : "9.9.9.9" },
358+ shouldErr : true ,
359+ },
360+ {
361+ name : "all match but pod not running" ,
362+ pod : & corev1.Pod {
363+ ObjectMeta : metav1.ObjectMeta {
364+ Name : "nginx-pod" ,
365+ Namespace : "default" ,
366+ Labels : map [string ]string {
367+ controller .AppNameLabel : "gateway-nginx" ,
368+ },
369+ },
370+ Status : corev1.PodStatus {PodIP : "1.2.3.4" , Phase : corev1 .PodPending },
371+ },
372+ gi : & grpcContext.GrpcInfo {Token : "dummy-token" , IPAddress : "1.2.3.4" },
373+ shouldErr : true ,
374+ },
375+ }
376+
377+ for _ , tc := range testCases {
378+ t .Run (tc .name , func (t * testing.T ) {
379+ t .Parallel ()
380+ g := NewWithT (t )
381+
382+ fakeClient := fake .NewClientBuilder ().
383+ WithObjects (tc .pod ).
384+ WithIndex (& corev1.Pod {}, "status.podIP" , func (obj client.Object ) []string {
385+ pod , ok := obj .(* corev1.Pod )
386+ g .Expect (ok ).To (BeTrue ())
387+ if pod .Status .PodIP != "" {
388+ return []string {pod .Status .PodIP }
389+ }
390+ return nil
391+ }).
392+ Build ()
393+
394+ patchedClient := & patchClient {fakeClient }
395+ csPatched := NewContextSetter (patchedClient , "ngf-audience" )
396+
397+ resultCtx , err := csPatched .validateToken (t .Context (), tc .gi )
398+ if tc .shouldErr {
399+ g .Expect (err ).To (HaveOccurred ())
400+ g .Expect (err .Error ()).To (ContainSubstring ("expected a single Running pod" ))
401+ } else {
402+ g .Expect (err ).ToNot (HaveOccurred ())
403+ g .Expect (resultCtx ).ToNot (BeNil ())
404+ }
405+ })
406+ }
407+ }
0 commit comments