@@ -26,6 +26,7 @@ import (
26
26
"sort"
27
27
"strings"
28
28
29
+ "github.com/jmespath/go-jmespath"
29
30
"gomodules.xyz/jsonpath"
30
31
core "k8s.io/api/core/v1"
31
32
kerr "k8s.io/apimachinery/pkg/api/errors"
@@ -304,25 +305,19 @@ func (finder ObjectFinder) ResourcesFor(src *unstructured.Unstructured, e *Edge)
304
305
// TODO: check that namespacePath must be empty
305
306
306
307
var out []* unstructured.Unstructured
307
-
308
308
for _ , reference := range e .Connection .References {
309
- j := jsonpath .New ("jsonpath" )
310
- j .AllowMissingKeys (true )
311
- err := j .Parse (reference )
312
- if err != nil {
313
- return nil , fmt .Errorf ("fails to parse reference %q between %s -> %s. err:%v" , e .Connection .References , e .Src , e .Dst , err )
314
- }
315
- buf := new (bytes.Buffer )
316
- err = j .Execute (buf , src .Object )
317
- if err != nil {
318
- return nil , fmt .Errorf ("fails to execute reference %q between %s -> %s. err:%v" , e .Connection .References , e .Src , e .Dst , err )
319
- }
320
- r := csv .NewReader (buf )
321
- // Mapper.Comma = ';'
322
- r .Comment = '#'
323
- records , err := r .ReadAll ()
324
- if err != nil {
325
- return nil , err
309
+ var records [][]string
310
+ var err error
311
+ if strings .HasPrefix (reference , "jmes:" ) {
312
+ records , err = execJmesPath (src .Object , reference [5 :], e .Src , e .Dst )
313
+ if err != nil {
314
+ return nil , err
315
+ }
316
+ } else {
317
+ records , err = execJsonPath (src .Object , reference , e .Src , e .Dst )
318
+ if err != nil {
319
+ return nil , err
320
+ }
326
321
}
327
322
refs , err := ParseResourceRefs (records )
328
323
if err != nil {
@@ -509,25 +504,18 @@ func (finder ObjectFinder) ResourcesFor(src *unstructured.Unstructured, e *Edge)
509
504
rs := result .Items [i ]
510
505
511
506
for _ , reference := range e .Connection .References {
512
-
513
- j := jsonpath .New ("jsonpath" )
514
- j .AllowMissingKeys (true )
515
- err := j .Parse (reference )
516
- if err != nil {
517
- return nil , fmt .Errorf ("fails to parse reference %q between %s -> %s. err:%v" , e .Connection .References , e .Src , e .Dst , err )
518
- }
519
-
520
- buf := new (bytes.Buffer )
521
- err = j .Execute (buf , rs .Object )
522
- if err != nil {
523
- return nil , fmt .Errorf ("fails to execute reference %q between %s -> %s. err:%v" , e .Connection .References , e .Src , e .Dst , err )
524
- }
525
- r := csv .NewReader (buf )
526
- // Mapper.Comma = ';'
527
- r .Comment = '#'
528
- records , err := r .ReadAll ()
529
- if err != nil {
530
- return nil , err
507
+ var records [][]string
508
+ var err error
509
+ if strings .HasPrefix (reference , "jmes:" ) {
510
+ records , err = execJmesPath (rs .Object , reference [5 :], e .Src , e .Dst )
511
+ if err != nil {
512
+ return nil , err
513
+ }
514
+ } else {
515
+ records , err = execJsonPath (rs .Object , reference , e .Src , e .Dst )
516
+ if err != nil {
517
+ return nil , err
518
+ }
531
519
}
532
520
refs , err := ParseResourceRefs (records )
533
521
if err != nil {
@@ -581,6 +569,44 @@ func (finder ObjectFinder) ResourcesFor(src *unstructured.Unstructured, e *Edge)
581
569
return nil , nil
582
570
}
583
571
572
+ func execJmesPath (data any , reference string , src , dst schema.GroupVersionKind ) ([][]string , error ) {
573
+ result , err := jmespath .Search (reference , data )
574
+ if err != nil {
575
+ return nil , fmt .Errorf ("fails to execute jmes reference %q between %s -> %s. err:%w" , reference , src , dst , err )
576
+ }
577
+ switch v := result .(type ) {
578
+ case string :
579
+ return [][]string {{v }}, nil
580
+ case []string :
581
+ out := make ([][]string , len (v ))
582
+ for i , s := range v {
583
+ out [i ] = []string {s }
584
+ }
585
+ return out , nil
586
+ case [][]string :
587
+ return v , nil
588
+ }
589
+ return nil , fmt .Errorf ("invalid result type %T for jmes reference %q between %s -> %s" , result , reference , src , dst )
590
+ }
591
+
592
+ func execJsonPath (data any , reference string , src , dst schema.GroupVersionKind ) ([][]string , error ) {
593
+ j := jsonpath .New ("jsonpath" )
594
+ j .AllowMissingKeys (true )
595
+ err := j .Parse (reference )
596
+ if err != nil {
597
+ return nil , fmt .Errorf ("fails to parse reference %q between %s -> %s. err:%v" , reference , src , dst , err )
598
+ }
599
+ buf := new (bytes.Buffer )
600
+ err = j .Execute (buf , data )
601
+ if err != nil {
602
+ return nil , fmt .Errorf ("fails to execute reference %q between %s -> %s. err:%v" , reference , src , dst , err )
603
+ }
604
+ r := csv .NewReader (buf )
605
+ // Mapper.Comma = ';'
606
+ r .Comment = '#'
607
+ return r .ReadAll ()
608
+ }
609
+
584
610
func isConnected (conn rsapi.OwnershipLevel , obj * unstructured.Unstructured , owner * unstructured.Unstructured ) bool {
585
611
switch conn {
586
612
case rsapi .Controller :
0 commit comments