@@ -106,6 +106,7 @@ func RegisterPermissionCmd(rootCmd *cobra.Command) *cobra.Command {
106
106
lookupSubjectsCmd .Flags ().Bool ("json" , false , "output as JSON" )
107
107
lookupSubjectsCmd .Flags ().String ("revision" , "" , "optional revision at which to check" )
108
108
lookupSubjectsCmd .Flags ().String ("caveat-context" , "" , "the caveat context to send along with the lookup, in JSON form" )
109
+ lookupSubjectsCmd .Flags ().Uint32 ("page-limit" , 100 , "limit of subject returned per page" )
109
110
registerConsistencyFlags (lookupSubjectsCmd .Flags ())
110
111
111
112
return permissionCmd
@@ -188,7 +189,7 @@ func checkCmdFunc(cmd *cobra.Command, args []string) error {
188
189
return err
189
190
}
190
191
191
- client , err := client .NewClient (cmd )
192
+ c , err := client .NewClient (cmd )
192
193
if err != nil {
193
194
return err
194
195
}
@@ -218,7 +219,7 @@ func checkCmdFunc(cmd *cobra.Command, args []string) error {
218
219
}
219
220
220
221
var trailerMD metadata.MD
221
- resp , err := client .CheckPermission (ctx , request , grpc .Trailer (& trailerMD ))
222
+ resp , err := c .CheckPermission (ctx , request , grpc .Trailer (& trailerMD ))
222
223
if err != nil {
223
224
var debugInfo * v1.DebugInformation
224
225
if resp != nil {
@@ -370,7 +371,7 @@ func expandCmdFunc(cmd *cobra.Command, args []string) error {
370
371
return err
371
372
}
372
373
373
- client , err := client .NewClient (cmd )
374
+ c , err := client .NewClient (cmd )
374
375
if err != nil {
375
376
return err
376
377
}
@@ -385,7 +386,7 @@ func expandCmdFunc(cmd *cobra.Command, args []string) error {
385
386
}
386
387
log .Trace ().Interface ("request" , request ).Send ()
387
388
388
- resp , err := client .ExpandPermissionTree (cmd .Context (), request )
389
+ resp , err := c .ExpandPermissionTree (cmd .Context (), request )
389
390
if err != nil {
390
391
return err
391
392
}
@@ -425,7 +426,7 @@ func lookupResourcesCmdFunc(cmd *cobra.Command, args []string) error {
425
426
return err
426
427
}
427
428
428
- client , err := client .NewClient (cmd )
429
+ c , err := client .NewClient (cmd )
429
430
if err != nil {
430
431
return err
431
432
}
@@ -444,7 +445,7 @@ func lookupResourcesCmdFunc(cmd *cobra.Command, args []string) error {
444
445
}
445
446
log .Trace ().Interface ("request" , request ).Send ()
446
447
447
- respStream , err := client .LookupResources (cmd .Context (), request )
448
+ respStream , err := c .LookupResources (cmd .Context (), request )
448
449
if err != nil {
449
450
return err
450
451
}
@@ -492,7 +493,7 @@ func lookupSubjectsCmdFunc(cmd *cobra.Command, args []string) error {
492
493
return err
493
494
}
494
495
495
- client , err := client .NewClient (cmd )
496
+ c , err := client .NewClient (cmd )
496
497
if err != nil {
497
498
return err
498
499
}
@@ -507,21 +508,37 @@ func lookupSubjectsCmdFunc(cmd *cobra.Command, args []string) error {
507
508
Context : caveatContext ,
508
509
Consistency : consistency ,
509
510
}
510
- log .Trace ().Interface ("request" , request ).Send ()
511
-
512
- respStream , err := client .LookupSubjects (cmd .Context (), request )
513
- if err != nil {
514
- return err
515
- }
516
511
512
+ limit := cobrautil .MustGetUint32 (cmd , "page-limit" )
513
+ request .OptionalConcreteLimit = limit
514
+ log .Trace ().Interface ("request" , request ).Send ()
515
+ lastCursor := request .OptionalCursor
517
516
for {
518
- resp , err := respStream .Recv ()
519
- switch {
520
- case errors .Is (err , io .EOF ):
521
- return nil
522
- case err != nil :
517
+ request .OptionalCursor = lastCursor
518
+ respStream , err := c .LookupSubjects (cmd .Context (), request )
519
+ if err != nil {
523
520
return err
524
- default :
521
+ }
522
+
523
+ var cursorToken string
524
+ if lastCursor != nil {
525
+ cursorToken = lastCursor .Token
526
+ }
527
+
528
+ log .Trace ().Interface ("request" , request ).Str ("cursor" , cursorToken ).Msg ("reading subjects page" )
529
+ var relCount uint32
530
+ for {
531
+ resp , err := respStream .Recv ()
532
+ if errors .Is (err , io .EOF ) {
533
+ break
534
+ }
535
+ if err != nil {
536
+ return err
537
+ }
538
+
539
+ lastCursor = resp .AfterResultCursor
540
+ relCount ++
541
+
525
542
if cobrautil .MustGetBool (cmd , "json" ) {
526
543
prettyProto , err := PrettyProto (resp )
527
544
if err != nil {
@@ -533,8 +550,16 @@ func lookupSubjectsCmdFunc(cmd *cobra.Command, args []string) error {
533
550
console .Printf ("%s:%s%s\n " ,
534
551
subjectType ,
535
552
prettyLookupPermissionship (resp .Subject .SubjectObjectId , resp .Subject .Permissionship , resp .Subject .PartialCaveatInfo ),
536
- excludedSubjectsString (resp .ExcludedSubjects ),
537
- )
553
+ excludedSubjectsString (resp .ExcludedSubjects ))
554
+ }
555
+
556
+ if relCount < limit || limit == 0 {
557
+ return nil
558
+ }
559
+
560
+ if relCount > limit {
561
+ log .Warn ().Uint32 ("limit-specified" , limit ).Uint32 ("relationships-received" , relCount ).Msg ("page limit ignored, pagination may not be supported by the server, consider updating SpiceDB" )
562
+ return nil
538
563
}
539
564
}
540
565
}
0 commit comments