Skip to content

Commit

Permalink
fix: order values in MultiResolutionResponse
Browse files Browse the repository at this point in the history
Signed-off-by: Guilhem Lettron <[email protected]>
  • Loading branch information
guilhem committed Jan 15, 2025
1 parent 0eae57e commit 5de3e3d
Showing 1 changed file with 24 additions and 9 deletions.
33 changes: 24 additions & 9 deletions pkg/reference/reference.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ limitations under the License.
package reference

import (
"cmp"
"context"
"maps"
"slices"

kerrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
Expand Down Expand Up @@ -238,20 +241,23 @@ func (r *APIResolver) ResolveMultiple(ctx context.Context, req MultiResolutionRe
return MultiResolutionResponse{ResolvedValues: req.CurrentValues, ResolvedReferences: req.References}, nil
}

var valueMap = make(map[string]xpv1.Reference)

// The references are already set - resolve them.
if len(req.References) > 0 {
vals := make([]string, len(req.References))
for i := range req.References {
if err := r.client.Get(ctx, types.NamespacedName{Name: req.References[i].Name}, req.To.Managed); err != nil {
if kerrors.IsNotFound(err) {
return MultiResolutionResponse{}, getResolutionError(req.References[i].Policy, errors.Wrap(err, errGetManaged))
}
return MultiResolutionResponse{}, errors.Wrap(err, errGetManaged)
}
vals[i] = req.Extract(req.To.Managed)
valueMap[req.Extract(req.To.Managed)] = req.References[i]
}

rsp := MultiResolutionResponse{ResolvedValues: vals, ResolvedReferences: req.References}
sortedKeys, sortedRefs := sortMapByKeys(valueMap)

rsp := MultiResolutionResponse{ResolvedValues: sortedKeys, ResolvedReferences: sortedRefs}
return rsp, rsp.Validate()
}

Expand All @@ -260,19 +266,17 @@ func (r *APIResolver) ResolveMultiple(ctx context.Context, req MultiResolutionRe
return MultiResolutionResponse{}, errors.Wrap(err, errListManaged)
}

items := req.To.List.GetItems()
refs := make([]xpv1.Reference, 0, len(items))
vals := make([]string, 0, len(items))
for _, to := range req.To.List.GetItems() {
if ControllersMustMatch(req.Selector) && !meta.HaveSameController(r.from, to) {
continue
}

vals = append(vals, req.Extract(to))
refs = append(refs, xpv1.Reference{Name: to.GetName()})
valueMap[req.Extract(to)] = xpv1.Reference{Name: to.GetName()}
}

rsp := MultiResolutionResponse{ResolvedValues: vals, ResolvedReferences: refs}
sortedKeys, sortedRefs := sortMapByKeys(valueMap)

rsp := MultiResolutionResponse{ResolvedValues: sortedKeys, ResolvedReferences: sortedRefs}
return rsp, getResolutionError(req.Selector.Policy, rsp.Validate())
}

Expand All @@ -283,6 +287,17 @@ func getResolutionError(p *xpv1.Policy, err error) error {
return nil
}

func sortMapByKeys[T cmp.Ordered, U any](m map[T]U) ([]T, []U) {
keys := maps.Keys(m)
slices.Sort(keys)

values := make([]U, 0, len(m))
for _, k := range keys {
values = append(values, m[k])
}
return keys, values
}

// ControllersMustMatch returns true if the supplied Selector requires that a
// reference be to a managed resource whose controller reference matches the
// referencing resource.
Expand Down

0 comments on commit 5de3e3d

Please sign in to comment.