@@ -251,27 +251,25 @@ func resolveRelatedResourceObjects(relatedOrigin, relatedDest syncSide, relRes s
251251func resolveRelatedResourceOriginNamespaces (relatedOrigin , relatedDest syncSide , origin syncagentv1alpha1.RelatedResourceOrigin , spec syncagentv1alpha1.RelatedResourceObjectSpec ) (map [string ]string , error ) {
252252 switch {
253253 case spec .Reference != nil :
254- originNamespace , err := resolveObjectReference (relatedOrigin .object , * spec .Reference )
254+ originNamespaces , err := resolveObjectReference (relatedOrigin .object , * spec .Reference )
255255 if err != nil {
256256 return nil , err
257257 }
258258
259- if originNamespace == "" {
259+ if len ( originNamespaces ) == 0 {
260260 return nil , nil
261261 }
262262
263- destNamespace , err := resolveObjectReference (relatedDest .object , * spec .Reference )
263+ destNamespaces , err := resolveObjectReference (relatedDest .object , * spec .Reference )
264264 if err != nil {
265265 return nil , err
266266 }
267267
268- if destNamespace == "" {
269- return nil , nil
268+ if len ( destNamespaces ) != len ( originNamespaces ) {
269+ return nil , fmt . Errorf ( "cannot sync related resources: found %d namespaces on the origin, but %d on the destination side" , len ( originNamespaces ), len ( destNamespaces ))
270270 }
271271
272- return map [string ]string {
273- originNamespace : destNamespace ,
274- }, nil
272+ return mapSlices (originNamespaces , destNamespaces ), nil
275273
276274 case spec .Selector != nil :
277275 namespaces := & corev1.NamespaceList {}
@@ -327,6 +325,22 @@ func resolveRelatedResourceOriginNamespaces(relatedOrigin, relatedDest syncSide,
327325 }
328326}
329327
328+ func mapSlices (a , b []string ) map [string ]string {
329+ mapping := map [string ]string {}
330+ for i , aItem := range a {
331+ bItem := b [i ]
332+
333+ // ignore any origin<->dest pair where either of the sides is empty
334+ if bItem == "" || aItem == "" {
335+ continue
336+ }
337+
338+ mapping [aItem ] = bItem
339+ }
340+
341+ return mapping
342+ }
343+
330344func resolveRelatedResourceObjectsInNamespaces (relatedOrigin , relatedDest syncSide , relRes syncagentv1alpha1.RelatedResourceSpec , spec syncagentv1alpha1.RelatedResourceObjectSpec , namespaceMap map [string ]string ) ([]resolvedObject , error ) {
331345 result := []resolvedObject {}
332346
@@ -368,27 +382,25 @@ func resolveRelatedResourceObjectsInNamespaces(relatedOrigin, relatedDest syncSi
368382func resolveRelatedResourceObjectsInNamespace (relatedOrigin , relatedDest syncSide , relRes syncagentv1alpha1.RelatedResourceSpec , spec syncagentv1alpha1.RelatedResourceObjectSpec , namespace string ) (map [string ]string , error ) {
369383 switch {
370384 case spec .Reference != nil :
371- originName , err := resolveObjectReference (relatedOrigin .object , * spec .Reference )
385+ originNames , err := resolveObjectReference (relatedOrigin .object , * spec .Reference )
372386 if err != nil {
373387 return nil , err
374388 }
375389
376- if originName == "" {
390+ if len ( originNames ) == 0 {
377391 return nil , nil
378392 }
379393
380- destName , err := resolveObjectReference (relatedDest .object , * spec .Reference )
394+ destNames , err := resolveObjectReference (relatedDest .object , * spec .Reference )
381395 if err != nil {
382396 return nil , err
383397 }
384398
385- if destName == "" {
386- return nil , nil
399+ if len ( destNames ) != len ( originNames ) {
400+ return nil , fmt . Errorf ( "cannot sync related resources: found %d names on the origin, but %d on the destination side" , len ( originNames ), len ( destNames ))
387401 }
388402
389- return map [string ]string {
390- originName : destName ,
391- }, nil
403+ return mapSlices (originNames , destNames ), nil
392404
393405 case spec .Selector != nil :
394406 originObjects := & unstructured.UnstructuredList {}
@@ -447,34 +459,44 @@ func resolveRelatedResourceObjectsInNamespace(relatedOrigin, relatedDest syncSid
447459 }
448460}
449461
450- func resolveObjectReference (object * unstructured.Unstructured , ref syncagentv1alpha1.RelatedResourceObjectReference ) (string , error ) {
462+ func resolveObjectReference (object * unstructured.Unstructured , ref syncagentv1alpha1.RelatedResourceObjectReference ) ([] string , error ) {
451463 data , err := object .MarshalJSON ()
452464 if err != nil {
453- return "" , err
465+ return nil , err
454466 }
455467
456468 return resolveReference (data , ref )
457469}
458470
459- func resolveReference (jsonData []byte , ref syncagentv1alpha1.RelatedResourceObjectReference ) (string , error ) {
460- gval := gjson .Get (string (jsonData ), ref .Path )
461- if ! gval .Exists () {
462- return "" , nil
471+ func resolveReference (jsonData []byte , ref syncagentv1alpha1.RelatedResourceObjectReference ) ([] string , error ) {
472+ result := gjson .Get (string (jsonData ), ref .Path )
473+ if ! result .Exists () {
474+ return nil , nil
463475 }
464476
465- // this does apply some coalescing, like turning numbers into strings
466- strVal := gval .String ()
477+ var values []string
478+ if result .IsArray () {
479+ for _ , elem := range result .Array () {
480+ values = append (values , strings .TrimSpace (elem .String ()))
481+ }
482+ } else {
483+ values = append (values , strings .TrimSpace (result .String ()))
484+ }
467485
468486 if re := ref .Regex ; re != nil {
469487 var err error
470488
471- strVal , err = applyRegularExpression (strVal , * re )
472- if err != nil {
473- return "" , err
489+ for i , value := range values {
490+ value , err = applyRegularExpression (value , * re )
491+ if err != nil {
492+ return nil , err
493+ }
494+
495+ values [i ] = value
474496 }
475497 }
476498
477- return strVal , nil
499+ return values , nil
478500}
479501
480502// applyTemplate is used after a label selector has been applied and a list of namespaces or objects
0 commit comments