@@ -24,7 +24,6 @@ import (
24
24
"slices"
25
25
"strings"
26
26
27
- "github.com/kcp-dev/logicalcluster/v3"
28
27
"github.com/tidwall/gjson"
29
28
"go.uber.org/zap"
30
29
@@ -296,7 +295,7 @@ func resolveRelatedResourceOriginNamespaces(relatedOrigin, relatedDest syncSide,
296
295
for _ , namespace := range namespaces .Items {
297
296
name := namespace .Name
298
297
299
- destinationName , err := applySelectorRewrites (relatedOrigin , relatedDest , name , spec .Selector .Rewrite )
298
+ destinationName , err := applySelectorRewrites (relatedOrigin , relatedDest , origin , name , nil , spec .Selector .Rewrite )
300
299
if err != nil {
301
300
return nil , fmt .Errorf ("failed to rewrite origin namespace: %w" , err )
302
301
}
@@ -416,7 +415,7 @@ func resolveRelatedResourceObjectsInNamespace(relatedOrigin, relatedDest syncSid
416
415
for _ , originObject := range originObjects .Items {
417
416
name := originObject .GetName ()
418
417
419
- destinationName , err := applySelectorRewrites (relatedOrigin , relatedDest , name , spec .Selector .Rewrite )
418
+ destinationName , err := applySelectorRewrites (relatedOrigin , relatedDest , relRes . Origin , name , & originObject , spec .Selector .Rewrite )
420
419
if err != nil {
421
420
return nil , fmt .Errorf ("failed to rewrite origin name: %w" , err )
422
421
}
@@ -475,12 +474,18 @@ func resolveReference(jsonData []byte, ref syncagentv1alpha1.RelatedResourceObje
475
474
return strVal , nil
476
475
}
477
476
478
- func applySelectorRewrites (relatedOrigin , relatedDest syncSide , value string , rewrite syncagentv1alpha1.RelatedResourceSelectorRewrite ) (string , error ) {
477
+ // applyTemplate is used after a label selector has been applied and a list of namespaces or objects
478
+ // has been selected. To map these to the destination side, rewrites can be applied, and these are
479
+ // first applied to all found namespaces (in which case, the value parameter here is the namespace
480
+ // name and originRelatedObject is nil) and then again to all found objects (in which case the value
481
+ // parameter is the object's name and originRelatedObject is set). In both cases the rewrite is supposed
482
+ // to return a string.
483
+ func applySelectorRewrites (relatedOrigin , relatedDest syncSide , origin syncagentv1alpha1.RelatedResourceOrigin , value string , originRelatedObject * unstructured.Unstructured , rewrite syncagentv1alpha1.RelatedResourceSelectorRewrite ) (string , error ) {
479
484
switch {
480
485
case rewrite .Regex != nil :
481
486
return applyRegularExpression (value , * rewrite .Regex )
482
487
case rewrite .Template != nil :
483
- return applyTemplate (relatedOrigin , relatedDest , * rewrite .Template , value )
488
+ return applyTemplate (relatedOrigin , relatedDest , origin , * rewrite .Template , value , originRelatedObject )
484
489
default :
485
490
return "" , errors .New ("invalid rewrite: no mechanism configured" )
486
491
}
@@ -499,22 +504,25 @@ func applyRegularExpression(value string, re syncagentv1alpha1.RegularExpression
499
504
return expr .ReplaceAllString (value , re .Replacement ), nil
500
505
}
501
506
502
- func applyTemplate (relatedOrigin , relatedDest syncSide , tpl syncagentv1alpha1.TemplateExpression , value string ) (string , error ) {
503
- return "" , errors .New ("not yet implemented" )
507
+ func applyTemplate (relatedOrigin , relatedDest syncSide , origin syncagentv1alpha1.RelatedResourceOrigin , tpl syncagentv1alpha1.TemplateExpression , value string , originRelatedObject * unstructured.Unstructured ) (string , error ) {
508
+ localSide , remoteSide := remapSyncSides (relatedOrigin , relatedDest , origin )
509
+ ctx := templating .NewRelatedObjectLabelRewriteContext (value , localSide .object , remoteSide .object , originRelatedObject , remoteSide .clusterName , remoteSide .workspacePath )
510
+
511
+ return templating .Render (tpl .Template , ctx )
504
512
}
505
513
506
514
func applyTemplateBothSides (relatedOrigin , relatedDest syncSide , origin syncagentv1alpha1.RelatedResourceOrigin , tpl syncagentv1alpha1.TemplateExpression ) (originValue , destValue string , err error ) {
507
- clusterName , workspacePath := clusterIdent (relatedOrigin , relatedDest , origin )
515
+ _ , remoteSide := remapSyncSides (relatedOrigin , relatedDest , origin )
508
516
509
517
// evaluate the template for the origin object side
510
- ctx := templating .NewRelatedObjectContext (relatedOrigin .object , clusterName , workspacePath )
518
+ ctx := templating .NewRelatedObjectContext (relatedOrigin .object , remoteSide . clusterName , remoteSide . workspacePath )
511
519
originValue , err = templating .Render (tpl .Template , ctx )
512
520
if err != nil {
513
521
return "" , "" , fmt .Errorf ("failed to evaluate template on origin side: %w" , err )
514
522
}
515
523
516
524
// and once more on the other side
517
- ctx = templating .NewRelatedObjectContext (relatedDest .object , clusterName , workspacePath )
525
+ ctx = templating .NewRelatedObjectContext (relatedDest .object , remoteSide . clusterName , remoteSide . workspacePath )
518
526
destValue , err = templating .Render (tpl .Template , ctx )
519
527
if err != nil {
520
528
return "" , "" , fmt .Errorf ("failed to evaluate template on destination side: %w" , err )
@@ -526,16 +534,9 @@ func applyTemplateBothSides(relatedOrigin, relatedDest syncSide, origin syncagen
526
534
// templateLabelSelector applies Go templating logic to all keys and values in the MatchLabels of
527
535
// a label selector.
528
536
func templateLabelSelector (relatedOrigin , relatedDest syncSide , origin syncagentv1alpha1.RelatedResourceOrigin , selector * metav1.LabelSelector ) (* metav1.LabelSelector , error ) {
529
- clusterName , workspacePath := clusterIdent (relatedOrigin , relatedDest , origin )
530
-
531
- localObject := relatedOrigin .object
532
- remoteObject := relatedDest .object
533
- if origin == syncagentv1alpha1 .RelatedResourceOriginKcp {
534
- localObject = relatedDest .object
535
- remoteObject = relatedOrigin .object
536
- }
537
+ localSide , remoteSide := remapSyncSides (relatedOrigin , relatedDest , origin )
537
538
538
- ctx := templating .NewRelatedObjectLabelContext (localObject , remoteObject , clusterName , workspacePath )
539
+ ctx := templating .NewRelatedObjectLabelContext (localSide . object , remoteSide . object , remoteSide . clusterName , remoteSide . workspacePath )
539
540
540
541
newMatchLabels := map [string ]string {}
541
542
for key , value := range selector .MatchLabels {
@@ -565,10 +566,10 @@ func templateLabelSelector(relatedOrigin, relatedDest syncSide, origin syncagent
565
566
return selector , nil
566
567
}
567
568
568
- func clusterIdent (relatedOrigin , relatedDest syncSide , origin syncagentv1alpha1.RelatedResourceOrigin ) (logicalcluster. Name , logicalcluster. Path ) {
569
+ func remapSyncSides (relatedOrigin , relatedDest syncSide , origin syncagentv1alpha1.RelatedResourceOrigin ) (localSide , remoteSide syncSide ) {
569
570
if origin == syncagentv1alpha1 .RelatedResourceOriginKcp {
570
- return relatedOrigin . clusterName , relatedOrigin . workspacePath
571
+ return relatedOrigin , relatedDest
571
572
}
572
573
573
- return relatedDest . clusterName , relatedDest . workspacePath
574
+ return relatedDest , relatedOrigin
574
575
}
0 commit comments