|
2 | 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | 3 | // file, You can obtain one at https://mozilla.org/MPL/2.0/. |
4 | 4 |
|
5 | | -//! Nexus external types that changed from 2025120300 to 2025121200 |
| 5 | +//! Nexus external types introduced in 2025120300 (LOCAL_STORAGE). |
| 6 | +//! |
| 7 | +//! This version introduced local storage support for instances. |
| 8 | +//! |
| 9 | +//! ## Instance Creation Types |
| 10 | +//! |
| 11 | +//! Valid until 2025122300 (IP_VERSION_AND_MULTIPLE_DEFAULT_POOLS). |
| 12 | +//! |
| 13 | +//! [`InstanceCreate`] and [`ExternalIpCreate`] are defined here for use |
| 14 | +//! by the `instance_create` endpoint in this version. These types don't |
| 15 | +//! have the `ip_version` field that was added in later versions. |
| 16 | +//! |
| 17 | +//! ## BGP Types |
| 18 | +//! |
| 19 | +//! Valid until 2025121200 (BGP_PEER_COLLISION_STATE). |
| 20 | +//! |
| 21 | +//! [`BgpPeerStatus`] and [`BgpPeerState`] are older versions without the |
| 22 | +//! `collision_state` field added in `BGP_PEER_COLLISION_STATE`. |
6 | 23 |
|
7 | 24 | use std::net::IpAddr; |
8 | 25 |
|
| 26 | +use nexus_types::external_api::params; |
9 | 27 | use omicron_common::api::external; |
10 | 28 | use schemars::JsonSchema; |
11 | 29 | use serde::{Deserialize, Serialize}; |
12 | 30 |
|
| 31 | +use crate::{v2025122300, v2026010100, v2026010300}; |
| 32 | + |
13 | 33 | /// The current status of a BGP peer. |
14 | 34 | #[derive(Clone, Debug, Deserialize, JsonSchema, Serialize, PartialEq)] |
15 | 35 | pub struct BgpPeerStatus { |
@@ -59,3 +79,172 @@ pub enum BgpPeerState { |
59 | 79 | /// messages with peers. |
60 | 80 | Established, |
61 | 81 | } |
| 82 | + |
| 83 | +/// The type of IP address to attach to an instance during creation. |
| 84 | +#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] |
| 85 | +#[serde(tag = "type", rename_all = "snake_case")] |
| 86 | +pub enum ExternalIpCreate { |
| 87 | + /// An IP address providing both inbound and outbound access. |
| 88 | + /// The address is automatically assigned from the provided IP pool |
| 89 | + /// or the default IP pool if not specified. |
| 90 | + Ephemeral { |
| 91 | + /// Name or ID of the IP pool to use. If unspecified, the |
| 92 | + /// default IP pool will be used. |
| 93 | + pool: Option<external::NameOrId>, |
| 94 | + }, |
| 95 | + /// A floating IP address. |
| 96 | + Floating { |
| 97 | + /// The name or ID of the floating IP address to attach. |
| 98 | + floating_ip: external::NameOrId, |
| 99 | + }, |
| 100 | +} |
| 101 | + |
| 102 | +impl From<ExternalIpCreate> for v2026010300::ExternalIpCreate { |
| 103 | + fn from(old: ExternalIpCreate) -> v2026010300::ExternalIpCreate { |
| 104 | + match old { |
| 105 | + ExternalIpCreate::Ephemeral { pool } => { |
| 106 | + v2026010300::ExternalIpCreate::Ephemeral { |
| 107 | + pool, |
| 108 | + ip_version: None, |
| 109 | + } |
| 110 | + } |
| 111 | + ExternalIpCreate::Floating { floating_ip } => { |
| 112 | + v2026010300::ExternalIpCreate::Floating { floating_ip } |
| 113 | + } |
| 114 | + } |
| 115 | + } |
| 116 | +} |
| 117 | + |
| 118 | +/// Create-time parameters for an `Instance` |
| 119 | +#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] |
| 120 | +pub struct InstanceCreate { |
| 121 | + #[serde(flatten)] |
| 122 | + pub identity: external::IdentityMetadataCreateParams, |
| 123 | + /// The number of vCPUs to be allocated to the instance |
| 124 | + pub ncpus: external::InstanceCpuCount, |
| 125 | + /// The amount of RAM (in bytes) to be allocated to the instance |
| 126 | + pub memory: external::ByteCount, |
| 127 | + /// The hostname to be assigned to the instance |
| 128 | + pub hostname: external::Hostname, |
| 129 | + |
| 130 | + /// User data for instance initialization systems (such as cloud-init). |
| 131 | + /// Must be a Base64-encoded string, as specified in RFC 4648 § 4 (+ and / |
| 132 | + /// characters with padding). Maximum 32 KiB unencoded data. |
| 133 | + #[serde(default, with = "params::UserData")] |
| 134 | + pub user_data: Vec<u8>, |
| 135 | + |
| 136 | + /// The network interfaces to be created for this instance. |
| 137 | + #[serde(default)] |
| 138 | + pub network_interfaces: v2026010100::InstanceNetworkInterfaceAttachment, |
| 139 | + |
| 140 | + /// The external IP addresses provided to this instance. |
| 141 | + /// |
| 142 | + /// By default, all instances have outbound connectivity, but no inbound |
| 143 | + /// connectivity. These external addresses can be used to provide a fixed, |
| 144 | + /// known IP address for making inbound connections to the instance. |
| 145 | + #[serde(default)] |
| 146 | + pub external_ips: Vec<ExternalIpCreate>, |
| 147 | + |
| 148 | + /// The multicast groups this instance should join. |
| 149 | + /// |
| 150 | + /// The instance will be automatically added as a member of the specified |
| 151 | + /// multicast groups during creation, enabling it to send and receive |
| 152 | + /// multicast traffic for those groups. |
| 153 | + #[serde(default)] |
| 154 | + pub multicast_groups: Vec<external::NameOrId>, |
| 155 | + |
| 156 | + /// A list of disks to be attached to the instance. |
| 157 | + /// |
| 158 | + /// Disk attachments of type "create" will be created, while those of type |
| 159 | + /// "attach" must already exist. |
| 160 | + /// |
| 161 | + /// The order of this list does not guarantee a boot order for the instance. |
| 162 | + /// Use the boot_disk attribute to specify a boot disk. When boot_disk is |
| 163 | + /// specified it will count against the disk attachment limit. |
| 164 | + #[serde(default)] |
| 165 | + pub disks: Vec<params::InstanceDiskAttachment>, |
| 166 | + |
| 167 | + /// The disk the instance is configured to boot from. |
| 168 | + /// |
| 169 | + /// This disk can either be attached if it already exists or created along |
| 170 | + /// with the instance. |
| 171 | + /// |
| 172 | + /// Specifying a boot disk is optional but recommended to ensure predictable |
| 173 | + /// boot behavior. The boot disk can be set during instance creation or |
| 174 | + /// later if the instance is stopped. The boot disk counts against the disk |
| 175 | + /// attachment limit. |
| 176 | + /// |
| 177 | + /// An instance that does not have a boot disk set will use the boot |
| 178 | + /// options specified in its UEFI settings, which are controlled by both the |
| 179 | + /// instance's UEFI firmware and the guest operating system. Boot options |
| 180 | + /// can change as disks are attached and detached, which may result in an |
| 181 | + /// instance that only boots to the EFI shell until a boot disk is set. |
| 182 | + #[serde(default)] |
| 183 | + pub boot_disk: Option<params::InstanceDiskAttachment>, |
| 184 | + |
| 185 | + /// An allowlist of SSH public keys to be transferred to the instance via |
| 186 | + /// cloud-init during instance creation. |
| 187 | + /// |
| 188 | + /// If not provided, all SSH public keys from the user's profile will be sent. |
| 189 | + /// If an empty list is provided, no public keys will be transmitted to the |
| 190 | + /// instance. |
| 191 | + pub ssh_public_keys: Option<Vec<external::NameOrId>>, |
| 192 | + |
| 193 | + /// Should this instance be started upon creation; true by default. |
| 194 | + #[serde(default = "params::bool_true")] |
| 195 | + pub start: bool, |
| 196 | + |
| 197 | + /// The auto-restart policy for this instance. |
| 198 | + /// |
| 199 | + /// This policy determines whether the instance should be automatically |
| 200 | + /// restarted by the control plane on failure. If this is `null`, no |
| 201 | + /// auto-restart policy will be explicitly configured for this instance, and |
| 202 | + /// the control plane will select the default policy when determining |
| 203 | + /// whether the instance can be automatically restarted. |
| 204 | + /// |
| 205 | + /// Currently, the global default auto-restart policy is "best-effort", so |
| 206 | + /// instances with `null` auto-restart policies will be automatically |
| 207 | + /// restarted. However, in the future, the default policy may be |
| 208 | + /// configurable through other mechanisms, such as on a per-project basis. |
| 209 | + /// In that case, any configured default policy will be used if this is |
| 210 | + /// `null`. |
| 211 | + #[serde(default)] |
| 212 | + pub auto_restart_policy: Option<external::InstanceAutoRestartPolicy>, |
| 213 | + |
| 214 | + /// Anti-Affinity groups which this instance should be added. |
| 215 | + #[serde(default)] |
| 216 | + pub anti_affinity_groups: Vec<external::NameOrId>, |
| 217 | + |
| 218 | + /// The CPU platform to be used for this instance. If this is `null`, the |
| 219 | + /// instance requires no particular CPU platform; when it is started the |
| 220 | + /// instance will have the most general CPU platform supported by the sled |
| 221 | + /// it is initially placed on. |
| 222 | + #[serde(default)] |
| 223 | + pub cpu_platform: Option<external::InstanceCpuPlatform>, |
| 224 | +} |
| 225 | + |
| 226 | +impl From<InstanceCreate> for v2025122300::InstanceCreate { |
| 227 | + fn from(old: InstanceCreate) -> v2025122300::InstanceCreate { |
| 228 | + v2025122300::InstanceCreate { |
| 229 | + identity: old.identity, |
| 230 | + ncpus: old.ncpus, |
| 231 | + memory: old.memory, |
| 232 | + hostname: old.hostname, |
| 233 | + user_data: old.user_data, |
| 234 | + network_interfaces: old.network_interfaces, |
| 235 | + external_ips: old |
| 236 | + .external_ips |
| 237 | + .into_iter() |
| 238 | + .map(Into::into) |
| 239 | + .collect(), |
| 240 | + multicast_groups: old.multicast_groups, |
| 241 | + disks: old.disks, |
| 242 | + boot_disk: old.boot_disk, |
| 243 | + ssh_public_keys: old.ssh_public_keys, |
| 244 | + start: old.start, |
| 245 | + auto_restart_policy: old.auto_restart_policy, |
| 246 | + anti_affinity_groups: old.anti_affinity_groups, |
| 247 | + cpu_platform: old.cpu_platform, |
| 248 | + } |
| 249 | + } |
| 250 | +} |
0 commit comments