Skip to content
Open
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
17 changes: 17 additions & 0 deletions api/v1alpha1/committed_resource_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,23 @@ type CommittedResource struct {
Status CommittedResourceStatus `json:"status,omitempty,omitzero"`
}

// IsActive reports whether the commitment spec has active Reservation slots
// (state is confirmed or guaranteed).
func (s *CommittedResourceSpec) IsActive() bool {
return s.State == CommitmentStatusConfirmed || s.State == CommitmentStatusGuaranteed
}

// IsActive reports whether the commitment has active Reservation slots
// (state is confirmed or guaranteed).
func (c *CommittedResource) IsActive() bool {
return c.Spec.IsActive()
}

// MatchesGroup reports whether the commitment targets the given project and flavor group.
func (c *CommittedResource) MatchesGroup(projectID, flavorGroup string) bool {
return c.Spec.ProjectID == projectID && c.Spec.FlavorGroupName == flavorGroup
}

// +kubebuilder:object:root=true

// CommittedResourceList contains a list of CommittedResource
Expand Down
70 changes: 70 additions & 0 deletions api/v1alpha1/committed_resource_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright SAP SE
// SPDX-License-Identifier: Apache-2.0

package v1alpha1

import "testing"

func TestCommittedResourceSpec_IsActive(t *testing.T) {
tests := []struct {
state CommitmentStatus
want bool
}{
{CommitmentStatusConfirmed, true},
{CommitmentStatusGuaranteed, true},
{CommitmentStatusPlanned, false},
{CommitmentStatusPending, false},
{CommitmentStatusSuperseded, false},
{CommitmentStatusExpired, false},
}
for _, tt := range tests {
spec := CommittedResourceSpec{State: tt.state}
if got := spec.IsActive(); got != tt.want {
t.Errorf("IsActive() with state %q = %v, want %v", tt.state, got, tt.want)
}
}
}

func TestCommittedResource_IsActive(t *testing.T) {
tests := []struct {
state CommitmentStatus
want bool
}{
{CommitmentStatusConfirmed, true},
{CommitmentStatusGuaranteed, true},
{CommitmentStatusPlanned, false},
{CommitmentStatusPending, false},
{CommitmentStatusSuperseded, false},
{CommitmentStatusExpired, false},
}
for _, tt := range tests {
cr := CommittedResource{Spec: CommittedResourceSpec{State: tt.state}}
if got := cr.IsActive(); got != tt.want {
t.Errorf("IsActive() with state %q = %v, want %v", tt.state, got, tt.want)
}
}
}

func TestCommittedResource_MatchesGroup(t *testing.T) {
cr := CommittedResource{
Spec: CommittedResourceSpec{
ProjectID: "proj-1",
FlavorGroupName: "kvm_v2",
},
}
tests := []struct {
project string
group string
want bool
}{
{"proj-1", "kvm_v2", true},
{"proj-X", "kvm_v2", false},
{"proj-1", "kvm_v3", false},
{"proj-X", "kvm_v3", false},
}
for _, tt := range tests {
if got := cr.MatchesGroup(tt.project, tt.group); got != tt.want {
t.Errorf("MatchesGroup(%q, %q) = %v, want %v", tt.project, tt.group, got, tt.want)
}
}
}
5 changes: 5 additions & 0 deletions api/v1alpha1/reservation_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,11 @@ type ReservationList struct {
Items []Reservation `json:"items"`
}

// MatchesGroup reports whether the reservation targets the given project and resource group.
func (s *CommittedResourceReservationSpec) MatchesGroup(projectID, resourceGroup string) bool {
return s.ProjectID == projectID && s.ResourceGroup == resourceGroup
}

// IsReady returns true if the reservation has the Ready condition set to True.
func (r *Reservation) IsReady() bool {
return meta.IsStatusConditionTrue(r.Status.Conditions, ReservationConditionReady)
Expand Down
28 changes: 28 additions & 0 deletions api/v1alpha1/reservation_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright SAP SE
// SPDX-License-Identifier: Apache-2.0

package v1alpha1

import "testing"

func TestCommittedResourceReservationSpec_MatchesGroup(t *testing.T) {
spec := CommittedResourceReservationSpec{
ProjectID: "proj-1",
ResourceGroup: "kvm_v2",
}
tests := []struct {
project string
group string
want bool
}{
{"proj-1", "kvm_v2", true},
{"proj-X", "kvm_v2", false},
{"proj-1", "kvm_v3", false},
{"proj-X", "kvm_v3", false},
}
for _, tt := range tests {
if got := spec.MatchesGroup(tt.project, tt.group); got != tt.want {
t.Errorf("MatchesGroup(%q, %q) = %v, want %v", tt.project, tt.group, got, tt.want)
}
}
}
8 changes: 7 additions & 1 deletion cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,10 +395,16 @@ func main() {
commitmentsAPI.Init(mux, metrics.Registry, ctrl.Log.WithName("commitments-api"))

if slices.Contains(mainConfig.EnabledControllers, "nova-pipeline-controllers") {
featureGates := conf.GetConfigOrDie[conf.FeatureGates]()
// Filter-weigher pipeline controller setup.
filterWeigherController := &nova.FilterWeigherPipelineController{
Monitor: filterWeigherPipelineMonitor,
Monitor: filterWeigherPipelineMonitor,
FeatureGates: featureGates,
NoHostFoundCounter: nova.NewNoHostFoundCounter(),
PlacementCounter: nova.NewPlacementCounter(),
}
metrics.Registry.MustRegister(filterWeigherController.NoHostFoundCounter)
metrics.Registry.MustRegister(filterWeigherController.PlacementCounter)
// Inferred through the base controller.
filterWeigherController.Client = multiclusterClient
if err := filterWeigherController.SetupWithManager(mgr, multiclusterClient); err != nil {
Expand Down
12 changes: 9 additions & 3 deletions helm/bundles/cortex-nova/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -136,15 +136,21 @@ cortex-scheduling-controllers:
- failover-reservations-controller
- quota-controller
- capacity-controller
enabledTasks:
- nova-history-cleanup-task
- commitments-sync-task # required for committed resources
# Feature gates control optional capabilities within running components.
featureGates:
# Enables VM allocation write-back into Reservation slots and no-host-found
# classification by committed resource coverage. Enable only on deployments
# that use committed resources. Requires also enabling of CR controllers and tasks
committedResourceTracking: false
# Pipeline used for the empty-state capacity probe (ignores allocations and reservations).
capacityTotalPipeline: "kvm-report-capacity"
# Pipeline used for the current-state capacity probe (considers current VM allocations).
capacityPlaceablePipeline: "kvm-general-purpose-load-balancing"
# How often the capacity controller re-runs its scheduler probes.
capacityReconcileInterval: 5m
enabledTasks:
- nova-history-cleanup-task
- commitments-sync-task
# If true, the external scheduler API will limit the list of hosts in its
# response to those included in the scheduling request.
novaLimitHostsToRequest: true
Expand Down
Loading