From cf7d7524534bd78c533ac32dfd760d8011bea249 Mon Sep 17 00:00:00 2001 From: Oguz Kilcan Date: Mon, 16 Mar 2026 10:01:42 +0100 Subject: [PATCH] feat: enforce configurable machine registration limit Add `account.maxRegisteredMachines` config option to cap the number of registered machines. The provision handler atomically checks the limit under a mutex before creating new Link resources, returning ResourceExhausted when the cap is reached. Introduce a Notification resource type (ephemeral namespace) so controllers can surface warnings to users. `omnictl` displays all active notifications on every command invocation. Frontend part of showing notifications will be implemented in a different PR. MachineStatusMetricsController creates a warning notification when the registration limit is reached and tears it down when it's not. Signed-off-by: Oguz Kilcan --- client/api/omni/specs/omni.pb.go | 841 ++++++++++-------- client/api/omni/specs/omni.proto | 16 + client/api/omni/specs/omni_vtproto.pb.go | 319 +++++++ .../pkg/omni/resources/omni/notification.go | 52 ++ client/pkg/omni/resources/omni/omni.go | 1 + client/pkg/omnictl/internal/access/client.go | 34 + cmd/omni/cmd/cmd.go | 1 + frontend/src/api/omni/specs/omni.pb.ts | 14 + frontend/src/api/resources.ts | 2 + hack/test/common.sh | 1 + hack/test/integration-qemu.sh | 3 + hack/test/templates/omni-config.yaml | 2 + .../omni/machine_status_metrics.go | 57 +- .../omni/machine_status_metrics_test.go | 104 +++ internal/backend/runtime/omni/omni.go | 2 +- internal/backend/runtime/omni/state_access.go | 2 + internal/backend/server.go | 19 +- internal/integration/auth_test.go | 5 + internal/pkg/config/accessors.generated.go | 11 + internal/pkg/config/schema.json | 8 + internal/pkg/config/types.generated.go | 4 + internal/pkg/siderolink/manager.go | 20 +- internal/pkg/siderolink/provision.go | 43 +- internal/pkg/siderolink/provision_test.go | 85 +- 24 files changed, 1261 insertions(+), 385 deletions(-) create mode 100644 client/pkg/omni/resources/omni/notification.go create mode 100644 internal/backend/runtime/omni/controllers/omni/machine_status_metrics_test.go diff --git a/client/api/omni/specs/omni.pb.go b/client/api/omni/specs/omni.pb.go index 18f1092d..e80152ea 100644 --- a/client/api/omni/specs/omni.pb.go +++ b/client/api/omni/specs/omni.pb.go @@ -1333,6 +1333,56 @@ func (SecretRotationSpec_Component) EnumDescriptor() ([]byte, []int) { return file_omni_specs_omni_proto_rawDescGZIP(), []int{97, 2} } +// Type describes the severity of a notification. +type NotificationSpec_Type int32 + +const ( + NotificationSpec_INFO NotificationSpec_Type = 0 + NotificationSpec_WARNING NotificationSpec_Type = 1 + NotificationSpec_ERROR NotificationSpec_Type = 2 +) + +// Enum value maps for NotificationSpec_Type. +var ( + NotificationSpec_Type_name = map[int32]string{ + 0: "INFO", + 1: "WARNING", + 2: "ERROR", + } + NotificationSpec_Type_value = map[string]int32{ + "INFO": 0, + "WARNING": 1, + "ERROR": 2, + } +) + +func (x NotificationSpec_Type) Enum() *NotificationSpec_Type { + p := new(NotificationSpec_Type) + *p = x + return p +} + +func (x NotificationSpec_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (NotificationSpec_Type) Descriptor() protoreflect.EnumDescriptor { + return file_omni_specs_omni_proto_enumTypes[25].Descriptor() +} + +func (NotificationSpec_Type) Type() protoreflect.EnumType { + return &file_omni_specs_omni_proto_enumTypes[25] +} + +func (x NotificationSpec_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use NotificationSpec_Type.Descriptor instead. +func (NotificationSpec_Type) EnumDescriptor() ([]byte, []int) { + return file_omni_specs_omni_proto_rawDescGZIP(), []int{102, 0} +} + // MachineSpec describes a Machine. type MachineSpec struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -6472,16 +6522,18 @@ func (x *MachineExtensionsStatusSpec) GetTalosVersion() string { // MachineStatusMetricsSpec provides aggregated state of the number of registered and connected machines for the Omni instance. type MachineStatusMetricsSpec struct { - state protoimpl.MessageState `protogen:"open.v1"` - RegisteredMachinesCount uint32 `protobuf:"varint,1,opt,name=registered_machines_count,json=registeredMachinesCount,proto3" json:"registered_machines_count,omitempty"` - ConnectedMachinesCount uint32 `protobuf:"varint,2,opt,name=connected_machines_count,json=connectedMachinesCount,proto3" json:"connected_machines_count,omitempty"` - AllocatedMachinesCount uint32 `protobuf:"varint,3,opt,name=allocated_machines_count,json=allocatedMachinesCount,proto3" json:"allocated_machines_count,omitempty"` - PendingMachinesCount uint32 `protobuf:"varint,4,opt,name=pending_machines_count,json=pendingMachinesCount,proto3" json:"pending_machines_count,omitempty"` - Platforms map[string]uint32 `protobuf:"bytes,6,rep,name=platforms,proto3" json:"platforms,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` - SecureBootStatus map[string]uint32 `protobuf:"bytes,7,rep,name=secure_boot_status,json=secureBootStatus,proto3" json:"secure_boot_status,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` - UkiStatus map[string]uint32 `protobuf:"bytes,8,rep,name=uki_status,json=ukiStatus,proto3" json:"uki_status,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + RegisteredMachinesCount uint32 `protobuf:"varint,1,opt,name=registered_machines_count,json=registeredMachinesCount,proto3" json:"registered_machines_count,omitempty"` + ConnectedMachinesCount uint32 `protobuf:"varint,2,opt,name=connected_machines_count,json=connectedMachinesCount,proto3" json:"connected_machines_count,omitempty"` + AllocatedMachinesCount uint32 `protobuf:"varint,3,opt,name=allocated_machines_count,json=allocatedMachinesCount,proto3" json:"allocated_machines_count,omitempty"` + PendingMachinesCount uint32 `protobuf:"varint,4,opt,name=pending_machines_count,json=pendingMachinesCount,proto3" json:"pending_machines_count,omitempty"` + Platforms map[string]uint32 `protobuf:"bytes,6,rep,name=platforms,proto3" json:"platforms,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` + SecureBootStatus map[string]uint32 `protobuf:"bytes,7,rep,name=secure_boot_status,json=secureBootStatus,proto3" json:"secure_boot_status,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` + UkiStatus map[string]uint32 `protobuf:"bytes,8,rep,name=uki_status,json=ukiStatus,proto3" json:"uki_status,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` + RegisteredMachinesLimit uint32 `protobuf:"varint,9,opt,name=registered_machines_limit,json=registeredMachinesLimit,proto3" json:"registered_machines_limit,omitempty"` + RegistrationLimitReached bool `protobuf:"varint,10,opt,name=registration_limit_reached,json=registrationLimitReached,proto3" json:"registration_limit_reached,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *MachineStatusMetricsSpec) Reset() { @@ -6563,6 +6615,20 @@ func (x *MachineStatusMetricsSpec) GetUkiStatus() map[string]uint32 { return nil } +func (x *MachineStatusMetricsSpec) GetRegisteredMachinesLimit() uint32 { + if x != nil { + return x.RegisteredMachinesLimit + } + return 0 +} + +func (x *MachineStatusMetricsSpec) GetRegistrationLimitReached() bool { + if x != nil { + return x.RegistrationLimitReached + } + return false +} + // ClusterMetricsSpec contains metrics about the clusters in the Omni instance. type ClusterMetricsSpec struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -7913,6 +7979,67 @@ func (x *UpgradeRolloutSpec) GetMachineSetsUpgradeQuota() map[string]int32 { return nil } +// NotificationSpec describes a generic notification emitted by a controller. +type NotificationSpec struct { + state protoimpl.MessageState `protogen:"open.v1"` + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + Body string `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"` + Type NotificationSpec_Type `protobuf:"varint,3,opt,name=type,proto3,enum=specs.NotificationSpec_Type" json:"type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NotificationSpec) Reset() { + *x = NotificationSpec{} + mi := &file_omni_specs_omni_proto_msgTypes[102] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NotificationSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NotificationSpec) ProtoMessage() {} + +func (x *NotificationSpec) ProtoReflect() protoreflect.Message { + mi := &file_omni_specs_omni_proto_msgTypes[102] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NotificationSpec.ProtoReflect.Descriptor instead. +func (*NotificationSpec) Descriptor() ([]byte, []int) { + return file_omni_specs_omni_proto_rawDescGZIP(), []int{102} +} + +func (x *NotificationSpec) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *NotificationSpec) GetBody() string { + if x != nil { + return x.Body + } + return "" +} + +func (x *NotificationSpec) GetType() NotificationSpec_Type { + if x != nil { + return x.Type + } + return NotificationSpec_INFO +} + // HardwareStatus describes machine hardware status. type MachineStatusSpec_HardwareStatus struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -7930,7 +8057,7 @@ type MachineStatusSpec_HardwareStatus struct { func (x *MachineStatusSpec_HardwareStatus) Reset() { *x = MachineStatusSpec_HardwareStatus{} - mi := &file_omni_specs_omni_proto_msgTypes[102] + mi := &file_omni_specs_omni_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7942,7 +8069,7 @@ func (x *MachineStatusSpec_HardwareStatus) String() string { func (*MachineStatusSpec_HardwareStatus) ProtoMessage() {} func (x *MachineStatusSpec_HardwareStatus) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[102] + mi := &file_omni_specs_omni_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8005,7 +8132,7 @@ type MachineStatusSpec_NetworkStatus struct { func (x *MachineStatusSpec_NetworkStatus) Reset() { *x = MachineStatusSpec_NetworkStatus{} - mi := &file_omni_specs_omni_proto_msgTypes[103] + mi := &file_omni_specs_omni_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8017,7 +8144,7 @@ func (x *MachineStatusSpec_NetworkStatus) String() string { func (*MachineStatusSpec_NetworkStatus) ProtoMessage() {} func (x *MachineStatusSpec_NetworkStatus) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[103] + mi := &file_omni_specs_omni_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8093,7 +8220,7 @@ type MachineStatusSpec_PlatformMetadata struct { func (x *MachineStatusSpec_PlatformMetadata) Reset() { *x = MachineStatusSpec_PlatformMetadata{} - mi := &file_omni_specs_omni_proto_msgTypes[104] + mi := &file_omni_specs_omni_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8105,7 +8232,7 @@ func (x *MachineStatusSpec_PlatformMetadata) String() string { func (*MachineStatusSpec_PlatformMetadata) ProtoMessage() {} func (x *MachineStatusSpec_PlatformMetadata) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[104] + mi := &file_omni_specs_omni_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8214,7 +8341,7 @@ type MachineStatusSpec_Schematic struct { func (x *MachineStatusSpec_Schematic) Reset() { *x = MachineStatusSpec_Schematic{} - mi := &file_omni_specs_omni_proto_msgTypes[105] + mi := &file_omni_specs_omni_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8226,7 +8353,7 @@ func (x *MachineStatusSpec_Schematic) String() string { func (*MachineStatusSpec_Schematic) ProtoMessage() {} func (x *MachineStatusSpec_Schematic) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[105] + mi := &file_omni_specs_omni_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8330,7 +8457,7 @@ type MachineStatusSpec_Diagnostic struct { func (x *MachineStatusSpec_Diagnostic) Reset() { *x = MachineStatusSpec_Diagnostic{} - mi := &file_omni_specs_omni_proto_msgTypes[106] + mi := &file_omni_specs_omni_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8342,7 +8469,7 @@ func (x *MachineStatusSpec_Diagnostic) String() string { func (*MachineStatusSpec_Diagnostic) ProtoMessage() {} func (x *MachineStatusSpec_Diagnostic) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[106] + mi := &file_omni_specs_omni_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8398,7 +8525,7 @@ type MachineStatusSpec_HardwareStatus_Processor struct { func (x *MachineStatusSpec_HardwareStatus_Processor) Reset() { *x = MachineStatusSpec_HardwareStatus_Processor{} - mi := &file_omni_specs_omni_proto_msgTypes[108] + mi := &file_omni_specs_omni_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8410,7 +8537,7 @@ func (x *MachineStatusSpec_HardwareStatus_Processor) String() string { func (*MachineStatusSpec_HardwareStatus_Processor) ProtoMessage() {} func (x *MachineStatusSpec_HardwareStatus_Processor) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[108] + mi := &file_omni_specs_omni_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8474,7 +8601,7 @@ type MachineStatusSpec_HardwareStatus_MemoryModule struct { func (x *MachineStatusSpec_HardwareStatus_MemoryModule) Reset() { *x = MachineStatusSpec_HardwareStatus_MemoryModule{} - mi := &file_omni_specs_omni_proto_msgTypes[109] + mi := &file_omni_specs_omni_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8486,7 +8613,7 @@ func (x *MachineStatusSpec_HardwareStatus_MemoryModule) String() string { func (*MachineStatusSpec_HardwareStatus_MemoryModule) ProtoMessage() {} func (x *MachineStatusSpec_HardwareStatus_MemoryModule) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[109] + mi := &file_omni_specs_omni_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8549,7 +8676,7 @@ type MachineStatusSpec_HardwareStatus_BlockDevice struct { func (x *MachineStatusSpec_HardwareStatus_BlockDevice) Reset() { *x = MachineStatusSpec_HardwareStatus_BlockDevice{} - mi := &file_omni_specs_omni_proto_msgTypes[110] + mi := &file_omni_specs_omni_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8561,7 +8688,7 @@ func (x *MachineStatusSpec_HardwareStatus_BlockDevice) String() string { func (*MachineStatusSpec_HardwareStatus_BlockDevice) ProtoMessage() {} func (x *MachineStatusSpec_HardwareStatus_BlockDevice) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[110] + mi := &file_omni_specs_omni_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8680,7 +8807,7 @@ type MachineStatusSpec_NetworkStatus_NetworkLinkStatus struct { func (x *MachineStatusSpec_NetworkStatus_NetworkLinkStatus) Reset() { *x = MachineStatusSpec_NetworkStatus_NetworkLinkStatus{} - mi := &file_omni_specs_omni_proto_msgTypes[111] + mi := &file_omni_specs_omni_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8692,7 +8819,7 @@ func (x *MachineStatusSpec_NetworkStatus_NetworkLinkStatus) String() string { func (*MachineStatusSpec_NetworkStatus_NetworkLinkStatus) ProtoMessage() {} func (x *MachineStatusSpec_NetworkStatus_NetworkLinkStatus) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[111] + mi := &file_omni_specs_omni_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8752,7 +8879,7 @@ type MachineStatusSpec_Schematic_InitialState struct { func (x *MachineStatusSpec_Schematic_InitialState) Reset() { *x = MachineStatusSpec_Schematic_InitialState{} - mi := &file_omni_specs_omni_proto_msgTypes[112] + mi := &file_omni_specs_omni_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8764,7 +8891,7 @@ func (x *MachineStatusSpec_Schematic_InitialState) String() string { func (*MachineStatusSpec_Schematic_InitialState) ProtoMessage() {} func (x *MachineStatusSpec_Schematic_InitialState) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[112] + mi := &file_omni_specs_omni_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8801,7 +8928,7 @@ type ClusterSpec_Features struct { func (x *ClusterSpec_Features) Reset() { *x = ClusterSpec_Features{} - mi := &file_omni_specs_omni_proto_msgTypes[113] + mi := &file_omni_specs_omni_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8813,7 +8940,7 @@ func (x *ClusterSpec_Features) String() string { func (*ClusterSpec_Features) ProtoMessage() {} func (x *ClusterSpec_Features) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[113] + mi := &file_omni_specs_omni_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8860,7 +8987,7 @@ type ClusterMachineStatusSpec_ProvisionStatus struct { func (x *ClusterMachineStatusSpec_ProvisionStatus) Reset() { *x = ClusterMachineStatusSpec_ProvisionStatus{} - mi := &file_omni_specs_omni_proto_msgTypes[114] + mi := &file_omni_specs_omni_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8872,7 +8999,7 @@ func (x *ClusterMachineStatusSpec_ProvisionStatus) String() string { func (*ClusterMachineStatusSpec_ProvisionStatus) ProtoMessage() {} func (x *ClusterMachineStatusSpec_ProvisionStatus) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[114] + mi := &file_omni_specs_omni_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8914,7 +9041,7 @@ type MachinePendingUpdatesSpec_Upgrade struct { func (x *MachinePendingUpdatesSpec_Upgrade) Reset() { *x = MachinePendingUpdatesSpec_Upgrade{} - mi := &file_omni_specs_omni_proto_msgTypes[115] + mi := &file_omni_specs_omni_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8926,7 +9053,7 @@ func (x *MachinePendingUpdatesSpec_Upgrade) String() string { func (*MachinePendingUpdatesSpec_Upgrade) ProtoMessage() {} func (x *MachinePendingUpdatesSpec_Upgrade) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[115] + mi := &file_omni_specs_omni_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8982,7 +9109,7 @@ type ClusterSecretsSpec_Certs struct { func (x *ClusterSecretsSpec_Certs) Reset() { *x = ClusterSecretsSpec_Certs{} - mi := &file_omni_specs_omni_proto_msgTypes[116] + mi := &file_omni_specs_omni_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8994,7 +9121,7 @@ func (x *ClusterSecretsSpec_Certs) String() string { func (*ClusterSecretsSpec_Certs) ProtoMessage() {} func (x *ClusterSecretsSpec_Certs) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[116] + mi := &file_omni_specs_omni_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9034,7 +9161,7 @@ type ClusterSecretsSpec_Certs_CA struct { func (x *ClusterSecretsSpec_Certs_CA) Reset() { *x = ClusterSecretsSpec_Certs_CA{} - mi := &file_omni_specs_omni_proto_msgTypes[117] + mi := &file_omni_specs_omni_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9046,7 +9173,7 @@ func (x *ClusterSecretsSpec_Certs_CA) String() string { func (*ClusterSecretsSpec_Certs_CA) ProtoMessage() {} func (x *ClusterSecretsSpec_Certs_CA) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[117] + mi := &file_omni_specs_omni_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9091,7 +9218,7 @@ type MachineSetSpec_MachineClass struct { func (x *MachineSetSpec_MachineClass) Reset() { *x = MachineSetSpec_MachineClass{} - mi := &file_omni_specs_omni_proto_msgTypes[118] + mi := &file_omni_specs_omni_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9103,7 +9230,7 @@ func (x *MachineSetSpec_MachineClass) String() string { func (*MachineSetSpec_MachineClass) ProtoMessage() {} func (x *MachineSetSpec_MachineClass) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[118] + mi := &file_omni_specs_omni_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9155,7 +9282,7 @@ type MachineSetSpec_MachineAllocation struct { func (x *MachineSetSpec_MachineAllocation) Reset() { *x = MachineSetSpec_MachineAllocation{} - mi := &file_omni_specs_omni_proto_msgTypes[119] + mi := &file_omni_specs_omni_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9167,7 +9294,7 @@ func (x *MachineSetSpec_MachineAllocation) String() string { func (*MachineSetSpec_MachineAllocation) ProtoMessage() {} func (x *MachineSetSpec_MachineAllocation) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[119] + mi := &file_omni_specs_omni_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9218,7 +9345,7 @@ type MachineSetSpec_BootstrapSpec struct { func (x *MachineSetSpec_BootstrapSpec) Reset() { *x = MachineSetSpec_BootstrapSpec{} - mi := &file_omni_specs_omni_proto_msgTypes[120] + mi := &file_omni_specs_omni_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9230,7 +9357,7 @@ func (x *MachineSetSpec_BootstrapSpec) String() string { func (*MachineSetSpec_BootstrapSpec) ProtoMessage() {} func (x *MachineSetSpec_BootstrapSpec) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[120] + mi := &file_omni_specs_omni_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9272,7 +9399,7 @@ type MachineSetSpec_RollingUpdateStrategyConfig struct { func (x *MachineSetSpec_RollingUpdateStrategyConfig) Reset() { *x = MachineSetSpec_RollingUpdateStrategyConfig{} - mi := &file_omni_specs_omni_proto_msgTypes[121] + mi := &file_omni_specs_omni_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9284,7 +9411,7 @@ func (x *MachineSetSpec_RollingUpdateStrategyConfig) String() string { func (*MachineSetSpec_RollingUpdateStrategyConfig) ProtoMessage() {} func (x *MachineSetSpec_RollingUpdateStrategyConfig) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[121] + mi := &file_omni_specs_omni_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9319,7 +9446,7 @@ type MachineSetSpec_UpdateStrategyConfig struct { func (x *MachineSetSpec_UpdateStrategyConfig) Reset() { *x = MachineSetSpec_UpdateStrategyConfig{} - mi := &file_omni_specs_omni_proto_msgTypes[122] + mi := &file_omni_specs_omni_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9331,7 +9458,7 @@ func (x *MachineSetSpec_UpdateStrategyConfig) String() string { func (*MachineSetSpec_UpdateStrategyConfig) ProtoMessage() {} func (x *MachineSetSpec_UpdateStrategyConfig) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[122] + mi := &file_omni_specs_omni_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9366,7 +9493,7 @@ type ControlPlaneStatusSpec_Condition struct { func (x *ControlPlaneStatusSpec_Condition) Reset() { *x = ControlPlaneStatusSpec_Condition{} - mi := &file_omni_specs_omni_proto_msgTypes[123] + mi := &file_omni_specs_omni_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9378,7 +9505,7 @@ func (x *ControlPlaneStatusSpec_Condition) String() string { func (*ControlPlaneStatusSpec_Condition) ProtoMessage() {} func (x *ControlPlaneStatusSpec_Condition) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[123] + mi := &file_omni_specs_omni_proto_msgTypes[124] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9433,7 +9560,7 @@ type KubernetesStatusSpec_NodeStatus struct { func (x *KubernetesStatusSpec_NodeStatus) Reset() { *x = KubernetesStatusSpec_NodeStatus{} - mi := &file_omni_specs_omni_proto_msgTypes[124] + mi := &file_omni_specs_omni_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9445,7 +9572,7 @@ func (x *KubernetesStatusSpec_NodeStatus) String() string { func (*KubernetesStatusSpec_NodeStatus) ProtoMessage() {} func (x *KubernetesStatusSpec_NodeStatus) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[124] + mi := &file_omni_specs_omni_proto_msgTypes[125] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9493,7 +9620,7 @@ type KubernetesStatusSpec_StaticPodStatus struct { func (x *KubernetesStatusSpec_StaticPodStatus) Reset() { *x = KubernetesStatusSpec_StaticPodStatus{} - mi := &file_omni_specs_omni_proto_msgTypes[125] + mi := &file_omni_specs_omni_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9505,7 +9632,7 @@ func (x *KubernetesStatusSpec_StaticPodStatus) String() string { func (*KubernetesStatusSpec_StaticPodStatus) ProtoMessage() {} func (x *KubernetesStatusSpec_StaticPodStatus) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[125] + mi := &file_omni_specs_omni_proto_msgTypes[126] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9552,7 +9679,7 @@ type KubernetesStatusSpec_NodeStaticPods struct { func (x *KubernetesStatusSpec_NodeStaticPods) Reset() { *x = KubernetesStatusSpec_NodeStaticPods{} - mi := &file_omni_specs_omni_proto_msgTypes[126] + mi := &file_omni_specs_omni_proto_msgTypes[127] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9564,7 +9691,7 @@ func (x *KubernetesStatusSpec_NodeStaticPods) String() string { func (*KubernetesStatusSpec_NodeStaticPods) ProtoMessage() {} func (x *KubernetesStatusSpec_NodeStaticPods) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[126] + mi := &file_omni_specs_omni_proto_msgTypes[127] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9608,7 +9735,7 @@ type MachineClassSpec_Provision struct { func (x *MachineClassSpec_Provision) Reset() { *x = MachineClassSpec_Provision{} - mi := &file_omni_specs_omni_proto_msgTypes[127] + mi := &file_omni_specs_omni_proto_msgTypes[128] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9620,7 +9747,7 @@ func (x *MachineClassSpec_Provision) String() string { func (*MachineClassSpec_Provision) ProtoMessage() {} func (x *MachineClassSpec_Provision) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[127] + mi := &file_omni_specs_omni_proto_msgTypes[128] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9691,7 +9818,7 @@ type MachineConfigGenOptionsSpec_InstallImage struct { func (x *MachineConfigGenOptionsSpec_InstallImage) Reset() { *x = MachineConfigGenOptionsSpec_InstallImage{} - mi := &file_omni_specs_omni_proto_msgTypes[128] + mi := &file_omni_specs_omni_proto_msgTypes[129] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9703,7 +9830,7 @@ func (x *MachineConfigGenOptionsSpec_InstallImage) String() string { func (*MachineConfigGenOptionsSpec_InstallImage) ProtoMessage() {} func (x *MachineConfigGenOptionsSpec_InstallImage) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[128] + mi := &file_omni_specs_omni_proto_msgTypes[129] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9772,7 +9899,7 @@ type KubernetesUsageSpec_Quantity struct { func (x *KubernetesUsageSpec_Quantity) Reset() { *x = KubernetesUsageSpec_Quantity{} - mi := &file_omni_specs_omni_proto_msgTypes[129] + mi := &file_omni_specs_omni_proto_msgTypes[130] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9784,7 +9911,7 @@ func (x *KubernetesUsageSpec_Quantity) String() string { func (*KubernetesUsageSpec_Quantity) ProtoMessage() {} func (x *KubernetesUsageSpec_Quantity) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[129] + mi := &file_omni_specs_omni_proto_msgTypes[130] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9831,7 +9958,7 @@ type KubernetesUsageSpec_Pod struct { func (x *KubernetesUsageSpec_Pod) Reset() { *x = KubernetesUsageSpec_Pod{} - mi := &file_omni_specs_omni_proto_msgTypes[130] + mi := &file_omni_specs_omni_proto_msgTypes[131] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9843,7 +9970,7 @@ func (x *KubernetesUsageSpec_Pod) String() string { func (*KubernetesUsageSpec_Pod) ProtoMessage() {} func (x *KubernetesUsageSpec_Pod) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[130] + mi := &file_omni_specs_omni_proto_msgTypes[131] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9883,7 +10010,7 @@ type ImagePullRequestSpec_NodeImageList struct { func (x *ImagePullRequestSpec_NodeImageList) Reset() { *x = ImagePullRequestSpec_NodeImageList{} - mi := &file_omni_specs_omni_proto_msgTypes[131] + mi := &file_omni_specs_omni_proto_msgTypes[132] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9895,7 +10022,7 @@ func (x *ImagePullRequestSpec_NodeImageList) String() string { func (*ImagePullRequestSpec_NodeImageList) ProtoMessage() {} func (x *ImagePullRequestSpec_NodeImageList) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[131] + mi := &file_omni_specs_omni_proto_msgTypes[132] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9940,7 +10067,7 @@ type TalosExtensionsSpec_Info struct { func (x *TalosExtensionsSpec_Info) Reset() { *x = TalosExtensionsSpec_Info{} - mi := &file_omni_specs_omni_proto_msgTypes[132] + mi := &file_omni_specs_omni_proto_msgTypes[133] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9952,7 +10079,7 @@ func (x *TalosExtensionsSpec_Info) String() string { func (*TalosExtensionsSpec_Info) ProtoMessage() {} func (x *TalosExtensionsSpec_Info) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[132] + mi := &file_omni_specs_omni_proto_msgTypes[133] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10021,7 +10148,7 @@ type MachineExtensionsStatusSpec_Item struct { func (x *MachineExtensionsStatusSpec_Item) Reset() { *x = MachineExtensionsStatusSpec_Item{} - mi := &file_omni_specs_omni_proto_msgTypes[133] + mi := &file_omni_specs_omni_proto_msgTypes[134] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10033,7 +10160,7 @@ func (x *MachineExtensionsStatusSpec_Item) String() string { func (*MachineExtensionsStatusSpec_Item) ProtoMessage() {} func (x *MachineExtensionsStatusSpec_Item) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[133] + mi := &file_omni_specs_omni_proto_msgTypes[134] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10080,7 +10207,7 @@ type ClusterDiagnosticsSpec_Node struct { func (x *ClusterDiagnosticsSpec_Node) Reset() { *x = ClusterDiagnosticsSpec_Node{} - mi := &file_omni_specs_omni_proto_msgTypes[139] + mi := &file_omni_specs_omni_proto_msgTypes[140] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10092,7 +10219,7 @@ func (x *ClusterDiagnosticsSpec_Node) String() string { func (*ClusterDiagnosticsSpec_Node) ProtoMessage() {} func (x *ClusterDiagnosticsSpec_Node) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[139] + mi := &file_omni_specs_omni_proto_msgTypes[140] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10134,7 +10261,7 @@ type InfraMachineBMCConfigSpec_IPMI struct { func (x *InfraMachineBMCConfigSpec_IPMI) Reset() { *x = InfraMachineBMCConfigSpec_IPMI{} - mi := &file_omni_specs_omni_proto_msgTypes[140] + mi := &file_omni_specs_omni_proto_msgTypes[141] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10146,7 +10273,7 @@ func (x *InfraMachineBMCConfigSpec_IPMI) String() string { func (*InfraMachineBMCConfigSpec_IPMI) ProtoMessage() {} func (x *InfraMachineBMCConfigSpec_IPMI) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[140] + mi := &file_omni_specs_omni_proto_msgTypes[141] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10199,7 +10326,7 @@ type InfraMachineBMCConfigSpec_API struct { func (x *InfraMachineBMCConfigSpec_API) Reset() { *x = InfraMachineBMCConfigSpec_API{} - mi := &file_omni_specs_omni_proto_msgTypes[141] + mi := &file_omni_specs_omni_proto_msgTypes[142] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10211,7 +10338,7 @@ func (x *InfraMachineBMCConfigSpec_API) String() string { func (*InfraMachineBMCConfigSpec_API) ProtoMessage() {} func (x *InfraMachineBMCConfigSpec_API) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[141] + mi := &file_omni_specs_omni_proto_msgTypes[142] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10245,7 +10372,7 @@ type InfraProviderCombinedStatusSpec_Health struct { func (x *InfraProviderCombinedStatusSpec_Health) Reset() { *x = InfraProviderCombinedStatusSpec_Health{} - mi := &file_omni_specs_omni_proto_msgTypes[142] + mi := &file_omni_specs_omni_proto_msgTypes[143] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10257,7 +10384,7 @@ func (x *InfraProviderCombinedStatusSpec_Health) String() string { func (*InfraProviderCombinedStatusSpec_Health) ProtoMessage() {} func (x *InfraProviderCombinedStatusSpec_Health) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[142] + mi := &file_omni_specs_omni_proto_msgTypes[143] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10303,7 +10430,7 @@ type InstallationMediaConfigSpec_Cloud struct { func (x *InstallationMediaConfigSpec_Cloud) Reset() { *x = InstallationMediaConfigSpec_Cloud{} - mi := &file_omni_specs_omni_proto_msgTypes[143] + mi := &file_omni_specs_omni_proto_msgTypes[144] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10315,7 +10442,7 @@ func (x *InstallationMediaConfigSpec_Cloud) String() string { func (*InstallationMediaConfigSpec_Cloud) ProtoMessage() {} func (x *InstallationMediaConfigSpec_Cloud) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[143] + mi := &file_omni_specs_omni_proto_msgTypes[144] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10348,7 +10475,7 @@ type InstallationMediaConfigSpec_SBC struct { func (x *InstallationMediaConfigSpec_SBC) Reset() { *x = InstallationMediaConfigSpec_SBC{} - mi := &file_omni_specs_omni_proto_msgTypes[144] + mi := &file_omni_specs_omni_proto_msgTypes[145] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10360,7 +10487,7 @@ func (x *InstallationMediaConfigSpec_SBC) String() string { func (*InstallationMediaConfigSpec_SBC) ProtoMessage() {} func (x *InstallationMediaConfigSpec_SBC) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[144] + mi := &file_omni_specs_omni_proto_msgTypes[145] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10408,7 +10535,7 @@ type ClusterMachineSecretsSpec_Rotation struct { func (x *ClusterMachineSecretsSpec_Rotation) Reset() { *x = ClusterMachineSecretsSpec_Rotation{} - mi := &file_omni_specs_omni_proto_msgTypes[146] + mi := &file_omni_specs_omni_proto_msgTypes[147] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10420,7 +10547,7 @@ func (x *ClusterMachineSecretsSpec_Rotation) String() string { func (*ClusterMachineSecretsSpec_Rotation) ProtoMessage() {} func (x *ClusterMachineSecretsSpec_Rotation) ProtoReflect() protoreflect.Message { - mi := &file_omni_specs_omni_proto_msgTypes[146] + mi := &file_omni_specs_omni_proto_msgTypes[147] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11107,7 +11234,7 @@ const file_omni_specs_omni_proto_rawDesc = "" + "\tInstalled\x10\x00\x12\x0e\n" + "\n" + "Installing\x10\x01\x12\f\n" + - "\bRemoving\x10\x02\"\xc9\x05\n" + + "\bRemoving\x10\x02\"\xc3\x06\n" + "\x18MachineStatusMetricsSpec\x12:\n" + "\x19registered_machines_count\x18\x01 \x01(\rR\x17registeredMachinesCount\x128\n" + "\x18connected_machines_count\x18\x02 \x01(\rR\x16connectedMachinesCount\x128\n" + @@ -11116,7 +11243,10 @@ const file_omni_specs_omni_proto_rawDesc = "" + "\tplatforms\x18\x06 \x03(\v2..specs.MachineStatusMetricsSpec.PlatformsEntryR\tplatforms\x12c\n" + "\x12secure_boot_status\x18\a \x03(\v25.specs.MachineStatusMetricsSpec.SecureBootStatusEntryR\x10secureBootStatus\x12M\n" + "\n" + - "uki_status\x18\b \x03(\v2..specs.MachineStatusMetricsSpec.UkiStatusEntryR\tukiStatus\x1a<\n" + + "uki_status\x18\b \x03(\v2..specs.MachineStatusMetricsSpec.UkiStatusEntryR\tukiStatus\x12:\n" + + "\x19registered_machines_limit\x18\t \x01(\rR\x17registeredMachinesLimit\x12<\n" + + "\x1aregistration_limit_reached\x18\n" + + " \x01(\bR\x18registrationLimitReached\x1a<\n" + "\x0ePlatformsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\rR\x05value:\x028\x01\x1aC\n" + @@ -11293,7 +11423,15 @@ const file_omni_specs_omni_proto_rawDesc = "" + "\x1amachine_sets_upgrade_quota\x18\x01 \x03(\v26.specs.UpgradeRolloutSpec.MachineSetsUpgradeQuotaEntryR\x17machineSetsUpgradeQuota\x1aJ\n" + "\x1cMachineSetsUpgradeQuotaEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\x05R\x05value:\x028\x01*F\n" + + "\x05value\x18\x02 \x01(\x05R\x05value:\x028\x01\"\x98\x01\n" + + "\x10NotificationSpec\x12\x14\n" + + "\x05title\x18\x01 \x01(\tR\x05title\x12\x12\n" + + "\x04body\x18\x02 \x01(\tR\x04body\x120\n" + + "\x04type\x18\x03 \x01(\x0e2\x1c.specs.NotificationSpec.TypeR\x04type\"(\n" + + "\x04Type\x12\b\n" + + "\x04INFO\x10\x00\x12\v\n" + + "\aWARNING\x10\x01\x12\t\n" + + "\x05ERROR\x10\x02*F\n" + "\x11ConfigApplyStatus\x12\v\n" + "\aUNKNOWN\x10\x00\x12\v\n" + "\aPENDING\x10\x01\x12\v\n" + @@ -11332,8 +11470,8 @@ func file_omni_specs_omni_proto_rawDescGZIP() []byte { return file_omni_specs_omni_proto_rawDescData } -var file_omni_specs_omni_proto_enumTypes = make([]protoimpl.EnumInfo, 25) -var file_omni_specs_omni_proto_msgTypes = make([]protoimpl.MessageInfo, 148) +var file_omni_specs_omni_proto_enumTypes = make([]protoimpl.EnumInfo, 26) +var file_omni_specs_omni_proto_msgTypes = make([]protoimpl.MessageInfo, 149) var file_omni_specs_omni_proto_goTypes = []any{ (ConfigApplyStatus)(0), // 0: specs.ConfigApplyStatus (MachineSetPhase)(0), // 1: specs.MachineSetPhase @@ -11360,290 +11498,293 @@ var file_omni_specs_omni_proto_goTypes = []any{ (SecretRotationSpec_Status)(0), // 22: specs.SecretRotationSpec.Status (SecretRotationSpec_Phase)(0), // 23: specs.SecretRotationSpec.Phase (SecretRotationSpec_Component)(0), // 24: specs.SecretRotationSpec.Component - (*MachineSpec)(nil), // 25: specs.MachineSpec - (*SecurityState)(nil), // 26: specs.SecurityState - (*Overlay)(nil), // 27: specs.Overlay - (*MetaValue)(nil), // 28: specs.MetaValue - (*MachineStatusSpec)(nil), // 29: specs.MachineStatusSpec - (*TalosConfigSpec)(nil), // 30: specs.TalosConfigSpec - (*ClusterSpec)(nil), // 31: specs.ClusterSpec - (*ClusterTaintSpec)(nil), // 32: specs.ClusterTaintSpec - (*EtcdBackupConf)(nil), // 33: specs.EtcdBackupConf - (*EtcdBackupEncryptionSpec)(nil), // 34: specs.EtcdBackupEncryptionSpec - (*EtcdBackupHeader)(nil), // 35: specs.EtcdBackupHeader - (*EtcdBackupSpec)(nil), // 36: specs.EtcdBackupSpec - (*BackupDataSpec)(nil), // 37: specs.BackupDataSpec - (*EtcdBackupS3ConfSpec)(nil), // 38: specs.EtcdBackupS3ConfSpec - (*EtcdBackupStatusSpec)(nil), // 39: specs.EtcdBackupStatusSpec - (*EtcdManualBackupSpec)(nil), // 40: specs.EtcdManualBackupSpec - (*EtcdBackupStoreStatusSpec)(nil), // 41: specs.EtcdBackupStoreStatusSpec - (*EtcdBackupOverallStatusSpec)(nil), // 42: specs.EtcdBackupOverallStatusSpec - (*ClusterMachineSpec)(nil), // 43: specs.ClusterMachineSpec - (*ClusterMachineConfigPatchesSpec)(nil), // 44: specs.ClusterMachineConfigPatchesSpec - (*ClusterMachineTalosVersionSpec)(nil), // 45: specs.ClusterMachineTalosVersionSpec - (*ClusterMachineConfigSpec)(nil), // 46: specs.ClusterMachineConfigSpec - (*RedactedClusterMachineConfigSpec)(nil), // 47: specs.RedactedClusterMachineConfigSpec - (*ClusterMachineIdentitySpec)(nil), // 48: specs.ClusterMachineIdentitySpec - (*ClusterMachineStatusSpec)(nil), // 49: specs.ClusterMachineStatusSpec - (*Machines)(nil), // 50: specs.Machines - (*ClusterStatusSpec)(nil), // 51: specs.ClusterStatusSpec - (*ClusterUUID)(nil), // 52: specs.ClusterUUID - (*ClusterConfigVersionSpec)(nil), // 53: specs.ClusterConfigVersionSpec - (*ClusterMachineConfigStatusSpec)(nil), // 54: specs.ClusterMachineConfigStatusSpec - (*MachinePendingUpdatesSpec)(nil), // 55: specs.MachinePendingUpdatesSpec - (*ClusterBootstrapStatusSpec)(nil), // 56: specs.ClusterBootstrapStatusSpec - (*ClusterSecretsSpec)(nil), // 57: specs.ClusterSecretsSpec - (*ImportedClusterSecretsSpec)(nil), // 58: specs.ImportedClusterSecretsSpec - (*LoadBalancerConfigSpec)(nil), // 59: specs.LoadBalancerConfigSpec - (*LoadBalancerStatusSpec)(nil), // 60: specs.LoadBalancerStatusSpec - (*KubernetesVersionSpec)(nil), // 61: specs.KubernetesVersionSpec - (*TalosVersionSpec)(nil), // 62: specs.TalosVersionSpec - (*InstallationMediaSpec)(nil), // 63: specs.InstallationMediaSpec - (*ConfigPatchSpec)(nil), // 64: specs.ConfigPatchSpec - (*MachineSetSpec)(nil), // 65: specs.MachineSetSpec - (*TalosUpgradeStatusSpec)(nil), // 66: specs.TalosUpgradeStatusSpec - (*MachineSetStatusSpec)(nil), // 67: specs.MachineSetStatusSpec - (*MachineSetConfigStatusSpec)(nil), // 68: specs.MachineSetConfigStatusSpec - (*MachineSetNodeSpec)(nil), // 69: specs.MachineSetNodeSpec - (*MachineLabelsSpec)(nil), // 70: specs.MachineLabelsSpec - (*MachineStatusSnapshotSpec)(nil), // 71: specs.MachineStatusSnapshotSpec - (*ControlPlaneStatusSpec)(nil), // 72: specs.ControlPlaneStatusSpec - (*ClusterEndpointSpec)(nil), // 73: specs.ClusterEndpointSpec - (*KubernetesStatusSpec)(nil), // 74: specs.KubernetesStatusSpec - (*KubernetesUpgradeStatusSpec)(nil), // 75: specs.KubernetesUpgradeStatusSpec - (*KubernetesUpgradeManifestStatusSpec)(nil), // 76: specs.KubernetesUpgradeManifestStatusSpec - (*DestroyStatusSpec)(nil), // 77: specs.DestroyStatusSpec - (*OngoingTaskSpec)(nil), // 78: specs.OngoingTaskSpec - (*ClusterMachineEncryptionKeySpec)(nil), // 79: specs.ClusterMachineEncryptionKeySpec - (*ExposedServiceSpec)(nil), // 80: specs.ExposedServiceSpec - (*ClusterWorkloadProxyStatusSpec)(nil), // 81: specs.ClusterWorkloadProxyStatusSpec - (*FeaturesConfigSpec)(nil), // 82: specs.FeaturesConfigSpec - (*UserPilotSettings)(nil), // 83: specs.UserPilotSettings - (*StripeSettings)(nil), // 84: specs.StripeSettings - (*Account)(nil), // 85: specs.Account - (*EtcdBackupSettings)(nil), // 86: specs.EtcdBackupSettings - (*MachineClassSpec)(nil), // 87: specs.MachineClassSpec - (*MachineConfigGenOptionsSpec)(nil), // 88: specs.MachineConfigGenOptionsSpec - (*EtcdAuditResultSpec)(nil), // 89: specs.EtcdAuditResultSpec - (*KubeconfigSpec)(nil), // 90: specs.KubeconfigSpec - (*KubernetesUsageSpec)(nil), // 91: specs.KubernetesUsageSpec - (*ImagePullRequestSpec)(nil), // 92: specs.ImagePullRequestSpec - (*ImagePullStatusSpec)(nil), // 93: specs.ImagePullStatusSpec - (*SchematicSpec)(nil), // 94: specs.SchematicSpec - (*TalosExtensionsSpec)(nil), // 95: specs.TalosExtensionsSpec - (*SchematicConfigurationSpec)(nil), // 96: specs.SchematicConfigurationSpec - (*ExtensionsConfigurationSpec)(nil), // 97: specs.ExtensionsConfigurationSpec - (*KernelArgsSpec)(nil), // 98: specs.KernelArgsSpec - (*KernelArgsStatusSpec)(nil), // 99: specs.KernelArgsStatusSpec - (*MachineUpgradeStatusSpec)(nil), // 100: specs.MachineUpgradeStatusSpec - (*MachineExtensionsSpec)(nil), // 101: specs.MachineExtensionsSpec - (*MachineExtensionsStatusSpec)(nil), // 102: specs.MachineExtensionsStatusSpec - (*MachineStatusMetricsSpec)(nil), // 103: specs.MachineStatusMetricsSpec - (*ClusterMetricsSpec)(nil), // 104: specs.ClusterMetricsSpec - (*ClusterStatusMetricsSpec)(nil), // 105: specs.ClusterStatusMetricsSpec - (*ClusterKubernetesNodesSpec)(nil), // 106: specs.ClusterKubernetesNodesSpec - (*KubernetesNodeAuditResultSpec)(nil), // 107: specs.KubernetesNodeAuditResultSpec - (*MachineRequestSetSpec)(nil), // 108: specs.MachineRequestSetSpec - (*MachineRequestSetStatusSpec)(nil), // 109: specs.MachineRequestSetStatusSpec - (*ClusterDiagnosticsSpec)(nil), // 110: specs.ClusterDiagnosticsSpec - (*MachineRequestSetPressureSpec)(nil), // 111: specs.MachineRequestSetPressureSpec - (*ClusterMachineRequestStatusSpec)(nil), // 112: specs.ClusterMachineRequestStatusSpec - (*InfraMachineConfigSpec)(nil), // 113: specs.InfraMachineConfigSpec - (*InfraMachineBMCConfigSpec)(nil), // 114: specs.InfraMachineBMCConfigSpec - (*MaintenanceConfigStatusSpec)(nil), // 115: specs.MaintenanceConfigStatusSpec - (*NodeForceDestroyRequestSpec)(nil), // 116: specs.NodeForceDestroyRequestSpec - (*DiscoveryAffiliateDeleteTaskSpec)(nil), // 117: specs.DiscoveryAffiliateDeleteTaskSpec - (*InfraProviderCombinedStatusSpec)(nil), // 118: specs.InfraProviderCombinedStatusSpec - (*MachineConfigDiffSpec)(nil), // 119: specs.MachineConfigDiffSpec - (*InstallationMediaConfigSpec)(nil), // 120: specs.InstallationMediaConfigSpec - (*RotateTalosCASpec)(nil), // 121: specs.RotateTalosCASpec - (*SecretRotationSpec)(nil), // 122: specs.SecretRotationSpec - (*ClusterSecretsRotationStatusSpec)(nil), // 123: specs.ClusterSecretsRotationStatusSpec - (*ClusterMachineSecretsSpec)(nil), // 124: specs.ClusterMachineSecretsSpec - (*RotateKubernetesCASpec)(nil), // 125: specs.RotateKubernetesCASpec - (*UpgradeRolloutSpec)(nil), // 126: specs.UpgradeRolloutSpec - (*MachineStatusSpec_HardwareStatus)(nil), // 127: specs.MachineStatusSpec.HardwareStatus - (*MachineStatusSpec_NetworkStatus)(nil), // 128: specs.MachineStatusSpec.NetworkStatus - (*MachineStatusSpec_PlatformMetadata)(nil), // 129: specs.MachineStatusSpec.PlatformMetadata - (*MachineStatusSpec_Schematic)(nil), // 130: specs.MachineStatusSpec.Schematic - (*MachineStatusSpec_Diagnostic)(nil), // 131: specs.MachineStatusSpec.Diagnostic - nil, // 132: specs.MachineStatusSpec.ImageLabelsEntry - (*MachineStatusSpec_HardwareStatus_Processor)(nil), // 133: specs.MachineStatusSpec.HardwareStatus.Processor - (*MachineStatusSpec_HardwareStatus_MemoryModule)(nil), // 134: specs.MachineStatusSpec.HardwareStatus.MemoryModule - (*MachineStatusSpec_HardwareStatus_BlockDevice)(nil), // 135: specs.MachineStatusSpec.HardwareStatus.BlockDevice - (*MachineStatusSpec_NetworkStatus_NetworkLinkStatus)(nil), // 136: specs.MachineStatusSpec.NetworkStatus.NetworkLinkStatus - (*MachineStatusSpec_Schematic_InitialState)(nil), // 137: specs.MachineStatusSpec.Schematic.InitialState - (*ClusterSpec_Features)(nil), // 138: specs.ClusterSpec.Features - (*ClusterMachineStatusSpec_ProvisionStatus)(nil), // 139: specs.ClusterMachineStatusSpec.ProvisionStatus - (*MachinePendingUpdatesSpec_Upgrade)(nil), // 140: specs.MachinePendingUpdatesSpec.Upgrade - (*ClusterSecretsSpec_Certs)(nil), // 141: specs.ClusterSecretsSpec.Certs - (*ClusterSecretsSpec_Certs_CA)(nil), // 142: specs.ClusterSecretsSpec.Certs.CA - (*MachineSetSpec_MachineClass)(nil), // 143: specs.MachineSetSpec.MachineClass - (*MachineSetSpec_MachineAllocation)(nil), // 144: specs.MachineSetSpec.MachineAllocation - (*MachineSetSpec_BootstrapSpec)(nil), // 145: specs.MachineSetSpec.BootstrapSpec - (*MachineSetSpec_RollingUpdateStrategyConfig)(nil), // 146: specs.MachineSetSpec.RollingUpdateStrategyConfig - (*MachineSetSpec_UpdateStrategyConfig)(nil), // 147: specs.MachineSetSpec.UpdateStrategyConfig - (*ControlPlaneStatusSpec_Condition)(nil), // 148: specs.ControlPlaneStatusSpec.Condition - (*KubernetesStatusSpec_NodeStatus)(nil), // 149: specs.KubernetesStatusSpec.NodeStatus - (*KubernetesStatusSpec_StaticPodStatus)(nil), // 150: specs.KubernetesStatusSpec.StaticPodStatus - (*KubernetesStatusSpec_NodeStaticPods)(nil), // 151: specs.KubernetesStatusSpec.NodeStaticPods - (*MachineClassSpec_Provision)(nil), // 152: specs.MachineClassSpec.Provision - (*MachineConfigGenOptionsSpec_InstallImage)(nil), // 153: specs.MachineConfigGenOptionsSpec.InstallImage - (*KubernetesUsageSpec_Quantity)(nil), // 154: specs.KubernetesUsageSpec.Quantity - (*KubernetesUsageSpec_Pod)(nil), // 155: specs.KubernetesUsageSpec.Pod - (*ImagePullRequestSpec_NodeImageList)(nil), // 156: specs.ImagePullRequestSpec.NodeImageList - (*TalosExtensionsSpec_Info)(nil), // 157: specs.TalosExtensionsSpec.Info - (*MachineExtensionsStatusSpec_Item)(nil), // 158: specs.MachineExtensionsStatusSpec.Item - nil, // 159: specs.MachineStatusMetricsSpec.PlatformsEntry - nil, // 160: specs.MachineStatusMetricsSpec.SecureBootStatusEntry - nil, // 161: specs.MachineStatusMetricsSpec.UkiStatusEntry - nil, // 162: specs.ClusterMetricsSpec.FeaturesEntry - nil, // 163: specs.ClusterStatusMetricsSpec.PhasesEntry - (*ClusterDiagnosticsSpec_Node)(nil), // 164: specs.ClusterDiagnosticsSpec.Node - (*InfraMachineBMCConfigSpec_IPMI)(nil), // 165: specs.InfraMachineBMCConfigSpec.IPMI - (*InfraMachineBMCConfigSpec_API)(nil), // 166: specs.InfraMachineBMCConfigSpec.API - (*InfraProviderCombinedStatusSpec_Health)(nil), // 167: specs.InfraProviderCombinedStatusSpec.Health - (*InstallationMediaConfigSpec_Cloud)(nil), // 168: specs.InstallationMediaConfigSpec.Cloud - (*InstallationMediaConfigSpec_SBC)(nil), // 169: specs.InstallationMediaConfigSpec.SBC - nil, // 170: specs.InstallationMediaConfigSpec.MachineLabelsEntry - (*ClusterMachineSecretsSpec_Rotation)(nil), // 171: specs.ClusterMachineSecretsSpec.Rotation - nil, // 172: specs.UpgradeRolloutSpec.MachineSetsUpgradeQuotaEntry - (*durationpb.Duration)(nil), // 173: google.protobuf.Duration - (*timestamppb.Timestamp)(nil), // 174: google.protobuf.Timestamp - (*machine.MachineStatusEvent)(nil), // 175: machine.MachineStatusEvent - (PlatformConfigSpec_Arch)(0), // 176: specs.PlatformConfigSpec.Arch - (management.SchematicBootloader)(0), // 177: management.SchematicBootloader + (NotificationSpec_Type)(0), // 25: specs.NotificationSpec.Type + (*MachineSpec)(nil), // 26: specs.MachineSpec + (*SecurityState)(nil), // 27: specs.SecurityState + (*Overlay)(nil), // 28: specs.Overlay + (*MetaValue)(nil), // 29: specs.MetaValue + (*MachineStatusSpec)(nil), // 30: specs.MachineStatusSpec + (*TalosConfigSpec)(nil), // 31: specs.TalosConfigSpec + (*ClusterSpec)(nil), // 32: specs.ClusterSpec + (*ClusterTaintSpec)(nil), // 33: specs.ClusterTaintSpec + (*EtcdBackupConf)(nil), // 34: specs.EtcdBackupConf + (*EtcdBackupEncryptionSpec)(nil), // 35: specs.EtcdBackupEncryptionSpec + (*EtcdBackupHeader)(nil), // 36: specs.EtcdBackupHeader + (*EtcdBackupSpec)(nil), // 37: specs.EtcdBackupSpec + (*BackupDataSpec)(nil), // 38: specs.BackupDataSpec + (*EtcdBackupS3ConfSpec)(nil), // 39: specs.EtcdBackupS3ConfSpec + (*EtcdBackupStatusSpec)(nil), // 40: specs.EtcdBackupStatusSpec + (*EtcdManualBackupSpec)(nil), // 41: specs.EtcdManualBackupSpec + (*EtcdBackupStoreStatusSpec)(nil), // 42: specs.EtcdBackupStoreStatusSpec + (*EtcdBackupOverallStatusSpec)(nil), // 43: specs.EtcdBackupOverallStatusSpec + (*ClusterMachineSpec)(nil), // 44: specs.ClusterMachineSpec + (*ClusterMachineConfigPatchesSpec)(nil), // 45: specs.ClusterMachineConfigPatchesSpec + (*ClusterMachineTalosVersionSpec)(nil), // 46: specs.ClusterMachineTalosVersionSpec + (*ClusterMachineConfigSpec)(nil), // 47: specs.ClusterMachineConfigSpec + (*RedactedClusterMachineConfigSpec)(nil), // 48: specs.RedactedClusterMachineConfigSpec + (*ClusterMachineIdentitySpec)(nil), // 49: specs.ClusterMachineIdentitySpec + (*ClusterMachineStatusSpec)(nil), // 50: specs.ClusterMachineStatusSpec + (*Machines)(nil), // 51: specs.Machines + (*ClusterStatusSpec)(nil), // 52: specs.ClusterStatusSpec + (*ClusterUUID)(nil), // 53: specs.ClusterUUID + (*ClusterConfigVersionSpec)(nil), // 54: specs.ClusterConfigVersionSpec + (*ClusterMachineConfigStatusSpec)(nil), // 55: specs.ClusterMachineConfigStatusSpec + (*MachinePendingUpdatesSpec)(nil), // 56: specs.MachinePendingUpdatesSpec + (*ClusterBootstrapStatusSpec)(nil), // 57: specs.ClusterBootstrapStatusSpec + (*ClusterSecretsSpec)(nil), // 58: specs.ClusterSecretsSpec + (*ImportedClusterSecretsSpec)(nil), // 59: specs.ImportedClusterSecretsSpec + (*LoadBalancerConfigSpec)(nil), // 60: specs.LoadBalancerConfigSpec + (*LoadBalancerStatusSpec)(nil), // 61: specs.LoadBalancerStatusSpec + (*KubernetesVersionSpec)(nil), // 62: specs.KubernetesVersionSpec + (*TalosVersionSpec)(nil), // 63: specs.TalosVersionSpec + (*InstallationMediaSpec)(nil), // 64: specs.InstallationMediaSpec + (*ConfigPatchSpec)(nil), // 65: specs.ConfigPatchSpec + (*MachineSetSpec)(nil), // 66: specs.MachineSetSpec + (*TalosUpgradeStatusSpec)(nil), // 67: specs.TalosUpgradeStatusSpec + (*MachineSetStatusSpec)(nil), // 68: specs.MachineSetStatusSpec + (*MachineSetConfigStatusSpec)(nil), // 69: specs.MachineSetConfigStatusSpec + (*MachineSetNodeSpec)(nil), // 70: specs.MachineSetNodeSpec + (*MachineLabelsSpec)(nil), // 71: specs.MachineLabelsSpec + (*MachineStatusSnapshotSpec)(nil), // 72: specs.MachineStatusSnapshotSpec + (*ControlPlaneStatusSpec)(nil), // 73: specs.ControlPlaneStatusSpec + (*ClusterEndpointSpec)(nil), // 74: specs.ClusterEndpointSpec + (*KubernetesStatusSpec)(nil), // 75: specs.KubernetesStatusSpec + (*KubernetesUpgradeStatusSpec)(nil), // 76: specs.KubernetesUpgradeStatusSpec + (*KubernetesUpgradeManifestStatusSpec)(nil), // 77: specs.KubernetesUpgradeManifestStatusSpec + (*DestroyStatusSpec)(nil), // 78: specs.DestroyStatusSpec + (*OngoingTaskSpec)(nil), // 79: specs.OngoingTaskSpec + (*ClusterMachineEncryptionKeySpec)(nil), // 80: specs.ClusterMachineEncryptionKeySpec + (*ExposedServiceSpec)(nil), // 81: specs.ExposedServiceSpec + (*ClusterWorkloadProxyStatusSpec)(nil), // 82: specs.ClusterWorkloadProxyStatusSpec + (*FeaturesConfigSpec)(nil), // 83: specs.FeaturesConfigSpec + (*UserPilotSettings)(nil), // 84: specs.UserPilotSettings + (*StripeSettings)(nil), // 85: specs.StripeSettings + (*Account)(nil), // 86: specs.Account + (*EtcdBackupSettings)(nil), // 87: specs.EtcdBackupSettings + (*MachineClassSpec)(nil), // 88: specs.MachineClassSpec + (*MachineConfigGenOptionsSpec)(nil), // 89: specs.MachineConfigGenOptionsSpec + (*EtcdAuditResultSpec)(nil), // 90: specs.EtcdAuditResultSpec + (*KubeconfigSpec)(nil), // 91: specs.KubeconfigSpec + (*KubernetesUsageSpec)(nil), // 92: specs.KubernetesUsageSpec + (*ImagePullRequestSpec)(nil), // 93: specs.ImagePullRequestSpec + (*ImagePullStatusSpec)(nil), // 94: specs.ImagePullStatusSpec + (*SchematicSpec)(nil), // 95: specs.SchematicSpec + (*TalosExtensionsSpec)(nil), // 96: specs.TalosExtensionsSpec + (*SchematicConfigurationSpec)(nil), // 97: specs.SchematicConfigurationSpec + (*ExtensionsConfigurationSpec)(nil), // 98: specs.ExtensionsConfigurationSpec + (*KernelArgsSpec)(nil), // 99: specs.KernelArgsSpec + (*KernelArgsStatusSpec)(nil), // 100: specs.KernelArgsStatusSpec + (*MachineUpgradeStatusSpec)(nil), // 101: specs.MachineUpgradeStatusSpec + (*MachineExtensionsSpec)(nil), // 102: specs.MachineExtensionsSpec + (*MachineExtensionsStatusSpec)(nil), // 103: specs.MachineExtensionsStatusSpec + (*MachineStatusMetricsSpec)(nil), // 104: specs.MachineStatusMetricsSpec + (*ClusterMetricsSpec)(nil), // 105: specs.ClusterMetricsSpec + (*ClusterStatusMetricsSpec)(nil), // 106: specs.ClusterStatusMetricsSpec + (*ClusterKubernetesNodesSpec)(nil), // 107: specs.ClusterKubernetesNodesSpec + (*KubernetesNodeAuditResultSpec)(nil), // 108: specs.KubernetesNodeAuditResultSpec + (*MachineRequestSetSpec)(nil), // 109: specs.MachineRequestSetSpec + (*MachineRequestSetStatusSpec)(nil), // 110: specs.MachineRequestSetStatusSpec + (*ClusterDiagnosticsSpec)(nil), // 111: specs.ClusterDiagnosticsSpec + (*MachineRequestSetPressureSpec)(nil), // 112: specs.MachineRequestSetPressureSpec + (*ClusterMachineRequestStatusSpec)(nil), // 113: specs.ClusterMachineRequestStatusSpec + (*InfraMachineConfigSpec)(nil), // 114: specs.InfraMachineConfigSpec + (*InfraMachineBMCConfigSpec)(nil), // 115: specs.InfraMachineBMCConfigSpec + (*MaintenanceConfigStatusSpec)(nil), // 116: specs.MaintenanceConfigStatusSpec + (*NodeForceDestroyRequestSpec)(nil), // 117: specs.NodeForceDestroyRequestSpec + (*DiscoveryAffiliateDeleteTaskSpec)(nil), // 118: specs.DiscoveryAffiliateDeleteTaskSpec + (*InfraProviderCombinedStatusSpec)(nil), // 119: specs.InfraProviderCombinedStatusSpec + (*MachineConfigDiffSpec)(nil), // 120: specs.MachineConfigDiffSpec + (*InstallationMediaConfigSpec)(nil), // 121: specs.InstallationMediaConfigSpec + (*RotateTalosCASpec)(nil), // 122: specs.RotateTalosCASpec + (*SecretRotationSpec)(nil), // 123: specs.SecretRotationSpec + (*ClusterSecretsRotationStatusSpec)(nil), // 124: specs.ClusterSecretsRotationStatusSpec + (*ClusterMachineSecretsSpec)(nil), // 125: specs.ClusterMachineSecretsSpec + (*RotateKubernetesCASpec)(nil), // 126: specs.RotateKubernetesCASpec + (*UpgradeRolloutSpec)(nil), // 127: specs.UpgradeRolloutSpec + (*NotificationSpec)(nil), // 128: specs.NotificationSpec + (*MachineStatusSpec_HardwareStatus)(nil), // 129: specs.MachineStatusSpec.HardwareStatus + (*MachineStatusSpec_NetworkStatus)(nil), // 130: specs.MachineStatusSpec.NetworkStatus + (*MachineStatusSpec_PlatformMetadata)(nil), // 131: specs.MachineStatusSpec.PlatformMetadata + (*MachineStatusSpec_Schematic)(nil), // 132: specs.MachineStatusSpec.Schematic + (*MachineStatusSpec_Diagnostic)(nil), // 133: specs.MachineStatusSpec.Diagnostic + nil, // 134: specs.MachineStatusSpec.ImageLabelsEntry + (*MachineStatusSpec_HardwareStatus_Processor)(nil), // 135: specs.MachineStatusSpec.HardwareStatus.Processor + (*MachineStatusSpec_HardwareStatus_MemoryModule)(nil), // 136: specs.MachineStatusSpec.HardwareStatus.MemoryModule + (*MachineStatusSpec_HardwareStatus_BlockDevice)(nil), // 137: specs.MachineStatusSpec.HardwareStatus.BlockDevice + (*MachineStatusSpec_NetworkStatus_NetworkLinkStatus)(nil), // 138: specs.MachineStatusSpec.NetworkStatus.NetworkLinkStatus + (*MachineStatusSpec_Schematic_InitialState)(nil), // 139: specs.MachineStatusSpec.Schematic.InitialState + (*ClusterSpec_Features)(nil), // 140: specs.ClusterSpec.Features + (*ClusterMachineStatusSpec_ProvisionStatus)(nil), // 141: specs.ClusterMachineStatusSpec.ProvisionStatus + (*MachinePendingUpdatesSpec_Upgrade)(nil), // 142: specs.MachinePendingUpdatesSpec.Upgrade + (*ClusterSecretsSpec_Certs)(nil), // 143: specs.ClusterSecretsSpec.Certs + (*ClusterSecretsSpec_Certs_CA)(nil), // 144: specs.ClusterSecretsSpec.Certs.CA + (*MachineSetSpec_MachineClass)(nil), // 145: specs.MachineSetSpec.MachineClass + (*MachineSetSpec_MachineAllocation)(nil), // 146: specs.MachineSetSpec.MachineAllocation + (*MachineSetSpec_BootstrapSpec)(nil), // 147: specs.MachineSetSpec.BootstrapSpec + (*MachineSetSpec_RollingUpdateStrategyConfig)(nil), // 148: specs.MachineSetSpec.RollingUpdateStrategyConfig + (*MachineSetSpec_UpdateStrategyConfig)(nil), // 149: specs.MachineSetSpec.UpdateStrategyConfig + (*ControlPlaneStatusSpec_Condition)(nil), // 150: specs.ControlPlaneStatusSpec.Condition + (*KubernetesStatusSpec_NodeStatus)(nil), // 151: specs.KubernetesStatusSpec.NodeStatus + (*KubernetesStatusSpec_StaticPodStatus)(nil), // 152: specs.KubernetesStatusSpec.StaticPodStatus + (*KubernetesStatusSpec_NodeStaticPods)(nil), // 153: specs.KubernetesStatusSpec.NodeStaticPods + (*MachineClassSpec_Provision)(nil), // 154: specs.MachineClassSpec.Provision + (*MachineConfigGenOptionsSpec_InstallImage)(nil), // 155: specs.MachineConfigGenOptionsSpec.InstallImage + (*KubernetesUsageSpec_Quantity)(nil), // 156: specs.KubernetesUsageSpec.Quantity + (*KubernetesUsageSpec_Pod)(nil), // 157: specs.KubernetesUsageSpec.Pod + (*ImagePullRequestSpec_NodeImageList)(nil), // 158: specs.ImagePullRequestSpec.NodeImageList + (*TalosExtensionsSpec_Info)(nil), // 159: specs.TalosExtensionsSpec.Info + (*MachineExtensionsStatusSpec_Item)(nil), // 160: specs.MachineExtensionsStatusSpec.Item + nil, // 161: specs.MachineStatusMetricsSpec.PlatformsEntry + nil, // 162: specs.MachineStatusMetricsSpec.SecureBootStatusEntry + nil, // 163: specs.MachineStatusMetricsSpec.UkiStatusEntry + nil, // 164: specs.ClusterMetricsSpec.FeaturesEntry + nil, // 165: specs.ClusterStatusMetricsSpec.PhasesEntry + (*ClusterDiagnosticsSpec_Node)(nil), // 166: specs.ClusterDiagnosticsSpec.Node + (*InfraMachineBMCConfigSpec_IPMI)(nil), // 167: specs.InfraMachineBMCConfigSpec.IPMI + (*InfraMachineBMCConfigSpec_API)(nil), // 168: specs.InfraMachineBMCConfigSpec.API + (*InfraProviderCombinedStatusSpec_Health)(nil), // 169: specs.InfraProviderCombinedStatusSpec.Health + (*InstallationMediaConfigSpec_Cloud)(nil), // 170: specs.InstallationMediaConfigSpec.Cloud + (*InstallationMediaConfigSpec_SBC)(nil), // 171: specs.InstallationMediaConfigSpec.SBC + nil, // 172: specs.InstallationMediaConfigSpec.MachineLabelsEntry + (*ClusterMachineSecretsSpec_Rotation)(nil), // 173: specs.ClusterMachineSecretsSpec.Rotation + nil, // 174: specs.UpgradeRolloutSpec.MachineSetsUpgradeQuotaEntry + (*durationpb.Duration)(nil), // 175: google.protobuf.Duration + (*timestamppb.Timestamp)(nil), // 176: google.protobuf.Timestamp + (*machine.MachineStatusEvent)(nil), // 177: machine.MachineStatusEvent + (PlatformConfigSpec_Arch)(0), // 178: specs.PlatformConfigSpec.Arch + (management.SchematicBootloader)(0), // 179: management.SchematicBootloader } var file_omni_specs_omni_proto_depIdxs = []int32{ - 127, // 0: specs.MachineStatusSpec.hardware:type_name -> specs.MachineStatusSpec.HardwareStatus - 128, // 1: specs.MachineStatusSpec.network:type_name -> specs.MachineStatusSpec.NetworkStatus + 129, // 0: specs.MachineStatusSpec.hardware:type_name -> specs.MachineStatusSpec.HardwareStatus + 130, // 1: specs.MachineStatusSpec.network:type_name -> specs.MachineStatusSpec.NetworkStatus 4, // 2: specs.MachineStatusSpec.role:type_name -> specs.MachineStatusSpec.Role - 129, // 3: specs.MachineStatusSpec.platform_metadata:type_name -> specs.MachineStatusSpec.PlatformMetadata - 132, // 4: specs.MachineStatusSpec.image_labels:type_name -> specs.MachineStatusSpec.ImageLabelsEntry - 130, // 5: specs.MachineStatusSpec.schematic:type_name -> specs.MachineStatusSpec.Schematic - 131, // 6: specs.MachineStatusSpec.diagnostics:type_name -> specs.MachineStatusSpec.Diagnostic + 131, // 3: specs.MachineStatusSpec.platform_metadata:type_name -> specs.MachineStatusSpec.PlatformMetadata + 134, // 4: specs.MachineStatusSpec.image_labels:type_name -> specs.MachineStatusSpec.ImageLabelsEntry + 132, // 5: specs.MachineStatusSpec.schematic:type_name -> specs.MachineStatusSpec.Schematic + 133, // 6: specs.MachineStatusSpec.diagnostics:type_name -> specs.MachineStatusSpec.Diagnostic 5, // 7: specs.MachineStatusSpec.power_state:type_name -> specs.MachineStatusSpec.PowerState - 26, // 8: specs.MachineStatusSpec.security_state:type_name -> specs.SecurityState - 138, // 9: specs.ClusterSpec.features:type_name -> specs.ClusterSpec.Features - 33, // 10: specs.ClusterSpec.backup_configuration:type_name -> specs.EtcdBackupConf - 173, // 11: specs.EtcdBackupConf.interval:type_name -> google.protobuf.Duration - 174, // 12: specs.EtcdBackupSpec.created_at:type_name -> google.protobuf.Timestamp - 173, // 13: specs.BackupDataSpec.interval:type_name -> google.protobuf.Duration + 27, // 8: specs.MachineStatusSpec.security_state:type_name -> specs.SecurityState + 140, // 9: specs.ClusterSpec.features:type_name -> specs.ClusterSpec.Features + 34, // 10: specs.ClusterSpec.backup_configuration:type_name -> specs.EtcdBackupConf + 175, // 11: specs.EtcdBackupConf.interval:type_name -> google.protobuf.Duration + 176, // 12: specs.EtcdBackupSpec.created_at:type_name -> google.protobuf.Timestamp + 175, // 13: specs.BackupDataSpec.interval:type_name -> google.protobuf.Duration 6, // 14: specs.EtcdBackupStatusSpec.status:type_name -> specs.EtcdBackupStatusSpec.Status - 174, // 15: specs.EtcdBackupStatusSpec.last_backup_time:type_name -> google.protobuf.Timestamp - 174, // 16: specs.EtcdBackupStatusSpec.last_backup_attempt:type_name -> google.protobuf.Timestamp - 174, // 17: specs.EtcdManualBackupSpec.backup_at:type_name -> google.protobuf.Timestamp - 39, // 18: specs.EtcdBackupOverallStatusSpec.last_backup_status:type_name -> specs.EtcdBackupStatusSpec + 176, // 15: specs.EtcdBackupStatusSpec.last_backup_time:type_name -> google.protobuf.Timestamp + 176, // 16: specs.EtcdBackupStatusSpec.last_backup_attempt:type_name -> google.protobuf.Timestamp + 176, // 17: specs.EtcdManualBackupSpec.backup_at:type_name -> google.protobuf.Timestamp + 40, // 18: specs.EtcdBackupOverallStatusSpec.last_backup_status:type_name -> specs.EtcdBackupStatusSpec 7, // 19: specs.ClusterMachineStatusSpec.stage:type_name -> specs.ClusterMachineStatusSpec.Stage 0, // 20: specs.ClusterMachineStatusSpec.config_apply_status:type_name -> specs.ConfigApplyStatus - 139, // 21: specs.ClusterMachineStatusSpec.provision_status:type_name -> specs.ClusterMachineStatusSpec.ProvisionStatus - 50, // 22: specs.ClusterStatusSpec.machines:type_name -> specs.Machines + 141, // 21: specs.ClusterMachineStatusSpec.provision_status:type_name -> specs.ClusterMachineStatusSpec.ProvisionStatus + 51, // 22: specs.ClusterStatusSpec.machines:type_name -> specs.Machines 8, // 23: specs.ClusterStatusSpec.phase:type_name -> specs.ClusterStatusSpec.Phase - 140, // 24: specs.MachinePendingUpdatesSpec.upgrade:type_name -> specs.MachinePendingUpdatesSpec.Upgrade - 141, // 25: specs.ClusterSecretsSpec.extra_certs:type_name -> specs.ClusterSecretsSpec.Certs + 142, // 24: specs.MachinePendingUpdatesSpec.upgrade:type_name -> specs.MachinePendingUpdatesSpec.Upgrade + 143, // 25: specs.ClusterSecretsSpec.extra_certs:type_name -> specs.ClusterSecretsSpec.Certs 9, // 26: specs.MachineSetSpec.update_strategy:type_name -> specs.MachineSetSpec.UpdateStrategy - 144, // 27: specs.MachineSetSpec.machine_class:type_name -> specs.MachineSetSpec.MachineAllocation - 145, // 28: specs.MachineSetSpec.bootstrap_spec:type_name -> specs.MachineSetSpec.BootstrapSpec + 146, // 27: specs.MachineSetSpec.machine_class:type_name -> specs.MachineSetSpec.MachineAllocation + 147, // 28: specs.MachineSetSpec.bootstrap_spec:type_name -> specs.MachineSetSpec.BootstrapSpec 9, // 29: specs.MachineSetSpec.delete_strategy:type_name -> specs.MachineSetSpec.UpdateStrategy - 147, // 30: specs.MachineSetSpec.update_strategy_config:type_name -> specs.MachineSetSpec.UpdateStrategyConfig - 147, // 31: specs.MachineSetSpec.delete_strategy_config:type_name -> specs.MachineSetSpec.UpdateStrategyConfig - 144, // 32: specs.MachineSetSpec.machine_allocation:type_name -> specs.MachineSetSpec.MachineAllocation + 149, // 30: specs.MachineSetSpec.update_strategy_config:type_name -> specs.MachineSetSpec.UpdateStrategyConfig + 149, // 31: specs.MachineSetSpec.delete_strategy_config:type_name -> specs.MachineSetSpec.UpdateStrategyConfig + 146, // 32: specs.MachineSetSpec.machine_allocation:type_name -> specs.MachineSetSpec.MachineAllocation 9, // 33: specs.MachineSetSpec.upgrade_strategy:type_name -> specs.MachineSetSpec.UpdateStrategy - 147, // 34: specs.MachineSetSpec.upgrade_strategy_config:type_name -> specs.MachineSetSpec.UpdateStrategyConfig + 149, // 34: specs.MachineSetSpec.upgrade_strategy_config:type_name -> specs.MachineSetSpec.UpdateStrategyConfig 12, // 35: specs.TalosUpgradeStatusSpec.phase:type_name -> specs.TalosUpgradeStatusSpec.Phase 1, // 36: specs.MachineSetStatusSpec.phase:type_name -> specs.MachineSetPhase - 50, // 37: specs.MachineSetStatusSpec.machines:type_name -> specs.Machines - 144, // 38: specs.MachineSetStatusSpec.machine_allocation:type_name -> specs.MachineSetSpec.MachineAllocation + 51, // 37: specs.MachineSetStatusSpec.machines:type_name -> specs.Machines + 146, // 38: specs.MachineSetStatusSpec.machine_allocation:type_name -> specs.MachineSetSpec.MachineAllocation 9, // 39: specs.MachineSetConfigStatusSpec.update_strategy:type_name -> specs.MachineSetSpec.UpdateStrategy - 147, // 40: specs.MachineSetConfigStatusSpec.update_strategy_config:type_name -> specs.MachineSetSpec.UpdateStrategyConfig - 175, // 41: specs.MachineStatusSnapshotSpec.machine_status:type_name -> machine.MachineStatusEvent + 149, // 40: specs.MachineSetConfigStatusSpec.update_strategy_config:type_name -> specs.MachineSetSpec.UpdateStrategyConfig + 177, // 41: specs.MachineStatusSnapshotSpec.machine_status:type_name -> machine.MachineStatusEvent 13, // 42: specs.MachineStatusSnapshotSpec.power_stage:type_name -> specs.MachineStatusSnapshotSpec.PowerStage - 148, // 43: specs.ControlPlaneStatusSpec.conditions:type_name -> specs.ControlPlaneStatusSpec.Condition - 149, // 44: specs.KubernetesStatusSpec.nodes:type_name -> specs.KubernetesStatusSpec.NodeStatus - 151, // 45: specs.KubernetesStatusSpec.static_pods:type_name -> specs.KubernetesStatusSpec.NodeStaticPods + 150, // 43: specs.ControlPlaneStatusSpec.conditions:type_name -> specs.ControlPlaneStatusSpec.Condition + 151, // 44: specs.KubernetesStatusSpec.nodes:type_name -> specs.KubernetesStatusSpec.NodeStatus + 153, // 45: specs.KubernetesStatusSpec.static_pods:type_name -> specs.KubernetesStatusSpec.NodeStaticPods 16, // 46: specs.KubernetesUpgradeStatusSpec.phase:type_name -> specs.KubernetesUpgradeStatusSpec.Phase - 66, // 47: specs.OngoingTaskSpec.talos_upgrade:type_name -> specs.TalosUpgradeStatusSpec - 75, // 48: specs.OngoingTaskSpec.kubernetes_upgrade:type_name -> specs.KubernetesUpgradeStatusSpec - 77, // 49: specs.OngoingTaskSpec.destroy:type_name -> specs.DestroyStatusSpec - 100, // 50: specs.OngoingTaskSpec.machine_upgrade:type_name -> specs.MachineUpgradeStatusSpec - 123, // 51: specs.OngoingTaskSpec.secrets_rotation:type_name -> specs.ClusterSecretsRotationStatusSpec - 86, // 52: specs.FeaturesConfigSpec.etcd_backup_settings:type_name -> specs.EtcdBackupSettings - 83, // 53: specs.FeaturesConfigSpec.user_pilot_settings:type_name -> specs.UserPilotSettings - 84, // 54: specs.FeaturesConfigSpec.stripe_settings:type_name -> specs.StripeSettings - 85, // 55: specs.FeaturesConfigSpec.account:type_name -> specs.Account - 173, // 56: specs.EtcdBackupSettings.tick_interval:type_name -> google.protobuf.Duration - 173, // 57: specs.EtcdBackupSettings.min_interval:type_name -> google.protobuf.Duration - 173, // 58: specs.EtcdBackupSettings.max_interval:type_name -> google.protobuf.Duration - 152, // 59: specs.MachineClassSpec.auto_provision:type_name -> specs.MachineClassSpec.Provision - 153, // 60: specs.MachineConfigGenOptionsSpec.install_image:type_name -> specs.MachineConfigGenOptionsSpec.InstallImage - 154, // 61: specs.KubernetesUsageSpec.cpu:type_name -> specs.KubernetesUsageSpec.Quantity - 154, // 62: specs.KubernetesUsageSpec.mem:type_name -> specs.KubernetesUsageSpec.Quantity - 154, // 63: specs.KubernetesUsageSpec.storage:type_name -> specs.KubernetesUsageSpec.Quantity - 155, // 64: specs.KubernetesUsageSpec.pods:type_name -> specs.KubernetesUsageSpec.Pod - 156, // 65: specs.ImagePullRequestSpec.node_image_list:type_name -> specs.ImagePullRequestSpec.NodeImageList - 157, // 66: specs.TalosExtensionsSpec.items:type_name -> specs.TalosExtensionsSpec.Info + 67, // 47: specs.OngoingTaskSpec.talos_upgrade:type_name -> specs.TalosUpgradeStatusSpec + 76, // 48: specs.OngoingTaskSpec.kubernetes_upgrade:type_name -> specs.KubernetesUpgradeStatusSpec + 78, // 49: specs.OngoingTaskSpec.destroy:type_name -> specs.DestroyStatusSpec + 101, // 50: specs.OngoingTaskSpec.machine_upgrade:type_name -> specs.MachineUpgradeStatusSpec + 124, // 51: specs.OngoingTaskSpec.secrets_rotation:type_name -> specs.ClusterSecretsRotationStatusSpec + 87, // 52: specs.FeaturesConfigSpec.etcd_backup_settings:type_name -> specs.EtcdBackupSettings + 84, // 53: specs.FeaturesConfigSpec.user_pilot_settings:type_name -> specs.UserPilotSettings + 85, // 54: specs.FeaturesConfigSpec.stripe_settings:type_name -> specs.StripeSettings + 86, // 55: specs.FeaturesConfigSpec.account:type_name -> specs.Account + 175, // 56: specs.EtcdBackupSettings.tick_interval:type_name -> google.protobuf.Duration + 175, // 57: specs.EtcdBackupSettings.min_interval:type_name -> google.protobuf.Duration + 175, // 58: specs.EtcdBackupSettings.max_interval:type_name -> google.protobuf.Duration + 154, // 59: specs.MachineClassSpec.auto_provision:type_name -> specs.MachineClassSpec.Provision + 155, // 60: specs.MachineConfigGenOptionsSpec.install_image:type_name -> specs.MachineConfigGenOptionsSpec.InstallImage + 156, // 61: specs.KubernetesUsageSpec.cpu:type_name -> specs.KubernetesUsageSpec.Quantity + 156, // 62: specs.KubernetesUsageSpec.mem:type_name -> specs.KubernetesUsageSpec.Quantity + 156, // 63: specs.KubernetesUsageSpec.storage:type_name -> specs.KubernetesUsageSpec.Quantity + 157, // 64: specs.KubernetesUsageSpec.pods:type_name -> specs.KubernetesUsageSpec.Pod + 158, // 65: specs.ImagePullRequestSpec.node_image_list:type_name -> specs.ImagePullRequestSpec.NodeImageList + 159, // 66: specs.TalosExtensionsSpec.items:type_name -> specs.TalosExtensionsSpec.Info 17, // 67: specs.MachineUpgradeStatusSpec.phase:type_name -> specs.MachineUpgradeStatusSpec.Phase - 158, // 68: specs.MachineExtensionsStatusSpec.extensions:type_name -> specs.MachineExtensionsStatusSpec.Item - 159, // 69: specs.MachineStatusMetricsSpec.platforms:type_name -> specs.MachineStatusMetricsSpec.PlatformsEntry - 160, // 70: specs.MachineStatusMetricsSpec.secure_boot_status:type_name -> specs.MachineStatusMetricsSpec.SecureBootStatusEntry - 161, // 71: specs.MachineStatusMetricsSpec.uki_status:type_name -> specs.MachineStatusMetricsSpec.UkiStatusEntry - 162, // 72: specs.ClusterMetricsSpec.features:type_name -> specs.ClusterMetricsSpec.FeaturesEntry - 163, // 73: specs.ClusterStatusMetricsSpec.phases:type_name -> specs.ClusterStatusMetricsSpec.PhasesEntry - 28, // 74: specs.MachineRequestSetSpec.meta_values:type_name -> specs.MetaValue + 160, // 68: specs.MachineExtensionsStatusSpec.extensions:type_name -> specs.MachineExtensionsStatusSpec.Item + 161, // 69: specs.MachineStatusMetricsSpec.platforms:type_name -> specs.MachineStatusMetricsSpec.PlatformsEntry + 162, // 70: specs.MachineStatusMetricsSpec.secure_boot_status:type_name -> specs.MachineStatusMetricsSpec.SecureBootStatusEntry + 163, // 71: specs.MachineStatusMetricsSpec.uki_status:type_name -> specs.MachineStatusMetricsSpec.UkiStatusEntry + 164, // 72: specs.ClusterMetricsSpec.features:type_name -> specs.ClusterMetricsSpec.FeaturesEntry + 165, // 73: specs.ClusterStatusMetricsSpec.phases:type_name -> specs.ClusterStatusMetricsSpec.PhasesEntry + 29, // 74: specs.MachineRequestSetSpec.meta_values:type_name -> specs.MetaValue 3, // 75: specs.MachineRequestSetSpec.grpc_tunnel:type_name -> specs.GrpcTunnelMode - 164, // 76: specs.ClusterDiagnosticsSpec.nodes:type_name -> specs.ClusterDiagnosticsSpec.Node + 166, // 76: specs.ClusterDiagnosticsSpec.nodes:type_name -> specs.ClusterDiagnosticsSpec.Node 19, // 77: specs.ClusterMachineRequestStatusSpec.stage:type_name -> specs.ClusterMachineRequestStatusSpec.Stage 21, // 78: specs.InfraMachineConfigSpec.power_state:type_name -> specs.InfraMachineConfigSpec.MachinePowerState 20, // 79: specs.InfraMachineConfigSpec.acceptance_status:type_name -> specs.InfraMachineConfigSpec.AcceptanceStatus - 165, // 80: specs.InfraMachineBMCConfigSpec.ipmi:type_name -> specs.InfraMachineBMCConfigSpec.IPMI - 166, // 81: specs.InfraMachineBMCConfigSpec.api:type_name -> specs.InfraMachineBMCConfigSpec.API - 167, // 82: specs.InfraProviderCombinedStatusSpec.health:type_name -> specs.InfraProviderCombinedStatusSpec.Health - 176, // 83: specs.InstallationMediaConfigSpec.architecture:type_name -> specs.PlatformConfigSpec.Arch - 168, // 84: specs.InstallationMediaConfigSpec.cloud:type_name -> specs.InstallationMediaConfigSpec.Cloud - 169, // 85: specs.InstallationMediaConfigSpec.sbc:type_name -> specs.InstallationMediaConfigSpec.SBC + 167, // 80: specs.InfraMachineBMCConfigSpec.ipmi:type_name -> specs.InfraMachineBMCConfigSpec.IPMI + 168, // 81: specs.InfraMachineBMCConfigSpec.api:type_name -> specs.InfraMachineBMCConfigSpec.API + 169, // 82: specs.InfraProviderCombinedStatusSpec.health:type_name -> specs.InfraProviderCombinedStatusSpec.Health + 178, // 83: specs.InstallationMediaConfigSpec.architecture:type_name -> specs.PlatformConfigSpec.Arch + 170, // 84: specs.InstallationMediaConfigSpec.cloud:type_name -> specs.InstallationMediaConfigSpec.Cloud + 171, // 85: specs.InstallationMediaConfigSpec.sbc:type_name -> specs.InstallationMediaConfigSpec.SBC 3, // 86: specs.InstallationMediaConfigSpec.grpc_tunnel:type_name -> specs.GrpcTunnelMode - 170, // 87: specs.InstallationMediaConfigSpec.machine_labels:type_name -> specs.InstallationMediaConfigSpec.MachineLabelsEntry - 177, // 88: specs.InstallationMediaConfigSpec.bootloader:type_name -> management.SchematicBootloader + 172, // 87: specs.InstallationMediaConfigSpec.machine_labels:type_name -> specs.InstallationMediaConfigSpec.MachineLabelsEntry + 179, // 88: specs.InstallationMediaConfigSpec.bootloader:type_name -> management.SchematicBootloader 22, // 89: specs.SecretRotationSpec.status:type_name -> specs.SecretRotationSpec.Status 23, // 90: specs.SecretRotationSpec.phase:type_name -> specs.SecretRotationSpec.Phase 24, // 91: specs.SecretRotationSpec.component:type_name -> specs.SecretRotationSpec.Component - 141, // 92: specs.SecretRotationSpec.certs:type_name -> specs.ClusterSecretsSpec.Certs - 141, // 93: specs.SecretRotationSpec.extra_certs:type_name -> specs.ClusterSecretsSpec.Certs - 142, // 94: specs.SecretRotationSpec.backup_certs_os:type_name -> specs.ClusterSecretsSpec.Certs.CA - 142, // 95: specs.SecretRotationSpec.backup_certs_k8s:type_name -> specs.ClusterSecretsSpec.Certs.CA + 143, // 92: specs.SecretRotationSpec.certs:type_name -> specs.ClusterSecretsSpec.Certs + 143, // 93: specs.SecretRotationSpec.extra_certs:type_name -> specs.ClusterSecretsSpec.Certs + 144, // 94: specs.SecretRotationSpec.backup_certs_os:type_name -> specs.ClusterSecretsSpec.Certs.CA + 144, // 95: specs.SecretRotationSpec.backup_certs_k8s:type_name -> specs.ClusterSecretsSpec.Certs.CA 23, // 96: specs.ClusterSecretsRotationStatusSpec.phase:type_name -> specs.SecretRotationSpec.Phase 24, // 97: specs.ClusterSecretsRotationStatusSpec.component:type_name -> specs.SecretRotationSpec.Component - 171, // 98: specs.ClusterMachineSecretsSpec.rotation:type_name -> specs.ClusterMachineSecretsSpec.Rotation - 172, // 99: specs.UpgradeRolloutSpec.machine_sets_upgrade_quota:type_name -> specs.UpgradeRolloutSpec.MachineSetsUpgradeQuotaEntry - 133, // 100: specs.MachineStatusSpec.HardwareStatus.processors:type_name -> specs.MachineStatusSpec.HardwareStatus.Processor - 134, // 101: specs.MachineStatusSpec.HardwareStatus.memory_modules:type_name -> specs.MachineStatusSpec.HardwareStatus.MemoryModule - 135, // 102: specs.MachineStatusSpec.HardwareStatus.blockdevices:type_name -> specs.MachineStatusSpec.HardwareStatus.BlockDevice - 136, // 103: specs.MachineStatusSpec.NetworkStatus.network_links:type_name -> specs.MachineStatusSpec.NetworkStatus.NetworkLinkStatus - 27, // 104: specs.MachineStatusSpec.Schematic.overlay:type_name -> specs.Overlay - 28, // 105: specs.MachineStatusSpec.Schematic.meta_values:type_name -> specs.MetaValue - 137, // 106: specs.MachineStatusSpec.Schematic.initial_state:type_name -> specs.MachineStatusSpec.Schematic.InitialState - 142, // 107: specs.ClusterSecretsSpec.Certs.os:type_name -> specs.ClusterSecretsSpec.Certs.CA - 142, // 108: specs.ClusterSecretsSpec.Certs.k8s:type_name -> specs.ClusterSecretsSpec.Certs.CA - 10, // 109: specs.MachineSetSpec.MachineClass.allocation_type:type_name -> specs.MachineSetSpec.MachineClass.Type - 11, // 110: specs.MachineSetSpec.MachineAllocation.allocation_type:type_name -> specs.MachineSetSpec.MachineAllocation.Type - 146, // 111: specs.MachineSetSpec.UpdateStrategyConfig.rolling:type_name -> specs.MachineSetSpec.RollingUpdateStrategyConfig - 2, // 112: specs.ControlPlaneStatusSpec.Condition.type:type_name -> specs.ConditionType - 14, // 113: specs.ControlPlaneStatusSpec.Condition.status:type_name -> specs.ControlPlaneStatusSpec.Condition.Status - 15, // 114: specs.ControlPlaneStatusSpec.Condition.severity:type_name -> specs.ControlPlaneStatusSpec.Condition.Severity - 150, // 115: specs.KubernetesStatusSpec.NodeStaticPods.static_pods:type_name -> specs.KubernetesStatusSpec.StaticPodStatus - 28, // 116: specs.MachineClassSpec.Provision.meta_values:type_name -> specs.MetaValue - 3, // 117: specs.MachineClassSpec.Provision.grpc_tunnel:type_name -> specs.GrpcTunnelMode - 26, // 118: specs.MachineConfigGenOptionsSpec.InstallImage.security_state:type_name -> specs.SecurityState - 18, // 119: specs.MachineExtensionsStatusSpec.Item.phase:type_name -> specs.MachineExtensionsStatusSpec.Item.Phase - 22, // 120: specs.ClusterMachineSecretsSpec.Rotation.status:type_name -> specs.SecretRotationSpec.Status - 23, // 121: specs.ClusterMachineSecretsSpec.Rotation.phase:type_name -> specs.SecretRotationSpec.Phase - 24, // 122: specs.ClusterMachineSecretsSpec.Rotation.component:type_name -> specs.SecretRotationSpec.Component - 141, // 123: specs.ClusterMachineSecretsSpec.Rotation.extra_certs:type_name -> specs.ClusterSecretsSpec.Certs - 124, // [124:124] is the sub-list for method output_type - 124, // [124:124] is the sub-list for method input_type - 124, // [124:124] is the sub-list for extension type_name - 124, // [124:124] is the sub-list for extension extendee - 0, // [0:124] is the sub-list for field type_name + 173, // 98: specs.ClusterMachineSecretsSpec.rotation:type_name -> specs.ClusterMachineSecretsSpec.Rotation + 174, // 99: specs.UpgradeRolloutSpec.machine_sets_upgrade_quota:type_name -> specs.UpgradeRolloutSpec.MachineSetsUpgradeQuotaEntry + 25, // 100: specs.NotificationSpec.type:type_name -> specs.NotificationSpec.Type + 135, // 101: specs.MachineStatusSpec.HardwareStatus.processors:type_name -> specs.MachineStatusSpec.HardwareStatus.Processor + 136, // 102: specs.MachineStatusSpec.HardwareStatus.memory_modules:type_name -> specs.MachineStatusSpec.HardwareStatus.MemoryModule + 137, // 103: specs.MachineStatusSpec.HardwareStatus.blockdevices:type_name -> specs.MachineStatusSpec.HardwareStatus.BlockDevice + 138, // 104: specs.MachineStatusSpec.NetworkStatus.network_links:type_name -> specs.MachineStatusSpec.NetworkStatus.NetworkLinkStatus + 28, // 105: specs.MachineStatusSpec.Schematic.overlay:type_name -> specs.Overlay + 29, // 106: specs.MachineStatusSpec.Schematic.meta_values:type_name -> specs.MetaValue + 139, // 107: specs.MachineStatusSpec.Schematic.initial_state:type_name -> specs.MachineStatusSpec.Schematic.InitialState + 144, // 108: specs.ClusterSecretsSpec.Certs.os:type_name -> specs.ClusterSecretsSpec.Certs.CA + 144, // 109: specs.ClusterSecretsSpec.Certs.k8s:type_name -> specs.ClusterSecretsSpec.Certs.CA + 10, // 110: specs.MachineSetSpec.MachineClass.allocation_type:type_name -> specs.MachineSetSpec.MachineClass.Type + 11, // 111: specs.MachineSetSpec.MachineAllocation.allocation_type:type_name -> specs.MachineSetSpec.MachineAllocation.Type + 148, // 112: specs.MachineSetSpec.UpdateStrategyConfig.rolling:type_name -> specs.MachineSetSpec.RollingUpdateStrategyConfig + 2, // 113: specs.ControlPlaneStatusSpec.Condition.type:type_name -> specs.ConditionType + 14, // 114: specs.ControlPlaneStatusSpec.Condition.status:type_name -> specs.ControlPlaneStatusSpec.Condition.Status + 15, // 115: specs.ControlPlaneStatusSpec.Condition.severity:type_name -> specs.ControlPlaneStatusSpec.Condition.Severity + 152, // 116: specs.KubernetesStatusSpec.NodeStaticPods.static_pods:type_name -> specs.KubernetesStatusSpec.StaticPodStatus + 29, // 117: specs.MachineClassSpec.Provision.meta_values:type_name -> specs.MetaValue + 3, // 118: specs.MachineClassSpec.Provision.grpc_tunnel:type_name -> specs.GrpcTunnelMode + 27, // 119: specs.MachineConfigGenOptionsSpec.InstallImage.security_state:type_name -> specs.SecurityState + 18, // 120: specs.MachineExtensionsStatusSpec.Item.phase:type_name -> specs.MachineExtensionsStatusSpec.Item.Phase + 22, // 121: specs.ClusterMachineSecretsSpec.Rotation.status:type_name -> specs.SecretRotationSpec.Status + 23, // 122: specs.ClusterMachineSecretsSpec.Rotation.phase:type_name -> specs.SecretRotationSpec.Phase + 24, // 123: specs.ClusterMachineSecretsSpec.Rotation.component:type_name -> specs.SecretRotationSpec.Component + 143, // 124: specs.ClusterMachineSecretsSpec.Rotation.extra_certs:type_name -> specs.ClusterSecretsSpec.Certs + 125, // [125:125] is the sub-list for method output_type + 125, // [125:125] is the sub-list for method input_type + 125, // [125:125] is the sub-list for extension type_name + 125, // [125:125] is the sub-list for extension extendee + 0, // [0:125] is the sub-list for field type_name } func init() { file_omni_specs_omni_proto_init() } @@ -11664,8 +11805,8 @@ func file_omni_specs_omni_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_omni_specs_omni_proto_rawDesc), len(file_omni_specs_omni_proto_rawDesc)), - NumEnums: 25, - NumMessages: 148, + NumEnums: 26, + NumMessages: 149, NumExtensions: 0, NumServices: 0, }, diff --git a/client/api/omni/specs/omni.proto b/client/api/omni/specs/omni.proto index 764e6aae..59b3e0ec 100644 --- a/client/api/omni/specs/omni.proto +++ b/client/api/omni/specs/omni.proto @@ -1353,6 +1353,8 @@ message MachineStatusMetricsSpec { map platforms = 6; map secure_boot_status = 7; map uki_status = 8; + uint32 registered_machines_limit = 9; + bool registration_limit_reached = 10; } // ClusterMetricsSpec contains metrics about the clusters in the Omni instance. @@ -1618,3 +1620,17 @@ message RotateKubernetesCASpec {} message UpgradeRolloutSpec { map machine_sets_upgrade_quota = 1; } + +// NotificationSpec describes a generic notification emitted by a controller. +message NotificationSpec { + // Type describes the severity of a notification. + enum Type { + INFO = 0; + WARNING = 1; + ERROR = 2; + } + + string title = 1; + string body = 2; + Type type = 3; +} diff --git a/client/api/omni/specs/omni_vtproto.pb.go b/client/api/omni/specs/omni_vtproto.pb.go index 27898c36..9bc768dd 100644 --- a/client/api/omni/specs/omni_vtproto.pb.go +++ b/client/api/omni/specs/omni_vtproto.pb.go @@ -2447,6 +2447,8 @@ func (m *MachineStatusMetricsSpec) CloneVT() *MachineStatusMetricsSpec { r.ConnectedMachinesCount = m.ConnectedMachinesCount r.AllocatedMachinesCount = m.AllocatedMachinesCount r.PendingMachinesCount = m.PendingMachinesCount + r.RegisteredMachinesLimit = m.RegisteredMachinesLimit + r.RegistrationLimitReached = m.RegistrationLimitReached if rhs := m.Platforms; rhs != nil { tmpContainer := make(map[string]uint32, len(rhs)) for k, v := range rhs { @@ -3109,6 +3111,25 @@ func (m *UpgradeRolloutSpec) CloneMessageVT() proto.Message { return m.CloneVT() } +func (m *NotificationSpec) CloneVT() *NotificationSpec { + if m == nil { + return (*NotificationSpec)(nil) + } + r := new(NotificationSpec) + r.Title = m.Title + r.Body = m.Body + r.Type = m.Type + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *NotificationSpec) CloneMessageVT() proto.Message { + return m.CloneVT() +} + func (this *MachineSpec) EqualVT(that *MachineSpec) bool { if this == that { return true @@ -6500,6 +6521,12 @@ func (this *MachineStatusMetricsSpec) EqualVT(that *MachineStatusMetricsSpec) bo return false } } + if this.RegisteredMachinesLimit != that.RegisteredMachinesLimit { + return false + } + if this.RegistrationLimitReached != that.RegistrationLimitReached { + return false + } return string(this.unknownFields) == string(that.unknownFields) } @@ -7346,6 +7373,31 @@ func (this *UpgradeRolloutSpec) EqualMessageVT(thatMsg proto.Message) bool { } return this.EqualVT(that) } +func (this *NotificationSpec) EqualVT(that *NotificationSpec) bool { + if this == that { + return true + } else if this == nil || that == nil { + return false + } + if this.Title != that.Title { + return false + } + if this.Body != that.Body { + return false + } + if this.Type != that.Type { + return false + } + return string(this.unknownFields) == string(that.unknownFields) +} + +func (this *NotificationSpec) EqualMessageVT(thatMsg proto.Message) bool { + that, ok := thatMsg.(*NotificationSpec) + if !ok { + return false + } + return this.EqualVT(that) +} func (m *MachineSpec) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -13986,6 +14038,21 @@ func (m *MachineStatusMetricsSpec) MarshalToSizedBufferVT(dAtA []byte) (int, err i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.RegistrationLimitReached { + i-- + if m.RegistrationLimitReached { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x50 + } + if m.RegisteredMachinesLimit != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.RegisteredMachinesLimit)) + i-- + dAtA[i] = 0x48 + } if len(m.UkiStatus) > 0 { for k := range m.UkiStatus { v := m.UkiStatus[k] @@ -15665,6 +15732,58 @@ func (m *UpgradeRolloutSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *NotificationSpec) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NotificationSpec) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *NotificationSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Type != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Type)) + i-- + dAtA[i] = 0x18 + } + if len(m.Body) > 0 { + i -= len(m.Body) + copy(dAtA[i:], m.Body) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Body))) + i-- + dAtA[i] = 0x12 + } + if len(m.Title) > 0 { + i -= len(m.Title) + copy(dAtA[i:], m.Title) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Title))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *MachineSpec) SizeVT() (n int) { if m == nil { return 0 @@ -18309,6 +18428,12 @@ func (m *MachineStatusMetricsSpec) SizeVT() (n int) { n += mapEntrySize + 1 + protohelpers.SizeOfVarint(uint64(mapEntrySize)) } } + if m.RegisteredMachinesLimit != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.RegisteredMachinesLimit)) + } + if m.RegistrationLimitReached { + n += 2 + } n += len(m.unknownFields) return n } @@ -18935,6 +19060,27 @@ func (m *UpgradeRolloutSpec) SizeVT() (n int) { return n } +func (m *NotificationSpec) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Title) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Body) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Type != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Type)) + } + n += len(m.unknownFields) + return n +} + func (m *MachineSpec) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -35935,6 +36081,45 @@ func (m *MachineStatusMetricsSpec) UnmarshalVT(dAtA []byte) error { } m.UkiStatus[mapkey] = mapvalue iNdEx = postIndex + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RegisteredMachinesLimit", wireType) + } + m.RegisteredMachinesLimit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RegisteredMachinesLimit |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RegistrationLimitReached", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.RegistrationLimitReached = bool(v != 0) default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -40045,3 +40230,137 @@ func (m *UpgradeRolloutSpec) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *NotificationSpec) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NotificationSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NotificationSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Title", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Title = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Body", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Body = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + m.Type = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Type |= NotificationSpec_Type(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} diff --git a/client/pkg/omni/resources/omni/notification.go b/client/pkg/omni/resources/omni/notification.go new file mode 100644 index 00000000..d17b01a5 --- /dev/null +++ b/client/pkg/omni/resources/omni/notification.go @@ -0,0 +1,52 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package omni + +import ( + "github.com/cosi-project/runtime/pkg/resource" + "github.com/cosi-project/runtime/pkg/resource/meta" + "github.com/cosi-project/runtime/pkg/resource/protobuf" + "github.com/cosi-project/runtime/pkg/resource/typed" + + "github.com/siderolabs/omni/client/api/omni/specs" + "github.com/siderolabs/omni/client/pkg/omni/resources" +) + +// NewNotification creates new Notification resource. +func NewNotification(id resource.ID) *Notification { + return typed.NewResource[NotificationSpec, NotificationExtension]( + resource.NewMetadata(resources.EphemeralNamespace, NotificationType, id, resource.VersionUndefined), + protobuf.NewResourceSpec(&specs.NotificationSpec{}), + ) +} + +const ( + // NotificationType is the type of the Notification resource. + // tsgen:NotificationType + NotificationType = resource.Type("Notifications.omni.sidero.dev") + + // NotificationMachineRegistrationLimitID is the ID for the machine registration limit notification. + // tsgen:NotificationMachineRegistrationLimitID + NotificationMachineRegistrationLimitID = "machine-registration-limit" +) + +// Notification describes a generic notification emitted by a controller. +type Notification = typed.Resource[NotificationSpec, NotificationExtension] + +// NotificationSpec wraps specs.NotificationSpec. +type NotificationSpec = protobuf.ResourceSpec[specs.NotificationSpec, *specs.NotificationSpec] + +// NotificationExtension provides auxiliary methods for Notification resource. +type NotificationExtension struct{} + +// ResourceDefinition implements [typed.Extension] interface. +func (NotificationExtension) ResourceDefinition() meta.ResourceDefinitionSpec { + return meta.ResourceDefinitionSpec{ + Type: NotificationType, + Aliases: []resource.Type{}, + DefaultNamespace: resources.EphemeralNamespace, + PrintColumns: []meta.PrintColumn{}, + } +} diff --git a/client/pkg/omni/resources/omni/omni.go b/client/pkg/omni/resources/omni/omni.go index 30303352..7ceda09c 100644 --- a/client/pkg/omni/resources/omni/omni.go +++ b/client/pkg/omni/resources/omni/omni.go @@ -79,6 +79,7 @@ func init() { registry.MustRegisterResource(MachineStatusSnapshotType, &MachineStatusSnapshot{}) registry.MustRegisterResource(MachineStatusLinkType, &MachineStatusLink{}) registry.MustRegisterResource(MachineStatusMetricsType, &MachineStatusMetrics{}) + registry.MustRegisterResource(NotificationType, &Notification{}) registry.MustRegisterResource(MaintenanceConfigStatusType, &MaintenanceConfigStatus{}) registry.MustRegisterResource(LoadBalancerConfigType, &LoadBalancerConfig{}) registry.MustRegisterResource(LoadBalancerStatusType, &LoadBalancerStatus{}) diff --git a/client/pkg/omnictl/internal/access/client.go b/client/pkg/omnictl/internal/access/client.go index d49580d5..fb725be0 100644 --- a/client/pkg/omnictl/internal/access/client.go +++ b/client/pkg/omnictl/internal/access/client.go @@ -16,9 +16,11 @@ import ( "github.com/siderolabs/go-api-signature/pkg/serviceaccount" "go.uber.org/zap" + "github.com/siderolabs/omni/client/api/omni/specs" "github.com/siderolabs/omni/client/pkg/client" "github.com/siderolabs/omni/client/pkg/client/omni" "github.com/siderolabs/omni/client/pkg/omni/resources" + omnires "github.com/siderolabs/omni/client/pkg/omni/resources/omni" "github.com/siderolabs/omni/client/pkg/omni/resources/system" "github.com/siderolabs/omni/client/pkg/omnictl/config" "github.com/siderolabs/omni/client/pkg/version" @@ -147,6 +149,10 @@ func WithClient(f func(ctx context.Context, client *client.Client) error, client return err } + if err = checkNotifications(ctx, client.Omni().State()); err != nil { + return err + } + return f(ctx, client) }) } @@ -180,6 +186,34 @@ If you want to enable the version validation and disable this warning, set githu return nil } +func checkNotifications(ctx context.Context, st state.State) error { + notifications, err := safe.StateListAll[*omnires.Notification](ctx, st) + if err != nil { + return fmt.Errorf("failed to list notifications: %w", err) + } + + for n := range notifications.All() { + spec := n.TypedSpec().Value + + var prefix string + + switch spec.Type { + case specs.NotificationSpec_ERROR: + prefix = "[ERROR]" + case specs.NotificationSpec_WARNING: + prefix = "[WARN]" + case specs.NotificationSpec_INFO: + prefix = "[INFO]" + default: + prefix = "[UNKNOWN]" + } + + fmt.Fprintf(os.Stderr, "%s %s: %s\n", prefix, spec.Title, spec.Body) //nolint:errcheck + } + + return nil +} + func checkVersionWarning(sysVersion *system.SysVersion) { backendVersion, err := semver.ParseTolerant(sysVersion.TypedSpec().Value.BackendVersion) if err != nil { diff --git a/cmd/omni/cmd/cmd.go b/cmd/omni/cmd/cmd.go index 05840794..42cafd3d 100644 --- a/cmd/omni/cmd/cmd.go +++ b/cmd/omni/cmd/cmd.go @@ -154,6 +154,7 @@ func buildRootCommand() (*cobra.Command, error) { rootCmdFlagBinder.StringVar("account-id", flagDescription("account.id", configSchema), &flagConfig.Account.Id) rootCmdFlagBinder.StringVar("name", flagDescription("account.name", configSchema), &flagConfig.Account.Name) rootCmdFlagBinder.StringVar("user-pilot-app-token", flagDescription("account.userPilot.appToken", configSchema), &flagConfig.Account.UserPilot.AppToken) + rootCmdFlagBinder.Uint32Var("account-max-registered-machines", flagDescription("account.maxRegisteredMachines", configSchema), &flagConfig.Account.MaxRegisteredMachines) if err := defineServiceFlags(rootCmd, rootCmdFlagBinder, flagConfig, configSchema); err != nil { return nil, fmt.Errorf("failed to define service flags: %w", err) diff --git a/frontend/src/api/omni/specs/omni.pb.ts b/frontend/src/api/omni/specs/omni.pb.ts index 0ccd648c..234b8e84 100644 --- a/frontend/src/api/omni/specs/omni.pb.ts +++ b/frontend/src/api/omni/specs/omni.pb.ts @@ -194,6 +194,12 @@ export enum SecretRotationSpecComponent { KUBERNETES_CA = 2, } +export enum NotificationSpecType { + INFO = 0, + WARNING = 1, + ERROR = 2, +} + export type MachineSpec = { management_address?: string connected?: boolean @@ -898,6 +904,8 @@ export type MachineStatusMetricsSpec = { platforms?: {[key: string]: number} secure_boot_status?: {[key: string]: number} uki_status?: {[key: string]: number} + registered_machines_limit?: number + registration_limit_reached?: boolean } export type ClusterMetricsSpec = { @@ -1066,4 +1074,10 @@ export type RotateKubernetesCASpec = { export type UpgradeRolloutSpec = { machine_sets_upgrade_quota?: {[key: string]: number} +} + +export type NotificationSpec = { + title?: string + body?: string + type?: NotificationSpecType } \ No newline at end of file diff --git a/frontend/src/api/resources.ts b/frontend/src/api/resources.ts index 2769fc86..d5d1785d 100644 --- a/frontend/src/api/resources.ts +++ b/frontend/src/api/resources.ts @@ -207,6 +207,8 @@ export const MachineStatusSnapshotType = "MachineStatusSnapshots.omni.sidero.dev export const MachineUpgradeStatusType = "MachineUpgradeStatuses.omni.sidero.dev"; export const MaintenanceConfigStatusType = "MaintenanceConfigStatuses.omni.sidero.dev"; export const NodeForceDestroyRequestType = "NodeForceDestroyRequests.omni.sidero.dev"; +export const NotificationType = "Notifications.omni.sidero.dev"; +export const NotificationMachineRegistrationLimitID = "machine-registration-limit"; export const OngoingTaskType = "OngoingTasks.omni.sidero.dev"; export const RedactedClusterMachineConfigType = "RedactedClusterMachineConfigs.omni.sidero.dev"; export const RotateKubernetesCAType = "RotateKubernetesCAs.omni.sidero.dev"; diff --git a/hack/test/common.sh b/hack/test/common.sh index 3a0dfd45..3b5b2ab1 100755 --- a/hack/test/common.sh +++ b/hack/test/common.sh @@ -47,6 +47,7 @@ export AUTH0_DOMAIN="${AUTH0_DOMAIN}" export OMNI_CONFIG="${TEST_OUTPUTS_DIR}/config.yaml" export MAX_USERS="${MAX_USERS:-0}" export MAX_SERVICE_ACCOUNTS="${MAX_SERVICE_ACCOUNTS:-0}" +export MAX_REGISTERED_MACHINES="${MAX_REGISTERED_MACHINES:-0}" export REGISTRY_MIRROR_FLAGS=() export REGISTRY_MIRROR_CONFIG="" export IMPORTED_CLUSTER_ARGS=() diff --git a/hack/test/integration-qemu.sh b/hack/test/integration-qemu.sh index 27ab747e..f023d3a1 100755 --- a/hack/test/integration-qemu.sh +++ b/hack/test/integration-qemu.sh @@ -61,6 +61,9 @@ prepare_vault # Start MinIO server. prepare_minio access_key="access" secret_key="secret123" +# Set the registration limit to the total number of machines so that the registration limit is actively enforced during the test. +export MAX_REGISTERED_MACHINES="${TOTAL_MACHINES}" + # Prepare omni config. prepare_omni_config diff --git a/hack/test/templates/omni-config.yaml b/hack/test/templates/omni-config.yaml index 7aaaf1b3..0ca5c7bb 100644 --- a/hack/test/templates/omni-config.yaml +++ b/hack/test/templates/omni-config.yaml @@ -1,3 +1,5 @@ +account: + maxRegisteredMachines: ${MAX_REGISTERED_MACHINES} services: api: endpoint: 0.0.0.0:8099 diff --git a/internal/backend/runtime/omni/controllers/omni/machine_status_metrics.go b/internal/backend/runtime/omni/controllers/omni/machine_status_metrics.go index 9a9da092..0a208395 100644 --- a/internal/backend/runtime/omni/controllers/omni/machine_status_metrics.go +++ b/internal/backend/runtime/omni/controllers/omni/machine_status_metrics.go @@ -7,6 +7,7 @@ package omni import ( "context" + "fmt" "iter" "strconv" "sync" @@ -24,6 +25,7 @@ import ( "github.com/siderolabs/omni/client/pkg/omni/resources" "github.com/siderolabs/omni/client/pkg/omni/resources/infra" "github.com/siderolabs/omni/client/pkg/omni/resources/omni" + "github.com/siderolabs/omni/internal/backend/runtime/omni/controllers/helpers" ) type nodeInfo struct { @@ -32,6 +34,13 @@ type nodeInfo struct { connected bool } +// NewMachineStatusMetricsController creates a new MachineStatusMetricsController. +func NewMachineStatusMetricsController(maxRegisteredMachines uint32) *MachineStatusMetricsController { + return &MachineStatusMetricsController{ + maxRegisteredMachines: maxRegisteredMachines, + } +} + // MachineStatusMetricsController provides metrics based on ClusterStatus. // //nolint:govet @@ -41,6 +50,8 @@ type MachineStatusMetricsController struct { metricsOnce sync.Once + maxRegisteredMachines uint32 + platformNames []string metricNumMachines prometheus.Gauge @@ -79,6 +90,10 @@ func (ctrl *MachineStatusMetricsController) Outputs() []controller.Output { Type: omni.MachineStatusMetricsType, Kind: controller.OutputExclusive, }, + { + Type: omni.NotificationType, + Kind: controller.OutputShared, + }, } } @@ -161,6 +176,12 @@ func (ctrl *MachineStatusMetricsController) Run(ctx context.Context, r controlle return err } + if ctrl.maxRegisteredMachines > 0 { + if err = ctrl.reconcileRegistrationLimitNotification(ctx, r, metricsSpec); err != nil { + return err + } + } + select { case <-ctx.Done(): return nil @@ -169,6 +190,26 @@ func (ctrl *MachineStatusMetricsController) Run(ctx context.Context, r controlle } } +func (ctrl *MachineStatusMetricsController) reconcileRegistrationLimitNotification(ctx context.Context, r controller.Runtime, metricsSpec *specs.MachineStatusMetricsSpec) error { + if metricsSpec.RegistrationLimitReached { + return safe.WriterModify(ctx, r, omni.NewNotification(omni.NotificationMachineRegistrationLimitID), + func(res *omni.Notification) error { + res.TypedSpec().Value.Title = "Machine Registration Limit Reached" + res.TypedSpec().Value.Body = fmt.Sprintf( + "%d/%d machines registered. New machines will be rejected.", + metricsSpec.RegisteredMachinesCount, metricsSpec.RegisteredMachinesLimit) + res.TypedSpec().Value.Type = specs.NotificationSpec_WARNING + + return nil + }, + ) + } + + _, err := helpers.TeardownAndDestroy(ctx, r, omni.NewNotification(omni.NotificationMachineRegistrationLimitID).Metadata()) + + return err +} + func (ctrl *MachineStatusMetricsController) gatherMetrics(statuses iter.Seq[*omni.MachineStatus], numPendingMachines int) *specs.MachineStatusMetricsSpec { platformMetrics := make(map[string]uint32, len(ctrl.platformNames)) for _, p := range ctrl.platformNames { @@ -245,13 +286,15 @@ func (ctrl *MachineStatusMetricsController) gatherMetrics(statuses iter.Seq[*omn } return &specs.MachineStatusMetricsSpec{ - ConnectedMachinesCount: uint32(connectedMachines), - RegisteredMachinesCount: uint32(machines), - AllocatedMachinesCount: uint32(allocatedMachines), - PendingMachinesCount: uint32(numPendingMachines), - Platforms: platformMetrics, - SecureBootStatus: secureBootStatusMetrics, - UkiStatus: ukiMetrics, + ConnectedMachinesCount: uint32(connectedMachines), + RegisteredMachinesCount: uint32(machines), + AllocatedMachinesCount: uint32(allocatedMachines), + PendingMachinesCount: uint32(numPendingMachines), + Platforms: platformMetrics, + SecureBootStatus: secureBootStatusMetrics, + UkiStatus: ukiMetrics, + RegisteredMachinesLimit: ctrl.maxRegisteredMachines, + RegistrationLimitReached: ctrl.maxRegisteredMachines > 0 && uint32(machines) >= ctrl.maxRegisteredMachines, } } diff --git a/internal/backend/runtime/omni/controllers/omni/machine_status_metrics_test.go b/internal/backend/runtime/omni/controllers/omni/machine_status_metrics_test.go new file mode 100644 index 00000000..2f8ff7ad --- /dev/null +++ b/internal/backend/runtime/omni/controllers/omni/machine_status_metrics_test.go @@ -0,0 +1,104 @@ +// Copyright (c) 2026 Sidero Labs, Inc. +// +// Use of this software is governed by the Business Source License +// included in the LICENSE file. + +package omni_test + +import ( + "context" + "testing" + "time" + + "github.com/cosi-project/runtime/pkg/resource/rtestutils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/siderolabs/omni/client/api/omni/specs" + "github.com/siderolabs/omni/client/pkg/omni/resources/omni" + omnictrl "github.com/siderolabs/omni/internal/backend/runtime/omni/controllers/omni" + "github.com/siderolabs/omni/internal/backend/runtime/omni/controllers/testutils" +) + +func TestMachineStatusMetricsController_RegistrationLimit(t *testing.T) { + t.Parallel() + + for _, tt := range []struct { + name string + machineIDs []string + maxRegistered uint32 + expectCount uint32 + expectLimit uint32 + expectLimitReached bool + }{ + { + name: "limit not reached", + machineIDs: []string{"m1", "m2"}, + maxRegistered: 5, + expectCount: 2, + expectLimit: 5, + expectLimitReached: false, + }, + { + name: "limit reached", + machineIDs: []string{"m1", "m2"}, + maxRegistered: 2, + expectCount: 2, + expectLimit: 2, + expectLimitReached: true, + }, + { + name: "limit exceeded", + machineIDs: []string{"m1", "m2", "m3"}, + maxRegistered: 1, + expectCount: 3, + expectLimit: 1, + expectLimitReached: true, + }, + { + name: "unlimited when zero", + machineIDs: []string{"m1", "m2"}, + maxRegistered: 0, + expectCount: 2, + expectLimit: 0, + expectLimitReached: false, + }, + } { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithTimeout(t.Context(), 30*time.Second) + t.Cleanup(cancel) + + testutils.WithRuntime(ctx, t, testutils.TestOptions{}, + func(_ context.Context, tc testutils.TestContext) { + require.NoError(t, tc.Runtime.RegisterController(omnictrl.NewMachineStatusMetricsController(tt.maxRegistered))) + }, + func(ctx context.Context, tc testutils.TestContext) { + for _, id := range tt.machineIDs { + require.NoError(t, tc.State.Create(ctx, omni.NewMachineStatus(id))) + } + + rtestutils.AssertResource(ctx, t, tc.State, omni.MachineStatusMetricsID, func(res *omni.MachineStatusMetrics, a *assert.Assertions) { + a.EqualValues(tt.expectCount, res.TypedSpec().Value.RegisteredMachinesCount) + a.EqualValues(tt.expectLimit, res.TypedSpec().Value.RegisteredMachinesLimit) + a.Equal(tt.expectLimitReached, res.TypedSpec().Value.RegistrationLimitReached) + }) + + if tt.expectLimitReached { + rtestutils.AssertResource(ctx, t, tc.State, omni.NotificationMachineRegistrationLimitID, func(res *omni.Notification, a *assert.Assertions) { + a.Equal("Machine Registration Limit Reached", res.TypedSpec().Value.Title) + a.Contains(res.TypedSpec().Value.Body, "machines registered") + a.Equal(specs.NotificationSpec_WARNING, res.TypedSpec().Value.Type) + }) + } else { + // Notification should not exist when limit is not reached. + // Sleep briefly since there is no state change to poll on. + time.Sleep(500 * time.Millisecond) + rtestutils.AssertNoResource[*omni.Notification](ctx, t, tc.State, omni.NotificationMachineRegistrationLimitID) + } + }, + ) + }) + } +} diff --git a/internal/backend/runtime/omni/omni.go b/internal/backend/runtime/omni/omni.go index cd7e2fc0..a936d774 100644 --- a/internal/backend/runtime/omni/omni.go +++ b/internal/backend/runtime/omni/omni.go @@ -164,7 +164,7 @@ func NewRuntime(cfg *config.Params, talosClientFactory *talos.ClientFactory, dns }, omnictrl.NewMachineCleanupController(), omnictrl.NewMachineStatusLinkController(linkCounterDeltaCh), - &omnictrl.MachineStatusMetricsController{}, + omnictrl.NewMachineStatusMetricsController(cfg.Account.GetMaxRegisteredMachines()), omnictrl.NewVersionsController(cfg.Registries.GetImageFactoryBaseURL(), cfg.Features.GetEnableTalosPreReleaseVersions(), cfg.Registries.GetKubernetes()), omnictrl.NewClusterLoadBalancerController( cfg.Services.LoadBalancer.GetMinPort(), diff --git a/internal/backend/runtime/omni/state_access.go b/internal/backend/runtime/omni/state_access.go index 28fd1067..11af2fba 100644 --- a/internal/backend/runtime/omni/state_access.go +++ b/internal/backend/runtime/omni/state_access.go @@ -468,6 +468,7 @@ func filterAccess(ctx context.Context, access state.Access) error { omni.InstallationMediaType, omni.OngoingTaskType, omni.MachineStatusMetricsType, + omni.NotificationType, omni.ClusterMetricsType, omni.ClusterStatusMetricsType, system.SysVersionType, @@ -595,6 +596,7 @@ func filterAccessByType(access state.Access) error { omni.MachineExtensionsStatusType, omni.MachineExtensionsType, omni.MachineStatusMetricsType, + omni.NotificationType, omni.UpgradeRolloutType, authres.AuthConfigType, authres.IdentityLastActiveType, diff --git a/internal/backend/server.go b/internal/backend/server.go index 50f0b58b..e52cf8b5 100644 --- a/internal/backend/server.go +++ b/internal/backend/server.go @@ -600,15 +600,16 @@ func (s *Server) runMachineAPI(ctx context.Context) error { wgAddress := s.cfg.Services.Siderolink.WireGuard.GetEndpoint() params := siderolink.Params{ - WireguardEndpoint: wgAddress, - AdvertisedEndpoint: s.cfg.Services.Siderolink.WireGuard.GetAdvertisedEndpoint(), - MachineAPIEndpoint: s.cfg.Services.MachineAPI.GetEndpoint(), - MachineAPITLSCert: s.cfg.Services.MachineAPI.GetCertFile(), - MachineAPITLSKey: s.cfg.Services.MachineAPI.GetKeyFile(), - EventSinkPort: strconv.Itoa(s.cfg.Services.Siderolink.GetEventSinkPort()), - JoinTokensMode: s.cfg.Services.Siderolink.GetJoinTokensMode(), - UseGRPCTunnel: s.cfg.Services.Siderolink.GetUseGRPCTunnel(), - DisableLastEndpoint: s.cfg.Services.Siderolink.GetDisableLastEndpoint(), + WireguardEndpoint: wgAddress, + AdvertisedEndpoint: s.cfg.Services.Siderolink.WireGuard.GetAdvertisedEndpoint(), + MachineAPIEndpoint: s.cfg.Services.MachineAPI.GetEndpoint(), + MachineAPITLSCert: s.cfg.Services.MachineAPI.GetCertFile(), + MachineAPITLSKey: s.cfg.Services.MachineAPI.GetKeyFile(), + EventSinkPort: strconv.Itoa(s.cfg.Services.Siderolink.GetEventSinkPort()), + JoinTokensMode: s.cfg.Services.Siderolink.GetJoinTokensMode(), + UseGRPCTunnel: s.cfg.Services.Siderolink.GetUseGRPCTunnel(), + DisableLastEndpoint: s.cfg.Services.Siderolink.GetDisableLastEndpoint(), + MaxRegisteredMachines: s.cfg.Account.GetMaxRegisteredMachines(), } omniState := s.state.Default() diff --git a/internal/integration/auth_test.go b/internal/integration/auth_test.go index a7af073b..6a90a30b 100644 --- a/internal/integration/auth_test.go +++ b/internal/integration/auth_test.go @@ -1251,6 +1251,11 @@ func AssertResourceAuthz(rootCtx context.Context, rootCli *client.Client, client allowedVerbSet: readOnlyVerbSet, isSignatureSufficient: true, }, + { + resource: omni.NewNotification(uuid.New().String()), + allowedVerbSet: readOnlyVerbSet, + isSignatureSufficient: true, + }, { resource: omni.NewClusterMetrics(uuid.New().String()), allowedVerbSet: readOnlyVerbSet, diff --git a/internal/pkg/config/accessors.generated.go b/internal/pkg/config/accessors.generated.go index 999a82f2..3741fb8d 100644 --- a/internal/pkg/config/accessors.generated.go +++ b/internal/pkg/config/accessors.generated.go @@ -17,6 +17,17 @@ func (s *Account) SetId(v string) { s.Id = &v } +func (s *Account) GetMaxRegisteredMachines() uint32 { + if s == nil || s.MaxRegisteredMachines == nil { + return *new(uint32) + } + return *s.MaxRegisteredMachines +} + +func (s *Account) SetMaxRegisteredMachines(v uint32) { + s.MaxRegisteredMachines = &v +} + func (s *Account) GetName() string { if s == nil || s.Name == nil { return *new(string) diff --git a/internal/pkg/config/schema.json b/internal/pkg/config/schema.json index 2166b5c1..5834fb3c 100644 --- a/internal/pkg/config/schema.json +++ b/internal/pkg/config/schema.json @@ -85,6 +85,14 @@ "userPilot": { "description": "UserPilot contains UserPilot-related configuration.", "$ref": "#/definitions/UserPilot" + }, + "maxRegisteredMachines": { + "description": "MaxRegisteredMachines is the maximum number of registered machines allowed. 0 means unlimited.", + "type": "integer", + "minimum": 0, + "goJSONSchema": { + "type": "uint32" + } } } }, diff --git a/internal/pkg/config/types.generated.go b/internal/pkg/config/types.generated.go index 358df0c9..59d2bfce 100644 --- a/internal/pkg/config/types.generated.go +++ b/internal/pkg/config/types.generated.go @@ -10,6 +10,10 @@ type Account struct { // initial setup. Id *string `json:"id" yaml:"id"` + // MaxRegisteredMachines is the maximum number of registered machines allowed. 0 + // means unlimited. + MaxRegisteredMachines *uint32 `json:"maxRegisteredMachines,omitempty" yaml:"maxRegisteredMachines,omitempty"` + // Name is the human-readable name of the account. Name *string `json:"name" yaml:"name"` diff --git a/internal/pkg/siderolink/manager.go b/internal/pkg/siderolink/manager.go index 89eb2d2a..8d99cbd3 100644 --- a/internal/pkg/siderolink/manager.go +++ b/internal/pkg/siderolink/manager.go @@ -113,6 +113,7 @@ func NewManager( state, params.JoinTokensMode, params.UseGRPCTunnel, + params.MaxRegisteredMachines, ), } @@ -179,15 +180,16 @@ func getJoinToken(logger *zap.Logger) (string, error) { // Params are the parameters for the Manager. type Params struct { - WireguardEndpoint string - AdvertisedEndpoint string - MachineAPIEndpoint string - MachineAPITLSCert string - MachineAPITLSKey string - EventSinkPort string - JoinTokensMode config.SiderolinkServiceJoinTokensMode - UseGRPCTunnel bool - DisableLastEndpoint bool + WireguardEndpoint string + AdvertisedEndpoint string + MachineAPIEndpoint string + MachineAPITLSCert string + MachineAPITLSKey string + EventSinkPort string + JoinTokensMode config.SiderolinkServiceJoinTokensMode + MaxRegisteredMachines uint32 + UseGRPCTunnel bool + DisableLastEndpoint bool } // NewListener creates a new listener. diff --git a/internal/pkg/siderolink/provision.go b/internal/pkg/siderolink/provision.go index 36be1488..3ba1a0dd 100644 --- a/internal/pkg/siderolink/provision.go +++ b/internal/pkg/siderolink/provision.go @@ -12,6 +12,7 @@ import ( "net" "net/netip" "strings" + "sync" "time" "github.com/cosi-project/runtime/pkg/controller/generic" @@ -72,12 +73,13 @@ func (pc *provisionContext) isAuthorizedSecureFlow() bool { } // NewProvisionHandler creates a new ProvisionHandler. -func NewProvisionHandler(logger *zap.Logger, state state.State, joinTokenMode config.SiderolinkServiceJoinTokensMode, forceWireguardOverGRPC bool) *ProvisionHandler { +func NewProvisionHandler(logger *zap.Logger, state state.State, joinTokenMode config.SiderolinkServiceJoinTokensMode, forceWireguardOverGRPC bool, maxRegisteredMachines uint32) *ProvisionHandler { return &ProvisionHandler{ logger: logger, state: state, joinTokenMode: joinTokenMode, forceWireguardOverGRPC: forceWireguardOverGRPC, + maxRegisteredMachines: maxRegisteredMachines, } } @@ -88,6 +90,8 @@ type ProvisionHandler struct { logger *zap.Logger state state.State joinTokenMode config.SiderolinkServiceJoinTokensMode + registrationMu sync.Mutex + maxRegisteredMachines uint32 forceWireguardOverGRPC bool } @@ -303,7 +307,7 @@ func (h *ProvisionHandler) provision(ctx context.Context, provisionContext *prov return nil, status.Error(codes.PermissionDenied, "unauthorized") } - return establishLink[*siderolinkres.Link](ctx, h.logger, h.state, provisionContext, nil, nil) + return establishLink[*siderolinkres.Link](ctx, h, provisionContext, nil, nil) } if !provisionContext.isAuthorizedSecureFlow() { @@ -316,7 +320,7 @@ func (h *ProvisionHandler) provision(ctx context.Context, provisionContext *prov // put the machine into the limbo state by creating the pending machine resource // the controller will then pick it up and create a wireguard peer for it if provisionContext.requestNodeUniqueToken == nil { - return establishLink[*siderolinkres.PendingMachine](ctx, h.logger, h.state, provisionContext, nil, nil) + return establishLink[*siderolinkres.PendingMachine](ctx, h, provisionContext, nil, nil) } annotationsToAdd := []string{} @@ -332,7 +336,7 @@ func (h *ProvisionHandler) provision(ctx context.Context, provisionContext *prov annotationsToAdd = append(annotationsToAdd, siderolinkres.ForceValidNodeUniqueToken) } - response, err := establishLink[*siderolinkres.Link](ctx, h.logger, h.state, provisionContext, annotationsToAdd, annotationsToRemove) + response, err := establishLink[*siderolinkres.Link](ctx, h, provisionContext, annotationsToAdd, annotationsToRemove) if err != nil { if errors.Is(err, errUUIDConflict) { logger.Info("detected UUID conflict", zap.String("peer", provisionContext.request.NodePublicKey)) @@ -340,7 +344,7 @@ func (h *ProvisionHandler) provision(ctx context.Context, provisionContext *prov // link is there, but the token doesn't match and the fingerprint differs, keep the machine in the limbo state // mark pending machine as having the UUID conflict, PendingMachineStatus controller should inject the new UUID // and the machine will re-join - return establishLink[*siderolinkres.PendingMachine](ctx, h.logger, h.state, provisionContext, []string{siderolinkres.PendingMachineUUIDConflict}, nil) + return establishLink[*siderolinkres.PendingMachine](ctx, h, provisionContext, []string{siderolinkres.PendingMachineUUIDConflict}, nil) } return nil, err @@ -349,6 +353,27 @@ func (h *ProvisionHandler) provision(ctx context.Context, provisionContext *prov return response, nil } +// createWithRegistrationLimit creates the resource, checking the registration limit for new Link resources under the registration mutex to prevent concurrent provisions from exceeding the limit. +func (h *ProvisionHandler) createWithRegistrationLimit(ctx context.Context, r resource.Resource, provisionContext *provisionContext) error { + isNewLink := provisionContext.link == nil && r.Metadata().Type() == siderolinkres.LinkType + + if isNewLink && h.maxRegisteredMachines > 0 { + h.registrationMu.Lock() + defer h.registrationMu.Unlock() + + links, err := safe.ReaderListAll[*siderolinkres.Link](ctx, h.state) + if err != nil { + return err + } + + if uint32(links.Len()) >= h.maxRegisteredMachines { + return status.Errorf(codes.ResourceExhausted, "machine registration limit reached: %d/%d machines registered", links.Len(), h.maxRegisteredMachines) + } + } + + return h.state.Create(ctx, r) +} + func (h *ProvisionHandler) removePendingMachine(ctx context.Context, pendingMachine *siderolinkres.PendingMachine) error { ctx, cancel := context.WithTimeout(ctx, time.Second*5) defer cancel() @@ -380,9 +405,11 @@ func (h *ProvisionHandler) removePendingMachine(ctx context.Context, pendingMach return nil } -func establishLink[T res](ctx context.Context, logger *zap.Logger, st state.State, provisionContext *provisionContext, - annotationsToAdd []string, annotationsToRemove []string, +func establishLink[T res](ctx context.Context, h *ProvisionHandler, provisionContext *provisionContext, annotationsToAdd []string, annotationsToRemove []string, ) (*pb.ProvisionResponse, error) { + logger := h.logger + st := h.state + link, err := newLink[T](provisionContext, annotationsToAdd, annotationsToRemove) if err != nil { return nil, err @@ -415,7 +442,7 @@ func establishLink[T res](ctx context.Context, logger *zap.Logger, st state.Stat } } - if err = st.Create(ctx, link); err != nil { + if err = h.createWithRegistrationLimit(ctx, link, provisionContext); err != nil { if !state.IsConflictError(err) { return nil, err } diff --git a/internal/pkg/siderolink/provision_test.go b/internal/pkg/siderolink/provision_test.go index c5cf3889..5777f19c 100644 --- a/internal/pkg/siderolink/provision_test.go +++ b/internal/pkg/siderolink/provision_test.go @@ -122,7 +122,7 @@ func TestProvision(t *testing.T) { require.NoError(t, eg.Wait()) }) - provisionHandler := siderolink.NewProvisionHandler(logger, state, mode, false) + provisionHandler := siderolink.NewProvisionHandler(logger, state, mode, false, 0) config := siderolinkres.NewConfig() config.TypedSpec().Value.ServerAddress = "127.0.0.1" @@ -745,4 +745,87 @@ func TestProvision(t *testing.T) { _, err = provisionHandler.Provision(ctx, request) require.Equal(t, codes.PermissionDenied, status.Code(err)) }) + + t.Run("registration limit blocks new machines", func(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithTimeout(t.Context(), time.Second*5) + t.Cleanup(cancel) + + st, _ := setup(ctx, t, config.SiderolinkServiceJoinTokensModeStrict) + + // Override the handler with one that has a limit of 2. + provisionHandler := siderolink.NewProvisionHandler(zaptest.NewLogger(t), st, config.SiderolinkServiceJoinTokensModeStrict, false, 2) + + // Create 2 links to reach the limit. + for _, id := range []string{"m1", "m2"} { + require.NoError(t, st.Create(ctx, siderolinkres.NewLink(id, &specs.SiderolinkSpec{}))) + } + + uniqueToken, tokenErr := jointoken.NewNodeUniqueToken(uuid.NewString(), uuid.NewString()).Encode() + require.NoError(t, tokenErr) + + _, err := provisionHandler.Provision(ctx, &pb.ProvisionRequest{ + NodeUuid: "m3", + NodePublicKey: genKey(), + TalosVersion: new("v1.9.0"), + JoinToken: new(validToken), + NodeUniqueToken: new(uniqueToken), + }) + require.Error(t, err) + require.Equal(t, codes.ResourceExhausted, status.Code(err)) + require.Contains(t, err.Error(), "2/2 machines registered") + }) + + t.Run("registration limit allows when under", func(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithTimeout(t.Context(), time.Second*5) + t.Cleanup(cancel) + + st, _ := setup(ctx, t, config.SiderolinkServiceJoinTokensModeStrict) + + provisionHandler := siderolink.NewProvisionHandler(zaptest.NewLogger(t), st, config.SiderolinkServiceJoinTokensModeStrict, false, 5) + + require.NoError(t, st.Create(ctx, siderolinkres.NewLink("m1", &specs.SiderolinkSpec{}))) + + uniqueToken, tokenErr := jointoken.NewNodeUniqueToken(uuid.NewString(), uuid.NewString()).Encode() + require.NoError(t, tokenErr) + + _, err := provisionHandler.Provision(ctx, &pb.ProvisionRequest{ + NodeUuid: "m2", + NodePublicKey: genKey(), + TalosVersion: new("v1.9.0"), + JoinToken: new(validToken), + NodeUniqueToken: new(uniqueToken), + }) + require.NoError(t, err) + }) + + t.Run("registration limit unlimited when zero", func(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithTimeout(t.Context(), time.Second*5) + t.Cleanup(cancel) + + st, _ := setup(ctx, t, config.SiderolinkServiceJoinTokensModeStrict) + + provisionHandler := siderolink.NewProvisionHandler(zaptest.NewLogger(t), st, config.SiderolinkServiceJoinTokensModeStrict, false, 0) + + for _, id := range []string{"m1", "m2", "m3"} { + require.NoError(t, st.Create(ctx, siderolinkres.NewLink(id, &specs.SiderolinkSpec{}))) + } + + uniqueToken, tokenErr := jointoken.NewNodeUniqueToken(uuid.NewString(), uuid.NewString()).Encode() + require.NoError(t, tokenErr) + + _, err := provisionHandler.Provision(ctx, &pb.ProvisionRequest{ + NodeUuid: "m4", + NodePublicKey: genKey(), + TalosVersion: new("v1.9.0"), + JoinToken: new(validToken), + NodeUniqueToken: new(uniqueToken), + }) + require.NoError(t, err) + }) }