diff --git a/cmd/metal-api/internal/metal/partition.go b/cmd/metal-api/internal/metal/partition.go index a1b89378e..b748debbc 100644 --- a/cmd/metal-api/internal/metal/partition.go +++ b/cmd/metal-api/internal/metal/partition.go @@ -6,6 +6,7 @@ type Partition struct { BootConfiguration BootConfiguration `rethinkdb:"bootconfig" json:"bootconfig"` MgmtServiceAddress string `rethinkdb:"mgmtserviceaddr" json:"mgmtserviceaddr"` PrivateNetworkPrefixLength int `rethinkdb:"privatenetworkprefixlength" json:"privatenetworkprefixlength"` + MachineReserve MachineReserve `rethinkdb:"machinereserve" json:"machinereserve"` } // BootConfiguration defines the metal-hammer initrd, kernel and commandline @@ -15,6 +16,9 @@ type BootConfiguration struct { CommandLine string `rethinkdb:"commandline" json:"commandline"` } +// MachineReserve configures spare machine size to count +type MachineReserve map[string]int + // Partitions is a list of partitions. type Partitions []Partition diff --git a/cmd/metal-api/internal/service/partition-service.go b/cmd/metal-api/internal/service/partition-service.go index 43bad6fba..1c13be334 100644 --- a/cmd/metal-api/internal/service/partition-service.go +++ b/cmd/metal-api/internal/service/partition-service.go @@ -193,6 +193,12 @@ func (r partitionResource) createPartition(request *restful.Request, response *r if requestPayload.PartitionBootConfiguration.CommandLine != nil { commandLine = *requestPayload.PartitionBootConfiguration.CommandLine } + mr := metal.MachineReserve{} + if requestPayload.MachineReserve != nil { + for k, v := range *requestPayload.MachineReserve { + mr[k] = v + } + } p := &metal.Partition{ Base: metal.Base{ @@ -207,6 +213,7 @@ func (r partitionResource) createPartition(request *restful.Request, response *r KernelURL: kernelURL, CommandLine: commandLine, }, + MachineReserve: mr, } fqn := metal.TopicMachine.GetFQN(p.GetID()) @@ -279,6 +286,13 @@ func (r partitionResource) updatePartition(request *restful.Request, response *r if requestPayload.PartitionBootConfiguration.CommandLine != nil { newPartition.BootConfiguration.CommandLine = *requestPayload.PartitionBootConfiguration.CommandLine } + if requestPayload.MachineReserve != nil { + mr := metal.MachineReserve{} + for k, v := range *requestPayload.MachineReserve { + mr[k] = v + } + newPartition.MachineReserve = mr + } err = r.ds.UpdatePartition(oldPartition, &newPartition) if checkError(request, response, utils.CurrentFuncName(), err) { @@ -361,6 +375,7 @@ func (r partitionResource) calcPartitionCapacity() ([]v1.PartitionCapacity, erro cap.OtherMachines = append(cap.OtherMachines, m.ID) } + cap.Reserved = p.MachineReserve[size] cap.Total++ } sc := []v1.ServerCapacity{} diff --git a/cmd/metal-api/internal/service/v1/partition.go b/cmd/metal-api/internal/service/v1/partition.go index b8e8e9abf..44afb8b6a 100644 --- a/cmd/metal-api/internal/service/v1/partition.go +++ b/cmd/metal-api/internal/service/v1/partition.go @@ -19,12 +19,14 @@ type PartitionCreateRequest struct { Common PartitionBase PartitionBootConfiguration PartitionBootConfiguration `json:"bootconfig" description:"the boot configuration of this partition"` + MachineReserve *MachineReserve `json:"machine_reserve,omitempty"` } type PartitionUpdateRequest struct { Common MgmtServiceAddress *string `json:"mgmtserviceaddress" description:"the address to the management service of this partition" optional:"true"` PartitionBootConfiguration *PartitionBootConfiguration `json:"bootconfig" description:"the boot configuration of this partition" optional:"true"` + MachineReserve *MachineReserve `json:"machine_reserve,omitempty"` } type PartitionResponse struct { @@ -32,6 +34,7 @@ type PartitionResponse struct { PartitionBase PartitionBootConfiguration PartitionBootConfiguration `json:"bootconfig" description:"the boot configuration of this partition"` Timestamps + MachineReserve *MachineReserve `json:"machine_reserve,omitempty"` } type PartitionCapacity struct { @@ -39,6 +42,8 @@ type PartitionCapacity struct { ServerCapacities []ServerCapacity `json:"servers" description:"servers available in this partition"` } +type MachineReserve map[string]int + type ServerCapacity struct { Size string `json:"size" description:"the size of the server"` Total int `json:"total" description:"total amount of servers with this size"` @@ -48,12 +53,17 @@ type ServerCapacity struct { FaultyMachines []string `json:"faultymachines" description:"servers with issues with this size"` Other int `json:"other" description:"servers neither free, allocated or faulty with this size"` OtherMachines []string `json:"othermachines" description:"servers neither free, allocated or faulty with this size"` + Reserved int `json:"reserved" description:"reserved machines"` } func NewPartitionResponse(p *metal.Partition) *PartitionResponse { if p == nil { return nil } + mr := MachineReserve{} + for k, v := range p.MachineReserve { + mr[k] = v + } return &PartitionResponse{ Common: Common{ Identifiable: Identifiable{ @@ -77,5 +87,6 @@ func NewPartitionResponse(p *metal.Partition) *PartitionResponse { Created: p.Created, Changed: p.Changed, }, + MachineReserve: &mr, } } diff --git a/spec/metal-api.json b/spec/metal-api.json index 2ef213c1c..8ee5e8445 100644 --- a/spec/metal-api.json +++ b/spec/metal-api.json @@ -1837,6 +1837,12 @@ "imageid" ] }, + "v1.MachineReserve": { + "additionalProperties": { + "type": "integer" + }, + "type": "object" + }, "v1.MachineResponse": { "properties": { "allocation": { @@ -2373,6 +2379,9 @@ "type": "string", "uniqueItems": true }, + "machine_reserve": { + "$ref": "#/definitions/v1.MachineReserve" + }, "mgmtserviceaddress": { "description": "the address to the management service of this partition", "type": "string" @@ -2421,6 +2430,9 @@ "type": "string", "uniqueItems": true }, + "machine_reserve": { + "$ref": "#/definitions/v1.MachineReserve" + }, "mgmtserviceaddress": { "description": "the address to the management service of this partition", "type": "string" @@ -2457,6 +2469,9 @@ "type": "string", "uniqueItems": true }, + "machine_reserve": { + "$ref": "#/definitions/v1.MachineReserve" + }, "mgmtserviceaddress": { "description": "the address to the management service of this partition", "type": "string" @@ -2607,6 +2622,11 @@ }, "type": "array" }, + "reserved": { + "description": "reserved machines", + "format": "int32", + "type": "integer" + }, "size": { "description": "the size of the server", "type": "string" @@ -2624,6 +2644,7 @@ "free", "other", "othermachines", + "reserved", "size", "total" ]