syntax = "proto3";
package specs;

option go_package = "github.com/siderolabs/omni/client/api/omni/specs";

import "talos/machine/machine.proto";
import "omni/specs/virtual.proto";
import "omni/management/management.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";


// MachineSpec describes a Machine.
message MachineSpec {
  // IP which can be used to access Talos API.
  string management_address = 1;
  // Connected is copied from the corresponding Link resource.
  bool connected = 2;
  reserved 3;
  reserved 4;
  // UseGrpcTunnel enables using gRPC tunnel for the machine.
  bool use_grpc_tunnel = 5;
}

// SecurityState describes the UKI and secure boot information of the machine.
message SecurityState {
  // SecureBoot is true if secure boot is detected to be available and enabled.
  bool secure_boot = 1; // use existing logic
  // BootedWithUki is true if the machine is booted with a UKI. Always true if secure boot is enabled.
  bool booted_with_uki = 2;
}

message Overlay {
  string name = 1;
  string image = 2;
}

message MetaValue {
  uint32 key = 1;
  string value = 2;
}

// MachineStatusSpec describes state of a Machine.
message MachineStatusSpec {
  // HardwareStatus describes machine hardware status.
  message HardwareStatus {
    // Processor describes machine CPU.
    message Processor {
      // Number of cores.
      uint32 core_count = 1;
      // Number of threads.
      uint32 thread_count = 2;
      // CPU frequency in MHz.
      uint32 frequency = 3;
      // CPU manufacturer and model.
      string description = 4;
      // CPU manufacturer.
      string manufacturer = 5;
    }

    // MemoryModule describes machine memory.
    message MemoryModule {
      // Size of memory in MB.
      uint32 size_mb = 1;
      // Memory manufacturer and model.
      string description = 2;
    }

    // BlockDevice describes a block device.
    message BlockDevice {
      // Size indicates the disk size in bytes.
      uint64 size = 1;
      // Model idicates the disk model.
      string model = 2;
      // Linux blockdevice name (e.g. `/dev/sda`).
      string linux_name = 3;
      // Name as in `/sys/block/<dev>/device/name`.
      string name = 4;
      // Serial as in `/sys/block/<dev>/device/serial`.
      string serial = 5;
      // Uuid as in `/sys/block/<dev>/device/uuid`.
      string uuid = 7;
      // Wwid as in `/sys/block/<dev>/device/wwid`.
      string wwid = 8;
      // Type is a type of the disk: nvme, ssd, hdd, sd card.
      string type = 9;
      // BusPath is the bus path of the disk.
      string bus_path = 10;
      // SystemDisk is the system disk flag.
      bool system_disk = 11;
      // Readonly disk.
      bool readonly = 12;
      // Transport is the disk transport.
      string transport = 13;
    }

    // CPU information.
    repeated Processor processors = 1;
    // Memory information.
    repeated MemoryModule memory_modules = 2;
    // Blockdevice information.
    repeated BlockDevice blockdevices = 3;
    // Machine architecture.
    string arch = 4;
  }

  // NetworkStatus describes the status of a machine network .
  message NetworkStatus {
    // Physical network interfaces.
    message NetworkLinkStatus {
      // Linux interface name.
      string linux_name = 1;
      // MAC address.
      string hardware_address = 2;
      // Speed in Mbps.
      uint32 speed_mbps = 3;
      // Link status.
      bool link_up = 4;
      // Hardware description.
      string description = 5;
    };

    // Current machine hostname.
    string hostname = 1;
    // Current machine domainname.
    string domainname = 2;
    // List of machine IPs.
    repeated string addresses = 3;
    // List of default gateway IPs.
    repeated string default_gateways = 4;
    // List of physical network interfaces.
    repeated NetworkLinkStatus network_links = 5;
  }

  // PlatformMetadata describes platform-specific information.
  message PlatformMetadata {
    // Platform is the name of the platform (e.g. `aws`, `gcp`, `azure`).
    string platform = 1;
    // Hostname is the hostname of the machine.
    string hostname = 2;
    // Region (in the cloud).
    string region = 3;
    // Availability zone (in the cloud).
    string zone = 4;
    // Instance type (in the cloud).
    string instance_type = 5;
    // Instance ID (in the cloud).
    string instance_id = 6;
    // Provider ID (for the Node resource).
    string provider_id = 7;
    // Spot instance flag.
    bool spot = 8;
  }

  message Schematic {
    message InitialState {
      repeated string extensions = 1;
    }

    // Id is the image factory schematic id used for the image generation.
    //
    // This must be be plain id computed solely from the system extensions, not including the kernel command line arguments, META content etc.
    string id = 1;

    // Invalid marks the machine as having extensions installed bypassing image factory.
    // Which makes it impossible to detect schematic id and manage the image generation
    // using image factory.
    bool invalid = 2;

    // Extensions is the list of extensions installed on the machine.
    repeated string extensions = 3;

    // InitialSchematic is the one first schematic the machine was using when it was connected to Omni for the first time.
    string initial_schematic = 4;

    reserved 5;

    // Overlay contains the information about the overlay used during the machine image generation.
    // It is used by SBC images.
    Overlay overlay = 6;

    // KernelArgs is the kernel command line arguments used during the machine image generation.
    repeated string kernel_args = 7;

    // MetaValues is the list of meta values used during the machine image generation.
    repeated MetaValue meta_values = 8;

    // FullId is the full id of the schematic - including the kernel command line arguments, META content etc.
    //
    // It is used instead of Id primarily when the machine has secure boot enabled.
    string full_id = 9;

    // InAgentMode indicates that the machine is running in agent mode.
    bool in_agent_mode = 10;

    // Raw contains the raw schematic data YAML as a string.
    string raw = 11;

    // InitialState is the initial schematic configuration of the machine.
    InitialState initial_state = 12;
  }

  message Diagnostic {
    string id = 1;
    string message = 2;
    repeated string details = 3;
  }

  // Talos version.
  string talos_version = 1;

  // Hardware-related information.
  HardwareStatus hardware = 2;

  // Network-related information.
  NetworkStatus network = 3;

  // Set if the last poll resulted in an error.
  string last_error = 4;

  // Management address is copied from the machine resource.
  string management_address = 5;

  // Connected is copied from the corresponding Link resource.
  bool connected = 6;

  // Maintenance flag means that the node is running in the maintenance mode.
  bool maintenance = 7;

  reserved 8;

  // Cluster is the name of the cluster the machine belongs to.
  string cluster = 9;

  enum Role {
    NONE = 0;
    CONTROL_PLANE = 1;
    WORKER = 2;
  }

  // Role is the role of the machine in the cluster.
  Role role = 10;

  // Platform-specific information.
  PlatformMetadata platform_metadata = 11;

  reserved 12;

  map<string, string> image_labels = 13;

  Schematic schematic = 14;

  reserved 15;

  // InitialTalosVersion is set only once when the machine first joined Omni.
  string initial_talos_version = 16;

  reserved 17;
  reserved 18;

  repeated Diagnostic diagnostics = 19;

  enum PowerState {
    POWER_STATE_UNKNOWN = 0;
    POWER_STATE_UNSUPPORTED = 1;
    POWER_STATE_ON = 2;
    POWER_STATE_OFF = 3;
  };

  PowerState power_state = 20;

  SecurityState security_state = 21;

  string kernel_cmdline = 22;
}

