@@ -24,7 +24,6 @@ import (
2424 "slices"
2525 "strings"
2626
27- "github.com/kcp-dev/logicalcluster/v3"
2827 "github.com/tidwall/gjson"
2928 "go.uber.org/zap"
3029
@@ -296,7 +295,7 @@ func resolveRelatedResourceOriginNamespaces(relatedOrigin, relatedDest syncSide,
296295 for _ , namespace := range namespaces .Items {
297296 name := namespace .Name
298297
299- destinationName , err := applySelectorRewrites (relatedOrigin , relatedDest , name , spec .Selector .Rewrite )
298+ destinationName , err := applySelectorRewrites (relatedOrigin , relatedDest , origin , name , nil , spec .Selector .Rewrite )
300299 if err != nil {
301300 return nil , fmt .Errorf ("failed to rewrite origin namespace: %w" , err )
302301 }
@@ -416,7 +415,7 @@ func resolveRelatedResourceObjectsInNamespace(relatedOrigin, relatedDest syncSid
416415 for _ , originObject := range originObjects .Items {
417416 name := originObject .GetName ()
418417
419- destinationName , err := applySelectorRewrites (relatedOrigin , relatedDest , name , spec .Selector .Rewrite )
418+ destinationName , err := applySelectorRewrites (relatedOrigin , relatedDest , relRes . Origin , name , & originObject , spec .Selector .Rewrite )
420419 if err != nil {
421420 return nil , fmt .Errorf ("failed to rewrite origin name: %w" , err )
422421 }
@@ -475,12 +474,18 @@ func resolveReference(jsonData []byte, ref syncagentv1alpha1.RelatedResourceObje
475474 return strVal , nil
476475}
477476
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 ) {
479484 switch {
480485 case rewrite .Regex != nil :
481486 return applyRegularExpression (value , * rewrite .Regex )
482487 case rewrite .Template != nil :
483- return applyTemplate (relatedOrigin , relatedDest , * rewrite .Template , value )
488+ return applyTemplate (relatedOrigin , relatedDest , origin , * rewrite .Template , value , originRelatedObject )
484489 default :
485490 return "" , errors .New ("invalid rewrite: no mechanism configured" )
486491 }
@@ -499,22 +504,25 @@ func applyRegularExpression(value string, re syncagentv1alpha1.RegularExpression
499504 return expr .ReplaceAllString (value , re .Replacement ), nil
500505}
501506
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 )
504512}
505513
506514func 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 )
508516
509517 // 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 )
511519 originValue , err = templating .Render (tpl .Template , ctx )
512520 if err != nil {
513521 return "" , "" , fmt .Errorf ("failed to evaluate template on origin side: %w" , err )
514522 }
515523
516524 // 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 )
518526 destValue , err = templating .Render (tpl .Template , ctx )
519527 if err != nil {
520528 return "" , "" , fmt .Errorf ("failed to evaluate template on destination side: %w" , err )
@@ -526,16 +534,9 @@ func applyTemplateBothSides(relatedOrigin, relatedDest syncSide, origin syncagen
526534// templateLabelSelector applies Go templating logic to all keys and values in the MatchLabels of
527535// a label selector.
528536func 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 )
537538
538- ctx := templating .NewRelatedObjectLabelContext (localObject , remoteObject , clusterName , workspacePath )
539+ ctx := templating .NewRelatedObjectLabelContext (localSide . object , remoteSide . object , remoteSide . clusterName , remoteSide . workspacePath )
539540
540541 newMatchLabels := map [string ]string {}
541542 for key , value := range selector .MatchLabels {
@@ -565,10 +566,10 @@ func templateLabelSelector(relatedOrigin, relatedDest syncSide, origin syncagent
565566 return selector , nil
566567}
567568
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 ) {
569570 if origin == syncagentv1alpha1 .RelatedResourceOriginKcp {
570- return relatedOrigin . clusterName , relatedOrigin . workspacePath
571+ return relatedOrigin , relatedDest
571572 }
572573
573- return relatedDest . clusterName , relatedDest . workspacePath
574+ return relatedDest , relatedOrigin
574575}
0 commit comments