Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/cobaltcore-dev/cortex
go 1.26.0

require (
github.com/cobaltcore-dev/openstack-hypervisor-operator v1.2.0
github.com/cobaltcore-dev/openstack-hypervisor-operator v1.1.1-0.20260430095528-58fbe3ff4c3e
github.com/go-gorp/gorp v2.2.0+incompatible
github.com/gophercloud/gophercloud/v2 v2.12.0
github.com/ironcore-dev/ironcore v0.3.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1x
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cobaltcore-dev/openstack-hypervisor-operator v1.2.0 h1:XYVIKTC19dj4jck2uinYzTNXcoED5HNTvv+BJ75M2E0=
github.com/cobaltcore-dev/openstack-hypervisor-operator v1.2.0/go.mod h1:iuhqhW6ozxfYWbGlEeh9rW9xyTb/EgelkDJqzJXBclk=
github.com/cobaltcore-dev/openstack-hypervisor-operator v1.1.1-0.20260430095528-58fbe3ff4c3e h1:gegFF2HeBNzpOqQTqPAEkllLDdIHXCiGUxlKT4i5D/o=
github.com/cobaltcore-dev/openstack-hypervisor-operator v1.1.1-0.20260430095528-58fbe3ff4c3e/go.mod h1:iuhqhW6ozxfYWbGlEeh9rW9xyTb/EgelkDJqzJXBclk=
github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4=
github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
Expand Down
25 changes: 25 additions & 0 deletions internal/shim/placement/field_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ const (
// by their metadata.name field, which represents the name of the hypervisor
// in Kubernetes.
idxHypervisorName = "metadata.name"
// idxBookingConsumerUUID is the name of the index for looking up
// hypervisors by the consumer UUIDs in their spec.bookings entries.
// A single hypervisor may index multiple consumer UUIDs.
idxBookingConsumerUUID = "spec.bookings.consumer.uuid"
)

// IndexFields indexes all fields that are needed by the shim to quickly
Expand Down Expand Up @@ -77,5 +81,26 @@ func IndexFields(ctx context.Context, mcl *multicluster.Client) error {
}
log.Info("Successfully set up index for hypervisor name")

if err := mcl.IndexField(ctx, h, hl, idxBookingConsumerUUID, func(obj client.Object) []string {
hv, ok := obj.(*hv1.Hypervisor)
if !ok {
log.Error(errors.New("unexpected type"), "object", obj)
return nil
}
consumers := hv1.GetConsumers(hv.Spec.Bookings)
if len(consumers) == 0 {
return nil
}
uuids := make([]string, 0, len(consumers))
for _, c := range consumers {
uuids = append(uuids, c.UUID)
}
return uuids
}); err != nil {
log.Error(err, "failed to set up index for booking consumer UUID")
return err
}
log.Info("Successfully set up index for booking consumer UUID")

return nil
}
59 changes: 59 additions & 0 deletions internal/shim/placement/field_index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ func TestIndexFields_RegistersAllIndexes(t *testing.T) {
idxHypervisorOpenStackId,
idxHypervisorKubernetesId,
idxHypervisorName,
idxBookingConsumerUUID,
}
if len(cc.calls) != len(wantFields) {
t.Fatalf("got %d IndexField calls, want %d", len(cc.calls), len(wantFields))
Expand Down Expand Up @@ -284,3 +285,61 @@ func strSliceEqual(a, b []string) bool {
}
return true
}

func TestExtractor_BookingConsumerUUID(t *testing.T) {
cc := &captureCache{}
mcl := buildClient(t, cc)
if err := IndexFields(context.Background(), mcl); err != nil {
t.Fatalf("IndexFields: %v", err)
}
fn := extractorByField(t, cc.calls, idxBookingConsumerUUID)

tests := []struct {
name string
obj client.Object
want []string
}{
{
name: "hypervisor with consumer bookings",
obj: &hv1.Hypervisor{
Spec: hv1.HypervisorSpec{
Bookings: []hv1.Booking{
{Consumer: &hv1.ConsumerBooking{UUID: "consumer-aaa"}},
{Consumer: &hv1.ConsumerBooking{UUID: "consumer-bbb"}},
{Reservation: &hv1.ReservationBooking{Name: "nova-reserved"}},
},
},
},
want: []string{"consumer-aaa", "consumer-bbb"},
},
{
name: "hypervisor with no bookings",
obj: &hv1.Hypervisor{},
want: nil,
},
{
name: "hypervisor with only reservation bookings",
obj: &hv1.Hypervisor{
Spec: hv1.HypervisorSpec{
Bookings: []hv1.Booking{
{Reservation: &hv1.ReservationBooking{Name: "nova-reserved"}},
},
},
},
want: nil,
},
{
name: "wrong type",
obj: &corev1.ConfigMap{},
want: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := fn(tt.obj)
if !strSliceEqual(got, tt.want) {
t.Errorf("got %v, want %v", got, tt.want)
}
})
}
}
Loading
Loading