// TalosConfigSpec describes a Talos cluster config.
message TalosConfigSpec {
  // Ca certificate authority.
  string ca = 1;

  // Crt certificate.
  string crt = 2;

  // Key certificate key.
  string key = 3;
}

// Cluster describes a Talos cluster.
message ClusterSpec {
  message Features {
    // EnableWorkloadProxy enables workload proxy.
    bool enable_workload_proxy = 1;
    // DiskEncryption enables disk encryption on all nodes.
    bool disk_encryption = 2;
    // UseEmbeddedDiscoveryService enables the embedded discovery service.
    bool use_embedded_discovery_service = 3;
  }

  reserved 1;

  // KubernetesVersion to use on the node.
  string kubernetes_version = 2;

  // TalosVersion cluster wide Talos version.
  string talos_version = 3;

  // Features are the cluster features.
  Features features = 4;

  // Backup describes the backup configuration. If it set to null that means that backups are disabled for this cluster.
  EtcdBackupConf backup_configuration = 5;
}

// ClusterTaintSpec describe a Talos cluster taint.
message ClusterTaintSpec {}

// EtcdBackupConf describes the backup configuration.
message EtcdBackupConf {
  // Interval is the interval between backups. If not set, backups are disabled.
  google.protobuf.Duration interval = 1;
  // Enabled etcd backups.
  bool enabled = 2;
}

// EtcdBackupEncryptionSpec describes the backup encryption.
message EtcdBackupEncryptionSpec {
  bytes encryption_key = 1;
}

// EtcdBackupHeader describes the backup header.
message EtcdBackupHeader {
  // Version is the version of the backup creator.
  int64 version = 1;
}

// EtcdBackupSpec describes the backup.
message EtcdBackupSpec {
  // CreatedAt is the time when the backup was created.
  google.protobuf.Timestamp created_at = 1;

  // Snapshot is the snapshot file name.
  string snapshot = 2;

  // Size specifies the etcd backup size.
  uint64 size = 3;
}

// BackupDataSpec describes the data needed for etcd backup.
message BackupDataSpec {
  google.protobuf.Duration interval = 1;
  string cluster_uuid = 2;
  bytes encryption_key = 3;
  string aes_cbc_encryption_secret = 4;
  string secretbox_encryption_secret = 5;
}

// EtcdBackupS3ConfSpec describes the S3 configuration for the backup process.
message EtcdBackupS3ConfSpec {
  string bucket = 1;
  string region = 2;
  string endpoint = 3;
  string access_key_id = 4;
  string secret_access_key = 5;
  string session_token = 6;
}

// EtcdBackupStatus describes cluster last backup status.
message EtcdBackupStatusSpec {
  enum Status {
    Unknown = 0;
    Ok = 1;
    Error = 2;
    Running = 3;
  }

  // Status is the status of the last backup.
  Status status = 1;

  // Error is the error message if the backup failed.
  string error = 2;

  // LastBackupTime is the time of the last backup.
  google.protobuf.Timestamp last_backup_time = 3;

  // LastBackupAttempt is the time of the last backup attempt.
  google.protobuf.Timestamp last_backup_attempt = 4;
}

// EtcdManualBackupSpec describes the manual backup request.
message EtcdManualBackupSpec {
  // BackupAt is the time when the backup should be created.
  google.protobuf.Timestamp backup_at = 1;
}

// EtcdBackupStoreStatusSpec is internal resource that describes store configuration name and configuration last error.
message EtcdBackupStoreStatusSpec {
  // ConfigurationName is the name of the configuration (disabled|local|s3).
  string configuration_name = 1;

  // ConfigurationError is the error message if the configuration is invalid.
  string configuration_error = 2;
}

// EtcdBackupOverallStatusSpec describes the overall etcd backup system status.
message EtcdBackupOverallStatusSpec {
  // ConfigurationName is the name of the configuration (disabled|local|s3).
  string configuration_name = 1;

  // ConfigurationError is the error message if the configuration is invalid.
  string configuration_error = 2;

  // LastBackupStatus is the status of the last backup.
  EtcdBackupStatusSpec last_backup_status = 3;
}

// ClusterMachineSpec describes a machine attached to a Cluster.
message ClusterMachineSpec {
  reserved 1;
  // KubernetesVersion to use on the machine (copied from Cluster at the moment of creation).
  string kubernetes_version = 2;
}

// ClusterMachineConfigPatchesSpec keeps the list of config patches to be applied on the machine.
message ClusterMachineConfigPatchesSpec {
  // List of patches combined from all sources, as a final list of patches to apply.
  //
  // Deprecated: use accessor methods GetUncompressedData/SetUncompressedData to manage this field.
  repeated string patches = 1;

  // List of patches combined from all sources, as a final list of patches to apply.
  //
  // Deprecated: use accessor methods GetUncompressedData/SetUncompressedData to manage this field.
  repeated bytes compressed_patches = 2;
}

// ClusterMachineTalosVersionSpec describes a machine Talos version and schematic.
message ClusterMachineTalosVersionSpec {
  string talos_version = 1;
  string schematic_id = 2;
}

