From f8bfbe1eee5f56a3222b4982f83d07d6b0d7a87d Mon Sep 17 00:00:00 2001 From: Rain Date: Fri, 21 Feb 2025 08:55:33 -0800 Subject: [PATCH] [meta] switch to once_cell impls in std (#7580) `once_cell` is now part of std, so switch over to it almost everywhere, and add lints for it. This is purely mechanical -- there are no semantic changes compared to `once_cell`. There's one place that still needs `once_cell`'s `try_`, so keep that around. See https://github.com/rust-lang/rust/issues/109737. --- Cargo.lock | 14 - clippy.toml | 11 + cockroach-admin/Cargo.toml | 1 - common/Cargo.toml | 1 - common/src/address.rs | 26 +- dev-tools/releng/Cargo.toml | 1 - dev-tools/releng/src/main.rs | 4 +- gateway/Cargo.toml | 1 - gateway/src/management_switch.rs | 6 +- nexus/Cargo.toml | 1 - nexus/auth/Cargo.toml | 1 - nexus/auth/src/authn/external/spoof.rs | 15 +- nexus/auth/src/authz/api_resources.rs | 7 +- nexus/db-fixed-data/Cargo.toml | 2 - nexus/db-fixed-data/src/lib.rs | 4 +- nexus/db-fixed-data/src/project.rs | 6 +- nexus/db-fixed-data/src/role_assignment.rs | 6 +- nexus/db-fixed-data/src/role_builtin.rs | 95 +- nexus/db-fixed-data/src/silo.rs | 6 +- nexus/db-fixed-data/src/silo_user.rs | 40 +- nexus/db-fixed-data/src/user_builtin.rs | 83 +- nexus/db-fixed-data/src/vpc.rs | 27 +- nexus/db-fixed-data/src/vpc_firewall_rule.rs | 10 +- nexus/db-fixed-data/src/vpc_subnet.rs | 47 +- nexus/db-model/Cargo.toml | 1 - nexus/db-model/src/schema_versions.rs | 5 +- nexus/db-queries/Cargo.toml | 1 - .../db-queries/src/db/datastore/deployment.rs | 6 +- .../src/db/queries/network_interface.rs | 10 +- nexus/defaults/Cargo.toml | 1 - nexus/defaults/src/lib.rs | 15 +- .../planning/src/blueprint_builder/builder.rs | 3 + nexus/saga-recovery/Cargo.toml | 1 - .../src/app/background/tasks/saga_recovery.rs | 14 +- nexus/src/app/sagas/mod.rs | 21 +- nexus/src/external_api/console_api.rs | 6 +- nexus/tests/integration_tests/endpoints.rs | 837 +++++++++--------- nexus/tests/integration_tests/unauthorized.rs | 8 +- sled-agent/Cargo.toml | 1 - sled-agent/src/services.rs | 15 +- wicket/Cargo.toml | 1 - wicket/src/state/inventory.rs | 17 +- wicketd/Cargo.toml | 1 - wicketd/src/rss_config.rs | 4 +- 44 files changed, 710 insertions(+), 673 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fe31f2ac63f..b493246305a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5736,7 +5736,6 @@ dependencies = [ "omicron-test-utils", "omicron-uuid-kinds", "omicron-workspace-hack", - "once_cell", "openssl", "oso", "pq-sys", @@ -5803,7 +5802,6 @@ dependencies = [ "omicron-common", "omicron-rpaths", "omicron-workspace-hack", - "once_cell", "pq-sys", "strum", "uuid", @@ -5836,7 +5834,6 @@ dependencies = [ "omicron-rpaths", "omicron-uuid-kinds", "omicron-workspace-hack", - "once_cell", "oxnet", "parse-display", "pq-sys", @@ -5899,7 +5896,6 @@ dependencies = [ "omicron-test-utils", "omicron-uuid-kinds", "omicron-workspace-hack", - "once_cell", "openapiv3", "oso", "oximeter", @@ -5944,7 +5940,6 @@ dependencies = [ "ipnetwork", "omicron-common", "omicron-workspace-hack", - "once_cell", "oxnet", "rand", "serde_json", @@ -6248,7 +6243,6 @@ dependencies = [ "omicron-rpaths", "omicron-test-utils", "omicron-workspace-hack", - "once_cell", "pq-sys", "pretty_assertions", "serde", @@ -6773,7 +6767,6 @@ dependencies = [ "omicron-test-utils", "omicron-uuid-kinds", "omicron-workspace-hack", - "once_cell", "openapi-lint", "openapiv3", "pq-sys", @@ -6817,7 +6810,6 @@ dependencies = [ "mg-admin-client", "omicron-uuid-kinds", "omicron-workspace-hack", - "once_cell", "oxnet", "parse-display", "progenitor-client 0.9.1", @@ -6922,7 +6914,6 @@ dependencies = [ "omicron-common", "omicron-test-utils", "omicron-workspace-hack", - "once_cell", "oximeter", "oximeter-instruments", "oximeter-producer", @@ -7081,7 +7072,6 @@ dependencies = [ "omicron-test-utils", "omicron-uuid-kinds", "omicron-workspace-hack", - "once_cell", "openapi-lint", "openapiv3", "openssl", @@ -7298,7 +7288,6 @@ dependencies = [ "omicron-pins", "omicron-workspace-hack", "omicron-zone-package", - "once_cell", "reqwest", "semver 1.0.25", "serde", @@ -7381,7 +7370,6 @@ dependencies = [ "omicron-test-utils", "omicron-uuid-kinds", "omicron-workspace-hack", - "once_cell", "opte-ioctl", "oximeter", "oximeter-instruments", @@ -13281,7 +13269,6 @@ dependencies = [ "omicron-common", "omicron-passwords", "omicron-workspace-hack", - "once_cell", "owo-colors", "proptest", "ratatui", @@ -13404,7 +13391,6 @@ dependencies = [ "omicron-test-utils", "omicron-uuid-kinds", "omicron-workspace-hack", - "once_cell", "openapi-lint", "openapiv3", "oxnet", diff --git a/clippy.toml b/clippy.toml index 677fb67aded..a3004e43bb5 100644 --- a/clippy.toml +++ b/clippy.toml @@ -16,4 +16,15 @@ disallowed-methods = [ # Instead, the "transaction_retry_wrapper" should be preferred, as it # automatically retries transactions experiencing contention. { path = "async_bb8_diesel::AsyncConnection::transaction_async", reason = "Prefer to use transaction_retry_wrapper, if possible. For tests and nested transactions, use transaction_non_retry_wrapper to at least get dtrace probes" }, + + # We use disallowed-methods for these rather than disallowed-types, because + # there's still one legitimate use for `once_cell`'s types: + # `get_or_try_init`, which isn't stablet yet. + # https://github.com/rust-lang/rust/issues/109737 + { path = "once_cell::unsync::OnceCell::get_or_init", reason = "use `std::cell::OnceCell` instead, unless you need get_or_try_init in which case #[expect] this lint" }, + { path = "once_cell::sync::OnceCell::get_or_init", reason = "use `std::sync::OnceLock` instead, unless you need get_or_try_init in which case #[expect] this lint" }, +] +disallowed-types = [ + { path = "once_cell::unsync::Lazy", reason = "use `std::cell::LazyCell` instead" }, + { path = "once_cell::unsync::LazyCell", reason = "use `std::cell::LazyCell` instead" }, ] diff --git a/cockroach-admin/Cargo.toml b/cockroach-admin/Cargo.toml index 1738fd98e59..bdaf49f3b40 100644 --- a/cockroach-admin/Cargo.toml +++ b/cockroach-admin/Cargo.toml @@ -20,7 +20,6 @@ http.workspace = true illumos-utils.workspace = true omicron-common.workspace = true omicron-uuid-kinds.workspace = true -once_cell.workspace = true # See omicron-rpaths for more about the "pq-sys" dependency. pq-sys = "*" schemars.workspace = true diff --git a/common/Cargo.toml b/common/Cargo.toml index 4eebfe9a8ab..349d00bcc64 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -49,7 +49,6 @@ uuid.workspace = true parse-display.workspace = true progenitor-client.workspace = true omicron-workspace-hack.workspace = true -once_cell.workspace = true regress.workspace = true [dev-dependencies] diff --git a/common/src/address.rs b/common/src/address.rs index a311bd688ed..dc79163581c 100644 --- a/common/src/address.rs +++ b/common/src/address.rs @@ -10,11 +10,13 @@ use crate::api::external::{self, Error}; use crate::policy::INTERNAL_DNS_REDUNDANCY; use ipnetwork::Ipv6Network; -use once_cell::sync::Lazy; use oxnet::{Ipv4Net, Ipv6Net}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV6}; +use std::{ + net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV6}, + sync::LazyLock, +}; pub const AZ_PREFIX: u8 = 48; pub const RACK_PREFIX: u8 = 56; @@ -101,7 +103,7 @@ pub const NUM_SOURCE_NAT_PORTS: u16 = 1 << 14; // prefix range (`fd00::/48`). See `random_vpc_ipv6_prefix`. // Furthermore, all the below *_OPTE_IPV6_SUBNET constants are // /64's within this prefix. -pub static SERVICE_VPC_IPV6_PREFIX: Lazy = Lazy::new(|| { +pub static SERVICE_VPC_IPV6_PREFIX: LazyLock = LazyLock::new(|| { Ipv6Net::new( Ipv6Addr::new(0xfd77, 0xe9d2, 0x9cd9, 0, 0, 0, 0, 0), VPC_IPV6_PREFIX_LENGTH, @@ -110,11 +112,11 @@ pub static SERVICE_VPC_IPV6_PREFIX: Lazy = Lazy::new(|| { }); /// The IPv4 subnet for External DNS OPTE ports. -pub static DNS_OPTE_IPV4_SUBNET: Lazy = - Lazy::new(|| Ipv4Net::new(Ipv4Addr::new(172, 30, 1, 0), 24).unwrap()); +pub static DNS_OPTE_IPV4_SUBNET: LazyLock = + LazyLock::new(|| Ipv4Net::new(Ipv4Addr::new(172, 30, 1, 0), 24).unwrap()); /// The IPv6 subnet for External DNS OPTE ports. -pub static DNS_OPTE_IPV6_SUBNET: Lazy = Lazy::new(|| { +pub static DNS_OPTE_IPV6_SUBNET: LazyLock = LazyLock::new(|| { Ipv6Net::new( Ipv6Addr::new(0xfd77, 0xe9d2, 0x9cd9, 1, 0, 0, 0, 0), VPC_SUBNET_IPV6_PREFIX_LENGTH, @@ -123,11 +125,11 @@ pub static DNS_OPTE_IPV6_SUBNET: Lazy = Lazy::new(|| { }); /// The IPv4 subnet for Nexus OPTE ports. -pub static NEXUS_OPTE_IPV4_SUBNET: Lazy = - Lazy::new(|| Ipv4Net::new(Ipv4Addr::new(172, 30, 2, 0), 24).unwrap()); +pub static NEXUS_OPTE_IPV4_SUBNET: LazyLock = + LazyLock::new(|| Ipv4Net::new(Ipv4Addr::new(172, 30, 2, 0), 24).unwrap()); /// The IPv6 subnet for Nexus OPTE ports. -pub static NEXUS_OPTE_IPV6_SUBNET: Lazy = Lazy::new(|| { +pub static NEXUS_OPTE_IPV6_SUBNET: LazyLock = LazyLock::new(|| { Ipv6Net::new( Ipv6Addr::new(0xfd77, 0xe9d2, 0x9cd9, 2, 0, 0, 0, 0), VPC_SUBNET_IPV6_PREFIX_LENGTH, @@ -136,11 +138,11 @@ pub static NEXUS_OPTE_IPV6_SUBNET: Lazy = Lazy::new(|| { }); /// The IPv4 subnet for Boundary NTP OPTE ports. -pub static NTP_OPTE_IPV4_SUBNET: Lazy = - Lazy::new(|| Ipv4Net::new(Ipv4Addr::new(172, 30, 3, 0), 24).unwrap()); +pub static NTP_OPTE_IPV4_SUBNET: LazyLock = + LazyLock::new(|| Ipv4Net::new(Ipv4Addr::new(172, 30, 3, 0), 24).unwrap()); /// The IPv6 subnet for Boundary NTP OPTE ports. -pub static NTP_OPTE_IPV6_SUBNET: Lazy = Lazy::new(|| { +pub static NTP_OPTE_IPV6_SUBNET: LazyLock = LazyLock::new(|| { Ipv6Net::new( Ipv6Addr::new(0xfd77, 0xe9d2, 0x9cd9, 3, 0, 0, 0, 0), VPC_SUBNET_IPV6_PREFIX_LENGTH, diff --git a/dev-tools/releng/Cargo.toml b/dev-tools/releng/Cargo.toml index 6aad69ae37b..69f7dae2d4e 100644 --- a/dev-tools/releng/Cargo.toml +++ b/dev-tools/releng/Cargo.toml @@ -18,7 +18,6 @@ omicron-common.workspace = true omicron-pins.workspace = true omicron-workspace-hack.workspace = true omicron-zone-package.workspace = true -once_cell.workspace = true reqwest.workspace = true semver.workspace = true serde.workspace = true diff --git a/dev-tools/releng/src/main.rs b/dev-tools/releng/src/main.rs index a7d98a299c8..e00020aa83f 100644 --- a/dev-tools/releng/src/main.rs +++ b/dev-tools/releng/src/main.rs @@ -8,6 +8,7 @@ mod job; mod tuf; use std::sync::Arc; +use std::sync::LazyLock; use std::time::Duration; use std::time::Instant; @@ -20,7 +21,6 @@ use clap::Parser; use fs_err::tokio as fs; use omicron_zone_package::config::Config; use omicron_zone_package::config::PackageName; -use once_cell::sync::Lazy; use semver::Version; use slog::debug; use slog::error; @@ -88,7 +88,7 @@ const TUF_PACKAGES: [&PackageName; 11] = [ const HELIOS_REPO: &str = "https://pkg.oxide.computer/helios/2/dev/"; -static WORKSPACE_DIR: Lazy = Lazy::new(|| { +static WORKSPACE_DIR: LazyLock = LazyLock::new(|| { // $CARGO_MANIFEST_DIR is at `.../omicron/dev-tools/releng` let mut dir = Utf8PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").expect( diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index bdf4a911afb..e754daf1855 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -25,7 +25,6 @@ hyper.workspace = true illumos-utils.workspace = true ipcc.workspace = true omicron-common.workspace = true -once_cell.workspace = true schemars.workspace = true serde.workspace = true signal-hook.workspace = true diff --git a/gateway/src/management_switch.rs b/gateway/src/management_switch.rs index 69c3d717f73..ce45d58c2f7 100644 --- a/gateway/src/management_switch.rs +++ b/gateway/src/management_switch.rs @@ -29,7 +29,6 @@ use gateway_sp_comms::HostPhase2Provider; use gateway_sp_comms::SharedSocket; use gateway_sp_comms::SingleSp; use gateway_sp_comms::SpRetryConfig; -use once_cell::sync::OnceCell; use serde::Deserialize; use serde::Serialize; use slog::o; @@ -39,6 +38,7 @@ use std::collections::HashMap; use std::net::Ipv6Addr; use std::net::SocketAddrV6; use std::sync::Arc; +use std::sync::OnceLock; use std::time::Duration; use tokio::net::UdpSocket; use tokio::task::JoinHandle; @@ -162,7 +162,7 @@ pub struct ManagementSwitch { // When it's dropped, it cancels the background tokio task that loops on // that socket receiving incoming packets. _shared_socket: Option, - location_map: Arc>>, + location_map: Arc>>, discovery_task: JoinHandle<()>, log: Logger, } @@ -290,7 +290,7 @@ impl ManagementSwitch { // completes (because we won't be able to map "the SP of sled 7" to a // correct switch port). let port_to_handle = Arc::new(port_to_handle); - let location_map = Arc::new(OnceCell::new()); + let location_map = Arc::new(OnceLock::new()); let discovery_task = { let log = log.clone(); let port_to_handle = Arc::clone(&port_to_handle); diff --git a/nexus/Cargo.toml b/nexus/Cargo.toml index 8afc36bc03b..4b73a8dd783 100644 --- a/nexus/Cargo.toml +++ b/nexus/Cargo.toml @@ -59,7 +59,6 @@ nexus-networking.workspace = true nexus-saga-recovery.workspace = true nexus-test-interface.workspace = true num-integer.workspace = true -once_cell.workspace = true openssl.workspace = true oximeter-client.workspace = true oximeter-db = { workspace = true, default-features = false, features = [ "oxql" ] } diff --git a/nexus/auth/Cargo.toml b/nexus/auth/Cargo.toml index 1a926f1789d..71e16eafbef 100644 --- a/nexus/auth/Cargo.toml +++ b/nexus/auth/Cargo.toml @@ -24,7 +24,6 @@ hyper.workspace = true newtype_derive.workspace = true # See omicron-rpaths for more about the "pq-sys" dependency. pq-sys = "*" -once_cell.workspace = true openssl.workspace = true oso.workspace = true samael.workspace = true diff --git a/nexus/auth/src/authn/external/spoof.rs b/nexus/auth/src/authn/external/spoof.rs index 326d5294317..4aa2b1b443d 100644 --- a/nexus/auth/src/authn/external/spoof.rs +++ b/nexus/auth/src/authn/external/spoof.rs @@ -4,6 +4,8 @@ //! Custom, test-only authn scheme that trusts whatever the client says +use std::sync::LazyLock; + use super::super::Details; use super::HttpAuthnScheme; use super::Reason; @@ -16,7 +18,6 @@ use anyhow::Context; use async_trait::async_trait; use headers::authorization::{Authorization, Bearer}; use headers::HeaderMapExt; -use once_cell::sync::Lazy; use slog::debug; use uuid::Uuid; @@ -56,20 +57,20 @@ const SPOOF_RESERVED_BAD_CREDS: &str = "this-fake-ID-it-is-truly-excellent"; const SPOOF_PREFIX: &str = "oxide-spoof-"; /// Actor (id) used for the special "bad credentials" error -static SPOOF_RESERVED_BAD_CREDS_ACTOR: Lazy = - Lazy::new(|| Actor::UserBuiltin { +static SPOOF_RESERVED_BAD_CREDS_ACTOR: LazyLock = + LazyLock::new(|| Actor::UserBuiltin { user_builtin_id: "22222222-2222-2222-2222-222222222222" .parse() .unwrap(), }); /// Complete HTTP header value to trigger the "bad actor" error -pub static SPOOF_HEADER_BAD_ACTOR: Lazy> = - Lazy::new(|| make_header_value_str(SPOOF_RESERVED_BAD_ACTOR).unwrap()); +pub static SPOOF_HEADER_BAD_ACTOR: LazyLock> = + LazyLock::new(|| make_header_value_str(SPOOF_RESERVED_BAD_ACTOR).unwrap()); /// Complete HTTP header value to trigger the "bad creds" error -pub static SPOOF_HEADER_BAD_CREDS: Lazy> = - Lazy::new(|| make_header_value_str(SPOOF_RESERVED_BAD_CREDS).unwrap()); +pub static SPOOF_HEADER_BAD_CREDS: LazyLock> = + LazyLock::new(|| make_header_value_str(SPOOF_RESERVED_BAD_CREDS).unwrap()); /// Implements a (test-only) authentication scheme where the client simply /// provides the actor information in a custom bearer token and we always trust diff --git a/nexus/auth/src/authz/api_resources.rs b/nexus/auth/src/authz/api_resources.rs index 745a699cf2b..64fac91a4e1 100644 --- a/nexus/auth/src/authz/api_resources.rs +++ b/nexus/auth/src/authz/api_resources.rs @@ -26,6 +26,8 @@ //! //! Most `authz` types are generated by the `authz_resource!` macro. +use std::sync::LazyLock; + use super::actor::AnyActor; use super::context::AuthorizedResource; use super::oso_generic::Init; @@ -40,7 +42,6 @@ use futures::FutureExt; use nexus_db_fixed_data::FLEET_ID; use nexus_types::external_api::shared::{FleetRole, ProjectRole, SiloRole}; use omicron_common::api::external::{Error, LookupType, ResourceType}; -use once_cell::sync::Lazy; use oso::PolarClass; use serde::{Deserialize, Serialize}; use uuid::Uuid; @@ -159,8 +160,8 @@ pub struct Fleet; /// Singleton representing the [`Fleet`] itself for authz purposes pub const FLEET: Fleet = Fleet; -pub static FLEET_LOOKUP: Lazy = - Lazy::new(|| LookupType::ById(*FLEET_ID)); +pub static FLEET_LOOKUP: LazyLock = + LazyLock::new(|| LookupType::ById(*FLEET_ID)); impl Eq for Fleet {} impl PartialEq for Fleet { diff --git a/nexus/db-fixed-data/Cargo.toml b/nexus/db-fixed-data/Cargo.toml index 486df156867..a6ac298452c 100644 --- a/nexus/db-fixed-data/Cargo.toml +++ b/nexus/db-fixed-data/Cargo.toml @@ -12,7 +12,6 @@ workspace = true omicron-rpaths.workspace = true [dependencies] -once_cell.workspace = true # See omicron-rpaths for more about the "pq-sys" dependency. pq-sys = "*" strum.workspace = true @@ -22,4 +21,3 @@ nexus-db-model.workspace = true nexus-types.workspace = true omicron-common.workspace = true omicron-workspace-hack.workspace = true - diff --git a/nexus/db-fixed-data/src/lib.rs b/nexus/db-fixed-data/src/lib.rs index 13444141cb3..0bfc0127ff2 100644 --- a/nexus/db-fixed-data/src/lib.rs +++ b/nexus/db-fixed-data/src/lib.rs @@ -32,7 +32,7 @@ // 001de000-c470 built-in services vpc subnets // 001de000-all0 singleton ID for source IP allowlist ("all0" is like "allow") -use once_cell::sync::Lazy; +use std::sync::LazyLock; pub mod allow_list; pub mod project; @@ -46,7 +46,7 @@ pub mod vpc_firewall_rule; pub mod vpc_subnet; /* See above for where this uuid comes from. */ -pub static FLEET_ID: Lazy = Lazy::new(|| { +pub static FLEET_ID: LazyLock = LazyLock::new(|| { "001de000-1334-4000-8000-000000000000" .parse() .expect("invalid uuid for builtin fleet id") diff --git a/nexus/db-fixed-data/src/project.rs b/nexus/db-fixed-data/src/project.rs index 77843908208..50e0e43e86d 100644 --- a/nexus/db-fixed-data/src/project.rs +++ b/nexus/db-fixed-data/src/project.rs @@ -5,20 +5,20 @@ use nexus_db_model as model; use nexus_types::{external_api::params, silo::INTERNAL_SILO_ID}; use omicron_common::api::external::IdentityMetadataCreateParams; -use once_cell::sync::Lazy; +use std::sync::LazyLock; /// The name of the built-in Project and VPC for Oxide services. pub const SERVICES_DB_NAME: &str = "oxide-services"; /// UUID of built-in project for internal services on the rack. -pub static SERVICES_PROJECT_ID: Lazy = Lazy::new(|| { +pub static SERVICES_PROJECT_ID: LazyLock = LazyLock::new(|| { "001de000-4401-4000-8000-000000000000" .parse() .expect("invalid uuid for builtin services project id") }); /// Built-in Project for internal services on the rack. -pub static SERVICES_PROJECT: Lazy = Lazy::new(|| { +pub static SERVICES_PROJECT: LazyLock = LazyLock::new(|| { model::Project::new_with_id( *SERVICES_PROJECT_ID, INTERNAL_SILO_ID, diff --git a/nexus/db-fixed-data/src/role_assignment.rs b/nexus/db-fixed-data/src/role_assignment.rs index 25b26786f8d..03ba63853b7 100644 --- a/nexus/db-fixed-data/src/role_assignment.rs +++ b/nexus/db-fixed-data/src/role_assignment.rs @@ -8,10 +8,10 @@ use super::user_builtin; use super::FLEET_ID; use nexus_db_model::IdentityType; use nexus_db_model::RoleAssignment; -use once_cell::sync::Lazy; +use std::sync::LazyLock; -pub static BUILTIN_ROLE_ASSIGNMENTS: Lazy> = - Lazy::new(|| { +pub static BUILTIN_ROLE_ASSIGNMENTS: LazyLock> = + LazyLock::new(|| { vec![ // The "internal-api" user gets the "admin" role on the sole Fleet. // This is a pretty elevated privilege. diff --git a/nexus/db-fixed-data/src/role_builtin.rs b/nexus/db-fixed-data/src/role_builtin.rs index c617874e98a..8646b3de3b2 100644 --- a/nexus/db-fixed-data/src/role_builtin.rs +++ b/nexus/db-fixed-data/src/role_builtin.rs @@ -4,7 +4,7 @@ //! Built-in roles use omicron_common::api; -use once_cell::sync::Lazy; +use std::sync::LazyLock; #[derive(Clone, Debug)] pub struct RoleBuiltinConfig { @@ -13,72 +13,73 @@ pub struct RoleBuiltinConfig { pub description: &'static str, } -pub static FLEET_ADMIN: Lazy = - Lazy::new(|| RoleBuiltinConfig { +pub static FLEET_ADMIN: LazyLock = + LazyLock::new(|| RoleBuiltinConfig { resource_type: api::external::ResourceType::Fleet, role_name: "admin", description: "Fleet Administrator", }); -pub static FLEET_AUTHENTICATOR: Lazy = - Lazy::new(|| RoleBuiltinConfig { +pub static FLEET_AUTHENTICATOR: LazyLock = + LazyLock::new(|| RoleBuiltinConfig { resource_type: api::external::ResourceType::Fleet, role_name: "external-authenticator", description: "Fleet External Authenticator", }); -pub static FLEET_VIEWER: Lazy = - Lazy::new(|| RoleBuiltinConfig { +pub static FLEET_VIEWER: LazyLock = + LazyLock::new(|| RoleBuiltinConfig { resource_type: api::external::ResourceType::Fleet, role_name: "viewer", description: "Fleet Viewer", }); -pub static SILO_ADMIN: Lazy = - Lazy::new(|| RoleBuiltinConfig { +pub static SILO_ADMIN: LazyLock = + LazyLock::new(|| RoleBuiltinConfig { resource_type: api::external::ResourceType::Silo, role_name: "admin", description: "Silo Administrator", }); -pub static BUILTIN_ROLES: Lazy> = Lazy::new(|| { - vec![ - FLEET_ADMIN.clone(), - FLEET_AUTHENTICATOR.clone(), - FLEET_VIEWER.clone(), - RoleBuiltinConfig { - resource_type: api::external::ResourceType::Fleet, - role_name: "collaborator", - description: "Fleet Collaborator", - }, - SILO_ADMIN.clone(), - RoleBuiltinConfig { - resource_type: api::external::ResourceType::Silo, - role_name: "collaborator", - description: "Silo Collaborator", - }, - RoleBuiltinConfig { - resource_type: api::external::ResourceType::Silo, - role_name: "viewer", - description: "Silo Viewer", - }, - RoleBuiltinConfig { - resource_type: api::external::ResourceType::Project, - role_name: "admin", - description: "Project Administrator", - }, - RoleBuiltinConfig { - resource_type: api::external::ResourceType::Project, - role_name: "collaborator", - description: "Project Collaborator", - }, - RoleBuiltinConfig { - resource_type: api::external::ResourceType::Project, - role_name: "viewer", - description: "Project Viewer", - }, - ] -}); +pub static BUILTIN_ROLES: LazyLock> = + LazyLock::new(|| { + vec![ + FLEET_ADMIN.clone(), + FLEET_AUTHENTICATOR.clone(), + FLEET_VIEWER.clone(), + RoleBuiltinConfig { + resource_type: api::external::ResourceType::Fleet, + role_name: "collaborator", + description: "Fleet Collaborator", + }, + SILO_ADMIN.clone(), + RoleBuiltinConfig { + resource_type: api::external::ResourceType::Silo, + role_name: "collaborator", + description: "Silo Collaborator", + }, + RoleBuiltinConfig { + resource_type: api::external::ResourceType::Silo, + role_name: "viewer", + description: "Silo Viewer", + }, + RoleBuiltinConfig { + resource_type: api::external::ResourceType::Project, + role_name: "admin", + description: "Project Administrator", + }, + RoleBuiltinConfig { + resource_type: api::external::ResourceType::Project, + role_name: "collaborator", + description: "Project Collaborator", + }, + RoleBuiltinConfig { + resource_type: api::external::ResourceType::Project, + role_name: "viewer", + description: "Project Viewer", + }, + ] + }); #[cfg(test)] mod test { diff --git a/nexus/db-fixed-data/src/silo.rs b/nexus/db-fixed-data/src/silo.rs index 10c624e30e0..d98fda3ef8f 100644 --- a/nexus/db-fixed-data/src/silo.rs +++ b/nexus/db-fixed-data/src/silo.rs @@ -11,13 +11,13 @@ use nexus_types::{ }, }; use omicron_common::api::external::IdentityMetadataCreateParams; -use once_cell::sync::Lazy; +use std::sync::LazyLock; /// "Default" Silo /// /// This was historically used for demos and the unit tests. The plan is to /// remove it per omicron#2305. -pub static DEFAULT_SILO: Lazy = Lazy::new(|| { +pub static DEFAULT_SILO: LazyLock = LazyLock::new(|| { model::Silo::new_with_id( DEFAULT_SILO_ID, params::SiloCreate { @@ -40,7 +40,7 @@ pub static DEFAULT_SILO: Lazy = Lazy::new(|| { /// Built-in Silo to house internal resources. It contains no users and /// can't be logged into. -pub static INTERNAL_SILO: Lazy = Lazy::new(|| { +pub static INTERNAL_SILO: LazyLock = LazyLock::new(|| { model::Silo::new_with_id( INTERNAL_SILO_ID, params::SiloCreate { diff --git a/nexus/db-fixed-data/src/silo_user.rs b/nexus/db-fixed-data/src/silo_user.rs index e6e6d7d0e5b..a8c500f336d 100644 --- a/nexus/db-fixed-data/src/silo_user.rs +++ b/nexus/db-fixed-data/src/silo_user.rs @@ -6,25 +6,26 @@ use super::role_builtin; use nexus_db_model as model; use nexus_types::{identity::Asset, silo::DEFAULT_SILO_ID}; -use once_cell::sync::Lazy; +use std::sync::LazyLock; /// Test user that's granted all privileges, used for automated testing and /// local development // TODO-security Once we have a way to bootstrap the initial Silo with the // initial privileged user, this user should be created in the test suite, // not automatically at Nexus startup. See omicron#2305. -pub static USER_TEST_PRIVILEGED: Lazy = Lazy::new(|| { - model::SiloUser::new( - DEFAULT_SILO_ID, - // "4007" looks a bit like "root". - "001de000-05e4-4000-8000-000000004007".parse().unwrap(), - "privileged".into(), - ) -}); +pub static USER_TEST_PRIVILEGED: LazyLock = + LazyLock::new(|| { + model::SiloUser::new( + DEFAULT_SILO_ID, + // "4007" looks a bit like "root". + "001de000-05e4-4000-8000-000000004007".parse().unwrap(), + "privileged".into(), + ) + }); /// Role assignments needed for the privileged user -pub static ROLE_ASSIGNMENTS_PRIVILEGED: Lazy> = - Lazy::new(|| { +pub static ROLE_ASSIGNMENTS_PRIVILEGED: LazyLock> = + LazyLock::new(|| { vec![ // The "test-privileged" user gets the "admin" role on the sole // Fleet as well as the default Silo. @@ -49,14 +50,15 @@ pub static ROLE_ASSIGNMENTS_PRIVILEGED: Lazy> = // TODO-security Once we have a way to bootstrap the initial Silo with the // initial privileged user, this user should be created in the test suite, // not automatically at Nexus startup. See omicron#2305. -pub static USER_TEST_UNPRIVILEGED: Lazy = Lazy::new(|| { - model::SiloUser::new( - DEFAULT_SILO_ID, - // 60001 is the decimal uid for "nobody" on Helios. - "001de000-05e4-4000-8000-000000060001".parse().unwrap(), - "unprivileged".into(), - ) -}); +pub static USER_TEST_UNPRIVILEGED: LazyLock = + LazyLock::new(|| { + model::SiloUser::new( + DEFAULT_SILO_ID, + // 60001 is the decimal uid for "nobody" on Helios. + "001de000-05e4-4000-8000-000000060001".parse().unwrap(), + "unprivileged".into(), + ) + }); #[cfg(test)] mod test { diff --git a/nexus/db-fixed-data/src/user_builtin.rs b/nexus/db-fixed-data/src/user_builtin.rs index 1e968026831..08236af5db3 100644 --- a/nexus/db-fixed-data/src/user_builtin.rs +++ b/nexus/db-fixed-data/src/user_builtin.rs @@ -4,7 +4,7 @@ //! Built-in users use omicron_common::api; -use once_cell::sync::Lazy; +use std::sync::LazyLock; use uuid::Uuid; pub struct UserBuiltinConfig { @@ -29,7 +29,7 @@ impl UserBuiltinConfig { /// Internal user used for seeding initial database data // NOTE: This uuid and name are duplicated in dbinit.sql. -pub static USER_DB_INIT: Lazy = Lazy::new(|| { +pub static USER_DB_INIT: LazyLock = LazyLock::new(|| { UserBuiltinConfig::new_static( // "0001" is the first possible user that wouldn't be confused with // 0, or root. @@ -41,51 +41,56 @@ pub static USER_DB_INIT: Lazy = Lazy::new(|| { /// Internal user for performing operations to manage the /// provisioning of services across the fleet. -pub static USER_SERVICE_BALANCER: Lazy = Lazy::new(|| { - UserBuiltinConfig::new_static( - "001de000-05e4-4000-8000-00000000bac3", - "service-balancer", - "used for Nexus-driven service balancing", - ) -}); +pub static USER_SERVICE_BALANCER: LazyLock = + LazyLock::new(|| { + UserBuiltinConfig::new_static( + "001de000-05e4-4000-8000-00000000bac3", + "service-balancer", + "used for Nexus-driven service balancing", + ) + }); /// Internal user used by Nexus when handling internal API requests -pub static USER_INTERNAL_API: Lazy = Lazy::new(|| { - UserBuiltinConfig::new_static( - "001de000-05e4-4000-8000-000000000002", - "internal-api", - "used by Nexus when handling internal API requests", - ) -}); +pub static USER_INTERNAL_API: LazyLock = + LazyLock::new(|| { + UserBuiltinConfig::new_static( + "001de000-05e4-4000-8000-000000000002", + "internal-api", + "used by Nexus when handling internal API requests", + ) + }); /// Internal user used by Nexus to read privileged control plane data -pub static USER_INTERNAL_READ: Lazy = Lazy::new(|| { - UserBuiltinConfig::new_static( - // "4ead" looks like "read" - "001de000-05e4-4000-8000-000000004ead", - "internal-read", - "used by Nexus to read privileged control plane data", - ) -}); +pub static USER_INTERNAL_READ: LazyLock = + LazyLock::new(|| { + UserBuiltinConfig::new_static( + // "4ead" looks like "read" + "001de000-05e4-4000-8000-000000004ead", + "internal-read", + "used by Nexus to read privileged control plane data", + ) + }); /// Internal user used by Nexus when recovering sagas -pub static USER_SAGA_RECOVERY: Lazy = Lazy::new(|| { - UserBuiltinConfig::new_static( - // "3a8a" looks a bit like "saga". - "001de000-05e4-4000-8000-000000003a8a", - "saga-recovery", - "used by Nexus when recovering sagas", - ) -}); +pub static USER_SAGA_RECOVERY: LazyLock = + LazyLock::new(|| { + UserBuiltinConfig::new_static( + // "3a8a" looks a bit like "saga". + "001de000-05e4-4000-8000-000000003a8a", + "saga-recovery", + "used by Nexus when recovering sagas", + ) + }); /// Internal user used by Nexus when authenticating external requests -pub static USER_EXTERNAL_AUTHN: Lazy = Lazy::new(|| { - UserBuiltinConfig::new_static( - "001de000-05e4-4000-8000-000000000003", - "external-authn", - "used by Nexus when authenticating external requests", - ) -}); +pub static USER_EXTERNAL_AUTHN: LazyLock = + LazyLock::new(|| { + UserBuiltinConfig::new_static( + "001de000-05e4-4000-8000-000000000003", + "external-authn", + "used by Nexus when authenticating external requests", + ) + }); #[cfg(test)] mod test { diff --git a/nexus/db-fixed-data/src/vpc.rs b/nexus/db-fixed-data/src/vpc.rs index 64a2563305e..fc263a02da1 100644 --- a/nexus/db-fixed-data/src/vpc.rs +++ b/nexus/db-fixed-data/src/vpc.rs @@ -7,47 +7,48 @@ use nexus_db_model as model; use nexus_types::external_api::params; use omicron_common::address::SERVICE_VPC_IPV6_PREFIX; use omicron_common::api::external::IdentityMetadataCreateParams; -use once_cell::sync::Lazy; +use std::sync::LazyLock; /// UUID of built-in VPC for internal services on the rack. -pub static SERVICES_VPC_ID: Lazy = Lazy::new(|| { +pub static SERVICES_VPC_ID: LazyLock = LazyLock::new(|| { "001de000-074c-4000-8000-000000000000" .parse() .expect("invalid uuid for builtin services vpc id") }); /// UUID of VpcRouter for built-in Services VPC. -pub static SERVICES_VPC_ROUTER_ID: Lazy = Lazy::new(|| { +pub static SERVICES_VPC_ROUTER_ID: LazyLock = LazyLock::new(|| { "001de000-074c-4000-8000-000000000001" .parse() .expect("invalid uuid for builtin services vpc router id") }); /// UUID of InternetGateway for built-in Services VPC. -pub static SERVICES_INTERNET_GATEWAY_ID: Lazy = Lazy::new(|| { - "001de000-074c-4000-8000-000000000002" - .parse() - .expect("invalid uuid for builtin services internet gateway id") -}); +pub static SERVICES_INTERNET_GATEWAY_ID: LazyLock = + LazyLock::new(|| { + "001de000-074c-4000-8000-000000000002" + .parse() + .expect("invalid uuid for builtin services internet gateway id") + }); /// UUID of InternetGateway IPv4 default route for built-in Services VPC. -pub static SERVICES_INTERNET_GATEWAY_DEFAULT_ROUTE_V4: Lazy = - Lazy::new(|| { +pub static SERVICES_INTERNET_GATEWAY_DEFAULT_ROUTE_V4: LazyLock = + LazyLock::new(|| { "001de000-074c-4000-8000-000000000003" .parse() .expect("invalid uuid for builtin services internet gateway default route v4") }); /// UUID of InternetGateway IPv6 default route for built-in Services VPC. -pub static SERVICES_INTERNET_GATEWAY_DEFAULT_ROUTE_V6: Lazy = - Lazy::new(|| { +pub static SERVICES_INTERNET_GATEWAY_DEFAULT_ROUTE_V6: LazyLock = + LazyLock::new(|| { "001de000-074c-4000-8000-000000000004" .parse() .expect("invalid uuid for builtin services internet gateway default route v4") }); /// Built-in VPC for internal services on the rack. -pub static SERVICES_VPC: Lazy = Lazy::new(|| { +pub static SERVICES_VPC: LazyLock = LazyLock::new(|| { model::IncompleteVpc::new( *SERVICES_VPC_ID, *super::project::SERVICES_PROJECT_ID, diff --git a/nexus/db-fixed-data/src/vpc_firewall_rule.rs b/nexus/db-fixed-data/src/vpc_firewall_rule.rs index 09cb9e1c72a..d59e1c556e6 100644 --- a/nexus/db-fixed-data/src/vpc_firewall_rule.rs +++ b/nexus/db-fixed-data/src/vpc_firewall_rule.rs @@ -8,11 +8,11 @@ use omicron_common::api::external::{ VpcFirewallRuleFilter, VpcFirewallRulePriority, VpcFirewallRuleProtocol, VpcFirewallRuleStatus, VpcFirewallRuleTarget, VpcFirewallRuleUpdate, }; -use once_cell::sync::Lazy; +use std::sync::LazyLock; /// Built-in VPC firewall rule for External DNS. -pub static DNS_VPC_FW_RULE: Lazy = - Lazy::new(|| VpcFirewallRuleUpdate { +pub static DNS_VPC_FW_RULE: LazyLock = + LazyLock::new(|| VpcFirewallRuleUpdate { name: "external-dns-inbound".parse().unwrap(), description: "allow inbound connections for DNS from anywhere" .to_string(), @@ -41,8 +41,8 @@ pub const NEXUS_VPC_FW_RULE_NAME: &str = "nexus-inbound"; /// Note that we currently rely on this being exactly one rule to implement the /// Nexus allowlist. See `nexus/networking/src/firewall_rules.rs` for more /// details. -pub static NEXUS_VPC_FW_RULE: Lazy = - Lazy::new(|| VpcFirewallRuleUpdate { +pub static NEXUS_VPC_FW_RULE: LazyLock = + LazyLock::new(|| VpcFirewallRuleUpdate { name: NEXUS_VPC_FW_RULE_NAME.parse().unwrap(), description: "allow inbound connections for console & api from anywhere" diff --git a/nexus/db-fixed-data/src/vpc_subnet.rs b/nexus/db-fixed-data/src/vpc_subnet.rs index c91581ac13d..2e4e5b215c4 100644 --- a/nexus/db-fixed-data/src/vpc_subnet.rs +++ b/nexus/db-fixed-data/src/vpc_subnet.rs @@ -8,52 +8,55 @@ use omicron_common::address::{ NEXUS_OPTE_IPV6_SUBNET, NTP_OPTE_IPV4_SUBNET, NTP_OPTE_IPV6_SUBNET, }; use omicron_common::api::external::IdentityMetadataCreateParams; -use once_cell::sync::Lazy; +use std::sync::LazyLock; /// UUID of built-in VPC Subnet for External DNS. -pub static DNS_VPC_SUBNET_ID: Lazy = Lazy::new(|| { +pub static DNS_VPC_SUBNET_ID: LazyLock = LazyLock::new(|| { "001de000-c470-4000-8000-000000000001" .parse() .expect("invalid uuid for builtin external dns vpc subnet id") }); /// UUID of built-in VPC Subnet for Nexus. -pub static NEXUS_VPC_SUBNET_ID: Lazy = Lazy::new(|| { +pub static NEXUS_VPC_SUBNET_ID: LazyLock = LazyLock::new(|| { "001de000-c470-4000-8000-000000000002" .parse() .expect("invalid uuid for builtin nexus vpc subnet id") }); /// UUID of built-in VPC Subnet for Boundary NTP. -pub static NTP_VPC_SUBNET_ID: Lazy = Lazy::new(|| { +pub static NTP_VPC_SUBNET_ID: LazyLock = LazyLock::new(|| { "001de000-c470-4000-8000-000000000003" .parse() .expect("invalid uuid for builtin boundary ntp vpc subnet id") }); /// UUID of built-in subnet route VPC Subnet route for External DNS. -pub static DNS_VPC_SUBNET_ROUTE_ID: Lazy = Lazy::new(|| { - "001de000-c470-4000-8000-000000000004" - .parse() - .expect("invalid uuid for builtin services vpc default route id") -}); +pub static DNS_VPC_SUBNET_ROUTE_ID: LazyLock = + LazyLock::new(|| { + "001de000-c470-4000-8000-000000000004" + .parse() + .expect("invalid uuid for builtin services vpc default route id") + }); /// UUID of built-in subnet route VPC Subnet route for Nexus. -pub static NEXUS_VPC_SUBNET_ROUTE_ID: Lazy = Lazy::new(|| { - "001de000-c470-4000-8000-000000000005" - .parse() - .expect("invalid uuid for builtin services vpc default route id") -}); +pub static NEXUS_VPC_SUBNET_ROUTE_ID: LazyLock = + LazyLock::new(|| { + "001de000-c470-4000-8000-000000000005" + .parse() + .expect("invalid uuid for builtin services vpc default route id") + }); /// UUID of built-in subnet route VPC Subnet route for Boundary NTP. -pub static NTP_VPC_SUBNET_ROUTE_ID: Lazy = Lazy::new(|| { - "001de000-c470-4000-8000-000000000006" - .parse() - .expect("invalid uuid for builtin services vpc default route id") -}); +pub static NTP_VPC_SUBNET_ROUTE_ID: LazyLock = + LazyLock::new(|| { + "001de000-c470-4000-8000-000000000006" + .parse() + .expect("invalid uuid for builtin services vpc default route id") + }); /// Built-in VPC Subnet for External DNS. -pub static DNS_VPC_SUBNET: Lazy = Lazy::new(|| { +pub static DNS_VPC_SUBNET: LazyLock = LazyLock::new(|| { VpcSubnet::new( *DNS_VPC_SUBNET_ID, *super::vpc::SERVICES_VPC_ID, @@ -68,7 +71,7 @@ pub static DNS_VPC_SUBNET: Lazy = Lazy::new(|| { }); /// Built-in VPC Subnet for Nexus. -pub static NEXUS_VPC_SUBNET: Lazy = Lazy::new(|| { +pub static NEXUS_VPC_SUBNET: LazyLock = LazyLock::new(|| { VpcSubnet::new( *NEXUS_VPC_SUBNET_ID, *super::vpc::SERVICES_VPC_ID, @@ -83,7 +86,7 @@ pub static NEXUS_VPC_SUBNET: Lazy = Lazy::new(|| { }); /// Built-in VPC Subnet for Boundary NTP. -pub static NTP_VPC_SUBNET: Lazy = Lazy::new(|| { +pub static NTP_VPC_SUBNET: LazyLock = LazyLock::new(|| { VpcSubnet::new( *NTP_VPC_SUBNET_ID, *super::vpc::SERVICES_VPC_ID, diff --git a/nexus/db-model/Cargo.toml b/nexus/db-model/Cargo.toml index 3e86f28b60f..26de4d9e890 100644 --- a/nexus/db-model/Cargo.toml +++ b/nexus/db-model/Cargo.toml @@ -22,7 +22,6 @@ ipnetwork.workspace = true macaddr.workspace = true newtype_derive.workspace = true omicron-uuid-kinds.workspace = true -once_cell.workspace = true oxnet.workspace = true parse-display.workspace = true # See omicron-rpaths for more about the "pq-sys" dependency. diff --git a/nexus/db-model/src/schema_versions.rs b/nexus/db-model/src/schema_versions.rs index 9caaa419400..b6511ec1924 100644 --- a/nexus/db-model/src/schema_versions.rs +++ b/nexus/db-model/src/schema_versions.rs @@ -9,8 +9,7 @@ use anyhow::{bail, ensure, Context}; use camino::Utf8Path; use omicron_common::api::external::SemverVersion; -use once_cell::sync::Lazy; -use std::collections::BTreeMap; +use std::{collections::BTreeMap, sync::LazyLock}; /// The version of the database schema this particular version of Nexus was /// built against @@ -22,7 +21,7 @@ pub const SCHEMA_VERSION: SemverVersion = SemverVersion::new(126, 0, 0); /// List of all past database schema versions, in *reverse* order /// /// If you want to change the Omicron database schema, you must update this. -static KNOWN_VERSIONS: Lazy> = Lazy::new(|| { +static KNOWN_VERSIONS: LazyLock> = LazyLock::new(|| { vec![ // +- The next version goes here! Duplicate this line, uncomment // | the *second* copy, then update that copy for your version, diff --git a/nexus/db-queries/Cargo.toml b/nexus/db-queries/Cargo.toml index db2b70488d7..fe5e299b89b 100644 --- a/nexus/db-queries/Cargo.toml +++ b/nexus/db-queries/Cargo.toml @@ -26,7 +26,6 @@ internal-dns-resolver.workspace = true internal-dns-types.workspace = true ipnetwork.workspace = true macaddr.workspace = true -once_cell.workspace = true oxnet.workspace = true paste.workspace = true # See omicron-rpaths for more about the "pq-sys" dependency. diff --git a/nexus/db-queries/src/db/datastore/deployment.rs b/nexus/db-queries/src/db/datastore/deployment.rs index ede962e561e..cc3a92214d2 100644 --- a/nexus/db-queries/src/db/datastore/deployment.rs +++ b/nexus/db-queries/src/db/datastore/deployment.rs @@ -2039,7 +2039,6 @@ mod tests { use omicron_uuid_kinds::PhysicalDiskUuid; use omicron_uuid_kinds::SledUuid; use omicron_uuid_kinds::ZpoolUuid; - use once_cell::sync::Lazy; use oxnet::IpNet; use pretty_assertions::assert_eq; use rand::thread_rng; @@ -2054,10 +2053,11 @@ mod tests { use std::sync::atomic::AtomicBool; use std::sync::atomic::Ordering; use std::sync::Arc; + use std::sync::LazyLock; use std::time::Duration; - static EMPTY_PLANNING_INPUT: Lazy = - Lazy::new(|| PlanningInputBuilder::empty_input()); + static EMPTY_PLANNING_INPUT: LazyLock = + LazyLock::new(|| PlanningInputBuilder::empty_input()); #[derive(Default)] pub struct NetworkResourceControlFlow { diff --git a/nexus/db-queries/src/db/queries/network_interface.rs b/nexus/db-queries/src/db/queries/network_interface.rs index 6f955edf735..57868f32809 100644 --- a/nexus/db-queries/src/db/queries/network_interface.rs +++ b/nexus/db-queries/src/db/queries/network_interface.rs @@ -31,9 +31,9 @@ use nexus_db_model::{NetworkInterfaceKind, MAX_NICS_PER_INSTANCE}; use nexus_db_model::{NetworkInterfaceKindEnum, SqlU8}; use omicron_common::api::external; use omicron_common::api::external::MacAddr; -use once_cell::sync::Lazy; use slog_error_chain::SlogInlineError; use std::net::{IpAddr, Ipv6Addr}; +use std::sync::LazyLock; use uuid::Uuid; // These are sentinel values and other constants used to verify the state of the @@ -62,11 +62,11 @@ const INSTANCE_DESTROYED: db::model::InstanceState = const INSTANCE_RUNNING: db::model::InstanceState = db::model::InstanceState::Vmm; -static NO_INSTANCE_SENTINEL_STRING: Lazy = - Lazy::new(|| String::from(NO_INSTANCE_SENTINEL)); +static NO_INSTANCE_SENTINEL_STRING: LazyLock = + LazyLock::new(|| String::from(NO_INSTANCE_SENTINEL)); -static INSTANCE_BAD_STATE_SENTINEL_STRING: Lazy = - Lazy::new(|| String::from(INSTANCE_BAD_STATE_SENTINEL)); +static INSTANCE_BAD_STATE_SENTINEL_STRING: LazyLock = + LazyLock::new(|| String::from(INSTANCE_BAD_STATE_SENTINEL)); // Uncastable sentinel used to detect when an instance exists, but is not // in the right state to have its network interfaces altered diff --git a/nexus/defaults/Cargo.toml b/nexus/defaults/Cargo.toml index 1d941deb8e0..96197d248a8 100644 --- a/nexus/defaults/Cargo.toml +++ b/nexus/defaults/Cargo.toml @@ -9,7 +9,6 @@ workspace = true [dependencies] ipnetwork.workspace = true -once_cell.workspace = true oxnet.workspace = true rand.workspace = true serde_json.workspace = true diff --git a/nexus/defaults/src/lib.rs b/nexus/defaults/src/lib.rs index 32def47b9e8..73c090a4d1b 100644 --- a/nexus/defaults/src/lib.rs +++ b/nexus/defaults/src/lib.rs @@ -5,11 +5,11 @@ //! Default values for data in the Nexus API, when not provided explicitly in a request. use omicron_common::api::external; -use once_cell::sync::Lazy; use oxnet::Ipv4Net; use oxnet::Ipv6Net; use std::net::Ipv4Addr; use std::net::Ipv6Addr; +use std::sync::LazyLock; /// The name provided for a default primary network interface for a guest /// instance. @@ -18,12 +18,13 @@ pub const DEFAULT_PRIMARY_NIC_NAME: &str = "net0"; /// The default IPv4 subnet range assigned to the default VPC Subnet, when /// the VPC is created, if one is not provided in the request. See /// for details. -pub static DEFAULT_VPC_SUBNET_IPV4_BLOCK: Lazy = - Lazy::new(|| Ipv4Net::new(Ipv4Addr::new(172, 30, 0, 0), 22).unwrap()); +pub static DEFAULT_VPC_SUBNET_IPV4_BLOCK: LazyLock = + LazyLock::new(|| Ipv4Net::new(Ipv4Addr::new(172, 30, 0, 0), 22).unwrap()); -pub static DEFAULT_FIREWALL_RULES: Lazy = - Lazy::new(|| { - serde_json::from_str(r#"{ +pub static DEFAULT_FIREWALL_RULES: LazyLock< + external::VpcFirewallRuleUpdateParams, +> = LazyLock::new(|| { + serde_json::from_str(r#"{ "rules": [ { "name": "allow-internal-inbound", @@ -57,7 +58,7 @@ pub static DEFAULT_FIREWALL_RULES: Lazy = } ] }"#).unwrap() - }); +}); /// Generate a random VPC IPv6 prefix, in the range `fd00::/48`. pub fn random_vpc_ipv6_prefix() -> Result { diff --git a/nexus/reconfigurator/planning/src/blueprint_builder/builder.rs b/nexus/reconfigurator/planning/src/blueprint_builder/builder.rs index 3fe20f8d0c7..15d85744f2a 100644 --- a/nexus/reconfigurator/planning/src/blueprint_builder/builder.rs +++ b/nexus/reconfigurator/planning/src/blueprint_builder/builder.rs @@ -380,6 +380,9 @@ pub struct BlueprintBuilder<'a> { // adding zones, so this delay allows us to reuse resources that just came // free. (This is implicit and awkward; as we rework the builder we should // rework this to make it more explicit.) + // + // Note: this is currently still a `once_cell` `OnceCell` rather than a std + // `OnceCell`, because `get_or_try_init` isn't stable yet. resource_allocator: OnceCell, // These fields will become part of the final blueprint. See the diff --git a/nexus/saga-recovery/Cargo.toml b/nexus/saga-recovery/Cargo.toml index 4356cc97891..c35a5c7b5fe 100644 --- a/nexus/saga-recovery/Cargo.toml +++ b/nexus/saga-recovery/Cargo.toml @@ -34,7 +34,6 @@ nexus-test-utils-macros.workspace = true nexus-types.workspace = true omicron-common.workspace = true omicron-test-utils.workspace = true -once_cell.workspace = true pretty_assertions.workspace = true steno.workspace = true tokio.workspace = true diff --git a/nexus/src/app/background/tasks/saga_recovery.rs b/nexus/src/app/background/tasks/saga_recovery.rs index ad32f854af7..652e3f2276c 100644 --- a/nexus/src/app/background/tasks/saga_recovery.rs +++ b/nexus/src/app/background/tasks/saga_recovery.rs @@ -493,9 +493,11 @@ mod test { self, poll::{wait_for_condition, CondCheckError}, }; - use once_cell::sync::Lazy; use pretty_assertions::assert_eq; - use std::sync::atomic::{AtomicBool, AtomicU32, Ordering}; + use std::sync::{ + atomic::{AtomicBool, AtomicU32, Ordering}, + LazyLock, + }; use steno::{ new_action_noop_undo, Action, ActionContext, ActionError, ActionRegistry, DagBuilder, Node, SagaDag, SagaId, SagaName, @@ -561,10 +563,10 @@ mod test { } } - static ACTION_N1: Lazy>> = - Lazy::new(|| new_action_noop_undo("n1_action", node_one)); - static ACTION_N2: Lazy>> = - Lazy::new(|| new_action_noop_undo("n2_action", node_two)); + static ACTION_N1: LazyLock>> = + LazyLock::new(|| new_action_noop_undo("n1_action", node_one)); + static ACTION_N2: LazyLock>> = + LazyLock::new(|| new_action_noop_undo("n2_action", node_two)); fn registry_create() -> Arc> { let mut registry = ActionRegistry::new(); diff --git a/nexus/src/app/sagas/mod.rs b/nexus/src/app/sagas/mod.rs index f114dee432d..f8020346116 100644 --- a/nexus/src/app/sagas/mod.rs +++ b/nexus/src/app/sagas/mod.rs @@ -10,8 +10,8 @@ // easier it will be to test, version, and update in deployed systems. use crate::saga_interface::SagaContext; -use once_cell::sync::Lazy; use std::sync::Arc; +use std::sync::LazyLock; use steno::new_action_noop_undo; use steno::ActionContext; use steno::ActionError; @@ -133,11 +133,12 @@ impl From for omicron_common::api::external::Error { } } -pub(super) static ACTION_GENERATE_ID: Lazy = Lazy::new(|| { - new_action_noop_undo("common.uuid_generate", saga_generate_uuid) -}); -pub(crate) static ACTION_REGISTRY: Lazy> = - Lazy::new(|| Arc::new(make_action_registry())); +pub(super) static ACTION_GENERATE_ID: LazyLock = + LazyLock::new(|| { + new_action_noop_undo("common.uuid_generate", saga_generate_uuid) + }); +pub(crate) static ACTION_REGISTRY: LazyLock> = + LazyLock::new(|| Arc::new(make_action_registry())); macro_rules! register_actions { ( $registry:ident, $( $saga: ty ),* ) => { @@ -289,8 +290,8 @@ macro_rules! declare_saga_actions { // Basically, everything to the left of "<>" is just us propagating state // through the macro, and everything to the right of it is user input. (S = $saga:ident $($nodes:ident),* <> $node:ident -> $out:literal { + $a:ident - $u:ident } $($tail:tt)*) => { - static $node: ::once_cell::sync::Lazy = - ::once_cell::sync::Lazy::new(|| { + static $node: ::std::sync::LazyLock = + ::std::sync::LazyLock::new(|| { ::steno::ActionFunc::new_action( crate::app::sagas::__action_name!($saga, $node), $a, $u, ) @@ -300,8 +301,8 @@ macro_rules! declare_saga_actions { }; // Same as the prior match, but without the undo action. (S = $saga:ident $($nodes:ident),* <> $node:ident -> $out:literal { + $a:ident } $($tail:tt)*) => { - static $node: ::once_cell::sync::Lazy = - ::once_cell::sync::Lazy::new(|| { + static $node: ::std::sync::LazyLock = + ::std::sync::LazyLock::new(|| { ::steno::new_action_noop_undo( crate::app::sagas::__action_name!($saga, $node), $a, ) diff --git a/nexus/src/external_api/console_api.rs b/nexus/src/external_api/console_api.rs index a07453627b4..535ba0f95f2 100644 --- a/nexus/src/external_api/console_api.rs +++ b/nexus/src/external_api/console_api.rs @@ -19,10 +19,10 @@ use nexus_types::external_api::params::{self, RelativeUri}; use nexus_types::identity::Resource; use omicron_common::api::external::http_pagination::PaginatedBy; use omicron_common::api::external::{DataPageParams, Error, NameOrId}; -use once_cell::sync::Lazy; use serde_urlencoded; use std::collections::HashMap; use std::num::NonZeroU32; +use std::sync::LazyLock; use tokio::fs::File; use tokio_util::codec::{BytesCodec, FramedRead}; @@ -296,7 +296,7 @@ fn with_gz_ext(path: &Utf8Path) -> Utf8PathBuf { // Define header values as const so that `HeaderValue::from_static` is given the // opportunity to panic at compile time -static ALLOWED_EXTENSIONS: Lazy> = { +static ALLOWED_EXTENSIONS: LazyLock> = { const CONTENT_TYPES: [(&str, HeaderValue); 10] = [ ("css", HeaderValue::from_static("text/css")), ("html", HeaderValue::from_static("text/html; charset=utf-8")), @@ -310,7 +310,7 @@ static ALLOWED_EXTENSIONS: Lazy> = { ("woff2", HeaderValue::from_static("font/woff2")), ]; - Lazy::new(|| HashMap::from(CONTENT_TYPES)) + LazyLock::new(|| HashMap::from(CONTENT_TYPES)) }; const CONTENT_ENCODING_GZIP: HeaderValue = HeaderValue::from_static("gzip"); // Web application security headers; these should stay in sync with the headers diff --git a/nexus/tests/integration_tests/endpoints.rs b/nexus/tests/integration_tests/endpoints.rs index 656b4ba8266..11d8e9f14eb 100644 --- a/nexus/tests/integration_tests/endpoints.rs +++ b/nexus/tests/integration_tests/endpoints.rs @@ -36,67 +36,73 @@ use omicron_common::api::external::RouteTarget; use omicron_common::api::external::UserId; use omicron_common::api::external::VpcFirewallRuleUpdateParams; use omicron_test_utils::certificates::CertificateChain; -use once_cell::sync::Lazy; use std::net::IpAddr; use std::net::Ipv4Addr; use std::str::FromStr; +use std::sync::LazyLock; type DiskTest<'a> = nexus_test_utils::resource_helpers::DiskTest<'a, omicron_nexus::Server>; -pub static HARDWARE_RACK_URL: Lazy = - Lazy::new(|| format!("/v1/system/hardware/racks/{}", RACK_UUID)); +pub static HARDWARE_RACK_URL: LazyLock = + LazyLock::new(|| format!("/v1/system/hardware/racks/{}", RACK_UUID)); pub const HARDWARE_UNINITIALIZED_SLEDS: &'static str = "/v1/system/hardware/sleds-uninitialized"; -pub static HARDWARE_SLED_URL: Lazy = - Lazy::new(|| format!("/v1/system/hardware/sleds/{}", SLED_AGENT_UUID)); -pub static HARDWARE_SLED_PROVISION_POLICY_URL: Lazy = Lazy::new(|| { - format!("/v1/system/hardware/sleds/{}/provision-policy", SLED_AGENT_UUID) -}); -pub static DEMO_SLED_PROVISION_POLICY: Lazy = - Lazy::new(|| params::SledProvisionPolicyParams { - state: SledProvisionPolicy::NonProvisionable, +pub static HARDWARE_SLED_URL: LazyLock = + LazyLock::new(|| format!("/v1/system/hardware/sleds/{}", SLED_AGENT_UUID)); +pub static HARDWARE_SLED_PROVISION_POLICY_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/system/hardware/sleds/{}/provision-policy", + SLED_AGENT_UUID + ) }); +pub static DEMO_SLED_PROVISION_POLICY: LazyLock< + params::SledProvisionPolicyParams, +> = LazyLock::new(|| params::SledProvisionPolicyParams { + state: SledProvisionPolicy::NonProvisionable, +}); -pub static HARDWARE_SWITCH_URL: Lazy = - Lazy::new(|| format!("/v1/system/hardware/switches/{}", SWITCH_UUID)); +pub static HARDWARE_SWITCH_URL: LazyLock = + LazyLock::new(|| format!("/v1/system/hardware/switches/{}", SWITCH_UUID)); pub const HARDWARE_DISKS_URL: &'static str = "/v1/system/hardware/disks"; -pub static HARDWARE_DISK_URL: Lazy = - Lazy::new(|| format!("/v1/system/hardware/disks/{}", PHYSICAL_DISK_UUID)); -pub static HARDWARE_SLED_DISK_URL: Lazy = Lazy::new(|| { +pub static HARDWARE_DISK_URL: LazyLock = LazyLock::new(|| { + format!("/v1/system/hardware/disks/{}", PHYSICAL_DISK_UUID) +}); +pub static HARDWARE_SLED_DISK_URL: LazyLock = LazyLock::new(|| { format!("/v1/system/hardware/sleds/{}/disks", SLED_AGENT_UUID) }); -pub static SLED_INSTANCES_URL: Lazy = Lazy::new(|| { +pub static SLED_INSTANCES_URL: LazyLock = LazyLock::new(|| { format!("/v1/system/hardware/sleds/{}/instances", SLED_AGENT_UUID) }); -pub static DEMO_UNINITIALIZED_SLED: Lazy = - Lazy::new(|| params::UninitializedSledId { +pub static DEMO_UNINITIALIZED_SLED: LazyLock = + LazyLock::new(|| params::UninitializedSledId { serial: "demo-serial".to_string(), part: "demo-part".to_string(), }); pub const SUPPORT_BUNDLES_URL: &'static str = "/experimental/v1/system/support-bundles"; -pub static SUPPORT_BUNDLE_URL: Lazy = - Lazy::new(|| format!("{SUPPORT_BUNDLES_URL}/{{id}}")); +pub static SUPPORT_BUNDLE_URL: LazyLock = + LazyLock::new(|| format!("{SUPPORT_BUNDLES_URL}/{{id}}")); // Global policy pub const SYSTEM_POLICY_URL: &'static str = "/v1/system/policy"; // Silo used for testing -pub static DEMO_SILO_NAME: Lazy = - Lazy::new(|| "demo-silo".parse().unwrap()); -pub static DEMO_SILO_URL: Lazy = - Lazy::new(|| format!("/v1/system/silos/{}", *DEMO_SILO_NAME)); -pub static DEMO_SILO_IP_POOLS_URL: Lazy = - Lazy::new(|| format!("{}/ip-pools", *DEMO_SILO_URL)); -pub static DEMO_SILO_POLICY_URL: Lazy = - Lazy::new(|| format!("/v1/system/silos/{}/policy", *DEMO_SILO_NAME)); -pub static DEMO_SILO_QUOTAS_URL: Lazy = - Lazy::new(|| format!("/v1/system/silos/{}/quotas", *DEMO_SILO_NAME)); -pub static DEMO_SILO_CREATE: Lazy = - Lazy::new(|| params::SiloCreate { +pub static DEMO_SILO_NAME: LazyLock = + LazyLock::new(|| "demo-silo".parse().unwrap()); +pub static DEMO_SILO_URL: LazyLock = + LazyLock::new(|| format!("/v1/system/silos/{}", *DEMO_SILO_NAME)); +pub static DEMO_SILO_IP_POOLS_URL: LazyLock = + LazyLock::new(|| format!("{}/ip-pools", *DEMO_SILO_URL)); +pub static DEMO_SILO_POLICY_URL: LazyLock = + LazyLock::new(|| format!("/v1/system/silos/{}/policy", *DEMO_SILO_NAME)); +pub static DEMO_SILO_QUOTAS_URL: LazyLock = + LazyLock::new(|| format!("/v1/system/silos/{}/quotas", *DEMO_SILO_NAME)); +pub static DEMO_SILO_CREATE: LazyLock = + LazyLock::new(|| params::SiloCreate { identity: IdentityMetadataCreateParams { name: DEMO_SILO_NAME.clone(), description: String::from(""), @@ -109,56 +115,60 @@ pub static DEMO_SILO_CREATE: Lazy = mapped_fleet_roles: Default::default(), }); -pub static DEMO_SILO_UTIL_URL: Lazy = - Lazy::new(|| format!("/v1/system/utilization/silos/{}", *DEMO_SILO_NAME)); +pub static DEMO_SILO_UTIL_URL: LazyLock = LazyLock::new(|| { + format!("/v1/system/utilization/silos/{}", *DEMO_SILO_NAME) +}); // Use the default Silo for testing the local IdP -pub static DEMO_SILO_USERS_CREATE_URL: Lazy = Lazy::new(|| { +pub static DEMO_SILO_USERS_CREATE_URL: LazyLock = LazyLock::new(|| { format!( "/v1/system/identity-providers/local/users?silo={}", DEFAULT_SILO.identity().name, ) }); -pub static DEMO_SILO_USERS_LIST_URL: Lazy = Lazy::new(|| { +pub static DEMO_SILO_USERS_LIST_URL: LazyLock = LazyLock::new(|| { format!("/v1/system/users?silo={}", DEFAULT_SILO.identity().name,) }); -pub static DEMO_SILO_USER_ID_GET_URL: Lazy = Lazy::new(|| { +pub static DEMO_SILO_USER_ID_GET_URL: LazyLock = LazyLock::new(|| { format!("/v1/system/users/{{id}}?silo={}", DEFAULT_SILO.identity().name,) }); -pub static DEMO_SILO_USER_ID_DELETE_URL: Lazy = Lazy::new(|| { - format!( - "/v1/system/identity-providers/local/users/{{id}}?silo={}", - DEFAULT_SILO.identity().name, - ) -}); -pub static DEMO_SILO_USER_ID_SET_PASSWORD_URL: Lazy = Lazy::new(|| { - format!( +pub static DEMO_SILO_USER_ID_DELETE_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/system/identity-providers/local/users/{{id}}?silo={}", + DEFAULT_SILO.identity().name, + ) + }); +pub static DEMO_SILO_USER_ID_SET_PASSWORD_URL: LazyLock = + LazyLock::new(|| { + format!( "/v1/system/identity-providers/local/users/{{id}}/set-password?silo={}", DEFAULT_SILO.identity().name, ) -}); + }); // Project used for testing -pub static DEMO_PROJECT_NAME: Lazy = - Lazy::new(|| "demo-project".parse().unwrap()); -pub static DEMO_PROJECT_URL: Lazy = - Lazy::new(|| format!("/v1/projects/{}", *DEMO_PROJECT_NAME)); -pub static DEMO_PROJECT_SELECTOR: Lazy = - Lazy::new(|| format!("project={}", *DEMO_PROJECT_NAME)); -pub static DEMO_PROJECT_POLICY_URL: Lazy = - Lazy::new(|| format!("/v1/projects/{}/policy", *DEMO_PROJECT_NAME)); -pub static DEMO_PROJECT_URL_IMAGES: Lazy = - Lazy::new(|| format!("/v1/images?project={}", *DEMO_PROJECT_NAME)); -pub static DEMO_PROJECT_URL_INSTANCES: Lazy = - Lazy::new(|| format!("/v1/instances?project={}", *DEMO_PROJECT_NAME)); -pub static DEMO_PROJECT_URL_SNAPSHOTS: Lazy = - Lazy::new(|| format!("/v1/snapshots?project={}", *DEMO_PROJECT_NAME)); -pub static DEMO_PROJECT_URL_VPCS: Lazy = - Lazy::new(|| format!("/v1/vpcs?project={}", *DEMO_PROJECT_NAME)); -pub static DEMO_PROJECT_URL_FIPS: Lazy = - Lazy::new(|| format!("/v1/floating-ips?project={}", *DEMO_PROJECT_NAME)); -pub static DEMO_PROJECT_CREATE: Lazy = - Lazy::new(|| params::ProjectCreate { +pub static DEMO_PROJECT_NAME: LazyLock = + LazyLock::new(|| "demo-project".parse().unwrap()); +pub static DEMO_PROJECT_URL: LazyLock = + LazyLock::new(|| format!("/v1/projects/{}", *DEMO_PROJECT_NAME)); +pub static DEMO_PROJECT_SELECTOR: LazyLock = + LazyLock::new(|| format!("project={}", *DEMO_PROJECT_NAME)); +pub static DEMO_PROJECT_POLICY_URL: LazyLock = + LazyLock::new(|| format!("/v1/projects/{}/policy", *DEMO_PROJECT_NAME)); +pub static DEMO_PROJECT_URL_IMAGES: LazyLock = + LazyLock::new(|| format!("/v1/images?project={}", *DEMO_PROJECT_NAME)); +pub static DEMO_PROJECT_URL_INSTANCES: LazyLock = + LazyLock::new(|| format!("/v1/instances?project={}", *DEMO_PROJECT_NAME)); +pub static DEMO_PROJECT_URL_SNAPSHOTS: LazyLock = + LazyLock::new(|| format!("/v1/snapshots?project={}", *DEMO_PROJECT_NAME)); +pub static DEMO_PROJECT_URL_VPCS: LazyLock = + LazyLock::new(|| format!("/v1/vpcs?project={}", *DEMO_PROJECT_NAME)); +pub static DEMO_PROJECT_URL_FIPS: LazyLock = LazyLock::new(|| { + format!("/v1/floating-ips?project={}", *DEMO_PROJECT_NAME) +}); +pub static DEMO_PROJECT_CREATE: LazyLock = + LazyLock::new(|| params::ProjectCreate { identity: IdentityMetadataCreateParams { name: DEMO_PROJECT_NAME.clone(), description: String::from(""), @@ -166,22 +176,22 @@ pub static DEMO_PROJECT_CREATE: Lazy = }); // VPC used for testing -pub static DEMO_VPC_NAME: Lazy = - Lazy::new(|| "demo-vpc".parse().unwrap()); -pub static DEMO_VPC_URL: Lazy = Lazy::new(|| { +pub static DEMO_VPC_NAME: LazyLock = + LazyLock::new(|| "demo-vpc".parse().unwrap()); +pub static DEMO_VPC_URL: LazyLock = LazyLock::new(|| { format!("/v1/vpcs/{}?{}", *DEMO_VPC_NAME, *DEMO_PROJECT_SELECTOR) }); -pub static DEMO_VPC_SELECTOR: Lazy = Lazy::new(|| { +pub static DEMO_VPC_SELECTOR: LazyLock = LazyLock::new(|| { format!("project={}&vpc={}", *DEMO_PROJECT_NAME, *DEMO_VPC_NAME) }); -pub static DEMO_VPC_URL_FIREWALL_RULES: Lazy = - Lazy::new(|| format!("/v1/vpc-firewall-rules?{}", *DEMO_VPC_SELECTOR)); -pub static DEMO_VPC_URL_ROUTERS: Lazy = - Lazy::new(|| format!("/v1/vpc-routers?{}", *DEMO_VPC_SELECTOR)); -pub static DEMO_VPC_URL_SUBNETS: Lazy = - Lazy::new(|| format!("/v1/vpc-subnets?{}", *DEMO_VPC_SELECTOR)); -pub static DEMO_VPC_CREATE: Lazy = - Lazy::new(|| params::VpcCreate { +pub static DEMO_VPC_URL_FIREWALL_RULES: LazyLock = + LazyLock::new(|| format!("/v1/vpc-firewall-rules?{}", *DEMO_VPC_SELECTOR)); +pub static DEMO_VPC_URL_ROUTERS: LazyLock = + LazyLock::new(|| format!("/v1/vpc-routers?{}", *DEMO_VPC_SELECTOR)); +pub static DEMO_VPC_URL_SUBNETS: LazyLock = + LazyLock::new(|| format!("/v1/vpc-subnets?{}", *DEMO_VPC_SELECTOR)); +pub static DEMO_VPC_CREATE: LazyLock = + LazyLock::new(|| params::VpcCreate { identity: IdentityMetadataCreateParams { name: DEMO_VPC_NAME.clone(), description: String::from(""), @@ -191,19 +201,20 @@ pub static DEMO_VPC_CREATE: Lazy = }); // VPC Subnet used for testing -pub static DEMO_VPC_SUBNET_NAME: Lazy = - Lazy::new(|| "demo-vpc-subnet".parse().unwrap()); -pub static DEMO_VPC_SUBNET_URL: Lazy = Lazy::new(|| { +pub static DEMO_VPC_SUBNET_NAME: LazyLock = + LazyLock::new(|| "demo-vpc-subnet".parse().unwrap()); +pub static DEMO_VPC_SUBNET_URL: LazyLock = LazyLock::new(|| { format!("/v1/vpc-subnets/{}?{}", *DEMO_VPC_SUBNET_NAME, *DEMO_VPC_SELECTOR) }); -pub static DEMO_VPC_SUBNET_INTERFACES_URL: Lazy = Lazy::new(|| { - format!( - "/v1/vpc-subnets/{}/network-interfaces?{}", - *DEMO_VPC_SUBNET_NAME, *DEMO_VPC_SELECTOR - ) -}); -pub static DEMO_VPC_SUBNET_CREATE: Lazy = - Lazy::new(|| params::VpcSubnetCreate { +pub static DEMO_VPC_SUBNET_INTERFACES_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/vpc-subnets/{}/network-interfaces?{}", + *DEMO_VPC_SUBNET_NAME, *DEMO_VPC_SELECTOR + ) + }); +pub static DEMO_VPC_SUBNET_CREATE: LazyLock = + LazyLock::new(|| params::VpcSubnetCreate { identity: IdentityMetadataCreateParams { name: DEMO_VPC_SUBNET_NAME.clone(), description: String::from(""), @@ -214,22 +225,22 @@ pub static DEMO_VPC_SUBNET_CREATE: Lazy = }); // VPC Router used for testing -pub static DEMO_VPC_ROUTER_NAME: Lazy = - Lazy::new(|| "demo-vpc-router".parse().unwrap()); -pub static DEMO_VPC_ROUTER_URL: Lazy = Lazy::new(|| { +pub static DEMO_VPC_ROUTER_NAME: LazyLock = + LazyLock::new(|| "demo-vpc-router".parse().unwrap()); +pub static DEMO_VPC_ROUTER_URL: LazyLock = LazyLock::new(|| { format!( "/v1/vpc-routers/{}?project={}&vpc={}", *DEMO_VPC_ROUTER_NAME, *DEMO_PROJECT_NAME, *DEMO_VPC_NAME ) }); -pub static DEMO_VPC_ROUTER_URL_ROUTES: Lazy = Lazy::new(|| { +pub static DEMO_VPC_ROUTER_URL_ROUTES: LazyLock = LazyLock::new(|| { format!( "/v1/vpc-router-routes?project={}&vpc={}&router={}", *DEMO_PROJECT_NAME, *DEMO_VPC_NAME, *DEMO_VPC_ROUTER_NAME ) }); -pub static DEMO_VPC_ROUTER_CREATE: Lazy = - Lazy::new(|| params::VpcRouterCreate { +pub static DEMO_VPC_ROUTER_CREATE: LazyLock = + LazyLock::new(|| params::VpcRouterCreate { identity: IdentityMetadataCreateParams { name: DEMO_VPC_ROUTER_NAME.clone(), description: String::from(""), @@ -237,9 +248,9 @@ pub static DEMO_VPC_ROUTER_CREATE: Lazy = }); // Router Route used for testing -pub static DEMO_ROUTER_ROUTE_NAME: Lazy = - Lazy::new(|| "demo-router-route".parse().unwrap()); -pub static DEMO_ROUTER_ROUTE_URL: Lazy = Lazy::new(|| { +pub static DEMO_ROUTER_ROUTE_NAME: LazyLock = + LazyLock::new(|| "demo-router-route".parse().unwrap()); +pub static DEMO_ROUTER_ROUTE_URL: LazyLock = LazyLock::new(|| { format!( "/v1/vpc-router-routes/{}?project={}&vpc={}&router={}", *DEMO_ROUTER_ROUTE_NAME, @@ -248,8 +259,8 @@ pub static DEMO_ROUTER_ROUTE_URL: Lazy = Lazy::new(|| { *DEMO_VPC_ROUTER_NAME ) }); -pub static DEMO_ROUTER_ROUTE_CREATE: Lazy = - Lazy::new(|| params::RouterRouteCreate { +pub static DEMO_ROUTER_ROUTE_CREATE: LazyLock = + LazyLock::new(|| params::RouterRouteCreate { identity: IdentityMetadataCreateParams { name: DEMO_ROUTER_ROUTE_NAME.clone(), description: String::from(""), @@ -259,107 +270,113 @@ pub static DEMO_ROUTER_ROUTE_CREATE: Lazy = }); // Internet Gateway used for testing -pub static DEMO_INTERNET_GATEWAY_NAME: Lazy = - Lazy::new(|| "demo-internet-gateway".parse().unwrap()); -pub static DEMO_INTERNET_GATEWAYS_URL: Lazy = Lazy::new(|| { +pub static DEMO_INTERNET_GATEWAY_NAME: LazyLock = + LazyLock::new(|| "demo-internet-gateway".parse().unwrap()); +pub static DEMO_INTERNET_GATEWAYS_URL: LazyLock = LazyLock::new(|| { format!( "/v1/internet-gateways?project={}&vpc={}", *DEMO_PROJECT_NAME, *DEMO_VPC_NAME ) }); -pub static DEMO_INTERNET_GATEWAY_URL: Lazy = Lazy::new(|| { +pub static DEMO_INTERNET_GATEWAY_URL: LazyLock = LazyLock::new(|| { format!( "/v1/internet-gateways/{}?project={}&vpc={}", *DEMO_INTERNET_GATEWAY_NAME, *DEMO_PROJECT_NAME, *DEMO_VPC_NAME ) }); -pub static DEMO_INTERNET_GATEWAY_CREATE: Lazy = - Lazy::new(|| params::InternetGatewayCreate { - identity: IdentityMetadataCreateParams { - name: DEMO_INTERNET_GATEWAY_NAME.clone(), - description: String::from(""), - }, - }); -pub static DEMO_INTERNET_GATEWAY_IP_POOL_CREATE: Lazy< +pub static DEMO_INTERNET_GATEWAY_CREATE: LazyLock< + params::InternetGatewayCreate, +> = LazyLock::new(|| params::InternetGatewayCreate { + identity: IdentityMetadataCreateParams { + name: DEMO_INTERNET_GATEWAY_NAME.clone(), + description: String::from(""), + }, +}); +pub static DEMO_INTERNET_GATEWAY_IP_POOL_CREATE: LazyLock< params::InternetGatewayIpPoolCreate, -> = Lazy::new(|| params::InternetGatewayIpPoolCreate { +> = LazyLock::new(|| params::InternetGatewayIpPoolCreate { identity: IdentityMetadataCreateParams { name: DEMO_INTERNET_GATEWAY_NAME.clone(), description: String::from(""), }, ip_pool: NameOrId::Id(uuid::Uuid::new_v4()), }); -pub static DEMO_INTERNET_GATEWAY_IP_ADDRESS_CREATE: Lazy< +pub static DEMO_INTERNET_GATEWAY_IP_ADDRESS_CREATE: LazyLock< params::InternetGatewayIpAddressCreate, -> = Lazy::new(|| params::InternetGatewayIpAddressCreate { +> = LazyLock::new(|| params::InternetGatewayIpAddressCreate { identity: IdentityMetadataCreateParams { name: DEMO_INTERNET_GATEWAY_NAME.clone(), description: String::from(""), }, address: IpAddr::V4(Ipv4Addr::UNSPECIFIED), }); -pub static DEMO_INTERNET_GATEWAY_IP_POOLS_URL: Lazy = Lazy::new(|| { - format!( - "/v1/internet-gateway-ip-pools?project={}&vpc={}&gateway={}", - *DEMO_PROJECT_NAME, *DEMO_VPC_NAME, *DEMO_INTERNET_GATEWAY_NAME, - ) -}); -pub static DEMO_INTERNET_GATEWAY_IP_ADDRS_URL: Lazy = Lazy::new(|| { - format!( - "/v1/internet-gateway-ip-addresses?project={}&vpc={}&gateway={}", - *DEMO_PROJECT_NAME, *DEMO_VPC_NAME, *DEMO_INTERNET_GATEWAY_NAME, - ) -}); -pub static DEMO_INTERNET_GATEWAY_IP_POOL_NAME: Lazy = - Lazy::new(|| "demo-igw-pool".parse().unwrap()); -pub static DEMO_INTERNET_GATEWAY_IP_ADDRESS_NAME: Lazy = - Lazy::new(|| "demo-igw-address".parse().unwrap()); -pub static DEMO_INTERNET_GATEWAY_IP_POOL_URL: Lazy = Lazy::new(|| { - format!( - "/v1/internet-gateway-ip-pools/{}?project={}&vpc={}&gateway={}", - *DEMO_INTERNET_GATEWAY_IP_POOL_NAME, - *DEMO_PROJECT_NAME, - *DEMO_VPC_NAME, - *DEMO_INTERNET_GATEWAY_NAME, - ) -}); -pub static DEMO_INTERNET_GATEWAY_IP_ADDR_URL: Lazy = Lazy::new(|| { - format!( - "/v1/internet-gateway-ip-addresses/{}?project={}&vpc={}&gateway={}", - *DEMO_INTERNET_GATEWAY_IP_ADDRESS_NAME, - *DEMO_PROJECT_NAME, - *DEMO_VPC_NAME, - *DEMO_INTERNET_GATEWAY_NAME, - ) -}); +pub static DEMO_INTERNET_GATEWAY_IP_POOLS_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/internet-gateway-ip-pools?project={}&vpc={}&gateway={}", + *DEMO_PROJECT_NAME, *DEMO_VPC_NAME, *DEMO_INTERNET_GATEWAY_NAME, + ) + }); +pub static DEMO_INTERNET_GATEWAY_IP_ADDRS_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/internet-gateway-ip-addresses?project={}&vpc={}&gateway={}", + *DEMO_PROJECT_NAME, *DEMO_VPC_NAME, *DEMO_INTERNET_GATEWAY_NAME, + ) + }); +pub static DEMO_INTERNET_GATEWAY_IP_POOL_NAME: LazyLock = + LazyLock::new(|| "demo-igw-pool".parse().unwrap()); +pub static DEMO_INTERNET_GATEWAY_IP_ADDRESS_NAME: LazyLock = + LazyLock::new(|| "demo-igw-address".parse().unwrap()); +pub static DEMO_INTERNET_GATEWAY_IP_POOL_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/internet-gateway-ip-pools/{}?project={}&vpc={}&gateway={}", + *DEMO_INTERNET_GATEWAY_IP_POOL_NAME, + *DEMO_PROJECT_NAME, + *DEMO_VPC_NAME, + *DEMO_INTERNET_GATEWAY_NAME, + ) + }); +pub static DEMO_INTERNET_GATEWAY_IP_ADDR_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/internet-gateway-ip-addresses/{}?project={}&vpc={}&gateway={}", + *DEMO_INTERNET_GATEWAY_IP_ADDRESS_NAME, + *DEMO_PROJECT_NAME, + *DEMO_VPC_NAME, + *DEMO_INTERNET_GATEWAY_NAME, + ) + }); // Disk used for testing -pub static DEMO_DISK_NAME: Lazy = - Lazy::new(|| "demo-disk".parse().unwrap()); +pub static DEMO_DISK_NAME: LazyLock = + LazyLock::new(|| "demo-disk".parse().unwrap()); // TODO: Once we can test a URL multiple times we should also a case to exercise // authz for disks filtered by instances -pub static DEMO_DISKS_URL: Lazy = - Lazy::new(|| format!("/v1/disks?{}", *DEMO_PROJECT_SELECTOR)); -pub static DEMO_DISK_URL: Lazy = Lazy::new(|| { +pub static DEMO_DISKS_URL: LazyLock = + LazyLock::new(|| format!("/v1/disks?{}", *DEMO_PROJECT_SELECTOR)); +pub static DEMO_DISK_URL: LazyLock = LazyLock::new(|| { format!("/v1/disks/{}?{}", *DEMO_DISK_NAME, *DEMO_PROJECT_SELECTOR) }); -pub static DEMO_DISK_CREATE: Lazy = Lazy::new(|| { - params::DiskCreate { - identity: IdentityMetadataCreateParams { - name: DEMO_DISK_NAME.clone(), - description: "".parse().unwrap(), - }, - disk_source: params::DiskSource::Blank { - block_size: params::BlockSize::try_from(4096).unwrap(), - }, - size: ByteCount::from_gibibytes_u32( - // divide by at least two to leave space for snapshot blocks - DiskTest::DEFAULT_ZPOOL_SIZE_GIB / 5, - ), - } -}); -pub static DEMO_DISK_METRICS_URL: Lazy = Lazy::new(|| { +pub static DEMO_DISK_CREATE: LazyLock = + LazyLock::new(|| { + params::DiskCreate { + identity: IdentityMetadataCreateParams { + name: DEMO_DISK_NAME.clone(), + description: "".parse().unwrap(), + }, + disk_source: params::DiskSource::Blank { + block_size: params::BlockSize::try_from(4096).unwrap(), + }, + size: ByteCount::from_gibibytes_u32( + // divide by at least two to leave space for snapshot blocks + DiskTest::DEFAULT_ZPOOL_SIZE_GIB / 5, + ), + } + }); +pub static DEMO_DISK_METRICS_URL: LazyLock = LazyLock::new(|| { format!( "/v1/disks/{}/metrics/activated?start_time={:?}&end_time={:?}&{}", *DEMO_DISK_NAME, @@ -370,10 +387,10 @@ pub static DEMO_DISK_METRICS_URL: Lazy = Lazy::new(|| { }); // Related to importing blocks from an external source -pub static DEMO_IMPORT_DISK_NAME: Lazy = - Lazy::new(|| "demo-import-disk".parse().unwrap()); -pub static DEMO_IMPORT_DISK_CREATE: Lazy = - Lazy::new(|| { +pub static DEMO_IMPORT_DISK_NAME: LazyLock = + LazyLock::new(|| "demo-import-disk".parse().unwrap()); +pub static DEMO_IMPORT_DISK_CREATE: LazyLock = + LazyLock::new(|| { params::DiskCreate { identity: IdentityMetadataCreateParams { name: DEMO_IMPORT_DISK_NAME.clone(), @@ -388,113 +405,120 @@ pub static DEMO_IMPORT_DISK_CREATE: Lazy = ), } }); -pub static DEMO_IMPORT_DISK_BULK_WRITE_START_URL: Lazy = - Lazy::new(|| { +pub static DEMO_IMPORT_DISK_BULK_WRITE_START_URL: LazyLock = + LazyLock::new(|| { format!( "/v1/disks/{}/bulk-write-start?{}", *DEMO_IMPORT_DISK_NAME, *DEMO_PROJECT_SELECTOR ) }); -pub static DEMO_IMPORT_DISK_BULK_WRITE_URL: Lazy = Lazy::new(|| { - format!( - "/v1/disks/{}/bulk-write?{}", - *DEMO_IMPORT_DISK_NAME, *DEMO_PROJECT_SELECTOR - ) -}); -pub static DEMO_IMPORT_DISK_BULK_WRITE_STOP_URL: Lazy = - Lazy::new(|| { +pub static DEMO_IMPORT_DISK_BULK_WRITE_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/disks/{}/bulk-write?{}", + *DEMO_IMPORT_DISK_NAME, *DEMO_PROJECT_SELECTOR + ) + }); +pub static DEMO_IMPORT_DISK_BULK_WRITE_STOP_URL: LazyLock = + LazyLock::new(|| { format!( "/v1/disks/{}/bulk-write-stop?{}", *DEMO_IMPORT_DISK_NAME, *DEMO_PROJECT_SELECTOR ) }); -pub static DEMO_IMPORT_DISK_FINALIZE_URL: Lazy = Lazy::new(|| { - format!( - "/v1/disks/{}/finalize?{}", - *DEMO_IMPORT_DISK_NAME, *DEMO_PROJECT_SELECTOR - ) -}); +pub static DEMO_IMPORT_DISK_FINALIZE_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/disks/{}/finalize?{}", + *DEMO_IMPORT_DISK_NAME, *DEMO_PROJECT_SELECTOR + ) + }); // Instance used for testing -pub static DEMO_INSTANCE_NAME: Lazy = - Lazy::new(|| "demo-instance".parse().unwrap()); -pub static DEMO_INSTANCE_URL: Lazy = Lazy::new(|| { +pub static DEMO_INSTANCE_NAME: LazyLock = + LazyLock::new(|| "demo-instance".parse().unwrap()); +pub static DEMO_INSTANCE_URL: LazyLock = LazyLock::new(|| { format!("/v1/instances/{}?{}", *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR) }); -pub static DEMO_INSTANCE_START_URL: Lazy = Lazy::new(|| { +pub static DEMO_INSTANCE_START_URL: LazyLock = LazyLock::new(|| { format!( "/v1/instances/{}/start?{}", *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR ) }); -pub static DEMO_INSTANCE_STOP_URL: Lazy = Lazy::new(|| { +pub static DEMO_INSTANCE_STOP_URL: LazyLock = LazyLock::new(|| { format!( "/v1/instances/{}/stop?{}", *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR ) }); -pub static DEMO_INSTANCE_REBOOT_URL: Lazy = Lazy::new(|| { +pub static DEMO_INSTANCE_REBOOT_URL: LazyLock = LazyLock::new(|| { format!( "/v1/instances/{}/reboot?{}", *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR ) }); -pub static DEMO_INSTANCE_SERIAL_URL: Lazy = Lazy::new(|| { +pub static DEMO_INSTANCE_SERIAL_URL: LazyLock = LazyLock::new(|| { format!( "/v1/instances/{}/serial-console?{}", *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR ) }); -pub static DEMO_INSTANCE_SERIAL_STREAM_URL: Lazy = Lazy::new(|| { - format!( - "/v1/instances/{}/serial-console/stream?{}", - *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR - ) -}); -pub static DEMO_INSTANCE_DISKS_URL: Lazy = Lazy::new(|| { +pub static DEMO_INSTANCE_SERIAL_STREAM_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/instances/{}/serial-console/stream?{}", + *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR + ) + }); +pub static DEMO_INSTANCE_DISKS_URL: LazyLock = LazyLock::new(|| { format!( "/v1/instances/{}/disks?{}", *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR ) }); -pub static DEMO_INSTANCE_DISKS_ATTACH_URL: Lazy = Lazy::new(|| { - format!( - "/v1/instances/{}/disks/attach?{}", - *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR - ) -}); -pub static DEMO_INSTANCE_DISKS_DETACH_URL: Lazy = Lazy::new(|| { - format!( - "/v1/instances/{}/disks/detach?{}", - *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR - ) -}); -pub static DEMO_INSTANCE_EPHEMERAL_IP_URL: Lazy = Lazy::new(|| { - format!( - "/v1/instances/{}/external-ips/ephemeral?{}", - *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR - ) -}); -pub static DEMO_INSTANCE_SSH_KEYS_URL: Lazy = Lazy::new(|| { +pub static DEMO_INSTANCE_DISKS_ATTACH_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/instances/{}/disks/attach?{}", + *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR + ) + }); +pub static DEMO_INSTANCE_DISKS_DETACH_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/instances/{}/disks/detach?{}", + *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR + ) + }); +pub static DEMO_INSTANCE_EPHEMERAL_IP_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/instances/{}/external-ips/ephemeral?{}", + *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR + ) + }); +pub static DEMO_INSTANCE_SSH_KEYS_URL: LazyLock = LazyLock::new(|| { format!( "/v1/instances/{}/ssh-public-keys?{}", *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR ) }); -pub static DEMO_INSTANCE_NICS_URL: Lazy = Lazy::new(|| { +pub static DEMO_INSTANCE_NICS_URL: LazyLock = LazyLock::new(|| { format!( "/v1/network-interfaces?project={}&instance={}", *DEMO_PROJECT_NAME, *DEMO_INSTANCE_NAME ) }); -pub static DEMO_INSTANCE_EXTERNAL_IPS_URL: Lazy = Lazy::new(|| { - format!( - "/v1/instances/{}/external-ips?{}", - *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR - ) -}); -pub static DEMO_INSTANCE_CREATE: Lazy = - Lazy::new(|| params::InstanceCreate { +pub static DEMO_INSTANCE_EXTERNAL_IPS_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/instances/{}/external-ips?{}", + *DEMO_INSTANCE_NAME, *DEMO_PROJECT_SELECTOR + ) + }); +pub static DEMO_INSTANCE_CREATE: LazyLock = + LazyLock::new(|| params::InstanceCreate { identity: IdentityMetadataCreateParams { name: DEMO_INSTANCE_NAME.clone(), description: String::from(""), @@ -513,8 +537,8 @@ pub static DEMO_INSTANCE_CREATE: Lazy = start: true, auto_restart_policy: Default::default(), }); -pub static DEMO_INSTANCE_UPDATE: Lazy = - Lazy::new(|| params::InstanceUpdate { +pub static DEMO_INSTANCE_UPDATE: LazyLock = + LazyLock::new(|| params::InstanceUpdate { boot_disk: None, auto_restart_policy: None, ncpus: InstanceCpuCount(1), @@ -522,17 +546,17 @@ pub static DEMO_INSTANCE_UPDATE: Lazy = }); // The instance needs a network interface, too. -pub static DEMO_INSTANCE_NIC_NAME: Lazy = - Lazy::new(|| nexus_defaults::DEFAULT_PRIMARY_NIC_NAME.parse().unwrap()); -pub static DEMO_INSTANCE_NIC_URL: Lazy = Lazy::new(|| { +pub static DEMO_INSTANCE_NIC_NAME: LazyLock = + LazyLock::new(|| nexus_defaults::DEFAULT_PRIMARY_NIC_NAME.parse().unwrap()); +pub static DEMO_INSTANCE_NIC_URL: LazyLock = LazyLock::new(|| { format!( "/v1/network-interfaces/{}?project={}&instance={}", *DEMO_INSTANCE_NIC_NAME, *DEMO_PROJECT_NAME, *DEMO_INSTANCE_NAME ) }); -pub static DEMO_INSTANCE_NIC_CREATE: Lazy< +pub static DEMO_INSTANCE_NIC_CREATE: LazyLock< params::InstanceNetworkInterfaceCreate, -> = Lazy::new(|| params::InstanceNetworkInterfaceCreate { +> = LazyLock::new(|| params::InstanceNetworkInterfaceCreate { identity: IdentityMetadataCreateParams { name: DEMO_INSTANCE_NIC_NAME.clone(), description: String::from(""), @@ -541,26 +565,27 @@ pub static DEMO_INSTANCE_NIC_CREATE: Lazy< subnet_name: DEMO_VPC_SUBNET_NAME.clone(), ip: None, }); -pub static DEMO_INSTANCE_NIC_PUT: Lazy = - Lazy::new(|| params::InstanceNetworkInterfaceUpdate { - identity: IdentityMetadataUpdateParams { - name: None, - description: Some(String::from("an updated description")), - }, - primary: false, - transit_ips: vec![], - }); +pub static DEMO_INSTANCE_NIC_PUT: LazyLock< + params::InstanceNetworkInterfaceUpdate, +> = LazyLock::new(|| params::InstanceNetworkInterfaceUpdate { + identity: IdentityMetadataUpdateParams { + name: None, + description: Some(String::from("an updated description")), + }, + primary: false, + transit_ips: vec![], +}); -pub static DEMO_CERTIFICATE_NAME: Lazy = - Lazy::new(|| "demo-certificate".parse().unwrap()); +pub static DEMO_CERTIFICATE_NAME: LazyLock = + LazyLock::new(|| "demo-certificate".parse().unwrap()); pub const DEMO_CERTIFICATES_URL: &'static str = "/v1/certificates"; pub const DEMO_CERTIFICATE_URL: &'static str = "/v1/certificates/demo-certificate"; -pub static DEMO_CERTIFICATE: Lazy = Lazy::new(|| { +pub static DEMO_CERTIFICATE: LazyLock = LazyLock::new(|| { CertificateChain::new(format!("*.sys.{DNS_ZONE_EXTERNAL_TESTING}")) }); -pub static DEMO_CERTIFICATE_CREATE: Lazy = - Lazy::new(|| params::CertificateCreate { +pub static DEMO_CERTIFICATE_CREATE: LazyLock = + LazyLock::new(|| params::CertificateCreate { identity: IdentityMetadataCreateParams { name: DEMO_CERTIFICATE_NAME.clone(), description: String::from(""), @@ -572,21 +597,21 @@ pub static DEMO_CERTIFICATE_CREATE: Lazy = pub const DEMO_SWITCH_PORT_URL: &'static str = "/v1/system/hardware/switch-port"; -pub static DEMO_SWITCH_PORT_SETTINGS_APPLY_URL: Lazy = Lazy::new( - || { +pub static DEMO_SWITCH_PORT_SETTINGS_APPLY_URL: LazyLock = + LazyLock::new(|| { format!( "/v1/system/hardware/switch-port/qsfp7/settings?rack_id={}&switch_location={}", uuid::Uuid::new_v4(), "switch0", ) - }, -); -pub static DEMO_SWITCH_PORT_SETTINGS: Lazy = - Lazy::new(|| params::SwitchPortApplySettings { - port_settings: NameOrId::Name("portofino".parse().unwrap()), }); +pub static DEMO_SWITCH_PORT_SETTINGS: LazyLock< + params::SwitchPortApplySettings, +> = LazyLock::new(|| params::SwitchPortApplySettings { + port_settings: NameOrId::Name("portofino".parse().unwrap()), +}); /* TODO requires dpd access -pub static DEMO_SWITCH_PORT_STATUS_URL: Lazy = Lazy::new(|| { +pub static DEMO_SWITCH_PORT_STATUS_URL: LazyLock = LazyLock::new(|| { format!( "/v1/system/hardware/switch-port/qsfp7/status?rack_id={}&switch_location={}", uuid::Uuid::new_v4(), @@ -595,9 +620,9 @@ pub static DEMO_SWITCH_PORT_STATUS_URL: Lazy = Lazy::new(|| { }); */ -pub static DEMO_LOOPBACK_CREATE_URL: Lazy = - Lazy::new(|| "/v1/system/networking/loopback-address".into()); -pub static DEMO_LOOPBACK_URL: Lazy = Lazy::new(|| { +pub static DEMO_LOOPBACK_CREATE_URL: LazyLock = + LazyLock::new(|| "/v1/system/networking/loopback-address".into()); +pub static DEMO_LOOPBACK_URL: LazyLock = LazyLock::new(|| { format!( "/v1/system/networking/loopback-address/{}/{}/{}", uuid::Uuid::new_v4(), @@ -605,8 +630,8 @@ pub static DEMO_LOOPBACK_URL: Lazy = Lazy::new(|| { "203.0.113.99/24", ) }); -pub static DEMO_LOOPBACK_CREATE: Lazy = - Lazy::new(|| params::LoopbackAddressCreate { +pub static DEMO_LOOPBACK_CREATE: LazyLock = + LazyLock::new(|| params::LoopbackAddressCreate { address_lot: NameOrId::Name("parkinglot".parse().unwrap()), rack_id: uuid::Uuid::new_v4(), switch_location: "switch0".parse().unwrap(), @@ -619,9 +644,9 @@ pub const DEMO_SWITCH_PORT_SETTINGS_URL: &'static str = "/v1/system/networking/switch-port-settings?port_settings=portofino"; pub const DEMO_SWITCH_PORT_SETTINGS_INFO_URL: &'static str = "/v1/system/networking/switch-port-settings/protofino"; -pub static DEMO_SWITCH_PORT_SETTINGS_CREATE: Lazy< +pub static DEMO_SWITCH_PORT_SETTINGS_CREATE: LazyLock< params::SwitchPortSettingsCreate, -> = Lazy::new(|| { +> = LazyLock::new(|| { params::SwitchPortSettingsCreate::new(IdentityMetadataCreateParams { name: "portofino".parse().unwrap(), description: "just a port".into(), @@ -634,8 +659,8 @@ pub const DEMO_ADDRESS_LOT_URL: &'static str = "/v1/system/networking/address-lot/parkinglot"; pub const DEMO_ADDRESS_LOT_BLOCKS_URL: &'static str = "/v1/system/networking/address-lot/parkinglot/blocks"; -pub static DEMO_ADDRESS_LOT_CREATE: Lazy = - Lazy::new(|| params::AddressLotCreate { +pub static DEMO_ADDRESS_LOT_CREATE: LazyLock = + LazyLock::new(|| params::AddressLotCreate { identity: IdentityMetadataCreateParams { name: "parkinglot".parse().unwrap(), description: "an address parking lot".into(), @@ -649,8 +674,8 @@ pub static DEMO_ADDRESS_LOT_CREATE: Lazy = pub const DEMO_BGP_CONFIG_CREATE_URL: &'static str = "/v1/system/networking/bgp?name_or_id=as47"; -pub static DEMO_BGP_CONFIG: Lazy = - Lazy::new(|| params::BgpConfigCreate { +pub static DEMO_BGP_CONFIG: LazyLock = + LazyLock::new(|| params::BgpConfigCreate { identity: IdentityMetadataCreateParams { name: "as47".parse().unwrap(), description: "BGP config for AS47".into(), @@ -663,8 +688,8 @@ pub static DEMO_BGP_CONFIG: Lazy = }); pub const DEMO_BGP_ANNOUNCE_SET_URL: &'static str = "/v1/system/networking/bgp-announce-set"; -pub static DEMO_BGP_ANNOUNCE: Lazy = - Lazy::new(|| params::BgpAnnounceSetCreate { +pub static DEMO_BGP_ANNOUNCE: LazyLock = + LazyLock::new(|| params::BgpAnnounceSetCreate { identity: IdentityMetadataCreateParams { name: "a-bag-of-addrs".parse().unwrap(), description: "a bag of addrs".into(), @@ -696,8 +721,8 @@ pub const DEMO_BFD_ENABLE_URL: &'static str = pub const DEMO_BFD_DISABLE_URL: &'static str = "/v1/system/networking/bfd-disable"; -pub static DEMO_BFD_ENABLE: Lazy = - Lazy::new(|| params::BfdSessionEnable { +pub static DEMO_BFD_ENABLE: LazyLock = + LazyLock::new(|| params::BfdSessionEnable { local: None, remote: "10.0.0.1".parse().unwrap(), detection_threshold: 3, @@ -706,36 +731,37 @@ pub static DEMO_BFD_ENABLE: Lazy = mode: omicron_common::api::external::BfdMode::MultiHop, }); -pub static DEMO_BFD_DISABLE: Lazy = - Lazy::new(|| params::BfdSessionDisable { +pub static DEMO_BFD_DISABLE: LazyLock = + LazyLock::new(|| params::BfdSessionDisable { remote: "10.0.0.1".parse().unwrap(), switch: "switch0".parse().unwrap(), }); // Project Images -pub static DEMO_IMAGE_NAME: Lazy = - Lazy::new(|| "demo-image".parse().unwrap()); -pub static DEMO_PROJECT_IMAGES_URL: Lazy = - Lazy::new(|| format!("/v1/images?project={}", *DEMO_PROJECT_NAME)); -pub static DEMO_PROJECT_IMAGE_URL: Lazy = Lazy::new(|| { +pub static DEMO_IMAGE_NAME: LazyLock = + LazyLock::new(|| "demo-image".parse().unwrap()); +pub static DEMO_PROJECT_IMAGES_URL: LazyLock = + LazyLock::new(|| format!("/v1/images?project={}", *DEMO_PROJECT_NAME)); +pub static DEMO_PROJECT_IMAGE_URL: LazyLock = LazyLock::new(|| { format!("/v1/images/{}?project={}", *DEMO_IMAGE_NAME, *DEMO_PROJECT_NAME) }); -pub static DEMO_PROJECT_PROMOTE_IMAGE_URL: Lazy = Lazy::new(|| { - format!( - "/v1/images/{}/promote?project={}", - *DEMO_IMAGE_NAME, *DEMO_PROJECT_NAME - ) -}); +pub static DEMO_PROJECT_PROMOTE_IMAGE_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/images/{}/promote?project={}", + *DEMO_IMAGE_NAME, *DEMO_PROJECT_NAME + ) + }); -pub static DEMO_SILO_DEMOTE_IMAGE_URL: Lazy = Lazy::new(|| { +pub static DEMO_SILO_DEMOTE_IMAGE_URL: LazyLock = LazyLock::new(|| { format!( "/v1/images/{}/demote?project={}", *DEMO_IMAGE_NAME, *DEMO_PROJECT_NAME ) }); -pub static DEMO_IMAGE_CREATE: Lazy = - Lazy::new(|| params::ImageCreate { +pub static DEMO_IMAGE_CREATE: LazyLock = + LazyLock::new(|| params::ImageCreate { identity: IdentityMetadataCreateParams { name: DEMO_IMAGE_NAME.clone(), description: String::from(""), @@ -746,49 +772,50 @@ pub static DEMO_IMAGE_CREATE: Lazy = }); // IP Pools -pub static DEMO_IP_POOLS_PROJ_URL: Lazy = - Lazy::new(|| "/v1/ip-pools".to_string()); +pub static DEMO_IP_POOLS_PROJ_URL: LazyLock = + LazyLock::new(|| "/v1/ip-pools".to_string()); pub const DEMO_IP_POOLS_URL: &'static str = "/v1/system/ip-pools"; -pub static DEMO_IP_POOL_NAME: Lazy = - Lazy::new(|| "default".parse().unwrap()); -pub static DEMO_IP_POOL_CREATE: Lazy = - Lazy::new(|| params::IpPoolCreate { +pub static DEMO_IP_POOL_NAME: LazyLock = + LazyLock::new(|| "default".parse().unwrap()); +pub static DEMO_IP_POOL_CREATE: LazyLock = + LazyLock::new(|| params::IpPoolCreate { identity: IdentityMetadataCreateParams { name: DEMO_IP_POOL_NAME.clone(), description: String::from("an IP pool"), }, }); -pub static DEMO_IP_POOL_PROJ_URL: Lazy = Lazy::new(|| { +pub static DEMO_IP_POOL_PROJ_URL: LazyLock = LazyLock::new(|| { format!( "/v1/ip-pools/{}?project={}", *DEMO_IP_POOL_NAME, *DEMO_PROJECT_NAME ) }); -pub static DEMO_IP_POOL_URL: Lazy = - Lazy::new(|| format!("/v1/system/ip-pools/{}", *DEMO_IP_POOL_NAME)); -pub static DEMO_IP_POOL_UTILIZATION_URL: Lazy = - Lazy::new(|| format!("{}/utilization", *DEMO_IP_POOL_URL)); -pub static DEMO_IP_POOL_UPDATE: Lazy = - Lazy::new(|| params::IpPoolUpdate { +pub static DEMO_IP_POOL_URL: LazyLock = + LazyLock::new(|| format!("/v1/system/ip-pools/{}", *DEMO_IP_POOL_NAME)); +pub static DEMO_IP_POOL_UTILIZATION_URL: LazyLock = + LazyLock::new(|| format!("{}/utilization", *DEMO_IP_POOL_URL)); +pub static DEMO_IP_POOL_UPDATE: LazyLock = + LazyLock::new(|| params::IpPoolUpdate { identity: IdentityMetadataUpdateParams { name: None, description: Some(String::from("a new IP pool")), }, }); -pub static DEMO_IP_POOL_SILOS_URL: Lazy = - Lazy::new(|| format!("{}/silos", *DEMO_IP_POOL_URL)); -pub static DEMO_IP_POOL_SILOS_BODY: Lazy = - Lazy::new(|| params::IpPoolLinkSilo { +pub static DEMO_IP_POOL_SILOS_URL: LazyLock = + LazyLock::new(|| format!("{}/silos", *DEMO_IP_POOL_URL)); +pub static DEMO_IP_POOL_SILOS_BODY: LazyLock = + LazyLock::new(|| params::IpPoolLinkSilo { silo: NameOrId::Id(DEFAULT_SILO.identity().id), is_default: true, // necessary for demo instance create to go through }); -pub static DEMO_IP_POOL_SILO_URL: Lazy = - Lazy::new(|| format!("{}/silos/{}", *DEMO_IP_POOL_URL, *DEMO_SILO_NAME)); -pub static DEMO_IP_POOL_SILO_UPDATE_BODY: Lazy = - Lazy::new(|| params::IpPoolSiloUpdate { is_default: false }); +pub static DEMO_IP_POOL_SILO_URL: LazyLock = LazyLock::new(|| { + format!("{}/silos/{}", *DEMO_IP_POOL_URL, *DEMO_SILO_NAME) +}); +pub static DEMO_IP_POOL_SILO_UPDATE_BODY: LazyLock = + LazyLock::new(|| params::IpPoolSiloUpdate { is_default: false }); -pub static DEMO_IP_POOL_RANGE: Lazy = Lazy::new(|| { +pub static DEMO_IP_POOL_RANGE: LazyLock = LazyLock::new(|| { IpRange::V4( Ipv4Range::new( std::net::Ipv4Addr::new(10, 0, 0, 0), @@ -797,34 +824,34 @@ pub static DEMO_IP_POOL_RANGE: Lazy = Lazy::new(|| { .unwrap(), ) }); -pub static DEMO_IP_POOL_RANGES_URL: Lazy = - Lazy::new(|| format!("{}/ranges", *DEMO_IP_POOL_URL)); -pub static DEMO_IP_POOL_RANGES_ADD_URL: Lazy = - Lazy::new(|| format!("{}/add", *DEMO_IP_POOL_RANGES_URL)); -pub static DEMO_IP_POOL_RANGES_DEL_URL: Lazy = - Lazy::new(|| format!("{}/remove", *DEMO_IP_POOL_RANGES_URL)); +pub static DEMO_IP_POOL_RANGES_URL: LazyLock = + LazyLock::new(|| format!("{}/ranges", *DEMO_IP_POOL_URL)); +pub static DEMO_IP_POOL_RANGES_ADD_URL: LazyLock = + LazyLock::new(|| format!("{}/add", *DEMO_IP_POOL_RANGES_URL)); +pub static DEMO_IP_POOL_RANGES_DEL_URL: LazyLock = + LazyLock::new(|| format!("{}/remove", *DEMO_IP_POOL_RANGES_URL)); // IP Pools (Services) pub const DEMO_IP_POOL_SERVICE_URL: &'static str = "/v1/system/ip-pools-service"; -pub static DEMO_IP_POOL_SERVICE_RANGES_URL: Lazy = - Lazy::new(|| format!("{}/ranges", DEMO_IP_POOL_SERVICE_URL)); -pub static DEMO_IP_POOL_SERVICE_RANGES_ADD_URL: Lazy = - Lazy::new(|| format!("{}/add", *DEMO_IP_POOL_SERVICE_RANGES_URL)); -pub static DEMO_IP_POOL_SERVICE_RANGES_DEL_URL: Lazy = - Lazy::new(|| format!("{}/remove", *DEMO_IP_POOL_SERVICE_RANGES_URL)); +pub static DEMO_IP_POOL_SERVICE_RANGES_URL: LazyLock = + LazyLock::new(|| format!("{}/ranges", DEMO_IP_POOL_SERVICE_URL)); +pub static DEMO_IP_POOL_SERVICE_RANGES_ADD_URL: LazyLock = + LazyLock::new(|| format!("{}/add", *DEMO_IP_POOL_SERVICE_RANGES_URL)); +pub static DEMO_IP_POOL_SERVICE_RANGES_DEL_URL: LazyLock = + LazyLock::new(|| format!("{}/remove", *DEMO_IP_POOL_SERVICE_RANGES_URL)); // Snapshots -pub static DEMO_SNAPSHOT_NAME: Lazy = - Lazy::new(|| "demo-snapshot".parse().unwrap()); -pub static DEMO_SNAPSHOT_URL: Lazy = Lazy::new(|| { +pub static DEMO_SNAPSHOT_NAME: LazyLock = + LazyLock::new(|| "demo-snapshot".parse().unwrap()); +pub static DEMO_SNAPSHOT_URL: LazyLock = LazyLock::new(|| { format!( "/v1/snapshots/{}?project={}", *DEMO_SNAPSHOT_NAME, *DEMO_PROJECT_NAME ) }); -pub static DEMO_SNAPSHOT_CREATE: Lazy = - Lazy::new(|| params::SnapshotCreate { +pub static DEMO_SNAPSHOT_CREATE: LazyLock = + LazyLock::new(|| params::SnapshotCreate { identity: IdentityMetadataCreateParams { name: DEMO_SNAPSHOT_NAME.clone(), description: String::from(""), @@ -834,11 +861,11 @@ pub static DEMO_SNAPSHOT_CREATE: Lazy = // SSH keys pub const DEMO_SSHKEYS_URL: &'static str = "/v1/me/ssh-keys"; -pub static DEMO_SSHKEY_NAME: Lazy = - Lazy::new(|| "aaaaa-ssh-key".parse().unwrap()); +pub static DEMO_SSHKEY_NAME: LazyLock = + LazyLock::new(|| "aaaaa-ssh-key".parse().unwrap()); -pub static DEMO_SSHKEY_CREATE: Lazy = - Lazy::new(|| params::SshKeyCreate { +pub static DEMO_SSHKEY_CREATE: LazyLock = + LazyLock::new(|| params::SshKeyCreate { identity: IdentityMetadataCreateParams { name: DEMO_SSHKEY_NAME.clone(), description: "a demo key".to_string(), @@ -847,35 +874,37 @@ pub static DEMO_SSHKEY_CREATE: Lazy = public_key: "AAAAAAAAAAAAAAA".to_string(), }); -pub static DEMO_SPECIFIC_SSHKEY_URL: Lazy = - Lazy::new(|| format!("{}/{}", DEMO_SSHKEYS_URL, *DEMO_SSHKEY_NAME)); +pub static DEMO_SPECIFIC_SSHKEY_URL: LazyLock = + LazyLock::new(|| format!("{}/{}", DEMO_SSHKEYS_URL, *DEMO_SSHKEY_NAME)); // Project Floating IPs -pub static DEMO_FLOAT_IP_NAME: Lazy = - Lazy::new(|| "float-ip".parse().unwrap()); +pub static DEMO_FLOAT_IP_NAME: LazyLock = + LazyLock::new(|| "float-ip".parse().unwrap()); -pub static DEMO_FLOAT_IP_URL: Lazy = Lazy::new(|| { +pub static DEMO_FLOAT_IP_URL: LazyLock = LazyLock::new(|| { format!( "/v1/floating-ips/{}?project={}", *DEMO_FLOAT_IP_NAME, *DEMO_PROJECT_NAME ) }); -pub static DEMO_FLOATING_IP_ATTACH_URL: Lazy = Lazy::new(|| { - format!( - "/v1/floating-ips/{}/attach?{}", - *DEMO_FLOAT_IP_NAME, *DEMO_PROJECT_SELECTOR - ) -}); -pub static DEMO_FLOATING_IP_DETACH_URL: Lazy = Lazy::new(|| { - format!( - "/v1/floating-ips/{}/detach?{}", - *DEMO_FLOAT_IP_NAME, *DEMO_PROJECT_SELECTOR - ) -}); +pub static DEMO_FLOATING_IP_ATTACH_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/floating-ips/{}/attach?{}", + *DEMO_FLOAT_IP_NAME, *DEMO_PROJECT_SELECTOR + ) + }); +pub static DEMO_FLOATING_IP_DETACH_URL: LazyLock = + LazyLock::new(|| { + format!( + "/v1/floating-ips/{}/detach?{}", + *DEMO_FLOAT_IP_NAME, *DEMO_PROJECT_SELECTOR + ) + }); -pub static DEMO_FLOAT_IP_CREATE: Lazy = - Lazy::new(|| params::FloatingIpCreate { +pub static DEMO_FLOAT_IP_CREATE: LazyLock = + LazyLock::new(|| params::FloatingIpCreate { identity: IdentityMetadataCreateParams { name: DEMO_FLOAT_IP_NAME.clone(), description: String::from("a new IP pool"), @@ -884,60 +913,61 @@ pub static DEMO_FLOAT_IP_CREATE: Lazy = pool: None, }); -pub static DEMO_FLOAT_IP_UPDATE: Lazy = - Lazy::new(|| params::FloatingIpUpdate { +pub static DEMO_FLOAT_IP_UPDATE: LazyLock = + LazyLock::new(|| params::FloatingIpUpdate { identity: IdentityMetadataUpdateParams { name: None, description: Some(String::from("an updated Floating IP")), }, }); -pub static DEMO_FLOAT_IP_ATTACH: Lazy = - Lazy::new(|| params::FloatingIpAttach { +pub static DEMO_FLOAT_IP_ATTACH: LazyLock = + LazyLock::new(|| params::FloatingIpAttach { kind: params::FloatingIpParentKind::Instance, parent: DEMO_FLOAT_IP_NAME.clone().into(), }); -pub static DEMO_EPHEMERAL_IP_ATTACH: Lazy = - Lazy::new(|| params::EphemeralIpCreate { pool: None }); +pub static DEMO_EPHEMERAL_IP_ATTACH: LazyLock = + LazyLock::new(|| params::EphemeralIpCreate { pool: None }); // Identity providers pub const IDENTITY_PROVIDERS_URL: &'static str = "/v1/system/identity-providers?silo=demo-silo"; pub const SAML_IDENTITY_PROVIDERS_URL: &'static str = "/v1/system/identity-providers/saml?silo=demo-silo"; -pub static DEMO_SAML_IDENTITY_PROVIDER_NAME: Lazy = - Lazy::new(|| "demo-saml-provider".parse().unwrap()); +pub static DEMO_SAML_IDENTITY_PROVIDER_NAME: LazyLock = + LazyLock::new(|| "demo-saml-provider".parse().unwrap()); -pub static SPECIFIC_SAML_IDENTITY_PROVIDER_URL: Lazy = - Lazy::new(|| { +pub static SPECIFIC_SAML_IDENTITY_PROVIDER_URL: LazyLock = + LazyLock::new(|| { format!( "/v1/system/identity-providers/saml/{}?silo=demo-silo", *DEMO_SAML_IDENTITY_PROVIDER_NAME ) }); -pub static SAML_IDENTITY_PROVIDER: Lazy = - Lazy::new(|| params::SamlIdentityProviderCreate { - identity: IdentityMetadataCreateParams { - name: DEMO_SAML_IDENTITY_PROVIDER_NAME.clone(), - description: "a demo provider".to_string(), - }, +pub static SAML_IDENTITY_PROVIDER: LazyLock< + params::SamlIdentityProviderCreate, +> = LazyLock::new(|| params::SamlIdentityProviderCreate { + identity: IdentityMetadataCreateParams { + name: DEMO_SAML_IDENTITY_PROVIDER_NAME.clone(), + description: "a demo provider".to_string(), + }, - idp_metadata_source: params::IdpMetadataSource::Url { - url: HTTP_SERVER.url("/descriptor").to_string(), - }, + idp_metadata_source: params::IdpMetadataSource::Url { + url: HTTP_SERVER.url("/descriptor").to_string(), + }, - idp_entity_id: "entity_id".to_string(), - sp_client_id: "client_id".to_string(), - acs_url: "http://acs".to_string(), - slo_url: "http://slo".to_string(), - technical_contact_email: "technical@fake".to_string(), + idp_entity_id: "entity_id".to_string(), + sp_client_id: "client_id".to_string(), + acs_url: "http://acs".to_string(), + slo_url: "http://slo".to_string(), + technical_contact_email: "technical@fake".to_string(), - signing_keypair: None, + signing_keypair: None, - group_attribute_name: None, - }); + group_attribute_name: None, +}); -pub static DEMO_SYSTEM_METRICS_URL: Lazy = Lazy::new(|| { +pub static DEMO_SYSTEM_METRICS_URL: LazyLock = LazyLock::new(|| { format!( "/v1/system/metrics/virtual_disk_space_provisioned?start_time={:?}&end_time={:?}", Utc::now(), @@ -945,7 +975,7 @@ pub static DEMO_SYSTEM_METRICS_URL: Lazy = Lazy::new(|| { ) }); -pub static DEMO_SILO_METRICS_URL: Lazy = Lazy::new(|| { +pub static DEMO_SILO_METRICS_URL: LazyLock = LazyLock::new(|| { format!( "/v1/metrics/virtual_disk_space_provisioned?start_time={:?}&end_time={:?}", Utc::now(), @@ -953,34 +983,35 @@ pub static DEMO_SILO_METRICS_URL: Lazy = Lazy::new(|| { ) }); -pub static TIMESERIES_QUERY_URL: Lazy = Lazy::new(|| { +pub static TIMESERIES_QUERY_URL: LazyLock = LazyLock::new(|| { format!("/v1/timeseries/query?project={}", *DEMO_PROJECT_NAME) }); -pub static SYSTEM_TIMESERIES_LIST_URL: Lazy = - Lazy::new(|| String::from("/v1/system/timeseries/schemas")); +pub static SYSTEM_TIMESERIES_LIST_URL: LazyLock = + LazyLock::new(|| String::from("/v1/system/timeseries/schemas")); -pub static SYSTEM_TIMESERIES_QUERY_URL: Lazy = - Lazy::new(|| String::from("/v1/system/timeseries/query")); +pub static SYSTEM_TIMESERIES_QUERY_URL: LazyLock = + LazyLock::new(|| String::from("/v1/system/timeseries/query")); -pub static DEMO_TIMESERIES_QUERY: Lazy = - Lazy::new(|| params::TimeseriesQuery { +pub static DEMO_TIMESERIES_QUERY: LazyLock = + LazyLock::new(|| params::TimeseriesQuery { query: String::from("get http_service:request_latency_histogram"), }); // Users -pub static DEMO_USER_CREATE: Lazy = - Lazy::new(|| params::UserCreate { +pub static DEMO_USER_CREATE: LazyLock = + LazyLock::new(|| params::UserCreate { external_id: UserId::from_str("dummy-user").unwrap(), password: params::UserPassword::LoginDisallowed, }); // Allowlist for user-facing services. -pub static ALLOW_LIST_URL: Lazy = - Lazy::new(|| String::from("/v1/system/networking/allow-list")); -pub static ALLOW_LIST_UPDATE: Lazy = Lazy::new(|| { - params::AllowListUpdate { allowed_ips: AllowedSourceIps::Any } -}); +pub static ALLOW_LIST_URL: LazyLock = + LazyLock::new(|| String::from("/v1/system/networking/allow-list")); +pub static ALLOW_LIST_UPDATE: LazyLock = + LazyLock::new(|| params::AllowListUpdate { + allowed_ips: AllowedSourceIps::Any, + }); /// Describes an API endpoint to be verified by the "unauthorized" test /// @@ -1126,13 +1157,14 @@ impl AllowedMethod { } } -pub static URL_USERS_DB_INIT: Lazy = Lazy::new(|| { +pub static URL_USERS_DB_INIT: LazyLock = LazyLock::new(|| { format!("/v1/system/users-builtin/{}", authn::USER_DB_INIT.name) }); /// List of endpoints to be verified -pub static VERIFY_ENDPOINTS: Lazy> = Lazy::new(|| { - vec![ +pub static VERIFY_ENDPOINTS: LazyLock> = LazyLock::new( + || { + vec![ // Global IAM policy VerifyEndpoint { url: &SYSTEM_POLICY_URL, @@ -2645,4 +2677,5 @@ pub static VERIFY_ENDPOINTS: Lazy> = Lazy::new(|| { ], }, ] -}); + }, +); diff --git a/nexus/tests/integration_tests/unauthorized.rs b/nexus/tests/integration_tests/unauthorized.rs index 45f87c96ce0..7ec33d97f89 100644 --- a/nexus/tests/integration_tests/unauthorized.rs +++ b/nexus/tests/integration_tests/unauthorized.rs @@ -23,7 +23,7 @@ use nexus_test_utils_macros::nexus_test; use omicron_common::disk::DatasetKind; use omicron_uuid_kinds::DatasetUuid; use omicron_uuid_kinds::ZpoolUuid; -use once_cell::sync::Lazy; +use std::sync::LazyLock; type ControlPlaneTestContext = nexus_test_utils::ControlPlaneTestContext; @@ -183,8 +183,8 @@ enum SetupReq { }, } -pub static HTTP_SERVER: Lazy = - Lazy::new(|| { +pub static HTTP_SERVER: LazyLock = + LazyLock::new(|| { // Run a httptest server let server = ServerBuilder::new().run().unwrap(); @@ -208,7 +208,7 @@ pub static HTTP_SERVER: Lazy = }); /// List of requests to execute at setup time -static SETUP_REQUESTS: Lazy> = Lazy::new(|| { +static SETUP_REQUESTS: LazyLock> = LazyLock::new(|| { vec![ // Create a separate Silo SetupReq::Post { diff --git a/sled-agent/Cargo.toml b/sled-agent/Cargo.toml index ffef7c6597e..421f8f6e098 100644 --- a/sled-agent/Cargo.toml +++ b/sled-agent/Cargo.toml @@ -59,7 +59,6 @@ nexus-types.workspace = true omicron-common.workspace = true omicron-ddm-admin-client.workspace = true omicron-uuid-kinds.workspace = true -once_cell.workspace = true oximeter.workspace = true oximeter-instruments.workspace = true oximeter-producer.workspace = true diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index cbef6101a00..f1033aa8a15 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -96,7 +96,6 @@ use omicron_common::disk::{DatasetKind, DatasetName}; use omicron_common::ledger::{self, Ledger, Ledgerable}; use omicron_ddm_admin_client::{Client as DdmAdminClient, DdmError}; use omicron_uuid_kinds::OmicronZoneUuid; -use once_cell::sync::OnceCell; use rand::prelude::SliceRandom; use sled_agent_types::{ time_sync::TimeSync, @@ -115,7 +114,7 @@ use std::collections::HashSet; use std::net::{IpAddr, Ipv6Addr, SocketAddr}; use std::str::FromStr; use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::Arc; +use std::sync::{Arc, OnceLock}; use tokio::io::AsyncWriteExt; use tokio::sync::Mutex; use tokio::sync::{oneshot, MutexGuard}; @@ -729,12 +728,12 @@ pub struct ServiceManagerInner { bootstrap_vnic_allocator: VnicAllocator, ddmd_client: DdmAdminClient, advertised_prefixes: Mutex>>, - sled_info: OnceCell, + sled_info: OnceLock, switch_zone_bootstrap_address: Ipv6Addr, storage: StorageHandle, zone_bundler: ZoneBundler, - ledger_directory_override: OnceCell, - image_directory_override: OnceCell, + ledger_directory_override: OnceLock, + image_directory_override: OnceLock, } // Late-binding information, only known once the sled agent is up and @@ -817,13 +816,13 @@ impl ServiceManager { ), ddmd_client, advertised_prefixes: Mutex::new(HashSet::new()), - sled_info: OnceCell::new(), + sled_info: OnceLock::new(), switch_zone_bootstrap_address: bootstrap_networking .switch_zone_bootstrap_ip, storage, zone_bundler, - ledger_directory_override: OnceCell::new(), - image_directory_override: OnceCell::new(), + ledger_directory_override: OnceLock::new(), + image_directory_override: OnceLock::new(), }), } } diff --git a/wicket/Cargo.toml b/wicket/Cargo.toml index 117a0128456..0de2c8d82c2 100644 --- a/wicket/Cargo.toml +++ b/wicket/Cargo.toml @@ -23,7 +23,6 @@ indexmap.workspace = true indicatif.workspace = true itertools.workspace = true omicron-common.workspace = true -once_cell.workspace = true owo-colors.workspace = true ratatui.workspace = true reqwest.workspace = true diff --git a/wicket/src/state/inventory.rs b/wicket/src/state/inventory.rs index d200f597e8c..858562c675d 100644 --- a/wicket/src/state/inventory.rs +++ b/wicket/src/state/inventory.rs @@ -6,23 +6,24 @@ use anyhow::{bail, Result}; use omicron_common::api::internal::nexus::KnownArtifactKind; -use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; use std::fmt::Display; use std::iter::Iterator; +use std::sync::LazyLock; use wicket_common::inventory::{ RackV1Inventory, RotInventory, RotSlot, SpComponentCaboose, SpComponentInfo, SpIgnition, SpState, SpType, }; -pub static ALL_COMPONENT_IDS: Lazy> = Lazy::new(|| { - (0..=31u8) - .map(ComponentId::Sled) - .chain((0..=1u8).map(ComponentId::Switch)) - .chain((0..=1u8).map(ComponentId::Psc)) - .collect() -}); +pub static ALL_COMPONENT_IDS: LazyLock> = + LazyLock::new(|| { + (0..=31u8) + .map(ComponentId::Sled) + .chain((0..=1u8).map(ComponentId::Switch)) + .chain((0..=1u8).map(ComponentId::Psc)) + .collect() + }); /// Inventory is the most recent information about rack composition as /// received from MGS. diff --git a/wicketd/Cargo.toml b/wicketd/Cargo.toml index 3145add700b..ab59afd39ac 100644 --- a/wicketd/Cargo.toml +++ b/wicketd/Cargo.toml @@ -34,7 +34,6 @@ illumos-utils.workspace = true internal-dns-resolver.workspace = true internal-dns-types.workspace = true itertools.workspace = true -once_cell.workspace = true oxnet.workspace = true reqwest.workspace = true schemars.workspace = true diff --git a/wicketd/src/rss_config.rs b/wicketd/src/rss_config.rs index badcb24a3f4..5f4a62d537e 100644 --- a/wicketd/src/rss_config.rs +++ b/wicketd/src/rss_config.rs @@ -24,7 +24,6 @@ use omicron_common::address::Ipv6Subnet; use omicron_common::address::RACK_PREFIX; use omicron_common::api::external::AllowedSourceIps; use omicron_common::api::external::SwitchLocation; -use once_cell::sync::Lazy; use sled_hardware_types::Baseboard; use slog::debug; use slog::warn; @@ -34,6 +33,7 @@ use std::collections::BTreeSet; use std::mem; use std::net::IpAddr; use std::net::Ipv6Addr; +use std::sync::LazyLock; use thiserror::Error; use wicket_common::inventory::RackV1Inventory; use wicket_common::inventory::SpType; @@ -55,7 +55,7 @@ use wicketd_api::SetBgpAuthKeyStatus; // TODO-correctness For now, we always use the same rack subnet when running // RSS. When we get to multirack, this will be wrong, but there are many other // RSS-related things that need to change then too. -static RACK_SUBNET: Lazy> = Lazy::new(|| { +static RACK_SUBNET: LazyLock> = LazyLock::new(|| { let ip = Ipv6Addr::new(0xfd00, 0x1122, 0x3344, 0x0100, 0, 0, 0, 0); Ipv6Subnet::new(ip) });