@@ -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
@@ -204,38 +206,6 @@ func TestInterceptor(t *testing.T) {
204206 expErrCode : codes .Unauthenticated ,
205207 expErrMsg : "must be of the format" ,
206208 },
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- },
239209 }
240210
241211 streamHandler := func (_ any , _ grpc.ServerStream ) error {
@@ -261,7 +231,7 @@ func TestInterceptor(t *testing.T) {
261231 }
262232 cs := NewContextSetter (mockK8sClient , "ngf-audience" )
263233
264- ctx := context . Background ()
234+ ctx := t . Context ()
265235 if test .md != nil {
266236 peerCtx := context .Background ()
267237 if test .peer != nil {
@@ -290,3 +260,132 @@ func TestInterceptor(t *testing.T) {
290260 })
291261 }
292262}
263+
264+ type patchClient struct {
265+ client.Client
266+ }
267+
268+ func (p * patchClient ) Create (_ context.Context , obj client.Object , _ ... client.CreateOption ) error {
269+ tr , ok := obj .(* authv1.TokenReview )
270+ if ok {
271+ tr .Status .Authenticated = true
272+ tr .Status .User .Username = "system:serviceaccount:default:gateway-nginx"
273+ }
274+ return nil
275+ }
276+
277+ func TestValidateToken_PodListOptions (t * testing.T ) {
278+ t .Parallel ()
279+
280+ testCases := []struct {
281+ pod * corev1.Pod
282+ gi * grpcContext.GrpcInfo
283+ name string
284+ shouldErr bool
285+ }{
286+ {
287+ name : "all match" ,
288+ pod : & corev1.Pod {
289+ ObjectMeta : metav1.ObjectMeta {
290+ Name : "nginx-pod" ,
291+ Namespace : "default" ,
292+ Labels : map [string ]string {
293+ controller .AppNameLabel : "gateway-nginx" ,
294+ },
295+ },
296+ Status : corev1.PodStatus {PodIP : "1.2.3.4" },
297+ },
298+ gi : & grpcContext.GrpcInfo {Token : "dummy-token" , IPAddress : "1.2.3.4" },
299+ shouldErr : false ,
300+ },
301+ {
302+ name : "ip matches, namespace does not" ,
303+ pod : & corev1.Pod {
304+ ObjectMeta : metav1.ObjectMeta {
305+ Name : "nginx-pod" ,
306+ Namespace : "other-namespace" ,
307+ Labels : map [string ]string {
308+ controller .AppNameLabel : "gateway-nginx" ,
309+ },
310+ },
311+ Status : corev1.PodStatus {PodIP : "1.2.3.4" },
312+ },
313+ gi : & grpcContext.GrpcInfo {Token : "dummy-token" , IPAddress : "1.2.3.4" },
314+ shouldErr : true ,
315+ },
316+ {
317+ name : "ip matches, label value does not match" ,
318+ pod : & corev1.Pod {
319+ ObjectMeta : metav1.ObjectMeta {
320+ Name : "nginx-pod" ,
321+ Namespace : "default" ,
322+ Labels : map [string ]string {
323+ controller .AppNameLabel : "not-gateway-nginx" ,
324+ },
325+ },
326+ Status : corev1.PodStatus {PodIP : "1.2.3.4" },
327+ },
328+ gi : & grpcContext.GrpcInfo {Token : "dummy-token" , IPAddress : "1.2.3.4" },
329+ shouldErr : true ,
330+ },
331+ {
332+ name : "ip matches, label does not exist" ,
333+ pod : & corev1.Pod {
334+ ObjectMeta : metav1.ObjectMeta {
335+ Name : "nginx-pod" ,
336+ Namespace : "default" ,
337+ Labels : map [string ]string {},
338+ },
339+ Status : corev1.PodStatus {PodIP : "1.2.3.4" },
340+ },
341+ gi : & grpcContext.GrpcInfo {Token : "dummy-token" , IPAddress : "1.2.3.4" },
342+ shouldErr : true ,
343+ },
344+ {
345+ name : "ip does not match" ,
346+ pod : & corev1.Pod {
347+ ObjectMeta : metav1.ObjectMeta {
348+ Name : "nginx-pod" ,
349+ Namespace : "default" ,
350+ Labels : map [string ]string {
351+ controller .AppNameLabel : "gateway-nginx" ,
352+ },
353+ },
354+ Status : corev1.PodStatus {PodIP : "1.2.3.4" },
355+ },
356+ gi : & grpcContext.GrpcInfo {Token : "dummy-token" , IPAddress : "9.9.9.9" },
357+ shouldErr : true ,
358+ },
359+ }
360+
361+ for _ , tc := range testCases {
362+ t .Run (tc .name , func (t * testing.T ) {
363+ t .Parallel ()
364+ g := NewWithT (t )
365+
366+ fakeClient := fake .NewClientBuilder ().
367+ WithObjects (tc .pod ).
368+ WithIndex (& corev1.Pod {}, "status.podIP" , func (obj client.Object ) []string {
369+ pod , ok := obj .(* corev1.Pod )
370+ g .Expect (ok ).To (BeTrue ())
371+ if pod .Status .PodIP != "" {
372+ return []string {pod .Status .PodIP }
373+ }
374+ return nil
375+ }).
376+ Build ()
377+
378+ patchedClient := & patchClient {fakeClient }
379+ csPatched := NewContextSetter (patchedClient , "ngf-audience" )
380+
381+ resultCtx , err := csPatched .validateToken (t .Context (), tc .gi )
382+ if tc .shouldErr {
383+ g .Expect (err ).To (HaveOccurred ())
384+ g .Expect (err .Error ()).To (ContainSubstring ("did not find any Pods" ))
385+ } else {
386+ g .Expect (err ).ToNot (HaveOccurred ())
387+ g .Expect (resultCtx ).ToNot (BeNil ())
388+ }
389+ })
390+ }
391+ }
0 commit comments