// ClusterMachineConfigSpec stores generated Talos node machine config.
message ClusterMachineConfigSpec {
  // Data contains the config bytes. It is only set if the config is not compressed. Otherwise, CompressedData is set instead.
  //
  // Deprecated: use accessor methods GetUncompressedData/SetUncompressedData to manage this field.
  bytes data = 1;
  reserved 2;
  string generation_error = 3;

  // CompressedData contains the config bytes. It is only set if the config is not compressed. Otherwise, CompressedData is set instead.
  //
  // Deprecated: use accessor methods GetUncompressedData/SetUncompressedData to manage this field.
  bytes compressed_data = 4;

  // WithoutComments indicates that the config was generated without comments.
  bool without_comments = 5;

  // GrubUseUkiCmdline indicates the .machine.install.grubUseUKICmdline status.
  bool grub_use_uki_cmdline = 6;
}

// ClusterMachineConfigSpec stores generated Talos node machine config.
message RedactedClusterMachineConfigSpec {
  // Data contains the config bytes. It is only set if the config is not compressed. Otherwise, CompressedData is set instead.
  //
  // Deprecated: use accessor methods GetUncompressedData/SetUncompressedData to manage this field.
  string data = 1;

  // CompressedData contains the config bytes. It is only set if the config is not compressed. Otherwise, CompressedData is set instead.
  //
  // Deprecated: use accessor methods GetUncompressedData/SetUncompressedData to manage this field.
  bytes compressed_data = 2;
}

// ClusterMachineIdentity keeps ClusterMachine related node information.
message ClusterMachineIdentitySpec {
  // NodeIdentity is Talos node identity from Identity resource.
  string node_identity = 1;
  // EtcdMemberId is the id of the node how it's represented in the etcd quorum.
  uint64 etcd_member_id = 2;
  // Nodename is the Kubernetes node name.
  string nodename = 3;
  // NodeIps are the IPs of the Kubernetes node.
  repeated string node_ips = 8;

  // DiscoveryServiceEndpoint is the endpoint of the discovery service used by the node.
  // It contains the protocol prefix (http://|https://) and the port.
  //
  // It is empty if discovery service is not enabled.
  string discovery_service_endpoint = 9;
}

enum ConfigApplyStatus {
  UNKNOWN = 0;
  PENDING = 1;
  APPLIED = 2;
  FAILED = 3;
}

// ClusterMachineStatusSpec
message ClusterMachineStatusSpec {
  message ProvisionStatus {
    string provider_id = 1;
    string request_id = 2;
  }

  // Ready is true if all services are healthy.
  bool ready = 1;

  enum Stage {
    UNKNOWN = 0;
    BOOTING = 1;
    INSTALLING = 2;
    UPGRADING = 6;
    CONFIGURING = 3;
    RUNNING = 4;
    REBOOTING = 7;
    SHUTTING_DOWN = 8;
    BEFORE_DESTROY = 9;
    DESTROYING = 5;
    POWERING_ON = 10;
    POWERED_OFF = 11;
  }

  Stage stage = 2;

  // ApidAvailable is true if the node is a control plane node and the apid service is healthy.
  bool apid_available = 3;

  bool config_up_to_date = 4;
  string last_config_error = 5;

  // Management address is copied from the machine status resource.
  string management_address = 6;

  ConfigApplyStatus config_apply_status = 7;

  // IsRemoved means that the machine removed from Omni.
  bool is_removed = 8;

  // ProvisionStatus is set when the cluster machine is provisioned using a machine request.
  ProvisionStatus provision_status = 9;
}

// Machines counts the number of machines in a set including health status.
message Machines {
  // Total machines currently allocated.
  uint32 total = 1;
  // Healthy machines.
  uint32 healthy = 2;
  // Connected represents the number of machines in a machine set connected to the wireguard network.
  uint32 connected = 3;
  // Requested machines count, same as total for manual allocation, may differ for machine class mode.
  uint32 requested = 4;
}

// ClusterStatusSpec aggregates general information about a cluster.
message ClusterStatusSpec {
  // Cluster is available when at least one controlplane node has APId up.
  bool available = 1;

  Machines machines = 2;

  enum Phase {
    UNKNOWN = 0;
    SCALING_UP = 1;
    SCALING_DOWN = 2;
    RUNNING = 3;
    DESTROYING = 4;
  }

  Phase phase = 3;

  bool ready = 4;
  bool kubernetesAPIReady = 5;
  bool controlplaneReady = 6;
  bool has_connected_control_planes = 7;

  // UseEmbeddedDiscoveryService indicates if the embedded discovery service should be used by this cluster or not.
  //
  // This is the final decision, taking the feature toggle, the version of the cluster and the Omni instance configuration (whether the feature is enabled or not) into account.
  bool use_embedded_discovery_service = 8;

  // TalosVersion is the Talos version of the cluster, copied from the Cluster spec.
  string talos_version = 9;

  // KubernetesVersion is the Kubernetes version of the cluster, copied from the Cluster spec.
  string kubernetes_version = 10;
}

// ClusterUUID keeps the UUID of the cluster.
message ClusterUUID {
  string uuid = 1;
}

// ClusterConfigVersion keeps the version of Talos which was used for initial config generation.
message ClusterConfigVersionSpec {
  string version = 1;
}

// ClusterMachineConfigStatusSpec machine configuration status spec.
message ClusterMachineConfigStatusSpec {
  reserved 1;
  reserved 2;

  string cluster_machine_config_version = 3;
  reserved 4;
  string cluster_machine_config_sha256 = 5;
  string last_config_error = 6;
  string talos_version = 7;
  string schematic_id = 8;

  // RedactedClusterMachineConfig contains the config bytes. It is only set if the config is not compressed. Otherwise, CompressedData is set instead.
  //
  // Deprecated: use accessor methods GetUncompressedData/SetUncompressedData to manage this field.
  string redacted_current_machine_config = 9;

  // CompressedRedactedMachineConfig contains the config bytes. It is only set if the config is not compressed. Otherwise, CompressedData is set instead.
  //
  // Deprecated: use accessor methods GetUncompressedData/SetUncompressedData to manage this field.
  bytes compressed_redacted_machine_config = 10;
}

message MachinePendingUpdatesSpec {
  message Upgrade {
    string from_schematic = 1;
    string to_schematic = 2;

    string from_version = 3;
    string to_version = 4;
  }

  // Upgrade represents pending machine upgrade.
  Upgrade upgrade = 1;
  // ConfigDiff represents the redacted machine config diff.
  string config_diff = 2;
}

