Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/metal-stack/metal-api int…
Browse files Browse the repository at this point in the history
…o dualstack-support
  • Loading branch information
majst01 committed Sep 29, 2024
2 parents 8f06d84 + 65f0c68 commit 10f49c7
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 50 deletions.
11 changes: 7 additions & 4 deletions cmd/metal-api/internal/metal/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,12 @@ func (nics Nics) FilterByHostname(hostname string) (res Nics) {
return res
}

// NicMap maps nic names to the corresponding nics
type NicMap map[string]*Nic

// ByName creates a map (nic names --> nic) from a nic list.
func (nics Nics) ByName() map[string]*Nic {
res := make(map[string]*Nic)
func (nics Nics) ByName() NicMap {
res := make(NicMap)

for i, n := range nics {
res[n.Name] = &nics[i]
Expand All @@ -341,8 +344,8 @@ func (nics Nics) ByName() map[string]*Nic {
}

// ByIdentifier creates a map (nic identifier --> nic) from a nic list.
func (nics Nics) ByIdentifier() map[string]*Nic {
res := make(map[string]*Nic)
func (nics Nics) ByIdentifier() NicMap {
res := make(NicMap)

for i, n := range nics {
res[n.GetIdentifier()] = &nics[i]
Expand Down
4 changes: 2 additions & 2 deletions cmd/metal-api/internal/metal/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ func TestNics_ByIdentifier(t *testing.T) {
nicArray[i].Neighbors = append(nicArray[0:i], nicArray[i+1:countOfNics]...)
}

map1 := map[string]*Nic{}
map1 := NicMap{}
for i, n := range nicArray {
map1[string(n.MacAddress)] = &nicArray[i]
}

tests := []struct {
name string
nics Nics
want map[string]*Nic
want NicMap
}{
{
name: "TestNics_ByIdentifier Test 1",
Expand Down
11 changes: 7 additions & 4 deletions cmd/metal-api/internal/service/partition-service.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,8 +436,9 @@ func (r *partitionResource) calcPartitionCapacity(pcr *v1.PartitionCapacityReque
switch {
case m.Allocation != nil:
cap.Allocated++
case m.Waiting && !m.PreAllocated && m.State.Value == metal.AvailableState:
// the free machine count considers the same aspects as the query for electing the machine candidate!
case m.Waiting && !m.PreAllocated && m.State.Value == metal.AvailableState && ec.Liveliness == metal.MachineLivelinessAlive:
// the free and allocatable machine counts consider the same aspects as the query for electing the machine candidate!
cap.Allocatable++
cap.Free++
default:
cap.Unavailable++
Expand All @@ -460,8 +461,6 @@ func (r *partitionResource) calcPartitionCapacity(pcr *v1.PartitionCapacityReque
pc := pc

for _, cap := range pc.ServerCapacities {
cap := cap

size := sizesByID[cap.Size]

for _, reservation := range size.Reservations.ForPartition(pc.ID) {
Expand All @@ -474,6 +473,10 @@ func (r *partitionResource) calcPartitionCapacity(pcr *v1.PartitionCapacityReque
}
}

for _, cap := range pc.ServerCapacities {
cap.RemainingReservations = cap.Reservations - cap.UsedReservations
}

res = append(res, *pc)
}

Expand Down
116 changes: 76 additions & 40 deletions cmd/metal-api/internal/service/partition-service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,15 +250,15 @@ func TestUpdatePartition(t *testing.T) {

func TestPartitionCapacity(t *testing.T) {
var (
mockMachines = func(mock *r.Mock, reservations []metal.Reservation, ms ...metal.Machine) {
mockMachines = func(mock *r.Mock, liveliness metal.MachineLiveliness, reservations []metal.Reservation, ms ...metal.Machine) {
var (
sizes metal.Sizes
events metal.ProvisioningEventContainers
partitions metal.Partitions
)

for _, m := range ms {
ec := metal.ProvisioningEventContainer{Base: metal.Base{ID: m.ID}, Liveliness: metal.MachineLivelinessAlive}
ec := metal.ProvisioningEventContainer{Base: metal.Base{ID: m.ID}, Liveliness: liveliness}
if m.Waiting {
ec.Events = append(ec.Events, metal.ProvisioningEvent{
Event: metal.ProvisioningEventWaiting,
Expand Down Expand Up @@ -327,7 +327,7 @@ func TestPartitionCapacity(t *testing.T) {
name: "one allocated machine",
mockFn: func(mock *r.Mock) {
m1 := machineTpl("1", "partition-a", "size-a", "project-123")
mockMachines(mock, nil, m1)
mockMachines(mock, metal.MachineLivelinessAlive, nil, m1)
},
want: []*v1.PartitionCapacity{
{
Expand All @@ -350,7 +350,7 @@ func TestPartitionCapacity(t *testing.T) {
mockFn: func(mock *r.Mock) {
m1 := machineTpl("1", "partition-a", "size-a", "project-123")
m2 := machineTpl("2", "partition-a", "size-a", "project-123")
mockMachines(mock, nil, m1, m2)
mockMachines(mock, metal.MachineLivelinessAlive, nil, m1, m2)
},
want: []*v1.PartitionCapacity{
{
Expand All @@ -373,7 +373,7 @@ func TestPartitionCapacity(t *testing.T) {
mockFn: func(mock *r.Mock) {
m1 := machineTpl("1", "partition-a", "size-a", "project-123")
m1.IPMI.Address = ""
mockMachines(mock, nil, m1)
mockMachines(mock, metal.MachineLivelinessAlive, nil, m1)
},
want: []*v1.PartitionCapacity{
{
Expand All @@ -398,7 +398,7 @@ func TestPartitionCapacity(t *testing.T) {
mockFn: func(mock *r.Mock) {
m1 := machineTpl("1", "partition-a", "size-a", "")
m1.Waiting = true
mockMachines(mock, nil, m1)
mockMachines(mock, metal.MachineLivelinessAlive, nil, m1)
},
want: []*v1.PartitionCapacity{
{
Expand All @@ -407,10 +407,37 @@ func TestPartitionCapacity(t *testing.T) {
},
ServerCapacities: v1.ServerCapacities{
{
Size: "size-a",
Total: 1,
Waiting: 1,
Free: 1,
Size: "size-a",
Total: 1,
Waiting: 1,
Free: 1,
Allocatable: 1,
},
},
},
},
},
{
name: "one dead machine",
mockFn: func(mock *r.Mock) {
m1 := machineTpl("1", "partition-a", "size-a", "")
m1.Waiting = true

mockMachines(mock, metal.MachineLivelinessDead, nil, m1)
},
want: []*v1.PartitionCapacity{
{
Common: v1.Common{
Identifiable: v1.Identifiable{ID: "partition-a"}, Describable: v1.Describable{Name: pointer.Pointer(""), Description: pointer.Pointer("")},
},
ServerCapacities: v1.ServerCapacities{
{
Size: "size-a",
Total: 1,
Waiting: 1,
Faulty: 1,
Unavailable: 1,
FaultyMachines: []string{"1"},
},
},
},
Expand All @@ -422,7 +449,7 @@ func TestPartitionCapacity(t *testing.T) {
m1 := machineTpl("1", "partition-a", "size-a", "")
m1.Waiting = true
m2 := machineTpl("2", "partition-a", "size-a", "project-123")
mockMachines(mock, nil, m1, m2)
mockMachines(mock, metal.MachineLivelinessAlive, nil, m1, m2)
},
want: []*v1.PartitionCapacity{
{
Expand All @@ -431,12 +458,13 @@ func TestPartitionCapacity(t *testing.T) {
},
ServerCapacities: v1.ServerCapacities{
{
Size: "size-a",
Total: 2,
Allocated: 1,
Waiting: 1,
PhonedHome: 1,
Free: 1,
Size: "size-a",
Total: 2,
Allocated: 1,
Waiting: 1,
PhonedHome: 1,
Free: 1,
Allocatable: 1,
},
},
},
Expand All @@ -448,7 +476,7 @@ func TestPartitionCapacity(t *testing.T) {
m1 := machineTpl("1", "partition-a", "size-a", "")
m1.Waiting = true
m1.State.Value = metal.AvailableState
mockMachines(mock, nil, m1)
mockMachines(mock, metal.MachineLivelinessAlive, nil, m1)
},
want: []*v1.PartitionCapacity{
{
Expand All @@ -457,10 +485,11 @@ func TestPartitionCapacity(t *testing.T) {
},
ServerCapacities: v1.ServerCapacities{
{
Size: "size-a",
Total: 1,
Waiting: 1,
Free: 1,
Size: "size-a",
Total: 1,
Waiting: 1,
Free: 1,
Allocatable: 1,
},
},
},
Expand All @@ -471,7 +500,7 @@ func TestPartitionCapacity(t *testing.T) {
mockFn: func(mock *r.Mock) {
m1 := machineTpl("1", "partition-a", "size-a", "")
m1.Waiting = false
mockMachines(mock, nil, m1)
mockMachines(mock, metal.MachineLivelinessAlive, nil, m1)
},
want: []*v1.PartitionCapacity{
{
Expand Down Expand Up @@ -504,7 +533,7 @@ func TestPartitionCapacity(t *testing.T) {
},
}

mockMachines(mock, reservations, m1)
mockMachines(mock, metal.MachineLivelinessAlive, reservations, m1)
},
want: []*v1.PartitionCapacity{
{
Expand All @@ -513,12 +542,14 @@ func TestPartitionCapacity(t *testing.T) {
},
ServerCapacities: v1.ServerCapacities{
{
Size: "size-a",
Total: 1,
Waiting: 1,
Free: 0,
Reservations: 1,
UsedReservations: 0,
Size: "size-a",
Total: 1,
Waiting: 1,
Free: 0,
Allocatable: 1,
Reservations: 1,
UsedReservations: 0,
RemainingReservations: 1,
},
},
},
Expand All @@ -543,7 +574,7 @@ func TestPartitionCapacity(t *testing.T) {
},
}

mockMachines(mock, reservations, m1)
mockMachines(mock, metal.MachineLivelinessAlive, reservations, m1)
},
want: []*v1.PartitionCapacity{
{
Expand All @@ -552,12 +583,14 @@ func TestPartitionCapacity(t *testing.T) {
},
ServerCapacities: v1.ServerCapacities{
{
Size: "size-a",
Total: 1,
Waiting: 1,
Free: 0,
Reservations: 3,
UsedReservations: 0,
Size: "size-a",
Total: 1,
Waiting: 1,
Free: 0,
Allocatable: 1,
Reservations: 3,
UsedReservations: 0,
RemainingReservations: 3,
},
},
},
Expand All @@ -579,7 +612,7 @@ func TestPartitionCapacity(t *testing.T) {
},
}

mockMachines(mock, reservations, m1, m2, m3)
mockMachines(mock, metal.MachineLivelinessAlive, reservations, m1, m2, m3)
},
want: []*v1.PartitionCapacity{
{
Expand All @@ -593,6 +626,7 @@ func TestPartitionCapacity(t *testing.T) {
Allocated: 2,
Waiting: 1,
Free: 1,
Allocatable: 1,
Reservations: 2,
UsedReservations: 2,
PhonedHome: 2,
Expand All @@ -617,7 +651,7 @@ func TestPartitionCapacity(t *testing.T) {
},
}

mockMachines(mock, reservations, m1, m2, m3)
mockMachines(mock, metal.MachineLivelinessAlive, reservations, m1, m2, m3)
},
want: []*v1.PartitionCapacity{
{
Expand All @@ -631,6 +665,7 @@ func TestPartitionCapacity(t *testing.T) {
Allocated: 2,
Waiting: 1,
Free: 1,
Allocatable: 1,
Reservations: 1,
UsedReservations: 1,
PhonedHome: 2,
Expand Down Expand Up @@ -660,7 +695,7 @@ func TestPartitionCapacity(t *testing.T) {
},
}

mockMachines(mock, reservations, m1, m2, m3)
mockMachines(mock, metal.MachineLivelinessAlive, reservations, m1, m2, m3)
},
want: []*v1.PartitionCapacity{
{
Expand All @@ -674,6 +709,7 @@ func TestPartitionCapacity(t *testing.T) {
Allocated: 2,
Waiting: 1,
Free: 1,
Allocatable: 1,
Reservations: 2,
UsedReservations: 2,
PhonedHome: 2,
Expand Down
5 changes: 5 additions & 0 deletions cmd/metal-api/internal/service/v1/partition.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ type ServerCapacity struct {

// Allocated is the amount of machines that are currently allocated.
Allocated int `json:"allocated,omitempty" description:"allocated machines"`
// Allocatable is the amount of machines in a partition is the amount of machines that can be allocated.
// Effectively this is the amount of waiting machines minus the machines that are unavailable due to machine state or un-allocatable. Size reservations are not considered in this count.
Allocatable int `json:"allocatable,omitempty" description:"free machines with this size, size reservations are not considered"`
// Free is the amount of machines in a partition that can be freely allocated at any given moment by a project.
// Effectively this is the amount of waiting machines minus the machines that are unavailable due to machine state or un-allocatable due to size reservations.
Free int `json:"free,omitempty" description:"free machines with this size (freely allocatable)"`
Expand All @@ -84,6 +87,8 @@ type ServerCapacity struct {
Reservations int `json:"reservations,omitempty" description:"the amount of reservations for this size"`
// UsedReservations is the amount of reservations already used up for this size.
UsedReservations int `json:"usedreservations,omitempty" description:"the amount of used reservations for this size"`
// RemainingReservations is the amount of reservations remaining for this size.
RemainingReservations int `json:"remainingreservations,omitempty" description:"the amount of unused / remaining / open reservations for this size"`
}

func NewPartitionResponse(p *metal.Partition) *PartitionResponse {
Expand Down
10 changes: 10 additions & 0 deletions spec/metal-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -4461,6 +4461,11 @@
},
"v1.ServerCapacity": {
"properties": {
"allocatable": {
"description": "free machines with this size, size reservations are not considered",
"format": "int32",
"type": "integer"
},
"allocated": {
"description": "allocated machines",
"format": "int32",
Expand Down Expand Up @@ -4500,6 +4505,11 @@
"format": "int32",
"type": "integer"
},
"remainingreservations": {
"description": "the amount of unused / remaining / open reservations for this size",
"format": "int32",
"type": "integer"
},
"reservations": {
"description": "the amount of reservations for this size",
"format": "int32",
Expand Down

0 comments on commit 10f49c7

Please sign in to comment.