From 242f99b18ed8752e8d177a6538825b04723f2d81 Mon Sep 17 00:00:00 2001 From: ostempel Date: Tue, 2 Sep 2025 09:58:05 +0200 Subject: [PATCH 1/2] consider all machines of partition for evaluating faulty machiens --- .../internal/service/partition-service.go | 17 ++- .../service/partition-service_test.go | 107 ++++++++++++++++++ 2 files changed, 121 insertions(+), 3 deletions(-) diff --git a/cmd/metal-api/internal/service/partition-service.go b/cmd/metal-api/internal/service/partition-service.go index 61f77486..9b339020 100644 --- a/cmd/metal-api/internal/service/partition-service.go +++ b/cmd/metal-api/internal/service/partition-service.go @@ -380,8 +380,9 @@ func (r *partitionResource) partitionCapacity(request *restful.Request, response func (r *partitionResource) calcPartitionCapacity(pcr *v1.PartitionCapacityRequest) ([]v1.PartitionCapacity, error) { var ( - ps metal.Partitions - ms metal.Machines + ps metal.Partitions + ms metal.Machines + allMs metal.Machines pcs = map[string]*v1.PartitionCapacity{} @@ -413,6 +414,16 @@ func (r *partitionResource) calcPartitionCapacity(pcr *v1.PartitionCapacityReque return nil, err } + // if filtered on partition get all without more filters for issues evaluation + if machineQuery.PartitionID != nil { + err = r.ds.SearchMachines(&datastore.MachineSearchQuery{PartitionID: machineQuery.PartitionID}, &allMs) + if err != nil { + return nil, err + } + } else { + allMs = ms + } + ecs, err := r.ds.ListProvisioningEventContainers() if err != nil { return nil, fmt.Errorf("unable to fetch provisioning event containers: %w", err) @@ -429,7 +440,7 @@ func (r *partitionResource) calcPartitionCapacity(pcr *v1.PartitionCapacityReque } machinesWithIssues, err := issues.Find(&issues.Config{ - Machines: ms, + Machines: allMs, EventContainers: ecs, Omit: []issues.Type{issues.TypeLastEventError}, }) diff --git a/cmd/metal-api/internal/service/partition-service_test.go b/cmd/metal-api/internal/service/partition-service_test.go index bac50f5b..cbd2e510 100644 --- a/cmd/metal-api/internal/service/partition-service_test.go +++ b/cmd/metal-api/internal/service/partition-service_test.go @@ -310,6 +310,27 @@ func TestPartitionCapacity(t *testing.T) { mock.On(r.DB("mockdb").Table("event")).Return(events, nil) mock.On(r.DB("mockdb").Table("partition")).Return(partitions, nil) mock.On(r.DB("mockdb").Table("size")).Return(sizes, nil) + + //Filtered mocks + var filteredPartition []metal.Partition + for _, partition := range partitions { + if partition.ID == "partition-a" { + filteredPartition = append(filteredPartition, partition) + } + } + var filteredMachinesByPartition []metal.Machine + var filteredMachinesByPartitionBySize []metal.Machine + for _, machine := range ms { + if machine.PartitionID == "partition-a" { + filteredMachinesByPartition = append(filteredMachinesByPartition, machine) + if machine.SizeID == "size-a" { + filteredMachinesByPartitionBySize = append(filteredMachinesByPartitionBySize, machine) + } + } + } + mock.On(r.DB("mockdb").Table("partition").Get("partition-a")).Return(filteredPartition, nil) + mock.On(r.DB("mockdb").Table("machine").Filter(func(var_1 r.Term) r.Term { return var_1.Field("partitionid").Eq("partition-a") })).Return(filteredMachinesByPartition, nil) + mock.On(r.DB("mockdb").Table("machine").Filter(func(var_1 r.Term) r.Term { return var_1.Field("partitionid").Eq("partition-a") }).Filter(func(var_1 r.Term) r.Term { return var_1.Field("sizeid").Eq("size-a") })).Return(filteredMachinesByPartitionBySize, nil) } machineTpl = func(id, partition, size, project string) metal.Machine { @@ -411,6 +432,92 @@ func TestPartitionCapacity(t *testing.T) { }, }, }, + { + name: "filter considers all machines", + pcr: &v1.PartitionCapacityRequest{ + ID: pointer.Pointer("partition-a"), + Size: pointer.Pointer("size-a"), + }, + mockFn: func(mock *r.Mock) { + m1 := machineTpl("1", "partition-a", "size-a", "project-123") + m2 := machineTpl("2", "partition-a", "size-a", "project-123") + m3 := machineTpl("3", "partition-a", "size-a", "project-123") + m4 := machineTpl("4", "partition-a", "size-b", "project-123") + m4.IPMI.Address = "1.2.3.1" + m5 := machineTpl("5", "partition-b", "size-a", "project-123") + mockMachines(mock, metal.MachineLivelinessAlive, nil, m1, m2, m3, m4, m5) + }, + + 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: 3, + PhonedHome: 3, + Faulty: 1, + Allocated: 3, + FaultyMachines: []string{"1"}, + }, + }, + }, + }, + }, + { + name: "non filter considers all machines", + pcr: &v1.PartitionCapacityRequest{}, + mockFn: func(mock *r.Mock) { + m1 := machineTpl("1", "partition-a", "size-a", "project-123") + m2 := machineTpl("2", "partition-a", "size-a", "project-123") + m3 := machineTpl("3", "partition-a", "size-a", "project-123") + m4 := machineTpl("4", "partition-a", "size-b", "project-123") + m4.IPMI.Address = "1.2.3.1" + m5 := machineTpl("5", "partition-b", "size-a", "project-123") + mockMachines(mock, metal.MachineLivelinessAlive, nil, m1, m2, m3, m4, m5) + }, + 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: 3, + PhonedHome: 3, + Faulty: 1, + Allocated: 3, + FaultyMachines: []string{"1"}, + }, + { + Size: "size-b", + Total: 1, + PhonedHome: 1, + Faulty: 1, + Allocated: 1, + FaultyMachines: []string{"4"}, + }, + }, + }, + { + Common: v1.Common{ + Identifiable: v1.Identifiable{ID: "partition-b"}, Describable: v1.Describable{Name: pointer.Pointer(""), Description: pointer.Pointer("")}, + }, + ServerCapacities: v1.ServerCapacities{ + { + Size: "size-a", + Total: 1, + PhonedHome: 1, + Faulty: 0, + Allocated: 1, + }, + }, + }, + }, + }, { name: "one waiting machine", mockFn: func(mock *r.Mock) { From 0634c2275eb3b0419a25ae14963bc81ff7affbc9 Mon Sep 17 00:00:00 2001 From: ostempel Date: Wed, 3 Sep 2025 08:20:19 +0200 Subject: [PATCH 2/2] fix all machines query --- .../internal/service/partition-service.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/cmd/metal-api/internal/service/partition-service.go b/cmd/metal-api/internal/service/partition-service.go index 9b339020..9eee4531 100644 --- a/cmd/metal-api/internal/service/partition-service.go +++ b/cmd/metal-api/internal/service/partition-service.go @@ -386,7 +386,8 @@ func (r *partitionResource) calcPartitionCapacity(pcr *v1.PartitionCapacityReque pcs = map[string]*v1.PartitionCapacity{} - machineQuery = datastore.MachineSearchQuery{} + machineQuery = datastore.MachineSearchQuery{} + allMachineQuery = datastore.MachineSearchQuery{} ) if pcr != nil && pcr.ID != nil { @@ -397,6 +398,7 @@ func (r *partitionResource) calcPartitionCapacity(pcr *v1.PartitionCapacityReque ps = metal.Partitions{*p} machineQuery.PartitionID = pcr.ID + allMachineQuery.PartitionID = pcr.ID } else { var err error ps, err = r.ds.ListPartitions() @@ -415,13 +417,9 @@ func (r *partitionResource) calcPartitionCapacity(pcr *v1.PartitionCapacityReque } // if filtered on partition get all without more filters for issues evaluation - if machineQuery.PartitionID != nil { - err = r.ds.SearchMachines(&datastore.MachineSearchQuery{PartitionID: machineQuery.PartitionID}, &allMs) - if err != nil { - return nil, err - } - } else { - allMs = ms + err = r.ds.SearchMachines(&allMachineQuery, &allMs) + if err != nil { + return nil, err } ecs, err := r.ds.ListProvisioningEventContainers()