// ClusterBootstrapStatusSpec keeps track of bootstrap calls for a cluster.
message ClusterBootstrapStatusSpec {
  bool bootstrapped = 1;
}

// ClusterSecretsSpec describes cluster secrets.
message ClusterSecretsSpec {
  // Data holds serialized cluster secrets.
  bytes data = 1;
  // Imported holds origin of the cluster secrets.
  bool imported = 2;

  message Certs {
    message CA {
      bytes crt = 1;
      bytes key = 2;
    }

    // Os holds the cluster OS CA.
    CA os = 1;

    // K8s holds the cluster Kubernetes CA.
    CA k8s = 2;
  }

  // Extra_certs holds extra cluster CAs to be used during CA rotation.
  Certs extra_certs = 3;
}

// ImportedClusterSecretsSpec describes imported cluster secrets.
message ImportedClusterSecretsSpec {
  // data holds imported cluster secrets.
  string data = 1;
}

// LoadBalancerConfigSpec describes the configuration of a load balancer.
message LoadBalancerConfigSpec {
  reserved 1;
  string bind_port = 2;
  // Full URL of the loadbalancer inside Omni environment.
  string siderolink_endpoint = 4;
  // IP adresses of the endpoints
  repeated string endpoints = 3;
}

// LoadBalancerStatusSpec reflects the status of a load balancer.
message LoadBalancerStatusSpec {
  reserved 1;
  reserved 2;
  bool healthy = 3;
  bool stopped = 4;
}

// KubernetesVersionSpec represents an available Kubernetes version.
message KubernetesVersionSpec {
  string version = 1;
}

// TalosVersionSpec represents an available Talos version.
message TalosVersionSpec {
  string version = 1;
  repeated string compatible_kubernetes_versions = 2;
  bool deprecated = 3;
}

// InstallationMediaSpec resource describes a Talos installation media that can be generated by the image factory. It also describes the necessary parameters to be passed to the image factory.
message InstallationMediaSpec {
  // Name is the human readable name of the image.
  string name = 1;
  string architecture = 2;
  string profile = 3;
  string contentType = 6;
  // SrcFilePrefix defines the src filename to download the image from.
  string src_file_prefix = 7;
  // DestFilePrefix defines the dest filename to download the image to.
  string dest_file_prefix = 8;
  // Extension defines the dest filename extension.
  string extension = 9;
  // NoSecureBoot means that the installation media doesn't support SecureBoot generation.
  bool no_secure_boot = 11;
  // Overlay is the overlay to be always used when generating the image of this type.
  string overlay = 12;
  // MinTalosVersion defines minimum Talos version supported for the supplied configuration.
  string min_talos_version = 13;
}

// ConfigPatchSpec represents the machine config patch.
message ConfigPatchSpec {
  // Data contains the config patch bytes. It is only set if the config patch is not compressed. Otherwise, CompressedData is set instead.
  //
  // Deprecated: use accessor methods GetUncompressedData/SetUncompressedData to manage this field.
  string data = 1;

  // CompressedData contains the config patch bytes. It is only set if the config patch is not compressed. Otherwise, CompressedData is set instead.
  //
  // Deprecated: use accessor methods GetUncompressedData/SetUncompressedData to manage this field.
  bytes compressed_data = 2;
}

// MachineSetPhaseSpec is machine set phase.
enum MachineSetPhase {
  Unknown = 0;
  ScalingUp = 1;
  ScalingDown = 2;
  Running = 3;
  Destroying = 4;
  Failed = 5;
  Reconfiguring = 6;
  Upgrading = 7;
}

// MachineSetSpec describes the cluster machine group.
message MachineSetSpec {
  // MachineClass defines the machine class allocation mode config.
  message MachineClass {
    enum Type {
      // Static uses the count defined in the count field.
      Static = 0;
      // Unlimited allocates all available machines from the machine class/request set.
      Unlimited = 1;
    }

    // Name defines the machine class/machine request set id to select the machines from.
    string name = 1;
    // MachineCount defines fixed amount of the machines to allocated from the machine class/request set.
    uint32 machine_count = 2;
    // AllocationType defines special constants for the amount of machines to be allocated.
    Type allocation_type = 3;
  }

  // MachineAllocation defines the machine automatic allocation configuration.
  message MachineAllocation {
    enum Type {
      // Static uses the count defined in the count field.
      Static = 0;
      // Unlimited allocates all available machines from the machine class/request set.
      Unlimited = 1;
    }

    // Name defines the machine class/machine request set id to select the machines from.
    string name = 1;
    // MachineCount defines fixed amount of the machines to allocated from the machine class/request set.
    uint32 machine_count = 2;
    // AllocationType defines special constants for the amount of machines to be allocated.
    Type allocation_type = 3;
    reserved 4;
  }

  // BootstrapSpec defines the bootstrap spec for the control plane machine set.
  // It can contain a reference to an etcd backup, which can be used to bootstrap etcd.
  message BootstrapSpec {
    // ClusterUuid is the UUID of the cluster to bootstrap. It can be obtained via `omnictl get clusteruuid <cluster-name>`
    string cluster_uuid = 1;

    // Snapshot is the file name of the etcd snapshot to restore from. It follows the format similar to `FFFFFFFFFFFFFFFF.snapshot`.
    string snapshot = 2;
  }

  // UpdateStrategy defines the update strategy of the machine set.
  enum UpdateStrategy {
    Unset = 0;
    Rolling = 1;
  }

  // RollingUpdateStrategyConfig defines the rolling update strategy configuration.
  message RollingUpdateStrategyConfig {
    // MaxParallelism is the maximum number of machines that can be processed in parallel.
    // When unset or set to 0, it defaults to 1.
    uint32 max_parallelism = 1;
  }

  // UpdateConfig defines the update configuration.
  message UpdateStrategyConfig {
    // Rolling is the rolling update configuration.
    // Used only when the UpdateStrategy is set to Rolling.
    RollingUpdateStrategyConfig rolling = 1;
  }

  // UpdateStrategy is the update strategy of the machine set.
  UpdateStrategy update_strategy = 1;

  // MachineClass is the machine class to pick machines from for the machine set.
  // Use MachineAllocation instead.
  MachineAllocation machine_class = 2 [deprecated = true];

  // BootstrapSpec defines the bootstrapping spec of the machine set.
  // This field is immutable, only valid for the control plane machine set and used only once at the creation time.
  // When set, the machine set won't be created from scratch, instead, it will be bootstrapped using the given spec.
  BootstrapSpec bootstrap_spec = 3;

  // DeleteStrategy defines the delete strategy of the machine set.
  UpdateStrategy delete_strategy = 4;

  // UpdateStrategyConfig defines the update strategy configuration.
  UpdateStrategyConfig update_strategy_config = 5;

  // DeleteStrategyConfig defines the delete strategy configuration.
  UpdateStrategyConfig delete_strategy_config = 6;

  // MachineAllocation rule to pick machines for the machine set.
  MachineAllocation machine_allocation = 7;

  // UpgradeStrategy defines the upgrade strategy of the machine set.
  UpdateStrategy upgrade_strategy = 8;

  // UpgradeStrategyConfig defines the upgrade strategy configuration.
  UpdateStrategyConfig upgrade_strategy_config = 9;
}

