diff --git a/api/v1/hypervisor_types.go b/api/v1/hypervisor_types.go index e38a2e3..a2d1a0b 100644 --- a/api/v1/hypervisor_types.go +++ b/api/v1/hypervisor_types.go @@ -93,6 +93,12 @@ type HypervisorSpec struct { // Aggregates are used to apply aggregates to the hypervisor. Aggregates []string `json:"aggregates"` + // +kubebuilder:default:={} + // AllowedProjects defines which openstack projects are allowed to schedule + // instances on this hypervisor. The values of this list should be project + // uuids. If left empty, all projects are allowed. + AllowedProjects []string `json:"allowedProjects"` + // +kubebuilder:default:=true // HighAvailability is used to enable the high availability handling of the hypervisor. HighAvailability bool `json:"highAvailability"` @@ -190,8 +196,17 @@ type OperatingSystemStatus struct { GardenLinuxFeatures []string `json:"gardenLinuxFeatures,omitempty"` } -// Current capabilities reported by libvirt. -type CapabilitiesStatus struct { +// Cell represents a single cell of the host's topology. +type Cell struct { + // ID is the identifier of the cell. + ID int `json:"id"` + // The cell's capacity, such as the number of cpus, memory, and hugepages. + // +kubebuilder:default:={} + Capacity map[string]resource.Quantity `json:"capacity,omitempty"` +} + +// Capabilities of the hypervisor as reported by libvirt. +type Capabilities struct { // +kubebuilder:default:=unknown // The hosts CPU architecture (not the guests). HostCpuArch string `json:"cpuArch,omitempty"` @@ -199,6 +214,82 @@ type CapabilitiesStatus struct { HostMemory resource.Quantity `json:"memory,omitempty"` // Total host cpus available as a sum of cpus over all numa cells. HostCpus resource.Quantity `json:"cpus,omitempty"` + // The host's cell topology (a.k.a. numa cells). + // +kubebuilder:validation:Optional + HostTopology []Cell `json:"hostTopology,omitempty"` +} + +// Domain capabilities of the hypervisor as reported by libvirt. +// These details are relevant to check if a VM can be scheduled on the hypervisor. +type DomainCapabilities struct { + // The available domain cpu architecture. + // +kubebuilder:default:=unknown + Arch string `json:"arch,omitempty"` + + // The supported type of virtualization for domains, such as "ch". + // +kubebuilder:default:=unknown + HypervisorType string `json:"hypervisorType,omitempty"` + + // Supported devices for domains. + // + // The format of this list is the device type, and if specified, a specific + // model. For example, the take the following xml domain device definition: + // + // + // + // The corresponding entries in this list would be "video" and "video/nvidia". + // + // +kubebuilder:default:={} + SupportedDevices []string `json:"supportedDevices,omitempty"` + + // Supported cpu modes for domains. + // + // The format of this list is cpu mode, and if specified, a specific + // submode. For example, the take the following xml domain cpu definition: + // + // + // + // + // + // The corresponding entries in this list would be "host-passthrough" and + // "host-passthrough/migratable". + // + // +kubebuilder:default:={} + SupportedCpuModes []string `json:"supportedCpuModes,omitempty"` + + // Supported features for domains, such as "sev" or "sgx". + // + // This is a flat list of supported features, meaning the following xml: + // + // + // + // + // + // + // Would correspond to the entries "sev" and "sgx" in this list. + // + // +kubebuilder:default:={} + SupportedFeatures []string `json:"supportedFeatures,omitempty"` +} + +// Domain information as reported by libvirt. +type DomainInfo struct { + // Name is the name of the domain. + Name string `json:"name"` + // UUID is the uuid of the domain. + UUID string `json:"uuid"` + // Resource allocation of the domain. + // This can include memory, cpu, and other. + Allocation map[string]resource.Quantity `json:"allocation,omitempty"` + // The memory numa cells of the domain, derived from the numa tune. + MemoryCells []int `json:"memoryCells,omitempty"` + // The cpu numa cells of the domain, derived from the numa information + // of the cpu mode. + CpuCells []int `json:"cpuCells,omitempty"` } // HypervisorStatus defines the observed state of Hypervisor @@ -216,8 +307,18 @@ type HypervisorStatus struct { // Represents the Hypervisor hosted Virtual Machines Instances []Instance `json:"instances,omitempty"` - // The capabilities of the hypervisors as reported by libvirt. - Capabilities CapabilitiesStatus `json:"capabilities,omitempty"` + // Auto-discovered capabilities as reported by libvirt. + // +kubebuilder:validation:Optional + Capabilities Capabilities `json:"capabilities"` + + // Auto-discovered domain capabilities relevant to check if a VM + // can be scheduled on the hypervisor. + // +kubebuilder:validation:Optional + DomainCapabilities DomainCapabilities `json:"domainCapabilities"` + + // Auto-discovered domain infos as reported by libvirt (dumpxml). + // +kubebuilder:default:={} + DomainInfos []DomainInfo `json:"domainInfos,omitempty"` // +kubebuilder:default:=0 // Represent the num of instances diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 1950f3b..d41ee12 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -22,23 +22,115 @@ limitations under the License. package v1 import ( + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CapabilitiesStatus) DeepCopyInto(out *CapabilitiesStatus) { +func (in *Capabilities) DeepCopyInto(out *Capabilities) { *out = *in out.HostMemory = in.HostMemory.DeepCopy() out.HostCpus = in.HostCpus.DeepCopy() + if in.HostTopology != nil { + in, out := &in.HostTopology, &out.HostTopology + *out = make([]Cell, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CapabilitiesStatus. -func (in *CapabilitiesStatus) DeepCopy() *CapabilitiesStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Capabilities. +func (in *Capabilities) DeepCopy() *Capabilities { if in == nil { return nil } - out := new(CapabilitiesStatus) + out := new(Capabilities) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Cell) DeepCopyInto(out *Cell) { + *out = *in + if in.Capacity != nil { + in, out := &in.Capacity, &out.Capacity + *out = make(map[string]resource.Quantity, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cell. +func (in *Cell) DeepCopy() *Cell { + if in == nil { + return nil + } + out := new(Cell) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DomainCapabilities) DeepCopyInto(out *DomainCapabilities) { + *out = *in + if in.SupportedDevices != nil { + in, out := &in.SupportedDevices, &out.SupportedDevices + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.SupportedCpuModes != nil { + in, out := &in.SupportedCpuModes, &out.SupportedCpuModes + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.SupportedFeatures != nil { + in, out := &in.SupportedFeatures, &out.SupportedFeatures + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DomainCapabilities. +func (in *DomainCapabilities) DeepCopy() *DomainCapabilities { + if in == nil { + return nil + } + out := new(DomainCapabilities) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DomainInfo) DeepCopyInto(out *DomainInfo) { + *out = *in + if in.Allocation != nil { + in, out := &in.Allocation, &out.Allocation + *out = make(map[string]resource.Quantity, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.MemoryCells != nil { + in, out := &in.MemoryCells, &out.MemoryCells + *out = make([]int, len(*in)) + copy(*out, *in) + } + if in.CpuCells != nil { + in, out := &in.CpuCells, &out.CpuCells + *out = make([]int, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DomainInfo. +func (in *DomainInfo) DeepCopy() *DomainInfo { + if in == nil { + return nil + } + out := new(DomainInfo) in.DeepCopyInto(out) return out } @@ -231,6 +323,11 @@ func (in *HypervisorSpec) DeepCopyInto(out *HypervisorSpec) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.AllowedProjects != nil { + in, out := &in.AllowedProjects, &out.AllowedProjects + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HypervisorSpec. @@ -254,6 +351,14 @@ func (in *HypervisorStatus) DeepCopyInto(out *HypervisorStatus) { copy(*out, *in) } in.Capabilities.DeepCopyInto(&out.Capabilities) + in.DomainCapabilities.DeepCopyInto(&out.DomainCapabilities) + if in.DomainInfos != nil { + in, out := &in.DomainInfos, &out.DomainInfos + *out = make([]DomainInfo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } if in.Traits != nil { in, out := &in.Traits, &out.Traits *out = make([]string, len(*in)) diff --git a/applyconfigurations/api/v1/capabilities.go b/applyconfigurations/api/v1/capabilities.go new file mode 100644 index 0000000..57d6da5 --- /dev/null +++ b/applyconfigurations/api/v1/capabilities.go @@ -0,0 +1,59 @@ +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +import ( + resource "k8s.io/apimachinery/pkg/api/resource" +) + +// CapabilitiesApplyConfiguration represents a declarative configuration of the Capabilities type for use +// with apply. +type CapabilitiesApplyConfiguration struct { + HostCpuArch *string `json:"cpuArch,omitempty"` + HostMemory *resource.Quantity `json:"memory,omitempty"` + HostCpus *resource.Quantity `json:"cpus,omitempty"` + HostTopology []CellApplyConfiguration `json:"hostTopology,omitempty"` +} + +// CapabilitiesApplyConfiguration constructs a declarative configuration of the Capabilities type for use with +// apply. +func Capabilities() *CapabilitiesApplyConfiguration { + return &CapabilitiesApplyConfiguration{} +} + +// WithHostCpuArch sets the HostCpuArch field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the HostCpuArch field is set to the value of the last call. +func (b *CapabilitiesApplyConfiguration) WithHostCpuArch(value string) *CapabilitiesApplyConfiguration { + b.HostCpuArch = &value + return b +} + +// WithHostMemory sets the HostMemory field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the HostMemory field is set to the value of the last call. +func (b *CapabilitiesApplyConfiguration) WithHostMemory(value resource.Quantity) *CapabilitiesApplyConfiguration { + b.HostMemory = &value + return b +} + +// WithHostCpus sets the HostCpus field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the HostCpus field is set to the value of the last call. +func (b *CapabilitiesApplyConfiguration) WithHostCpus(value resource.Quantity) *CapabilitiesApplyConfiguration { + b.HostCpus = &value + return b +} + +// WithHostTopology adds the given value to the HostTopology field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the HostTopology field. +func (b *CapabilitiesApplyConfiguration) WithHostTopology(values ...*CellApplyConfiguration) *CapabilitiesApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithHostTopology") + } + b.HostTopology = append(b.HostTopology, *values[i]) + } + return b +} diff --git a/applyconfigurations/api/v1/capabilitiesstatus.go b/applyconfigurations/api/v1/capabilitiesstatus.go deleted file mode 100644 index 0ab1ec7..0000000 --- a/applyconfigurations/api/v1/capabilitiesstatus.go +++ /dev/null @@ -1,45 +0,0 @@ -// Code generated by controller-gen. DO NOT EDIT. - -package v1 - -import ( - resource "k8s.io/apimachinery/pkg/api/resource" -) - -// CapabilitiesStatusApplyConfiguration represents a declarative configuration of the CapabilitiesStatus type for use -// with apply. -type CapabilitiesStatusApplyConfiguration struct { - HostCpuArch *string `json:"cpuArch,omitempty"` - HostMemory *resource.Quantity `json:"memory,omitempty"` - HostCpus *resource.Quantity `json:"cpus,omitempty"` -} - -// CapabilitiesStatusApplyConfiguration constructs a declarative configuration of the CapabilitiesStatus type for use with -// apply. -func CapabilitiesStatus() *CapabilitiesStatusApplyConfiguration { - return &CapabilitiesStatusApplyConfiguration{} -} - -// WithHostCpuArch sets the HostCpuArch field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the HostCpuArch field is set to the value of the last call. -func (b *CapabilitiesStatusApplyConfiguration) WithHostCpuArch(value string) *CapabilitiesStatusApplyConfiguration { - b.HostCpuArch = &value - return b -} - -// WithHostMemory sets the HostMemory field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the HostMemory field is set to the value of the last call. -func (b *CapabilitiesStatusApplyConfiguration) WithHostMemory(value resource.Quantity) *CapabilitiesStatusApplyConfiguration { - b.HostMemory = &value - return b -} - -// WithHostCpus sets the HostCpus field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the HostCpus field is set to the value of the last call. -func (b *CapabilitiesStatusApplyConfiguration) WithHostCpus(value resource.Quantity) *CapabilitiesStatusApplyConfiguration { - b.HostCpus = &value - return b -} diff --git a/applyconfigurations/api/v1/cell.go b/applyconfigurations/api/v1/cell.go new file mode 100644 index 0000000..e749966 --- /dev/null +++ b/applyconfigurations/api/v1/cell.go @@ -0,0 +1,42 @@ +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +import ( + resource "k8s.io/apimachinery/pkg/api/resource" +) + +// CellApplyConfiguration represents a declarative configuration of the Cell type for use +// with apply. +type CellApplyConfiguration struct { + ID *int `json:"id,omitempty"` + Capacity map[string]resource.Quantity `json:"capacity,omitempty"` +} + +// CellApplyConfiguration constructs a declarative configuration of the Cell type for use with +// apply. +func Cell() *CellApplyConfiguration { + return &CellApplyConfiguration{} +} + +// WithID sets the ID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ID field is set to the value of the last call. +func (b *CellApplyConfiguration) WithID(value int) *CellApplyConfiguration { + b.ID = &value + return b +} + +// WithCapacity puts the entries into the Capacity field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Capacity field, +// overwriting an existing map entries in Capacity field with the same key. +func (b *CellApplyConfiguration) WithCapacity(entries map[string]resource.Quantity) *CellApplyConfiguration { + if b.Capacity == nil && len(entries) > 0 { + b.Capacity = make(map[string]resource.Quantity, len(entries)) + } + for k, v := range entries { + b.Capacity[k] = v + } + return b +} diff --git a/applyconfigurations/api/v1/domaincapabilities.go b/applyconfigurations/api/v1/domaincapabilities.go new file mode 100644 index 0000000..8985c23 --- /dev/null +++ b/applyconfigurations/api/v1/domaincapabilities.go @@ -0,0 +1,65 @@ +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +// DomainCapabilitiesApplyConfiguration represents a declarative configuration of the DomainCapabilities type for use +// with apply. +type DomainCapabilitiesApplyConfiguration struct { + Arch *string `json:"arch,omitempty"` + HypervisorType *string `json:"hypervisorType,omitempty"` + SupportedDevices []string `json:"supportedDevices,omitempty"` + SupportedCpuModes []string `json:"supportedCpuModes,omitempty"` + SupportedFeatures []string `json:"supportedFeatures,omitempty"` +} + +// DomainCapabilitiesApplyConfiguration constructs a declarative configuration of the DomainCapabilities type for use with +// apply. +func DomainCapabilities() *DomainCapabilitiesApplyConfiguration { + return &DomainCapabilitiesApplyConfiguration{} +} + +// WithArch sets the Arch field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Arch field is set to the value of the last call. +func (b *DomainCapabilitiesApplyConfiguration) WithArch(value string) *DomainCapabilitiesApplyConfiguration { + b.Arch = &value + return b +} + +// WithHypervisorType sets the HypervisorType field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the HypervisorType field is set to the value of the last call. +func (b *DomainCapabilitiesApplyConfiguration) WithHypervisorType(value string) *DomainCapabilitiesApplyConfiguration { + b.HypervisorType = &value + return b +} + +// WithSupportedDevices adds the given value to the SupportedDevices field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the SupportedDevices field. +func (b *DomainCapabilitiesApplyConfiguration) WithSupportedDevices(values ...string) *DomainCapabilitiesApplyConfiguration { + for i := range values { + b.SupportedDevices = append(b.SupportedDevices, values[i]) + } + return b +} + +// WithSupportedCpuModes adds the given value to the SupportedCpuModes field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the SupportedCpuModes field. +func (b *DomainCapabilitiesApplyConfiguration) WithSupportedCpuModes(values ...string) *DomainCapabilitiesApplyConfiguration { + for i := range values { + b.SupportedCpuModes = append(b.SupportedCpuModes, values[i]) + } + return b +} + +// WithSupportedFeatures adds the given value to the SupportedFeatures field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the SupportedFeatures field. +func (b *DomainCapabilitiesApplyConfiguration) WithSupportedFeatures(values ...string) *DomainCapabilitiesApplyConfiguration { + for i := range values { + b.SupportedFeatures = append(b.SupportedFeatures, values[i]) + } + return b +} diff --git a/applyconfigurations/api/v1/domaininfo.go b/applyconfigurations/api/v1/domaininfo.go new file mode 100644 index 0000000..b521f81 --- /dev/null +++ b/applyconfigurations/api/v1/domaininfo.go @@ -0,0 +1,73 @@ +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +import ( + resource "k8s.io/apimachinery/pkg/api/resource" +) + +// DomainInfoApplyConfiguration represents a declarative configuration of the DomainInfo type for use +// with apply. +type DomainInfoApplyConfiguration struct { + Name *string `json:"name,omitempty"` + UUID *string `json:"uuid,omitempty"` + Allocation map[string]resource.Quantity `json:"allocation,omitempty"` + MemoryCells []int `json:"memoryCells,omitempty"` + CpuCells []int `json:"cpuCells,omitempty"` +} + +// DomainInfoApplyConfiguration constructs a declarative configuration of the DomainInfo type for use with +// apply. +func DomainInfo() *DomainInfoApplyConfiguration { + return &DomainInfoApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *DomainInfoApplyConfiguration) WithName(value string) *DomainInfoApplyConfiguration { + b.Name = &value + return b +} + +// WithUUID sets the UUID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UUID field is set to the value of the last call. +func (b *DomainInfoApplyConfiguration) WithUUID(value string) *DomainInfoApplyConfiguration { + b.UUID = &value + return b +} + +// WithAllocation puts the entries into the Allocation field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Allocation field, +// overwriting an existing map entries in Allocation field with the same key. +func (b *DomainInfoApplyConfiguration) WithAllocation(entries map[string]resource.Quantity) *DomainInfoApplyConfiguration { + if b.Allocation == nil && len(entries) > 0 { + b.Allocation = make(map[string]resource.Quantity, len(entries)) + } + for k, v := range entries { + b.Allocation[k] = v + } + return b +} + +// WithMemoryCells adds the given value to the MemoryCells field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MemoryCells field. +func (b *DomainInfoApplyConfiguration) WithMemoryCells(values ...int) *DomainInfoApplyConfiguration { + for i := range values { + b.MemoryCells = append(b.MemoryCells, values[i]) + } + return b +} + +// WithCpuCells adds the given value to the CpuCells field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the CpuCells field. +func (b *DomainInfoApplyConfiguration) WithCpuCells(values ...int) *DomainInfoApplyConfiguration { + for i := range values { + b.CpuCells = append(b.CpuCells, values[i]) + } + return b +} diff --git a/applyconfigurations/api/v1/hypervisorspec.go b/applyconfigurations/api/v1/hypervisorspec.go index 0aa2dc1..6fa5d4a 100644 --- a/applyconfigurations/api/v1/hypervisorspec.go +++ b/applyconfigurations/api/v1/hypervisorspec.go @@ -12,6 +12,7 @@ type HypervisorSpecApplyConfiguration struct { SkipTests *bool `json:"skipTests,omitempty"` CustomTraits []string `json:"customTraits,omitempty"` Aggregates []string `json:"aggregates,omitempty"` + AllowedProjects []string `json:"allowedProjects,omitempty"` HighAvailability *bool `json:"highAvailability,omitempty"` CreateCertManagerCertificate *bool `json:"createCertManagerCertificate,omitempty"` InstallCertificate *bool `json:"installCertificate,omitempty"` @@ -84,6 +85,16 @@ func (b *HypervisorSpecApplyConfiguration) WithAggregates(values ...string) *Hyp return b } +// WithAllowedProjects adds the given value to the AllowedProjects field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the AllowedProjects field. +func (b *HypervisorSpecApplyConfiguration) WithAllowedProjects(values ...string) *HypervisorSpecApplyConfiguration { + for i := range values { + b.AllowedProjects = append(b.AllowedProjects, values[i]) + } + return b +} + // WithHighAvailability sets the HighAvailability field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the HighAvailability field is set to the value of the last call. diff --git a/applyconfigurations/api/v1/hypervisorstatus.go b/applyconfigurations/api/v1/hypervisorstatus.go index e51cdc9..a82dcf0 100644 --- a/applyconfigurations/api/v1/hypervisorstatus.go +++ b/applyconfigurations/api/v1/hypervisorstatus.go @@ -9,20 +9,22 @@ import ( // HypervisorStatusApplyConfiguration represents a declarative configuration of the HypervisorStatus type for use // with apply. type HypervisorStatusApplyConfiguration struct { - LibVirtVersion *string `json:"libVirtVersion,omitempty"` - OperatingSystem *OperatingSystemStatusApplyConfiguration `json:"operatingSystem,omitempty"` - Update *HyperVisorUpdateStatusApplyConfiguration `json:"updateStatus,omitempty"` - Instances []InstanceApplyConfiguration `json:"instances,omitempty"` - Capabilities *CapabilitiesStatusApplyConfiguration `json:"capabilities,omitempty"` - NumInstances *int `json:"numInstances,omitempty"` - HypervisorID *string `json:"hypervisorId,omitempty"` - ServiceID *string `json:"serviceId,omitempty"` - Traits []string `json:"traits,omitempty"` - Aggregates []string `json:"aggregates,omitempty"` - InternalIP *string `json:"internalIp,omitempty"` - Evicted *bool `json:"evicted,omitempty"` - Conditions []metav1.ConditionApplyConfiguration `json:"conditions,omitempty"` - SpecHash *string `json:"specHash,omitempty"` + LibVirtVersion *string `json:"libVirtVersion,omitempty"` + OperatingSystem *OperatingSystemStatusApplyConfiguration `json:"operatingSystem,omitempty"` + Update *HyperVisorUpdateStatusApplyConfiguration `json:"updateStatus,omitempty"` + Instances []InstanceApplyConfiguration `json:"instances,omitempty"` + Capabilities *CapabilitiesApplyConfiguration `json:"capabilities,omitempty"` + DomainCapabilities *DomainCapabilitiesApplyConfiguration `json:"domainCapabilities,omitempty"` + DomainInfos []DomainInfoApplyConfiguration `json:"domainInfos,omitempty"` + NumInstances *int `json:"numInstances,omitempty"` + HypervisorID *string `json:"hypervisorId,omitempty"` + ServiceID *string `json:"serviceId,omitempty"` + Traits []string `json:"traits,omitempty"` + Aggregates []string `json:"aggregates,omitempty"` + InternalIP *string `json:"internalIp,omitempty"` + Evicted *bool `json:"evicted,omitempty"` + Conditions []metav1.ConditionApplyConfiguration `json:"conditions,omitempty"` + SpecHash *string `json:"specHash,omitempty"` } // HypervisorStatusApplyConfiguration constructs a declarative configuration of the HypervisorStatus type for use with @@ -71,11 +73,32 @@ func (b *HypervisorStatusApplyConfiguration) WithInstances(values ...*InstanceAp // WithCapabilities sets the Capabilities field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Capabilities field is set to the value of the last call. -func (b *HypervisorStatusApplyConfiguration) WithCapabilities(value *CapabilitiesStatusApplyConfiguration) *HypervisorStatusApplyConfiguration { +func (b *HypervisorStatusApplyConfiguration) WithCapabilities(value *CapabilitiesApplyConfiguration) *HypervisorStatusApplyConfiguration { b.Capabilities = value return b } +// WithDomainCapabilities sets the DomainCapabilities field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DomainCapabilities field is set to the value of the last call. +func (b *HypervisorStatusApplyConfiguration) WithDomainCapabilities(value *DomainCapabilitiesApplyConfiguration) *HypervisorStatusApplyConfiguration { + b.DomainCapabilities = value + return b +} + +// WithDomainInfos adds the given value to the DomainInfos field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the DomainInfos field. +func (b *HypervisorStatusApplyConfiguration) WithDomainInfos(values ...*DomainInfoApplyConfiguration) *HypervisorStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithDomainInfos") + } + b.DomainInfos = append(b.DomainInfos, *values[i]) + } + return b +} + // WithNumInstances sets the NumInstances field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the NumInstances field is set to the value of the last call. diff --git a/applyconfigurations/utils.go b/applyconfigurations/utils.go index 3ecf8f6..fcaf808 100644 --- a/applyconfigurations/utils.go +++ b/applyconfigurations/utils.go @@ -8,7 +8,7 @@ import ( internal "github.com/cobaltcore-dev/openstack-hypervisor-operator/applyconfigurations/internal" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" - managedfields "k8s.io/apimachinery/pkg/util/managedfields" + "k8s.io/apimachinery/pkg/util/managedfields" ) // ForKind returns an apply configuration type for the given GroupVersionKind, or nil if no @@ -16,8 +16,8 @@ import ( func ForKind(kind schema.GroupVersionKind) interface{} { switch kind { // Group=kvm.cloud.sap, Version=v1 - case v1.SchemeGroupVersion.WithKind("CapabilitiesStatus"): - return &apiv1.CapabilitiesStatusApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("Capabilities"): + return &apiv1.CapabilitiesApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("Eviction"): return &apiv1.EvictionApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("EvictionSpec"): diff --git a/charts/openstack-hypervisor-operator/crds/hypervisor-crd.yaml b/charts/openstack-hypervisor-operator/crds/hypervisor-crd.yaml index fe36d98..f8b5bf4 100644 --- a/charts/openstack-hypervisor-operator/crds/hypervisor-crd.yaml +++ b/charts/openstack-hypervisor-operator/crds/hypervisor-crd.yaml @@ -109,6 +109,15 @@ spec: items: type: string type: array + allowedProjects: + default: [] + description: |- + AllowedProjects defines which openstack projects are allowed to schedule + instances on this hypervisor. The values of this list should be project + uuids. If left empty, all projects are allowed. + items: + type: string + type: array createCertManagerCertificate: default: false description: |- @@ -166,6 +175,7 @@ spec: type: string required: - aggregates + - allowedProjects - createCertManagerCertificate - customTraits - evacuateOnReboot @@ -184,7 +194,7 @@ spec: type: string type: array capabilities: - description: The capabilities of the hypervisors as reported by libvirt. + description: Auto-discovered capabilities as reported by libvirt. properties: cpuArch: default: unknown @@ -198,6 +208,29 @@ spec: numa cells. pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true + hostTopology: + description: The host's cell topology (a.k.a. numa cells). + items: + description: Cell represents a single cell of the host's topology. + properties: + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + default: {} + description: The cell's capacity, such as the number of + cpus, memory, and hugepages. + type: object + id: + description: ID is the identifier of the cell. + type: integer + required: + - id + type: object + type: array memory: anyOf: - type: integer @@ -264,6 +297,113 @@ spec: - type type: object type: array + domainCapabilities: + description: |- + Auto-discovered domain capabilities relevant to check if a VM + can be scheduled on the hypervisor. + properties: + arch: + default: unknown + description: The available domain cpu architecture. + type: string + hypervisorType: + default: unknown + description: The supported type of virtualization for domains, + such as "ch". + type: string + supportedCpuModes: + default: [] + description: |- + Supported cpu modes for domains. + + The format of this list is cpu mode, and if specified, a specific + submode. For example, the take the following xml domain cpu definition: + + + + + + The corresponding entries in this list would be "host-passthrough" and + "host-passthrough/migratable". + items: + type: string + type: array + supportedDevices: + default: [] + description: |- + Supported devices for domains. + + The format of this list is the device type, and if specified, a specific + model. For example, the take the following xml domain device definition: + + + + The corresponding entries in this list would be "video" and "video/nvidia". + items: + type: string + type: array + supportedFeatures: + default: [] + description: |- + Supported features for domains, such as "sev" or "sgx". + + This is a flat list of supported features, meaning the following xml: + + + + + + + Would correspond to the entries "sev" and "sgx" in this list. + items: + type: string + type: array + type: object + domainInfos: + default: [] + description: Auto-discovered domain infos as reported by libvirt (dumpxml). + items: + description: Domain information as reported by libvirt. + properties: + allocation: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Resource allocation of the domain. + This can include memory, cpu, and other. + type: object + cpuCells: + description: |- + The cpu numa cells of the domain, derived from the numa information + of the cpu mode. + items: + type: integer + type: array + memoryCells: + description: The memory numa cells of the domain, derived from + the numa tune. + items: + type: integer + type: array + name: + description: Name is the name of the domain. + type: string + uuid: + description: UUID is the uuid of the domain. + type: string + required: + - name + - uuid + type: object + type: array evicted: description: Evicted indicates whether the hypervisor is evicted. (no instances left with active maintenance mode) diff --git a/config/crd/bases/kvm.cloud.sap_hypervisors.yaml b/config/crd/bases/kvm.cloud.sap_hypervisors.yaml index 311ba15..056cfcf 100644 --- a/config/crd/bases/kvm.cloud.sap_hypervisors.yaml +++ b/config/crd/bases/kvm.cloud.sap_hypervisors.yaml @@ -110,6 +110,15 @@ spec: items: type: string type: array + allowedProjects: + default: [] + description: |- + AllowedProjects defines which openstack projects are allowed to schedule + instances on this hypervisor. The values of this list should be project + uuids. If left empty, all projects are allowed. + items: + type: string + type: array createCertManagerCertificate: default: false description: |- @@ -167,6 +176,7 @@ spec: type: string required: - aggregates + - allowedProjects - createCertManagerCertificate - customTraits - evacuateOnReboot @@ -185,7 +195,7 @@ spec: type: string type: array capabilities: - description: The capabilities of the hypervisors as reported by libvirt. + description: Auto-discovered capabilities as reported by libvirt. properties: cpuArch: default: unknown @@ -199,6 +209,29 @@ spec: numa cells. pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true + hostTopology: + description: The host's cell topology (a.k.a. numa cells). + items: + description: Cell represents a single cell of the host's topology. + properties: + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + default: {} + description: The cell's capacity, such as the number of + cpus, memory, and hugepages. + type: object + id: + description: ID is the identifier of the cell. + type: integer + required: + - id + type: object + type: array memory: anyOf: - type: integer @@ -265,6 +298,113 @@ spec: - type type: object type: array + domainCapabilities: + description: |- + Auto-discovered domain capabilities relevant to check if a VM + can be scheduled on the hypervisor. + properties: + arch: + default: unknown + description: The available domain cpu architecture. + type: string + hypervisorType: + default: unknown + description: The supported type of virtualization for domains, + such as "ch". + type: string + supportedCpuModes: + default: [] + description: |- + Supported cpu modes for domains. + + The format of this list is cpu mode, and if specified, a specific + submode. For example, the take the following xml domain cpu definition: + + + + + + The corresponding entries in this list would be "host-passthrough" and + "host-passthrough/migratable". + items: + type: string + type: array + supportedDevices: + default: [] + description: |- + Supported devices for domains. + + The format of this list is the device type, and if specified, a specific + model. For example, the take the following xml domain device definition: + + + + The corresponding entries in this list would be "video" and "video/nvidia". + items: + type: string + type: array + supportedFeatures: + default: [] + description: |- + Supported features for domains, such as "sev" or "sgx". + + This is a flat list of supported features, meaning the following xml: + + + + + + + Would correspond to the entries "sev" and "sgx" in this list. + items: + type: string + type: array + type: object + domainInfos: + default: [] + description: Auto-discovered domain infos as reported by libvirt (dumpxml). + items: + description: Domain information as reported by libvirt. + properties: + allocation: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Resource allocation of the domain. + This can include memory, cpu, and other. + type: object + cpuCells: + description: |- + The cpu numa cells of the domain, derived from the numa information + of the cpu mode. + items: + type: integer + type: array + memoryCells: + description: The memory numa cells of the domain, derived from + the numa tune. + items: + type: integer + type: array + name: + description: Name is the name of the domain. + type: string + uuid: + description: UUID is the uuid of the domain. + type: string + required: + - name + - uuid + type: object + type: array evicted: description: Evicted indicates whether the hypervisor is evicted. (no instances left with active maintenance mode)