// TalosUpgradeStatusSpec contains the status of the Talos upgrade process.
message TalosUpgradeStatusSpec {
  enum Phase {
    Unknown = 0;
    Upgrading = 1;
    Done = 2;
    Failed = 3;
    Reverting = 4;
    UpdatingMachineSchematics = 5;
  }

  // Current upgrade phase.
  Phase phase = 1;

  // If phase is Failed, this contains the error message.
  string error = 2;

  // If phase is Upgrading, this contains the current upgrade step.
  string step = 3;

  // If phase is Upgrading, this contains the current upgrade step progress.
  string status = 4;

  // Last successful upgrade version.
  string last_upgrade_version = 5;

  // Current version of the upgrade (if phase == Upgrading).
  string current_upgrade_version = 6;

  // List of versions available for upgrade.
  repeated string upgrade_versions = 7;
}

// MachineSetStatusSpec describes machine set status.
message MachineSetStatusSpec {
  MachineSetPhase phase = 1;
  bool ready = 2;
  string error = 3;
  Machines machines = 4;
  // config_hash is the combined hash of all cluster machines which are part of the machine set.
  string config_hash = 5;
  // MachineAllocation is copied from the input MachineSet resource.
  MachineSetSpec.MachineAllocation machine_allocation = 6;
  // LockedUpdates is the number of machines which have pending config update but are locked.
  uint32 locked_updates = 7;
  reserved 8;
  reserved 9;
  reserved 10;
}

// MachineSetConfigStatusSpec is the settings used by the MachineConfigStatus controller:
// - update strategy is copied from the MachineSet
// - config updates allow flag is controller by the MachineSetStatus controller phase.
message MachineSetConfigStatusSpec {
  // ConfigUpdatesAllowed controls graceful rollout of the machine config.
  // If false, no new config updates should happen.
  bool config_updates_allowed = 1;

  // ShouldResetGraceful controls graceful reset of the machine config.
  bool should_reset_graceful = 2;

  // UpdateStrategy is the update strategy of the machine set.
  MachineSetSpec.UpdateStrategy update_strategy = 3;

  // UpdateStrategyConfig defines the update strategy configuration.
  MachineSetSpec.UpdateStrategyConfig update_strategy_config = 4;
}

// MachineSetNodeSpec is a binding between ClusterMachine and MachineSet.
message MachineSetNodeSpec {}

// MachineLabelsSpec is the resource that adds user defined labels to the MachineStatus.
message MachineLabelsSpec {}

// MachineStatusSnapshotSpec describes latest known status of MachineStatus Talos resource.
message MachineStatusSnapshotSpec {
  enum PowerStage {
    POWER_STAGE_NONE = 0;
    POWER_STAGE_POWERED_OFF = 1;
    POWER_STAGE_POWERING_ON = 2;
  }

  machine.MachineStatusEvent machine_status = 1;
  PowerStage power_stage = 2;
}

enum ConditionType {
  UnknownCondition = 0;
  Etcd = 1;
  WireguardConnection = 2;
}

// ControlPlaneStatusSpec contains the status of the MachineSets which manage control plane nodes.
message ControlPlaneStatusSpec {
  message Condition {
    enum Status {
      Unknown = 0;
      Ready = 1;
      NotReady = 2;
    }

    enum Severity {
      Info = 0;
      Warning = 1;
      Error = 2;
    }

    ConditionType type = 1;
    string reason = 2;
    Status status = 3;
    Severity severity = 4;
  }

  repeated Condition conditions = 1;
}

// ClusterEndpointSpec contains a list of SideroLink (management) control plane endpoints.
message ClusterEndpointSpec {
  // List of SideroLink addresses for control plane nodes.
  repeated string management_addresses = 1;
}

// KubernetesStatusSpec contains the status of the Kubernetes critical resources in the cluster.
message KubernetesStatusSpec {
  message NodeStatus {
    string nodename = 1;
    string kubelet_version = 2;
    bool ready = 3;
  }

  // status of each node, sorted by nodename
  repeated NodeStatus nodes = 1;

  message StaticPodStatus {
    string app = 1;
    string version = 2;
    bool ready = 3;
  }

  message NodeStaticPods {
    string nodename = 1;
    repeated StaticPodStatus static_pods = 2;
  }

  // status of each static pod on each node, sorted by nodename, then by pod's app
  repeated NodeStaticPods static_pods = 2;
}

// KubernetesUpgradeStatus spec contains the status of the Kubernetes upgrade process.
message KubernetesUpgradeStatusSpec {
  enum Phase {
    Unknown = 0;
    Upgrading = 1;
    Done = 2;
    Failed = 3;
    Reverting = 4;
  }

  // Current upgrade phase.
  Phase phase = 1;

  // If phase is Failed, this contains the error message.
  string error = 2;

  // If phase is Upgrading, this contains the current upgrade step.
  string step = 3;

  // If phase is Upgrading, this contains the current upgrade step progress.
  string status = 4;

  // Last successful upgrade version.
  string last_upgrade_version = 5;

  // Current version of the upgrade (if phase == Upgrading).
  string current_upgrade_version = 7;

  // List of versions available for upgrade.
  repeated string upgrade_versions = 6;
}

// KubernetesUpgradeManifestStatus contains status of Kubernetes upgrade manifest sync.
message KubernetesUpgradeManifestStatusSpec {
  // Number of manifests out of sync.
  int32 out_of_sync = 1;
  // Last fatal error encountered (which prevented the sync).
  string last_fatal_error = 2;
}

// DestroyStatusSpec describes the state of resource destroy.
message DestroyStatusSpec {
  // Phase describes the current destroy phase.
  string phase = 1;
}

// OngoingTaskSpec describes any ongoing tasks.
message OngoingTaskSpec {
  // Title of the ongoing task.
  string title = 1;

  // Details contains the detailed task description.
  oneof details {
    TalosUpgradeStatusSpec talos_upgrade = 2;
    KubernetesUpgradeStatusSpec kubernetes_upgrade = 3;
    DestroyStatusSpec destroy = 4;
    MachineUpgradeStatusSpec machine_upgrade = 5;
    ClusterSecretsRotationStatusSpec secrets_rotation = 7;
  }

  // ResourceId is the ID of the resource the task is being performed on.
  string resource_id = 6;
}

// ClusterMachineEncryptionKeySpec keeps generated encryption key for the machine disk encryption.
message ClusterMachineEncryptionKeySpec {
  // Data stores generated encryption key for the machine.
  bytes data = 1;
}

// ExposedServiceSpec describes a Kubernetes service exposed through Omni from a workload cluster.
message ExposedServiceSpec {
  // Port is the host port the service is exposed on.
  uint32 port = 1;

  // Label is the human-readable label of the service to be displayed on Omni Web.
  string label = 2;

  // IconBase64 is the icon of the service to be displayed on Omni Web.
  string icon_base64 = 3;

  // Url is the full URL to access the service.
  string url = 4;

  // Error is the last error that occurred when trying to expose the service.
  string error = 5;

  // HasExplicitAlias is true if the service alias is set explicitly.
  bool has_explicit_alias = 6;
}

// ClusterWorkloadProxyStatusSpec describes the status of the exposed services in a cluster.
message ClusterWorkloadProxyStatusSpec {
  uint32 num_exposed_services = 1;
}

message FeaturesConfigSpec {
  // EnableWorkloadProxying enables workload proxying feature.
  bool enable_workload_proxying = 1;

  // EtcdBackupSettings represents omni etcd backup settings.
  EtcdBackupSettings etcd_backup_settings = 2;

  // EmbeddedDiscoveryService enables the embedded discovery service.
  bool embedded_discovery_service = 3;

  // AuditLogEnabled is true when Omni is configured to collect the audit logs.
  bool audit_log_enabled = 4;

  // ImageFactoryBaseUrl is the base URL of the image factory.
  string image_factory_base_url = 5;

  // UserPilotSettings enables UserPilot on the frontend side.
  UserPilotSettings user_pilot_settings = 6;

  // StripeSettings enables Stripe on the frontend side.
  StripeSettings stripe_settings = 7;

  // TalosPreReleaseVersionsEnabled is true when --enable-talos-pre-release-versions is set.
  bool talos_pre_release_versions_enabled = 8;

  // ImageFactoryPxeBaseUrl is the base URL of the image factory PXE server.
  string image_factory_pxe_base_url = 9;

  // Account represents omni account information.
  Account account = 10;
}

message UserPilotSettings {
  string app_token = 1;
}

message StripeSettings {
  bool enabled = 1;
  uint32 min_commit = 2;
}


message Account {
  string id = 1;
  string name = 2;
}

message EtcdBackupSettings {
  // TickInterval is the interval between checking for backups in controller.
  google.protobuf.Duration tick_interval = 1;

  // MinInterval is the minimum interval between backups.
  google.protobuf.Duration min_interval = 2;

  // MaxInterval is the maximum interval between backups.
  google.protobuf.Duration max_interval = 3;

  reserved 4;
}

// MachineClassSpec describes an Omni MachineClass resource spec.
message MachineClassSpec {
  // MachineProvisionSpec describes the rules for creating and scaling the machine request set.
  message Provision {
    string provider_id = 1;

    repeated string kernel_args = 2;
    repeated MetaValue meta_values = 3;

    string provider_data = 4;

    GrpcTunnelMode grpc_tunnel = 5;
  }

  // MatchLabels is the list of labels to match the machine to make it part of the machine class.
  repeated string match_labels = 1;

  // AutoProvision configures the machine class to automatically provision the machines.
  Provision auto_provision = 2;
}

// MachineConfigGenOptionsSpec describes machine related config generation inputs.
message MachineConfigGenOptionsSpec {
  message InstallImage {
    // TalosVersion is the Talos version to use for the install image.
    string talos_version = 1;
    // SchematicId is the schematic id to use for the install image.
    string schematic_id = 2;
    // SchematicInitialized is true if the schematic is initialized.
    bool schematic_initialized = 3;
    // SchematicInvalid is true if the schematic is invalid.
    bool schematic_invalid = 4;
    reserved 5;
    // Platform is the machine platform to use for the install image.
    string platform = 6;
    // SecurityState is used to decide the secure boot enablement in the install image.
    SecurityState security_state = 7;
  }

  string install_disk = 1;

  // InstallImage contains the information needed to build the install image URL of a machine to be used by the Talos installer.
  InstallImage install_image = 2;
}

// EtcdAuditResult is updated when the etcd audit removes a member.
//
// This resource is used to re-trigger the controlplane status checks when etcd audit removes a member.
message EtcdAuditResultSpec {
  // EtcdMemberIds contains the list of ids of the members that were last removed.
  // The list is always sorted.
  repeated uint64 etcd_member_ids = 1;
}

// KubeconfigSpec describes a Kubernetes client configuration for a cluster.
message KubeconfigSpec {
  // Marshalled kubeconfig.
  bytes data = 1;
}

// KubernetesUsageSpec represents kubernetes resource usage for a cluster.
message KubernetesUsageSpec {
  message Quantity {
    double requests = 1;
    double limits = 2;
    double capacity = 3;
  }

  message Pod {
    int32 count = 1;
    int32 capacity = 3;
  }

  Quantity cpu = 1;
  Quantity mem = 2;
  Quantity storage = 3;
  Pod pods = 4;
}

// ImagePullRequestSpec describes an Omni ImagePullRequest resource spec.
message ImagePullRequestSpec {
  message NodeImageList {
    string node = 1;
    repeated string images = 2;
  }

  // NodeImageList are the images to be pulled into the node.
  repeated NodeImageList node_image_list = 1;
}

// ImagePullStatusSpec describes an Omni ImagePullStatus resource spec.
message ImagePullStatusSpec {
  string last_processed_node = 1;
  string last_processed_image = 2;
  string last_processed_error = 3;
  uint32 processed_count = 4;
  uint32 total_count = 5;

  // RequestVersion is the version of the ImagePullRequest that this status is for.
  string request_version = 6;
}

// SchematicSpec keeps all schematics generated by Omni.
// For each schematic it keeps information about the list of extensions.
message SchematicSpec {
  reserved 1;
}

// TalosExtensionsSpec represents all available extensions for a particular Talos version.
message TalosExtensionsSpec {
  // Info is a merged representation of the extensions manifest and image factory versions response.
  message Info {
    string name = 1;
    string author = 2;
    string version = 3;
    string description = 4;
    string ref = 5;
    string digest = 6;
  }

  repeated Info items = 1;
}

// SchematicConfigurationSpec is the desired Image Factory schematic for a machine, machine set or a cluster.
message SchematicConfigurationSpec {
  string schematic_id = 1;
  string talos_version = 2;

  // KernelArgs are the kernel args which were used to compute the SchematicId.
  repeated string kernel_args = 3;
}

// ExtensionsConfigurationSpec is the desired list of extensions to be installed on the machine or the set of machines.
message ExtensionsConfigurationSpec {
  repeated string extensions = 1;
}

// KernelArgsSpec is the desired list of extra kernel args to be added to the machine or the set of machines.
message KernelArgsSpec {
  repeated string args = 1;
}

message KernelArgsStatusSpec {
  repeated string args = 1;
  repeated string current_args = 2;
  repeated string unmet_conditions = 3;
  string current_cmdline = 4;
}

message MachineUpgradeStatusSpec {
  enum Phase {
    Unknown = 0;
    Pending = 1;
    Upgrading = 2;
    UpToDate = 3;
  }

  string schematic_id = 1;
  string talos_version = 2;
  string current_schematic_id = 3;
  string current_talos_version = 4;
  Phase phase = 5;
  string status = 6;
  string error = 7;
  bool is_maintenance = 8;
}

// MachineExtensionsSpec is the extensions list to be used for a machine.
message MachineExtensionsSpec {
  repeated string extensions = 1;
}

// MachineExtensionsStatusSpec defines status of each extension on the machine.
message MachineExtensionsStatusSpec {
  message Item {
    enum Phase {
      Installed = 0;
      Installing = 1;
      Removing = 2;
    }

    string name = 1;
    bool immutable = 2;
    Phase phase = 3;
  }

  repeated Item extensions = 1;
  string talos_version = 2;
}

// MachineStatusMetricsSpec provides aggregated state of the number of registered and connected machines for the Omni instance.
message MachineStatusMetricsSpec {
  reserved 5;

  uint32 registered_machines_count = 1;
  uint32 connected_machines_count = 2;
  uint32 allocated_machines_count = 3;
  uint32 pending_machines_count = 4;

  map<string, uint32> platforms = 6;
  map<string, uint32> secure_boot_status = 7;
  map<string, uint32> uki_status = 8;
  uint32 registered_machines_limit = 9;
  bool registration_limit_reached = 10;
  uint32 invalid_schematic_machines_count = 11;
}

// ClusterMetricsSpec contains metrics about the clusters in the Omni instance.
message ClusterMetricsSpec {
  map<string, uint32> features = 3;
}

// ClusterStatusMetricsSpec provides aggregated state of the number of clusters in not ready phase.
// and the number of clusters in each phase.
message ClusterStatusMetricsSpec {
  uint32 not_ready_count = 1;
  map<int32, uint32> phases = 2;
}

// ClusterKubernetesNodesSpec describes the list of nodes in a Kubernetes cluster.
message ClusterKubernetesNodesSpec {
  // Nodes is the list of nodes in the cluster.
  //
  // It is always sorted.
  repeated string nodes = 1;
}

// KubernetesNodeAuditResultSpec describes the result of the Kubernetes node audit.
//
// It contains the list of nodes that were last removed.
message KubernetesNodeAuditResultSpec {
  // DeletedNodes contains the list of nodes that were last removed.
  repeated string deleted_nodes = 1;
}

// MachineRequestSetSpec creates the number of machine requests.
// Can be either connected to a machine class or be manual.
message MachineRequestSetSpec {
  string provider_id = 1;
  int32 machine_count = 2;

  string talos_version = 3;

  reserved 4;
  repeated string extensions = 5;
  repeated string kernel_args = 6;
  repeated MetaValue meta_values = 7;

  string provider_data = 8;
  GrpcTunnelMode grpc_tunnel = 9;
}

// MachineRequestSetStatusSpec describes the status of the machine request set.
message MachineRequestSetStatusSpec {}

// ClusterDiagnosticSpec describes the nodes in a cluster with diagnostics information available (indicating potential problems).
message ClusterDiagnosticsSpec {
  message Node {
    string id = 1;
    uint32 num_diagnostics = 2;
  }

  repeated Node nodes = 1;
}

// MachineRequestSetPressureSpec describes an Omni MachineRequestSetPressure resource spec.
message MachineRequestSetPressureSpec {
  // RequiredMachines is the number of machines required by all machine sets which are using the request set.
  uint32 required_machines = 1;
}

enum GrpcTunnelMode {
  UNSET = 0;
  ENABLED = 1;
  DISABLED = 2;
}

// ClusterMachineRequestStatusSpec is generated from the MachineRequestStatus when the machine is being automatically provisioned
// for a specific machine set and is used in the UI.
message ClusterMachineRequestStatusSpec {
  enum Stage {
    UNKNOWN = 0;
    PENDING = 1;
    PROVISIONING = 2;
    PROVISIONED = 3;
    DEPROVISIONING = 4;
    FAILED = 5;
  }

  string status = 1;
  string machine_uuid = 2;
  string provider_id = 3;
  Stage stage = 4;
}

// InfraMachineConfigSpec is the spec of the user-owned InfraMachineConfig resource.
message InfraMachineConfigSpec {
  enum AcceptanceStatus {
    PENDING = 0;
    ACCEPTED = 1;
    REJECTED = 2;
  }

  enum MachinePowerState {
    POWER_STATE_DEFAULT = 0;
    POWER_STATE_OFF = 1;
    POWER_STATE_ON = 2;
  }

  MachinePowerState power_state = 1;
  AcceptanceStatus acceptance_status = 2;
  string extra_kernel_args = 3;
  string requested_reboot_id = 4;
  bool cordoned = 5;
}

message InfraMachineBMCConfigSpec {
  message IPMI {
    string address = 1;
    uint32 port = 2;
    string username = 3;
    string password = 4;
  }

  message API {
    string address = 1;
  }

  IPMI ipmi = 1;
  API api = 2;
}

message MaintenanceConfigStatusSpec {
  // PublicKeyAtLastApply is the SideroLink public key of the machine at the time of the last apply.
  string public_key_at_last_apply = 1;
}

// NodeForceDestroyRequestSpec is used to force delete a node.
message NodeForceDestroyRequestSpec {}

message DiscoveryAffiliateDeleteTaskSpec {
  string cluster_id = 1;
  string discovery_service_endpoint = 2;
}

// InfraProviderCombinedStatusSpec unifies ProviderStatus and ProviderHealthStatus.
message InfraProviderCombinedStatusSpec {
  string name = 1;
  string description = 2;
  string icon = 3;

  message Health {
    bool connected = 1;
    string error = 2;
    bool initialized = 3;
  }

  Health health = 4;
}

message MachineConfigDiffSpec {
  string diff = 1;
}

message InstallationMediaConfigSpec {
  message Cloud {
    string platform = 1;
  }

  message SBC {
    string overlay = 1;
    string overlay_options = 2;
  }

  string talos_version = 1;
  PlatformConfigSpec.Arch architecture = 2;
  repeated string install_extensions = 3;
  string kernel_args = 4;

  Cloud cloud = 5;
  SBC sbc = 6;

  string join_token = 7;
  bool secure_boot = 8;
  GrpcTunnelMode grpc_tunnel = 9;
  map<string, string> machine_labels = 10;
  management.SchematicBootloader bootloader = 11;
}

// RotateTalosCASpec is used to initiate Talos CA rotation.
message RotateTalosCASpec {}

message SecretRotationSpec {
  enum Status {
    IDLE = 0;
    IN_PROGRESS = 1;
  }

  enum Phase {
    OK = 0;
    PRE_ROTATE = 1;
    ROTATE = 2;
    POST_ROTATE = 3;
  }

  enum Component {
    NONE = 0;
    TALOS_CA = 1;
    KUBERNETES_CA = 2;
  }

  // Status holds the status of the secrets rotation.
  Status status = 1;
  // Phase of the ongoing secrets rotation.
  Phase phase = 2;
  // Component currently being rotated.
  Component component = 3;
  // Certs holds cluster CAs used during CA rotation.
  ClusterSecretsSpec.Certs certs = 4;
  // Extra_certs holds extra cluster CAs to be used during CA rotation.
  ClusterSecretsSpec.Certs extra_certs = 5;
  // Backup_certs_os holds backup of the original OS CA certs before rotation started.
  repeated ClusterSecretsSpec.Certs.CA backup_certs_os = 6;
  // Backup_certs_k8s holds backup of the original Kubernetes CA certs before rotation started.
  repeated ClusterSecretsSpec.Certs.CA backup_certs_k8s = 7;
}

// ClusterSecretsRotationStatusSpec contains the status of the cluster secrets rotation process.
message ClusterSecretsRotationStatusSpec {
  // Phase of the ongoing secrets rotation.
  SecretRotationSpec.Phase phase = 1;
  // Component currently being rotated.
  SecretRotationSpec.Component component = 2;
  // If phase is Failed, this contains the error message.
  string error = 3;
  // Contains the current rotation step.
  string step = 4;
  // Contains the current rotation step progress.
  string status = 5;
}

// ClusterMachineSecretsSpec describes cluster machine secrets.
message ClusterMachineSecretsSpec {
  // Data holds serialized cluster machine secrets.
  bytes data = 1;

  message Rotation {
    // Status holds the status of the secrets rotation.
    SecretRotationSpec.Status status = 1;
    // Phase holds the current phase of the ongoing secrets rotation.
    SecretRotationSpec.Phase phase = 2;
    // Component holds the component currently being rotated.
    SecretRotationSpec.Component component = 3;
    // Extra_certs holds extra cluster CAs to be used during CA rotation.
    ClusterSecretsSpec.Certs extra_certs = 4;
    // Secret_rotation_version holds the version of the SecretsRotation used to build Rotation.
    string secret_rotation_version = 5;
  }

  // Rotation holds the status of the ongoing secrets rotation.
  Rotation rotation = 2;
}

// RotateKubernetesCASpec is used to initiate Kubernetes CA rotation.
message RotateKubernetesCASpec {}

// UpgradeRolloutSpec describes the rollout for the cluster upgrade process.
message UpgradeRolloutSpec {
  map<string, int32> 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;
}

// KubernetesManifestGroup is the collection (or a single) kubernetes manifests to be applied on the cluster.
message KubernetesManifestGroupSpec {
  enum Mode {
    UNKNOWN = 0;
    FULL = 1;
    ONE_TIME = 2;
  }

  // Deprecated: use accessor methods GetUncompressedData/SetUncompressedData to manage this field.
  bytes compressed_data = 1;
  // Deprecated: use accessor methods GetUncompressedData/SetUncompressedData to manage this field.
  string data = 2;
  reserved 3;
  Mode mode = 4;
}

message ClusterKubernetesManifestsStatusSpec {
  message ManifestStatus {
    enum Phase {
      UNKNOWN = 0;
      PENDING = 1;
      APPLIED = 2;
      DELETING = 3;
    }

    Phase phase = 1;
    string kind = 2;
    string name = 3;
    string namespace = 4;
    string group = 5;
  }

  message GroupStatus {
    enum Phase {
      UNKNOWN = 0;
      PENDING = 1;
      PROGRESSING = 2;
      APPLIED = 3;
      DELETING = 4;
    }

    Phase phase = 1;
    KubernetesManifestGroupSpec.Mode mode = 2;
    map<string, ManifestStatus> manifests = 3;
  }

  map<string, GroupStatus> groups = 1;
  int32 out_of_sync = 2;
  int32 total = 3;
  string last_error = 4;
}
