From c758366779aa244e1cba4c2362a22925a245cd60 Mon Sep 17 00:00:00 2001 From: Benjamin Naecker Date: Tue, 14 May 2024 00:14:00 +0000 Subject: [PATCH] Add the server kind to the Nexus API context - Adds a server kind enum, used to distinguish which API server is running any particular handler. - Wraps the existing `ServerContext` into a higher-level `ApiContext` type, which includes the former in addition to the kind of server handling the request. - Fixes #5651 --- .../reconfigurator-cli/tests/test_basic.rs | 2 +- .../reconfigurator/execution/src/datasets.rs | 2 +- nexus/reconfigurator/execution/src/dns.rs | 2 +- .../execution/src/external_networking.rs | 4 +- .../execution/src/omicron_physical_disks.rs | 2 +- .../execution/src/omicron_zones.rs | 2 +- nexus/src/app/allow_list.rs | 10 +- .../src/app/background/blueprint_execution.rs | 2 +- nexus/src/app/background/blueprint_load.rs | 2 +- nexus/src/app/background/common.rs | 6 +- nexus/src/app/background/dns_config.rs | 2 +- nexus/src/app/background/dns_propagation.rs | 2 +- .../src/app/background/external_endpoints.rs | 2 +- nexus/src/app/background/init.rs | 2 +- .../app/background/inventory_collection.rs | 4 +- .../src/app/background/metrics_producer_gc.rs | 2 +- nexus/src/app/external_endpoints.rs | 4 +- nexus/src/app/mod.rs | 10 + nexus/src/app/sagas/disk_create.rs | 14 +- nexus/src/app/sagas/disk_delete.rs | 8 +- nexus/src/app/sagas/instance_create.rs | 10 +- nexus/src/app/sagas/instance_delete.rs | 13 +- nexus/src/app/sagas/instance_ip_attach.rs | 10 +- nexus/src/app/sagas/instance_ip_detach.rs | 10 +- nexus/src/app/sagas/instance_migrate.rs | 4 +- nexus/src/app/sagas/instance_start.rs | 8 +- nexus/src/app/sagas/project_create.rs | 6 +- nexus/src/app/sagas/snapshot_create.rs | 14 +- nexus/src/app/sagas/test_helpers.rs | 20 +- nexus/src/app/sagas/test_saga.rs | 2 +- nexus/src/app/sagas/vpc_create.rs | 10 +- nexus/src/context.rs | 76 +- nexus/src/external_api/console_api.rs | 90 +- nexus/src/external_api/device_auth.rs | 25 +- nexus/src/external_api/http_entrypoints.rs | 1919 ++++++++++++----- nexus/src/internal_api/http_entrypoints.rs | 149 +- nexus/src/lib.rs | 71 +- nexus/test-interface/src/lib.rs | 1 + nexus/test-utils/src/lib.rs | 13 + nexus/tests/integration_tests/allow_list.rs | 7 +- nexus/tests/integration_tests/disks.rs | 30 +- nexus/tests/integration_tests/external_ips.rs | 8 +- nexus/tests/integration_tests/instances.rs | 42 +- nexus/tests/integration_tests/ip_pools.rs | 4 +- nexus/tests/integration_tests/metrics.rs | 8 +- nexus/tests/integration_tests/pantry.rs | 16 +- nexus/tests/integration_tests/rack.rs | 7 +- nexus/tests/integration_tests/saml.rs | 6 +- nexus/tests/integration_tests/silo_users.rs | 4 +- nexus/tests/integration_tests/silos.rs | 26 +- nexus/tests/integration_tests/sleds.rs | 2 +- nexus/tests/integration_tests/snapshots.rs | 16 +- .../integration_tests/subnet_allocation.rs | 8 +- .../integration_tests/volume_management.rs | 34 +- nexus/tests/integration_tests/vpc_subnets.rs | 2 +- 55 files changed, 1827 insertions(+), 928 deletions(-) diff --git a/dev-tools/reconfigurator-cli/tests/test_basic.rs b/dev-tools/reconfigurator-cli/tests/test_basic.rs index a8fd91f156..1ae78487a3 100644 --- a/dev-tools/reconfigurator-cli/tests/test_basic.rs +++ b/dev-tools/reconfigurator-cli/tests/test_basic.rs @@ -56,7 +56,7 @@ type ControlPlaneTestContext = #[nexus_test] async fn test_blueprint_edit(cptestctx: &ControlPlaneTestContext) { // Setup - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let log = &cptestctx.logctx.log; let opctx = OpContext::for_background( diff --git a/nexus/reconfigurator/execution/src/datasets.rs b/nexus/reconfigurator/execution/src/datasets.rs index 6e4286f9db..c4f5cbae82 100644 --- a/nexus/reconfigurator/execution/src/datasets.rs +++ b/nexus/reconfigurator/execution/src/datasets.rs @@ -147,7 +147,7 @@ mod tests { const TEST_NAME: &str = "test_ensure_crucible_dataset_records_exist"; // Set up. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests( cptestctx.logctx.log.clone(), diff --git a/nexus/reconfigurator/execution/src/dns.rs b/nexus/reconfigurator/execution/src/dns.rs index 6a3c1755cf..6753016e76 100644 --- a/nexus/reconfigurator/execution/src/dns.rs +++ b/nexus/reconfigurator/execution/src/dns.rs @@ -1126,7 +1126,7 @@ mod test { async fn test_silos_external_dns_end_to_end( cptestctx: &ControlPlaneTestContext, ) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let log = &cptestctx.logctx.log; let opctx = OpContext::for_background( diff --git a/nexus/reconfigurator/execution/src/external_networking.rs b/nexus/reconfigurator/execution/src/external_networking.rs index 40ad65816e..cff912c137 100644 --- a/nexus/reconfigurator/execution/src/external_networking.rs +++ b/nexus/reconfigurator/execution/src/external_networking.rs @@ -883,7 +883,7 @@ mod tests { cptestctx: &ControlPlaneTestContext, ) { // Set up. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests( cptestctx.logctx.log.clone(), @@ -1141,7 +1141,7 @@ mod tests { cptestctx: &ControlPlaneTestContext, ) { // Set up. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests( cptestctx.logctx.log.clone(), diff --git a/nexus/reconfigurator/execution/src/omicron_physical_disks.rs b/nexus/reconfigurator/execution/src/omicron_physical_disks.rs index 89287713c2..ab0c5cab45 100644 --- a/nexus/reconfigurator/execution/src/omicron_physical_disks.rs +++ b/nexus/reconfigurator/execution/src/omicron_physical_disks.rs @@ -149,7 +149,7 @@ mod test { #[nexus_test] async fn test_deploy_omicron_disks(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests( cptestctx.logctx.log.clone(), diff --git a/nexus/reconfigurator/execution/src/omicron_zones.rs b/nexus/reconfigurator/execution/src/omicron_zones.rs index 3248269175..68c1455ee4 100644 --- a/nexus/reconfigurator/execution/src/omicron_zones.rs +++ b/nexus/reconfigurator/execution/src/omicron_zones.rs @@ -139,7 +139,7 @@ mod test { #[nexus_test] async fn test_deploy_omicron_zones(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests( cptestctx.logctx.log.clone(), diff --git a/nexus/src/app/allow_list.rs b/nexus/src/app/allow_list.rs index 8f53db68a2..f3efb3f66c 100644 --- a/nexus/src/app/allow_list.rs +++ b/nexus/src/app/allow_list.rs @@ -13,6 +13,8 @@ use omicron_common::api::external; use omicron_common::api::external::Error; use std::net::IpAddr; +use crate::context::ServerKind; + impl super::Nexus { /// Fetch the allowlist of source IPs that can reach user-facing services. pub async fn allow_list_view( @@ -30,6 +32,7 @@ impl super::Nexus { &self, opctx: &OpContext, remote_addr: IpAddr, + server_kind: ServerKind, params: params::AllowListUpdate, ) -> Result { if let external::AllowedSourceIps::List(list) = ¶ms.allowed_ips { @@ -50,6 +53,10 @@ impl super::Nexus { // the request came from is on the allowlist. This is our only real // guardrail to prevent accidentally preventing any future access to // the rack! + // + // Note that we elide this check when handling a request proxied + // from `wicketd`. This is intentional and used as a safety + // mechanism in the even of lockout or other recovery scenarios. let mut contains_remote = false; for entry in list.iter() { contains_remote |= entry.contains(remote_addr); @@ -67,7 +74,8 @@ impl super::Nexus { )); } } - if !contains_remote { + if !contains_remote && !matches!(server_kind, ServerKind::Techport) + { return Err(Error::invalid_request( "The source IP allow list would prevent access \ from the current client! Ensure that the allowlist \ diff --git a/nexus/src/app/background/blueprint_execution.rs b/nexus/src/app/background/blueprint_execution.rs index 1291e72a9b..2ac1b3fd35 100644 --- a/nexus/src/app/background/blueprint_execution.rs +++ b/nexus/src/app/background/blueprint_execution.rs @@ -178,7 +178,7 @@ mod test { #[nexus_test(server = crate::Server)] async fn test_deploy_omicron_zones(cptestctx: &ControlPlaneTestContext) { // Set up the test. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_background( cptestctx.logctx.log.clone(), diff --git a/nexus/src/app/background/blueprint_load.rs b/nexus/src/app/background/blueprint_load.rs index 8334abecb5..cda1d07fcb 100644 --- a/nexus/src/app/background/blueprint_load.rs +++ b/nexus/src/app/background/blueprint_load.rs @@ -233,7 +233,7 @@ mod test { #[nexus_test(server = crate::Server)] async fn test_load_blueprints(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests( cptestctx.logctx.log.clone(), diff --git a/nexus/src/app/background/common.rs b/nexus/src/app/background/common.rs index 0fbfa9938d..da595dc4e1 100644 --- a/nexus/src/app/background/common.rs +++ b/nexus/src/app/background/common.rs @@ -533,7 +533,7 @@ mod test { // activated #[nexus_test(server = crate::Server)] async fn test_driver_basic(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests( cptestctx.logctx.log.clone(), @@ -698,7 +698,7 @@ mod test { // activated. #[nexus_test(server = crate::Server)] async fn test_activation_in_progress(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests( cptestctx.logctx.log.clone(), @@ -843,7 +843,7 @@ mod test { #[nexus_test(server = crate::Server)] async fn test_saga_request_flow(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests( cptestctx.logctx.log.clone(), diff --git a/nexus/src/app/background/dns_config.rs b/nexus/src/app/background/dns_config.rs index be18ac3612..71e0a812a7 100644 --- a/nexus/src/app/background/dns_config.rs +++ b/nexus/src/app/background/dns_config.rs @@ -175,7 +175,7 @@ mod test { #[nexus_test(server = crate::Server)] async fn test_basic(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests( cptestctx.logctx.log.clone(), diff --git a/nexus/src/app/background/dns_propagation.rs b/nexus/src/app/background/dns_propagation.rs index cf7a399999..7d650f6f27 100644 --- a/nexus/src/app/background/dns_propagation.rs +++ b/nexus/src/app/background/dns_propagation.rs @@ -196,7 +196,7 @@ mod test { #[nexus_test(server = crate::Server)] async fn test_basic(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests( cptestctx.logctx.log.clone(), diff --git a/nexus/src/app/background/external_endpoints.rs b/nexus/src/app/background/external_endpoints.rs index ed530e0775..1a587298d5 100644 --- a/nexus/src/app/background/external_endpoints.rs +++ b/nexus/src/app/background/external_endpoints.rs @@ -131,7 +131,7 @@ mod test { #[nexus_test(server = crate::Server)] async fn test_basic(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests( cptestctx.logctx.log.clone(), diff --git a/nexus/src/app/background/init.rs b/nexus/src/app/background/init.rs index 9d9a65c23b..d2f940018d 100644 --- a/nexus/src/app/background/init.rs +++ b/nexus/src/app/background/init.rs @@ -503,7 +503,7 @@ pub mod test { // the new DNS configuration #[nexus_test(server = crate::Server)] async fn test_dns_propagation_basic(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests( cptestctx.logctx.log.clone(), diff --git a/nexus/src/app/background/inventory_collection.rs b/nexus/src/app/background/inventory_collection.rs index 7455a14afb..52ee8f6e13 100644 --- a/nexus/src/app/background/inventory_collection.rs +++ b/nexus/src/app/background/inventory_collection.rs @@ -214,7 +214,7 @@ mod test { // collections, too. #[nexus_test(server = crate::Server)] async fn test_basic(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests( cptestctx.logctx.log.clone(), @@ -328,7 +328,7 @@ mod test { #[nexus_test(server = crate::Server)] async fn test_db_sled_enumerator(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests( cptestctx.logctx.log.clone(), diff --git a/nexus/src/app/background/metrics_producer_gc.rs b/nexus/src/app/background/metrics_producer_gc.rs index 7bd2bd6c8c..1e3b070249 100644 --- a/nexus/src/app/background/metrics_producer_gc.rs +++ b/nexus/src/app/background/metrics_producer_gc.rs @@ -170,7 +170,7 @@ mod tests { #[nexus_test(server = crate::Server)] async fn test_pruning(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests( cptestctx.logctx.log.clone(), diff --git a/nexus/src/app/external_endpoints.rs b/nexus/src/app/external_endpoints.rs index db87632bbf..18d2399eb5 100644 --- a/nexus/src/app/external_endpoints.rs +++ b/nexus/src/app/external_endpoints.rs @@ -26,7 +26,7 @@ //! "certificate resolver" object that impls //! [`rustls::server::ResolvesServerCert`]. See [`NexusCertResolver`]. -use crate::ServerContext; +use crate::context::ApiContext; use anyhow::anyhow; use anyhow::bail; use anyhow::Context; @@ -674,7 +674,7 @@ impl super::Nexus { /// case, we'll choose an arbitrary Silo. pub fn endpoint_for_request( &self, - rqctx: &dropshot::RequestContext>, + rqctx: &dropshot::RequestContext, ) -> Result, Error> { let log = &rqctx.log; let rqinfo = &rqctx.request; diff --git a/nexus/src/app/mod.rs b/nexus/src/app/mod.rs index a22fad0c81..2e77f9fd25 100644 --- a/nexus/src/app/mod.rs +++ b/nexus/src/app/mod.rs @@ -643,6 +643,16 @@ impl Nexus { .map(|server| server.local_addr()) } + pub(crate) async fn get_techport_server_address( + &self, + ) -> Option { + self.techport_external_server + .lock() + .unwrap() + .as_ref() + .map(|server| server.local_addr()) + } + pub(crate) async fn get_internal_server_address( &self, ) -> Option { diff --git a/nexus/src/app/sagas/disk_create.rs b/nexus/src/app/sagas/disk_create.rs index 165bf7573c..ad31998e71 100644 --- a/nexus/src/app/sagas/disk_create.rs +++ b/nexus/src/app/sagas/disk_create.rs @@ -882,7 +882,7 @@ pub(crate) mod test { pub fn test_opctx(cptestctx: &ControlPlaneTestContext) -> OpContext { OpContext::for_tests( cptestctx.logctx.log.new(o!()), - cptestctx.server.apictx().nexus.datastore().clone(), + cptestctx.server.server_context().nexus.datastore().clone(), ) } @@ -893,7 +893,7 @@ pub(crate) mod test { DiskTest::new(cptestctx).await; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let project_id = create_project(&client, PROJECT_NAME).await.identity.id; @@ -1033,7 +1033,7 @@ pub(crate) mod test { test: &DiskTest, ) { let sled_agent = &cptestctx.sled_agent.sled_agent; - let datastore = cptestctx.server.apictx().nexus.datastore(); + let datastore = cptestctx.server.server_context().nexus.datastore(); crate::app::sagas::test_helpers::assert_no_failed_undo_steps( &cptestctx.logctx.log, @@ -1063,7 +1063,7 @@ pub(crate) mod test { let log = &cptestctx.logctx.log; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let project_id = create_project(&client, PROJECT_NAME).await.identity.id; let opctx = test_opctx(cptestctx); @@ -1093,7 +1093,7 @@ pub(crate) mod test { let log = &cptestctx.logctx.log; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx.nexus; + let nexus = &cptestctx.server.apictx.context.nexus; let project_id = create_project(&client, PROJECT_NAME).await.identity.id; let opctx = test_opctx(&cptestctx); @@ -1111,7 +1111,7 @@ pub(crate) mod test { } async fn destroy_disk(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx.nexus; + let nexus = &cptestctx.server.apictx.context.nexus; let opctx = test_opctx(&cptestctx); let disk_selector = params::DiskSelector { project: Some( @@ -1134,7 +1134,7 @@ pub(crate) mod test { let test = DiskTest::new(cptestctx).await; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx.nexus; + let nexus = &cptestctx.server.apictx.context.nexus; let project_id = create_project(&client, PROJECT_NAME).await.identity.id; diff --git a/nexus/src/app/sagas/disk_delete.rs b/nexus/src/app/sagas/disk_delete.rs index 333e6c1672..2d377f9a06 100644 --- a/nexus/src/app/sagas/disk_delete.rs +++ b/nexus/src/app/sagas/disk_delete.rs @@ -201,12 +201,12 @@ pub(crate) mod test { pub fn test_opctx(cptestctx: &ControlPlaneTestContext) -> OpContext { OpContext::for_tests( cptestctx.logctx.log.new(o!()), - cptestctx.server.apictx.nexus.datastore().clone(), + cptestctx.server.apictx.context.nexus.datastore().clone(), ) } async fn create_disk(cptestctx: &ControlPlaneTestContext) -> Disk { - let nexus = &cptestctx.server.apictx.nexus; + let nexus = &cptestctx.server.apictx.context.nexus; let opctx = test_opctx(&cptestctx); let project_selector = params::ProjectSelector { @@ -232,7 +232,7 @@ pub(crate) mod test { DiskTest::new(cptestctx).await; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx.nexus; + let nexus = &cptestctx.server.apictx.context.nexus; let project_id = create_project(client, PROJECT_NAME).await.identity.id; let disk = create_disk(&cptestctx).await; @@ -258,7 +258,7 @@ pub(crate) mod test { let test = DiskTest::new(cptestctx).await; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx.nexus; + let nexus = &cptestctx.server.apictx.context.nexus; let project_id = create_project(client, PROJECT_NAME).await.identity.id; let disk = create_disk(&cptestctx).await; diff --git a/nexus/src/app/sagas/instance_create.rs b/nexus/src/app/sagas/instance_create.rs index 73fe910c76..a6df7183d1 100644 --- a/nexus/src/app/sagas/instance_create.rs +++ b/nexus/src/app/sagas/instance_create.rs @@ -1137,7 +1137,7 @@ pub mod test { ) { DiskTest::new(cptestctx).await; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let project_id = create_org_project_and_disk(&client).await; // Build the saga DAG with the provided test parameters @@ -1264,7 +1264,7 @@ pub mod test { cptestctx: &ControlPlaneTestContext, ) { let sled_agent = &cptestctx.sled_agent.sled_agent; - let datastore = cptestctx.server.apictx().nexus.datastore(); + let datastore = cptestctx.server.server_context().nexus.datastore(); // Check that no partial artifacts of instance creation exist assert!(no_instance_records_exist(datastore).await); @@ -1300,7 +1300,7 @@ pub mod test { let log = &cptestctx.logctx.log; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let project_id = create_org_project_and_disk(&client).await; // Build the saga DAG with the provided test parameters @@ -1329,7 +1329,7 @@ pub mod test { let log = &cptestctx.logctx.log; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let project_id = create_org_project_and_disk(&client).await; let opctx = test_helpers::test_opctx(&cptestctx); @@ -1353,7 +1353,7 @@ pub mod test { DiskTest::new(cptestctx).await; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let project_id = create_org_project_and_disk(&client).await; // Build the saga DAG with the provided test parameters diff --git a/nexus/src/app/sagas/instance_delete.rs b/nexus/src/app/sagas/instance_delete.rs index 0e253913b0..d93c1455ad 100644 --- a/nexus/src/app/sagas/instance_delete.rs +++ b/nexus/src/app/sagas/instance_delete.rs @@ -210,7 +210,7 @@ mod test { instance_id: Uuid, ) -> Params { let opctx = test_opctx(&cptestctx); - let datastore = cptestctx.server.apictx().nexus.datastore(); + let datastore = cptestctx.server.server_context().nexus.datastore(); let (.., authz_instance, instance) = LookupPath::new(&opctx, &datastore) @@ -253,7 +253,7 @@ mod test { pub fn test_opctx(cptestctx: &ControlPlaneTestContext) -> OpContext { OpContext::for_tests( cptestctx.logctx.log.new(o!()), - cptestctx.server.apictx().nexus.datastore().clone(), + cptestctx.server.server_context().nexus.datastore().clone(), ) } @@ -263,7 +263,7 @@ mod test { ) { DiskTest::new(cptestctx).await; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; create_org_project_and_disk(&client).await; // Build the saga DAG with the provided test parameters @@ -290,7 +290,7 @@ mod test { cptestctx: &ControlPlaneTestContext, params: params::InstanceCreate, ) -> db::model::Instance { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let opctx = test_opctx(&cptestctx); let project_selector = params::ProjectSelector { @@ -304,7 +304,8 @@ mod test { .await .unwrap(); - let datastore = cptestctx.server.apictx().nexus.datastore().clone(); + let datastore = + cptestctx.server.server_context().nexus.datastore().clone(); let (.., db_instance) = LookupPath::new(&opctx, &datastore) .instance_id(instance_state.instance().id()) .fetch() @@ -321,7 +322,7 @@ mod test { DiskTest::new(cptestctx).await; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; create_org_project_and_disk(&client).await; // Build the saga DAG with the provided test parameters diff --git a/nexus/src/app/sagas/instance_ip_attach.rs b/nexus/src/app/sagas/instance_ip_attach.rs index 3cd6ac1c46..3332b71274 100644 --- a/nexus/src/app/sagas/instance_ip_attach.rs +++ b/nexus/src/app/sagas/instance_ip_attach.rs @@ -410,7 +410,7 @@ pub(crate) mod test { cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let sled_agent = &cptestctx.sled_agent.sled_agent; @@ -460,7 +460,7 @@ pub(crate) mod test { use nexus_db_queries::db::schema::external_ip::dsl; let sled_agent = &cptestctx.sled_agent.sled_agent; - let datastore = cptestctx.server.apictx().nexus.datastore(); + let datastore = cptestctx.server.server_context().nexus.datastore(); let conn = datastore.pool_connection_for_tests().await.unwrap(); @@ -500,7 +500,7 @@ pub(crate) mod test { ) { let log = &cptestctx.logctx.log; let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let opctx = test_helpers::test_opctx(cptestctx); @@ -526,7 +526,7 @@ pub(crate) mod test { ) { let log = &cptestctx.logctx.log; let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let opctx = test_helpers::test_opctx(cptestctx); @@ -555,7 +555,7 @@ pub(crate) mod test { cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let opctx = test_helpers::test_opctx(cptestctx); diff --git a/nexus/src/app/sagas/instance_ip_detach.rs b/nexus/src/app/sagas/instance_ip_detach.rs index 7a71824376..2f1d76c853 100644 --- a/nexus/src/app/sagas/instance_ip_detach.rs +++ b/nexus/src/app/sagas/instance_ip_detach.rs @@ -381,7 +381,7 @@ pub(crate) mod test { cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let sled_agent = &cptestctx.sled_agent.sled_agent; @@ -425,7 +425,7 @@ pub(crate) mod test { let opctx = test_helpers::test_opctx(cptestctx); let sled_agent = &cptestctx.sled_agent.sled_agent; - let datastore = cptestctx.server.apictx().nexus.datastore(); + let datastore = cptestctx.server.server_context().nexus.datastore(); let conn = datastore.pool_connection_for_tests().await.unwrap(); @@ -475,7 +475,7 @@ pub(crate) mod test { ) { let log = &cptestctx.logctx.log; let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let opctx = test_helpers::test_opctx(cptestctx); @@ -503,7 +503,7 @@ pub(crate) mod test { ) { let log = &cptestctx.logctx.log; let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let opctx = test_helpers::test_opctx(cptestctx); @@ -534,7 +534,7 @@ pub(crate) mod test { cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let opctx = test_helpers::test_opctx(cptestctx); diff --git a/nexus/src/app/sagas/instance_migrate.rs b/nexus/src/app/sagas/instance_migrate.rs index a727debbea..1cfd170faf 100644 --- a/nexus/src/app/sagas/instance_migrate.rs +++ b/nexus/src/app/sagas/instance_migrate.rs @@ -614,7 +614,7 @@ mod tests { ) { let other_sleds = add_sleds(cptestctx, 1).await; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let _project_id = setup_test_project(&client).await; let opctx = test_helpers::test_opctx(cptestctx); @@ -658,7 +658,7 @@ mod tests { let log = &cptestctx.logctx.log; let other_sleds = add_sleds(cptestctx, 1).await; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let _project_id = setup_test_project(&client).await; let opctx = test_helpers::test_opctx(cptestctx); diff --git a/nexus/src/app/sagas/instance_start.rs b/nexus/src/app/sagas/instance_start.rs index 55c00d8707..b76bc2e37d 100644 --- a/nexus/src/app/sagas/instance_start.rs +++ b/nexus/src/app/sagas/instance_start.rs @@ -767,7 +767,7 @@ mod test { cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let _project_id = setup_test_project(&client).await; let opctx = test_helpers::test_opctx(cptestctx); let instance = create_instance(client).await; @@ -806,7 +806,7 @@ mod test { ) { let log = &cptestctx.logctx.log; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let _project_id = setup_test_project(&client).await; let opctx = test_helpers::test_opctx(cptestctx); let instance = create_instance(client).await; @@ -868,7 +868,7 @@ mod test { cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let _project_id = setup_test_project(&client).await; let opctx = test_helpers::test_opctx(cptestctx); let instance = create_instance(client).await; @@ -910,7 +910,7 @@ mod test { #[nexus_test(server = crate::Server)] async fn test_ensure_running_unwind(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let _project_id = setup_test_project(&client).await; let opctx = test_helpers::test_opctx(cptestctx); let instance = create_instance(client).await; diff --git a/nexus/src/app/sagas/project_create.rs b/nexus/src/app/sagas/project_create.rs index b31dd821f0..6893590519 100644 --- a/nexus/src/app/sagas/project_create.rs +++ b/nexus/src/app/sagas/project_create.rs @@ -188,7 +188,7 @@ mod test { fn test_opctx(cptestctx: &ControlPlaneTestContext) -> OpContext { OpContext::for_tests( cptestctx.logctx.log.new(o!()), - cptestctx.server.apictx().nexus.datastore().clone(), + cptestctx.server.server_context().nexus.datastore().clone(), ) } @@ -258,7 +258,7 @@ mod test { async fn test_saga_basic_usage_succeeds( cptestctx: &ControlPlaneTestContext, ) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; // Before running the test, confirm we have no records of any projects. verify_clean_slate(nexus.datastore()).await; @@ -279,7 +279,7 @@ mod test { cptestctx: &ControlPlaneTestContext, ) { let log = &cptestctx.logctx.log; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let opctx = test_opctx(&cptestctx); crate::app::sagas::test_helpers::action_failure_can_unwind::< SagaProjectCreate, diff --git a/nexus/src/app/sagas/snapshot_create.rs b/nexus/src/app/sagas/snapshot_create.rs index ff57470a5f..53e06e310d 100644 --- a/nexus/src/app/sagas/snapshot_create.rs +++ b/nexus/src/app/sagas/snapshot_create.rs @@ -1876,7 +1876,7 @@ mod test { pub fn test_opctx(cptestctx: &ControlPlaneTestContext) -> OpContext { OpContext::for_tests( cptestctx.logctx.log.new(o!()), - cptestctx.server.apictx().nexus.datastore().clone(), + cptestctx.server.server_context().nexus.datastore().clone(), ) } @@ -1889,7 +1889,7 @@ mod test { DiskTest::new(cptestctx).await; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let disk_id = create_project_and_disk_and_pool(&client).await; // Build the saga DAG with the provided test parameters @@ -1976,7 +1976,7 @@ mod test { // Verifies: // - No snapshot records exist // - No region snapshot records exist - let datastore = cptestctx.server.apictx().nexus.datastore(); + let datastore = cptestctx.server.server_context().nexus.datastore(); assert!(no_snapshot_records_exist(datastore).await); assert!(no_region_snapshot_records_exist(datastore).await); } @@ -2016,7 +2016,7 @@ mod test { // Read out the instance's assigned sled, then poke the instance to get // it from the Starting state to the Running state so the test disk can // be snapshotted. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let opctx = test_opctx(&cptestctx); let (.., authz_instance) = LookupPath::new(&opctx, nexus.datastore()) .instance_id(instance.identity.id) @@ -2080,7 +2080,7 @@ mod test { let log = &cptestctx.logctx.log; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let disk_id = create_project_and_disk_and_pool(&client).await; // Build the saga DAG with the provided test parameters @@ -2219,7 +2219,7 @@ mod test { DiskTest::new(cptestctx).await; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let disk_id = create_project_and_disk_and_pool(&client).await; // Build the saga DAG with the provided test parameters @@ -2324,7 +2324,7 @@ mod test { DiskTest::new(cptestctx).await; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let disk_id = create_project_and_disk_and_pool(&client).await; // Build the saga DAG with the provided test parameters diff --git a/nexus/src/app/sagas/test_helpers.rs b/nexus/src/app/sagas/test_helpers.rs index 1b383d27bb..bacd0f1c9d 100644 --- a/nexus/src/app/sagas/test_helpers.rs +++ b/nexus/src/app/sagas/test_helpers.rs @@ -34,7 +34,7 @@ type ControlPlaneTestContext = pub fn test_opctx(cptestctx: &ControlPlaneTestContext) -> OpContext { OpContext::for_tests( cptestctx.logctx.log.new(o!()), - cptestctx.server.apictx().nexus.datastore().clone(), + cptestctx.server.server_context().nexus.datastore().clone(), ) } @@ -42,7 +42,7 @@ pub(crate) async fn instance_start( cptestctx: &ControlPlaneTestContext, id: &Uuid, ) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let opctx = test_opctx(&cptestctx); let instance_selector = nexus_types::external_api::params::InstanceSelector { @@ -62,7 +62,7 @@ pub(crate) async fn instance_stop( cptestctx: &ControlPlaneTestContext, id: &Uuid, ) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let opctx = test_opctx(&cptestctx); let instance_selector = nexus_types::external_api::params::InstanceSelector { @@ -83,7 +83,7 @@ pub(crate) async fn instance_stop_by_name( name: &str, project_name: &str, ) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let opctx = test_opctx(&cptestctx); let instance_selector = nexus_types::external_api::params::InstanceSelector { @@ -104,7 +104,7 @@ pub(crate) async fn instance_delete_by_name( name: &str, project_name: &str, ) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let opctx = test_opctx(&cptestctx); let instance_selector = nexus_types::external_api::params::InstanceSelector { @@ -126,7 +126,7 @@ pub(crate) async fn instance_simulate( ) { info!(&cptestctx.logctx.log, "Poking simulated instance"; "instance_id" => %instance_id); - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let sa = nexus .instance_sled_by_id(instance_id) .await @@ -145,7 +145,7 @@ pub(crate) async fn instance_simulate_by_name( "instance_name" => %name, "project_name" => %project_name); - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let opctx = test_opctx(&cptestctx); let instance_selector = nexus_types::external_api::params::InstanceSelector { @@ -168,7 +168,7 @@ pub async fn instance_fetch( cptestctx: &ControlPlaneTestContext, instance_id: Uuid, ) -> InstanceAndActiveVmm { - let datastore = cptestctx.server.apictx().nexus.datastore().clone(); + let datastore = cptestctx.server.server_context().nexus.datastore().clone(); let opctx = test_opctx(&cptestctx); let (.., authz_instance) = LookupPath::new(&opctx, &datastore) .instance_id(instance_id) @@ -194,7 +194,7 @@ pub async fn no_virtual_provisioning_resource_records_exist( use nexus_db_queries::db::model::VirtualProvisioningResource; use nexus_db_queries::db::schema::virtual_provisioning_resource::dsl; - let datastore = cptestctx.server.apictx().nexus.datastore().clone(); + let datastore = cptestctx.server.server_context().nexus.datastore().clone(); let conn = datastore.pool_connection_for_tests().await.unwrap(); datastore @@ -223,7 +223,7 @@ pub async fn no_virtual_provisioning_collection_records_using_instances( use nexus_db_queries::db::model::VirtualProvisioningCollection; use nexus_db_queries::db::schema::virtual_provisioning_collection::dsl; - let datastore = cptestctx.server.apictx().nexus.datastore().clone(); + let datastore = cptestctx.server.server_context().nexus.datastore().clone(); let conn = datastore.pool_connection_for_tests().await.unwrap(); datastore diff --git a/nexus/src/app/sagas/test_saga.rs b/nexus/src/app/sagas/test_saga.rs index 0520a17602..9ccdc4aebc 100644 --- a/nexus/src/app/sagas/test_saga.rs +++ b/nexus/src/app/sagas/test_saga.rs @@ -75,7 +75,7 @@ type ControlPlaneTestContext = #[nexus_test(server = crate::Server)] async fn test_saga_stuck(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let params = Params {}; let dag = create_saga_dag::(params).unwrap(); let runnable_saga = nexus.create_runnable_saga(dag.clone()).await.unwrap(); diff --git a/nexus/src/app/sagas/vpc_create.rs b/nexus/src/app/sagas/vpc_create.rs index 6b48e4087a..fdd117b850 100644 --- a/nexus/src/app/sagas/vpc_create.rs +++ b/nexus/src/app/sagas/vpc_create.rs @@ -496,7 +496,7 @@ pub(crate) mod test { fn test_opctx(cptestctx: &ControlPlaneTestContext) -> OpContext { OpContext::for_tests( cptestctx.logctx.log.new(o!()), - cptestctx.server.apictx().nexus.datastore().clone(), + cptestctx.server.server_context().nexus.datastore().clone(), ) } @@ -505,7 +505,7 @@ pub(crate) mod test { project_id: Uuid, action: authz::Action, ) -> authz::Project { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let project_selector = params::ProjectSelector { project: NameOrId::Id(project_id) }; let opctx = test_opctx(&cptestctx); @@ -523,7 +523,7 @@ pub(crate) mod test { project_id: Uuid, ) { let opctx = test_opctx(&cptestctx); - let datastore = cptestctx.server.apictx().nexus.datastore(); + let datastore = cptestctx.server.server_context().nexus.datastore(); let default_name = Name::try_from("default".to_string()).unwrap(); let system_name = Name::try_from("system".to_string()).unwrap(); @@ -710,7 +710,7 @@ pub(crate) mod test { cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let project_id = create_org_and_project(&client).await; delete_project_vpc_defaults(&cptestctx, project_id).await; @@ -740,7 +740,7 @@ pub(crate) mod test { let log = &cptestctx.logctx.log; let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let project_id = create_org_and_project(&client).await; delete_project_vpc_defaults(&cptestctx, project_id).await; diff --git a/nexus/src/context.rs b/nexus/src/context.rs index cf2b9d6f17..b388d1d89c 100644 --- a/nexus/src/context.rs +++ b/nexus/src/context.rs @@ -29,6 +29,61 @@ use std::str::FromStr; use std::sync::Arc; use uuid::Uuid; +/// Indicates the kind of HTTP server. +#[derive(Clone, Copy)] +pub enum ServerKind { + /// This serves the internal API. + Internal, + /// This serves the external API over the normal public network. + External, + /// This serves the external API proxied over the technician port. + Techport, +} + +/// The API context for each distinct Dropshot server. +/// +/// This packages up the main server context, which is shared by all API servers +/// (e.g., internal, external, and techport). It also includes the +/// [`ServerKind`], which makes it possible to know which server is handling any +/// particular request. +#[derive(Clone)] +pub struct ApiContext { + /// The kind of server. + pub kind: ServerKind, + /// Shared state available to all endpoint handlers. + pub context: Arc, +} + +impl ApiContext { + /// Create a new context with a rack ID and logger. This creates the + /// underlying `Nexus` as well. + pub async fn new( + rack_id: Uuid, + log: Logger, + config: &NexusConfig, + ) -> Result { + ServerContext::new(rack_id, log, config) + .await + .map(|context| Self { kind: ServerKind::Internal, context }) + } + + /// Clone self for use by the external Dropshot server. + pub fn for_external(&self) -> Self { + Self { kind: ServerKind::External, context: self.context.clone() } + } + + /// Clone self for use by the techport Dropshot server. + pub fn for_techport(&self) -> Self { + Self { kind: ServerKind::Techport, context: self.context.clone() } + } +} + +impl std::borrow::Borrow for ApiContext { + fn borrow(&self) -> &ServerContext { + &self.context + } +} + /// Shared state available to all API request handlers pub struct ServerContext { /// reference to the underlying nexus @@ -262,18 +317,19 @@ impl ServerContext { /// Authenticates an incoming request to the external API and produces a new /// operation context for it pub(crate) async fn op_context_for_external_api( - rqctx: &dropshot::RequestContext>, + rqctx: &dropshot::RequestContext, ) -> Result { let apictx = rqctx.context(); OpContext::new_async( &rqctx.log, async { - let authn = - Arc::new(apictx.external_authn.authn_request(rqctx).await?); - let datastore = Arc::clone(apictx.nexus.datastore()); + let authn = Arc::new( + apictx.context.external_authn.authn_request(rqctx).await?, + ); + let datastore = Arc::clone(apictx.context.nexus.datastore()); let authz = authz::Context::new( Arc::clone(&authn), - Arc::clone(&apictx.authz), + Arc::clone(&apictx.context.authz), datastore, ); Ok((authn, authz)) @@ -285,17 +341,17 @@ pub(crate) async fn op_context_for_external_api( } pub(crate) async fn op_context_for_internal_api( - rqctx: &dropshot::RequestContext>, + rqctx: &dropshot::RequestContext, ) -> OpContext { - let apictx = rqctx.context(); + let apictx = &rqctx.context(); OpContext::new_async( &rqctx.log, async { - let authn = Arc::clone(&apictx.internal_authn); - let datastore = Arc::clone(apictx.nexus.datastore()); + let authn = Arc::clone(&apictx.context.internal_authn); + let datastore = Arc::clone(apictx.context.nexus.datastore()); let authz = authz::Context::new( Arc::clone(&authn), - Arc::clone(&apictx.authz), + Arc::clone(&apictx.context.authz), datastore, ); Ok::<_, std::convert::Infallible>((authn, authz)) diff --git a/nexus/src/external_api/console_api.rs b/nexus/src/external_api/console_api.rs index d49e7f3be4..caff195047 100644 --- a/nexus/src/external_api/console_api.rs +++ b/nexus/src/external_api/console_api.rs @@ -21,7 +21,7 @@ // toolchain; we can remove this attribute then. #![allow(clippy::declare_interior_mutable_const)] -use crate::ServerContext; +use crate::context::ApiContext; use anyhow::Context; use camino::{Utf8Path, Utf8PathBuf}; use dropshot::{ @@ -56,7 +56,6 @@ use serde_urlencoded; use std::collections::HashMap; use std::num::NonZeroU32; use std::str::FromStr; -use std::sync::Arc; use tokio::fs::File; use tokio_util::codec::{BytesCodec, FramedRead}; @@ -239,7 +238,7 @@ impl RelayState { unpublished = true, }] pub(crate) async fn login_saml_begin( - rqctx: RequestContext>, + rqctx: RequestContext, _path_params: Path, _query_params: Query, ) -> Result, HttpError> { @@ -258,13 +257,13 @@ pub(crate) async fn login_saml_begin( unpublished = true, }] pub(crate) async fn login_saml_redirect( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path_params = path_params.into_inner(); // Use opctx_external_authn because this request will be @@ -303,7 +302,11 @@ pub(crate) async fn login_saml_redirect( } }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Authenticate a user via SAML @@ -313,13 +316,13 @@ pub(crate) async fn login_saml_redirect( tags = ["login"], }] pub(crate) async fn login_saml( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, body_bytes: dropshot::UntypedBody, ) -> Result { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path_params = path_params.into_inner(); // By definition, this request is not authenticated. These operations @@ -379,14 +382,18 @@ pub(crate) async fn login_saml( // use absolute timeout even though session might idle out first. // browser expiration is mostly for convenience, as the API will // reject requests with an expired session regardless - apictx.session_absolute_timeout(), - apictx.external_tls_enabled, + apictx.context.session_absolute_timeout(), + apictx.context.external_tls_enabled, )?; headers.append(header::SET_COOKIE, cookie); } Ok(response) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } #[derive(Deserialize, JsonSchema)] @@ -401,14 +408,14 @@ pub struct LoginPathParam { unpublished = true, }] pub(crate) async fn login_local_begin( - rqctx: RequestContext>, + rqctx: RequestContext, _path_params: Path, _query_params: Query, ) -> Result, HttpError> { // TODO: figure out why instrumenting doesn't work // let apictx = rqctx.context(); // let handler = async { serve_console_index(rqctx.context()).await }; - // apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + // apictx.context.external_latencies.instrument_dropshot_handler(&rqctx, handler).await serve_console_index(rqctx).await } @@ -419,13 +426,13 @@ pub(crate) async fn login_local_begin( tags = ["login"], }] pub(crate) async fn login_local( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, credentials: dropshot::TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let credentials = credentials.into_inner(); let silo = path.silo_name.into(); @@ -448,22 +455,26 @@ pub(crate) async fn login_local( // use absolute timeout even though session might idle out first. // browser expiration is mostly for convenience, as the API will // reject requests with an expired session regardless - apictx.session_absolute_timeout(), - apictx.external_tls_enabled, + apictx.context.session_absolute_timeout(), + apictx.context.external_tls_enabled, )?; headers.append(header::SET_COOKIE, cookie); } Ok(response) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } async fn create_session( opctx: &OpContext, - apictx: &ServerContext, + apictx: &ApiContext, user: Option, ) -> Result { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let session = match user { Some(user) => nexus.session_create(&opctx, user.id()).await?, None => Err(Error::Unauthenticated { @@ -483,12 +494,12 @@ async fn create_session( tags = ["hidden"], }] pub(crate) async fn logout( - rqctx: RequestContext>, + rqctx: RequestContext, cookies: Cookies, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let opctx = crate::context::op_context_for_external_api(&rqctx).await; let token = cookies.get(SESSION_COOKIE_COOKIE_NAME); @@ -513,14 +524,20 @@ pub(crate) async fn logout( let headers = response.headers_mut(); headers.append( header::SET_COOKIE, - clear_session_cookie_header_value(apictx.external_tls_enabled)?, + clear_session_cookie_header_value( + apictx.context.external_tls_enabled, + )?, ); }; Ok(response) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } #[derive(Deserialize, JsonSchema)] @@ -574,10 +591,10 @@ pub struct LoginUrlQuery { /// `redirect_uri` represents the URL to send the user back to after successful /// login, and is included in `state` query param if present async fn get_login_url( - rqctx: &RequestContext>, + rqctx: &RequestContext, redirect_uri: Option, ) -> Result { - let nexus = &rqctx.context().nexus; + let nexus = &rqctx.context().context.nexus; let endpoint = nexus.endpoint_for_request(rqctx)?; let silo = endpoint.silo(); @@ -643,7 +660,7 @@ async fn get_login_url( unpublished = true, }] pub(crate) async fn login_begin( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result { let apictx = rqctx.context(); @@ -652,11 +669,15 @@ pub(crate) async fn login_begin( let login_url = get_login_url(&rqctx, query.redirect_uri).await?; http_response_found(login_url) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } pub(crate) async fn console_index_or_login_redirect( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result, HttpError> { let opctx = crate::context::op_context_for_external_api(&rqctx).await; @@ -692,7 +713,7 @@ macro_rules! console_page { ($name:ident, $path:literal) => { #[endpoint { method = GET, path = $path, unpublished = true, }] pub(crate) async fn $name( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result, HttpError> { console_index_or_login_redirect(rqctx).await } @@ -704,7 +725,7 @@ macro_rules! console_page_wildcard { ($name:ident, $path:literal) => { #[endpoint { method = GET, path = $path, unpublished = true, }] pub(crate) async fn $name( - rqctx: RequestContext>, + rqctx: RequestContext, _path_params: Path, ) -> Result, HttpError> { console_index_or_login_redirect(rqctx).await @@ -784,12 +805,13 @@ const WEB_SECURITY_HEADERS: [(HeaderName, HeaderValue); 3] = [ /// file is present in the directory and `gzip` is listed in the request's /// `Accept-Encoding` header. async fn serve_static( - rqctx: RequestContext>, + rqctx: RequestContext, path: &Utf8Path, cache_control: HeaderValue, ) -> Result, HttpError> { let apictx = rqctx.context(); let static_dir = apictx + .context .console_config .static_dir .as_deref() @@ -854,7 +876,7 @@ async fn serve_static( unpublished = true, }] pub(crate) async fn asset( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { // asset URLs contain hashes, so cache for 1 year @@ -868,7 +890,7 @@ pub(crate) async fn asset( /// Serve `/index.html` via [`serve_static`]. Disallow caching. pub(crate) async fn serve_console_index( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result, HttpError> { // do not cache this response in browser const CACHE_CONTROL: HeaderValue = HeaderValue::from_static("no-store"); diff --git a/nexus/src/external_api/device_auth.rs b/nexus/src/external_api/device_auth.rs index 1697722f6f..2aa1965e79 100644 --- a/nexus/src/external_api/device_auth.rs +++ b/nexus/src/external_api/device_auth.rs @@ -12,7 +12,7 @@ use super::console_api::console_index_or_login_redirect; use super::views::DeviceAccessTokenGrant; use crate::app::external_endpoints::authority_for_request; -use crate::ServerContext; +use crate::ApiContext; use dropshot::{ endpoint, HttpError, HttpResponseUpdatedNoContent, RequestContext, TypedBody, @@ -23,7 +23,6 @@ use nexus_db_queries::db::model::DeviceAccessToken; use omicron_common::api::external::InternalContext; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::sync::Arc; use uuid::Uuid; // Token granting à la RFC 8628 (OAuth 2.0 Device Authorization Grant) @@ -64,11 +63,11 @@ pub struct DeviceAuthRequest { tags = ["hidden"], // "token" }] pub(crate) async fn device_auth_request( - rqctx: RequestContext>, + rqctx: RequestContext, params: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let params = params.into_inner(); let handler = async { let opctx = nexus.opctx_external_authn(); @@ -116,7 +115,7 @@ pub struct DeviceAuthVerify { unpublished = true, }] pub(crate) async fn device_auth_verify( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result, HttpError> { console_index_or_login_redirect(rqctx).await } @@ -127,7 +126,7 @@ pub(crate) async fn device_auth_verify( unpublished = true, }] pub(crate) async fn device_auth_success( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result, HttpError> { console_index_or_login_redirect(rqctx).await } @@ -143,11 +142,11 @@ pub(crate) async fn device_auth_success( tags = ["hidden"], // "token" }] pub(crate) async fn device_auth_confirm( - rqctx: RequestContext>, + rqctx: RequestContext, params: TypedBody, ) -> Result { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let params = params.into_inner(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -163,7 +162,11 @@ pub(crate) async fn device_auth_confirm( .await?; Ok(HttpResponseUpdatedNoContent()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } #[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] @@ -192,11 +195,11 @@ pub enum DeviceAccessTokenResponse { tags = ["hidden"], // "token" }] pub(crate) async fn device_access_token( - rqctx: RequestContext>, + rqctx: RequestContext, params: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let params = params.into_inner(); let handler = async { // RFC 8628 §3.4 diff --git a/nexus/src/external_api/http_entrypoints.rs b/nexus/src/external_api/http_entrypoints.rs index 5283d2b30e..28b507f6ea 100644 --- a/nexus/src/external_api/http_entrypoints.rs +++ b/nexus/src/external_api/http_entrypoints.rs @@ -13,8 +13,7 @@ use super::{ Utilization, Vpc, VpcRouter, VpcSubnet, }, }; -use crate::external_api::shared; -use crate::ServerContext; +use crate::{context::ApiContext, external_api::shared}; use dropshot::HttpError; use dropshot::HttpResponseAccepted; use dropshot::HttpResponseCreated; @@ -97,10 +96,9 @@ use schemars::JsonSchema; use serde::Deserialize; use serde::Serialize; use std::net::IpAddr; -use std::sync::Arc; use uuid::Uuid; -type NexusApiDescription = ApiDescription>; +type NexusApiDescription = ApiDescription; /// Returns a description of the external nexus API pub(crate) fn external_api() -> NexusApiDescription { @@ -374,9 +372,9 @@ pub(crate) fn external_api() -> NexusApiDescription { endpoint: T, ) -> Result<(), String> where - T: Into>>, + T: Into>, { - let mut ep: ApiEndpoint> = endpoint.into(); + let mut ep: ApiEndpoint = endpoint.into(); // only one tag is allowed ep.tags = vec![String::from("hidden")]; ep.path = String::from("/experimental") + &ep.path; @@ -452,7 +450,7 @@ pub(crate) fn external_api() -> NexusApiDescription { tags = ["system/status"], }] async fn ping( - _rqctx: RequestContext>, + _rqctx: RequestContext, ) -> Result, HttpError> { Ok(HttpResponseOk(views::Ping { status: views::PingStatus::Ok })) } @@ -464,16 +462,20 @@ async fn ping( tags = ["policy"], }] async fn system_policy_view( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let policy = nexus.fleet_fetch_policy(&opctx).await?; Ok(HttpResponseOk(policy)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Update top-level IAM policy @@ -483,12 +485,12 @@ async fn system_policy_view( tags = ["policy"], }] async fn system_policy_update( - rqctx: RequestContext>, + rqctx: RequestContext, new_policy: TypedBody>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let new_policy = new_policy.into_inner(); let nasgns = new_policy.role_assignments.len(); // This should have been validated during parsing. @@ -497,7 +499,11 @@ async fn system_policy_update( let policy = nexus.fleet_update_policy(&opctx, &new_policy).await?; Ok(HttpResponseOk(policy)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch current silo's IAM policy @@ -507,11 +513,11 @@ async fn system_policy_update( tags = ["silos"], }] pub(crate) async fn policy_view( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let silo: NameOrId = opctx .authn @@ -524,7 +530,11 @@ pub(crate) async fn policy_view( let policy = nexus.silo_fetch_policy(&opctx, &silo_lookup).await?; Ok(HttpResponseOk(policy)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Update current silo's IAM policy @@ -534,12 +544,12 @@ pub(crate) async fn policy_view( tags = ["silos"], }] async fn policy_update( - rqctx: RequestContext>, + rqctx: RequestContext, new_policy: TypedBody>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let new_policy = new_policy.into_inner(); let nasgns = new_policy.role_assignments.len(); // This should have been validated during parsing. @@ -556,7 +566,11 @@ async fn policy_update( nexus.silo_update_policy(&opctx, &silo_lookup, &new_policy).await?; Ok(HttpResponseOk(policy)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch resource utilization for user's current silo @@ -566,11 +580,11 @@ async fn policy_update( tags = ["silos"], }] async fn utilization_view( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let silo_lookup = nexus.current_silo_lookup(&opctx)?; let utilization = @@ -578,7 +592,11 @@ async fn utilization_view( Ok(HttpResponseOk(utilization.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch current utilization for given silo @@ -588,12 +606,12 @@ async fn utilization_view( tags = ["system/silos"], }] async fn silo_utilization_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let silo_lookup = @@ -602,7 +620,11 @@ async fn silo_utilization_view( Ok(HttpResponseOk(quotas.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List current utilization state for all silos #[endpoint { @@ -611,12 +633,12 @@ async fn silo_utilization_view( tags = ["system/silos"], }] async fn silo_utilization_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pagparams = data_page_params_for(&rqctx, &query)?; @@ -637,7 +659,11 @@ async fn silo_utilization_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Lists resource quotas for all silos @@ -647,12 +673,12 @@ async fn silo_utilization_list( tags = ["system/silos"], }] async fn system_quotas_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pagparams = data_page_params_for(&rqctx, &query)?; @@ -671,7 +697,11 @@ async fn system_quotas_list( &|_, quota: &SiloQuotas| quota.silo_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch resource quotas for silo @@ -681,12 +711,12 @@ async fn system_quotas_list( tags = ["system/silos"], }] async fn silo_quotas_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let silo_lookup = @@ -694,7 +724,11 @@ async fn silo_quotas_view( let quota = nexus.silo_quotas_view(&opctx, &silo_lookup).await?; Ok(HttpResponseOk(quota.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Update resource quotas for silo @@ -706,13 +740,13 @@ async fn silo_quotas_view( tags = ["system/silos"], }] async fn silo_quotas_update( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, new_quota: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let silo_lookup = @@ -722,7 +756,11 @@ async fn silo_quotas_update( .await?; Ok(HttpResponseOk(quota.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List silos @@ -734,12 +772,12 @@ async fn silo_quotas_update( tags = ["system/silos"], }] async fn silo_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -757,7 +795,11 @@ async fn silo_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create a silo @@ -767,18 +809,22 @@ async fn silo_list( tags = ["system/silos"], }] async fn silo_create( - rqctx: RequestContext>, + rqctx: RequestContext, new_silo_params: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let silo = nexus.silo_create(&opctx, new_silo_params.into_inner()).await?; Ok(HttpResponseCreated(silo.try_into()?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch silo @@ -790,19 +836,23 @@ async fn silo_create( tags = ["system/silos"], }] async fn silo_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let silo_lookup = nexus.silo_lookup(&opctx, path.silo)?; let (.., silo) = silo_lookup.fetch().await?; Ok(HttpResponseOk(silo.try_into()?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List IP pools linked to silo @@ -816,14 +866,14 @@ async fn silo_view( tags = ["system/silos"], }] async fn silo_ip_pool_list( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); @@ -848,7 +898,11 @@ async fn silo_ip_pool_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete a silo @@ -860,19 +914,23 @@ async fn silo_ip_pool_list( tags = ["system/silos"], }] async fn silo_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let params = path_params.into_inner(); let silo_lookup = nexus.silo_lookup(&opctx, params.silo)?; nexus.silo_delete(&opctx, &silo_lookup).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch silo IAM policy @@ -882,19 +940,23 @@ async fn silo_delete( tags = ["system/silos"], }] async fn silo_policy_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let silo_lookup = nexus.silo_lookup(&opctx, path.silo)?; let policy = nexus.silo_fetch_policy(&opctx, &silo_lookup).await?; Ok(HttpResponseOk(policy)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Update silo IAM policy @@ -904,7 +966,7 @@ async fn silo_policy_view( tags = ["system/silos"], }] async fn silo_policy_update( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, new_policy: TypedBody>, ) -> Result>, HttpError> { @@ -915,14 +977,18 @@ async fn silo_policy_update( // This should have been validated during parsing. bail_unless!(nasgns <= shared::MAX_ROLE_ASSIGNMENTS_PER_RESOURCE); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let silo_lookup = nexus.silo_lookup(&opctx, path.silo)?; let policy = nexus.silo_update_policy(&opctx, &silo_lookup, &new_policy).await?; Ok(HttpResponseOk(policy)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Silo-specific user endpoints @@ -934,13 +1000,13 @@ async fn silo_policy_update( tags = ["system/silos"], }] async fn silo_user_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanById::from_query(&query)?; @@ -958,7 +1024,11 @@ async fn silo_user_list( &|_, user: &User| user.id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Path parameters for Silo User requests @@ -975,14 +1045,14 @@ struct UserParam { tags = ["system/silos"], }] async fn silo_user_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let silo_lookup = nexus.silo_lookup(&opctx, query.silo)?; @@ -990,7 +1060,11 @@ async fn silo_user_view( nexus.silo_user_fetch(&opctx, &silo_lookup, path.user_id).await?; Ok(HttpResponseOk(user.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Silo identity providers @@ -1002,13 +1076,13 @@ async fn silo_user_view( tags = ["system/silos"], }] async fn silo_identity_provider_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -1027,7 +1101,11 @@ async fn silo_identity_provider_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Silo SAML identity providers @@ -1039,14 +1117,14 @@ async fn silo_identity_provider_list( tags = ["system/silos"], }] async fn saml_identity_provider_create( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, new_provider: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let silo_lookup = nexus.silo_lookup(&opctx, query.silo)?; let provider = nexus @@ -1058,7 +1136,11 @@ async fn saml_identity_provider_create( .await?; Ok(HttpResponseCreated(provider.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch SAML IdP @@ -1068,14 +1150,14 @@ async fn saml_identity_provider_create( tags = ["system/silos"], }] async fn saml_identity_provider_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let saml_identity_provider_selector = @@ -1092,7 +1174,11 @@ async fn saml_identity_provider_view( .await?; Ok(HttpResponseOk(provider.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // TODO: no DELETE for identity providers? @@ -1110,14 +1196,14 @@ async fn saml_identity_provider_view( tags = ["system/silos"], }] async fn local_idp_user_create( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, new_user_params: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let silo_lookup = nexus.silo_lookup(&opctx, query.silo)?; let user = nexus @@ -1129,7 +1215,11 @@ async fn local_idp_user_create( .await?; Ok(HttpResponseCreated(user.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete user @@ -1139,21 +1229,25 @@ async fn local_idp_user_create( tags = ["system/silos"], }] async fn local_idp_user_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let silo_lookup = nexus.silo_lookup(&opctx, query.silo)?; nexus.local_idp_delete_user(&opctx, &silo_lookup, path.user_id).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Set or invalidate user's password @@ -1166,7 +1260,7 @@ async fn local_idp_user_delete( tags = ["system/silos"], }] async fn local_idp_user_set_password( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, update: TypedBody, @@ -1174,7 +1268,7 @@ async fn local_idp_user_set_password( let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let silo_lookup = nexus.silo_lookup(&opctx, query.silo)?; @@ -1188,7 +1282,11 @@ async fn local_idp_user_set_password( .await?; Ok(HttpResponseUpdatedNoContent()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List projects @@ -1198,12 +1296,12 @@ async fn local_idp_user_set_password( tags = ["projects"], }] async fn project_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -1221,7 +1319,11 @@ async fn project_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create project @@ -1231,18 +1333,22 @@ async fn project_list( tags = ["projects"], }] async fn project_create( - rqctx: RequestContext>, + rqctx: RequestContext, new_project: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let project = nexus.project_create(&opctx, &new_project.into_inner()).await?; Ok(HttpResponseCreated(project.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch project @@ -1252,11 +1358,11 @@ async fn project_create( tags = ["projects"], }] async fn project_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -1266,7 +1372,11 @@ async fn project_view( nexus.project_lookup(&opctx, project_selector)?.fetch().await?; Ok(HttpResponseOk(project.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete project @@ -1276,11 +1386,11 @@ async fn project_view( tags = ["projects"], }] async fn project_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -1290,7 +1400,11 @@ async fn project_delete( nexus.project_delete(&opctx, &project_lookup).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // TODO-correctness: Is it valid for PUT to accept application/json that's a @@ -1305,12 +1419,12 @@ async fn project_delete( tags = ["projects"], }] async fn project_update( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, updated_project: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let updated_project = updated_project.into_inner(); let handler = async { @@ -1323,7 +1437,11 @@ async fn project_update( .await?; Ok(HttpResponseOk(project.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch project's IAM policy @@ -1333,11 +1451,11 @@ async fn project_update( tags = ["projects"], }] async fn project_policy_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result>, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -1348,7 +1466,11 @@ async fn project_policy_view( nexus.project_fetch_policy(&opctx, &project_lookup).await?; Ok(HttpResponseOk(policy)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Update project's IAM policy @@ -1358,12 +1480,12 @@ async fn project_policy_view( tags = ["projects"], }] async fn project_policy_update( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, new_policy: TypedBody>, ) -> Result>, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let new_policy = new_policy.into_inner(); let handler = async { @@ -1376,7 +1498,11 @@ async fn project_policy_update( .await?; Ok(HttpResponseOk(new_policy)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // IP Pools @@ -1388,12 +1514,12 @@ async fn project_policy_update( tags = ["projects"], }] async fn project_ip_pool_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -1414,7 +1540,11 @@ async fn project_ip_pool_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch IP pool @@ -1424,13 +1554,13 @@ async fn project_ip_pool_list( tags = ["projects"], }] async fn project_ip_pool_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let pool_selector = path_params.into_inner().pool; let (pool, silo_link) = nexus.silo_ip_pool_fetch(&opctx, &pool_selector).await?; @@ -1439,7 +1569,11 @@ async fn project_ip_pool_view( is_default: silo_link.is_default, })) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List IP pools @@ -1449,12 +1583,12 @@ async fn project_ip_pool_view( tags = ["system/networking"], }] async fn ip_pool_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -1472,7 +1606,11 @@ async fn ip_pool_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } #[derive(Deserialize, JsonSchema)] @@ -1487,18 +1625,22 @@ pub struct IpPoolPathParam { tags = ["system/networking"], }] async fn ip_pool_create( - rqctx: RequestContext>, + rqctx: RequestContext, pool_params: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let pool_params = pool_params.into_inner(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let pool = nexus.ip_pool_create(&opctx, &pool_params).await?; Ok(HttpResponseCreated(IpPool::from(pool))) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch IP pool @@ -1508,13 +1650,13 @@ async fn ip_pool_create( tags = ["system/networking"], }] async fn ip_pool_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let pool_selector = path_params.into_inner().pool; // We do not prevent the service pool from being fetched by name or ID // like we do for update, delete, associate. @@ -1522,7 +1664,11 @@ async fn ip_pool_view( nexus.ip_pool_lookup(&opctx, &pool_selector)?.fetch().await?; Ok(HttpResponseOk(IpPool::from(pool))) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete IP pool @@ -1532,19 +1678,23 @@ async fn ip_pool_view( tags = ["system/networking"], }] async fn ip_pool_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let pool_lookup = nexus.ip_pool_lookup(&opctx, &path.pool)?; nexus.ip_pool_delete(&opctx, &pool_lookup).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Update IP pool @@ -1554,21 +1704,25 @@ async fn ip_pool_delete( tags = ["system/networking"], }] async fn ip_pool_update( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, updates: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let updates = updates.into_inner(); let pool_lookup = nexus.ip_pool_lookup(&opctx, &path.pool)?; let pool = nexus.ip_pool_update(&opctx, &pool_lookup, &updates).await?; Ok(HttpResponseOk(pool.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch IP pool utilization @@ -1578,13 +1732,13 @@ async fn ip_pool_update( tags = ["system/networking"], }] async fn ip_pool_utilization_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let pool_selector = path_params.into_inner().pool; // We do not prevent the service pool from being fetched by name or ID // like we do for update, delete, associate. @@ -1593,7 +1747,11 @@ async fn ip_pool_utilization_view( nexus.ip_pool_utilization_view(&opctx, &pool_lookup).await?; Ok(HttpResponseOk(utilization.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List IP pool's linked silos @@ -1603,7 +1761,7 @@ async fn ip_pool_utilization_view( tags = ["system/networking"], }] async fn ip_pool_silo_list( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, // paginating by resource_id because they're unique per pool. most robust // option would be to paginate by a composite key representing the (pool, @@ -1620,7 +1778,7 @@ async fn ip_pool_silo_list( let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; @@ -1641,7 +1799,11 @@ async fn ip_pool_silo_list( &|_, x: &views::IpPoolSiloLink| x.silo_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Link IP pool to silo @@ -1655,14 +1817,14 @@ async fn ip_pool_silo_list( tags = ["system/networking"], }] async fn ip_pool_silo_link( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, resource_assoc: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let resource_assoc = resource_assoc.into_inner(); let pool_lookup = nexus.ip_pool_lookup(&opctx, &path.pool)?; @@ -1671,7 +1833,11 @@ async fn ip_pool_silo_link( .await?; Ok(HttpResponseCreated(assoc.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Unlink IP pool from silo @@ -1683,20 +1849,24 @@ async fn ip_pool_silo_link( tags = ["system/networking"], }] async fn ip_pool_silo_unlink( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let pool_lookup = nexus.ip_pool_lookup(&opctx, &path.pool)?; let silo_lookup = nexus.silo_lookup(&opctx, path.silo)?; nexus.ip_pool_unlink_silo(&opctx, &pool_lookup, &silo_lookup).await?; Ok(HttpResponseUpdatedNoContent()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Make IP pool default for silo @@ -1711,14 +1881,14 @@ async fn ip_pool_silo_unlink( tags = ["system/networking"], }] async fn ip_pool_silo_update( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, update: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let update = update.into_inner(); let pool_lookup = nexus.ip_pool_lookup(&opctx, &path.pool)?; @@ -1728,7 +1898,11 @@ async fn ip_pool_silo_update( .await?; Ok(HttpResponseOk(assoc.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch Oxide service IP pool @@ -1738,16 +1912,20 @@ async fn ip_pool_silo_update( tags = ["system/networking"], }] async fn ip_pool_service_view( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let pool = nexus.ip_pool_service_fetch(&opctx).await?; Ok(HttpResponseOk(IpPool::from(pool))) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } type IpPoolRangePaginationParams = PaginationParams; @@ -1761,14 +1939,14 @@ type IpPoolRangePaginationParams = PaginationParams; tags = ["system/networking"], }] async fn ip_pool_range_list( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let path = path_params.into_inner(); let marker = match query.page { @@ -1795,7 +1973,11 @@ async fn ip_pool_range_list( }, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Add range to IP pool @@ -1807,21 +1989,25 @@ async fn ip_pool_range_list( tags = ["system/networking"], }] async fn ip_pool_range_add( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, range_params: TypedBody, ) -> Result, HttpError> { let apictx = &rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let range = range_params.into_inner(); let pool_lookup = nexus.ip_pool_lookup(&opctx, &path.pool)?; let out = nexus.ip_pool_add_range(&opctx, &pool_lookup, &range).await?; Ok(HttpResponseCreated(out.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Remove range from IP pool @@ -1831,21 +2017,25 @@ async fn ip_pool_range_add( tags = ["system/networking"], }] async fn ip_pool_range_remove( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, range_params: TypedBody, ) -> Result { let apictx = &rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let range = range_params.into_inner(); let pool_lookup = nexus.ip_pool_lookup(&opctx, &path.pool)?; nexus.ip_pool_delete_range(&opctx, &pool_lookup, &range).await?; Ok(HttpResponseUpdatedNoContent()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List IP ranges for the Oxide service pool @@ -1857,13 +2047,13 @@ async fn ip_pool_range_remove( tags = ["system/networking"], }] async fn ip_pool_service_range_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let marker = match query.page { WhichPage::First(_) => None, @@ -1888,7 +2078,11 @@ async fn ip_pool_service_range_list( }, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Add IP range to Oxide service pool @@ -1900,18 +2094,22 @@ async fn ip_pool_service_range_list( tags = ["system/networking"], }] async fn ip_pool_service_range_add( - rqctx: RequestContext>, + rqctx: RequestContext, range_params: TypedBody, ) -> Result, HttpError> { let apictx = &rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let range = range_params.into_inner(); let out = nexus.ip_pool_service_add_range(&opctx, &range).await?; Ok(HttpResponseCreated(out.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Remove IP range from Oxide service pool @@ -1921,18 +2119,22 @@ async fn ip_pool_service_range_add( tags = ["system/networking"], }] async fn ip_pool_service_range_remove( - rqctx: RequestContext>, + rqctx: RequestContext, range_params: TypedBody, ) -> Result { let apictx = &rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let range = range_params.into_inner(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; nexus.ip_pool_service_delete_range(&opctx, &range).await?; Ok(HttpResponseUpdatedNoContent()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Floating IP Addresses @@ -1944,12 +2146,12 @@ async fn ip_pool_service_range_remove( tags = ["floating-ips"], }] async fn floating_ip_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; @@ -1966,7 +2168,11 @@ async fn floating_ip_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create floating IP @@ -1976,12 +2182,12 @@ async fn floating_ip_list( tags = ["floating-ips"], }] async fn floating_ip_create( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, floating_params: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let floating_params = floating_params.into_inner(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -1992,7 +2198,11 @@ async fn floating_ip_create( .await?; Ok(HttpResponseCreated(ip)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Update floating IP @@ -2002,14 +2212,14 @@ async fn floating_ip_create( tags = ["floating-ips"], }] async fn floating_ip_update( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, updated_floating_ip: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let updated_floating_ip_params = updated_floating_ip.into_inner(); @@ -2029,7 +2239,11 @@ async fn floating_ip_update( .await?; Ok(HttpResponseOk(floating_ip)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete floating IP @@ -2039,14 +2253,14 @@ async fn floating_ip_update( tags = ["floating-ips"], }] async fn floating_ip_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let floating_ip_selector = params::FloatingIpSelector { @@ -2059,7 +2273,11 @@ async fn floating_ip_delete( nexus.floating_ip_delete(&opctx, fip_lookup).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch floating IP @@ -2069,14 +2287,14 @@ async fn floating_ip_delete( tags = ["floating-ips"] }] async fn floating_ip_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let floating_ip_selector = params::FloatingIpSelector { @@ -2089,7 +2307,11 @@ async fn floating_ip_view( .await?; Ok(HttpResponseOk(fip.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Attach floating IP @@ -2101,7 +2323,7 @@ async fn floating_ip_view( tags = ["floating-ips"], }] async fn floating_ip_attach( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, target: TypedBody, @@ -2109,7 +2331,7 @@ async fn floating_ip_attach( let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let floating_ip_selector = params::FloatingIpSelector { @@ -2125,7 +2347,11 @@ async fn floating_ip_attach( .await?; Ok(HttpResponseAccepted(ip)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Detach floating IP @@ -2137,14 +2363,14 @@ async fn floating_ip_attach( tags = ["floating-ips"], }] async fn floating_ip_detach( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let floating_ip_selector = params::FloatingIpSelector { @@ -2156,7 +2382,11 @@ async fn floating_ip_detach( let ip = nexus.floating_ip_detach(&opctx, fip_lookup).await?; Ok(HttpResponseAccepted(ip)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Disks @@ -2168,13 +2398,13 @@ async fn floating_ip_detach( tags = ["disks"], }] async fn disk_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -2193,7 +2423,11 @@ async fn disk_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // TODO-correctness See note about instance create. This should be async. @@ -2204,14 +2438,14 @@ async fn disk_list( tags = ["disks"] }] async fn disk_create( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, new_disk: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let params = new_disk.into_inner(); let project_lookup = nexus.project_lookup(&opctx, query)?; @@ -2219,7 +2453,11 @@ async fn disk_create( nexus.project_create_disk(&opctx, &project_lookup, ¶ms).await?; Ok(HttpResponseCreated(disk.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch disk @@ -2229,14 +2467,14 @@ async fn disk_create( tags = ["disks"] }] async fn disk_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let disk_selector = @@ -2245,7 +2483,11 @@ async fn disk_view( nexus.disk_lookup(&opctx, disk_selector)?.fetch().await?; Ok(HttpResponseOk(disk.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete disk @@ -2255,14 +2497,14 @@ async fn disk_view( tags = ["disks"], }] async fn disk_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let disk_selector = @@ -2271,7 +2513,11 @@ async fn disk_delete( nexus.project_delete_disk(&opctx, &disk_lookup).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } #[derive(Display, Serialize, Deserialize, JsonSchema)] @@ -2299,7 +2545,7 @@ struct DiskMetricsPath { tags = ["disks"], }] async fn disk_metrics_list( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query< PaginationParams, @@ -2308,7 +2554,7 @@ async fn disk_metrics_list( ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); @@ -2333,7 +2579,11 @@ async fn disk_metrics_list( Ok(HttpResponseOk(result)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Start importing blocks into disk @@ -2345,14 +2595,14 @@ async fn disk_metrics_list( tags = ["disks"], }] async fn disk_bulk_write_import_start( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); @@ -2364,7 +2614,11 @@ async fn disk_bulk_write_import_start( Ok(HttpResponseUpdatedNoContent()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Import blocks into disk @@ -2374,7 +2628,7 @@ async fn disk_bulk_write_import_start( tags = ["disks"], }] async fn disk_bulk_write_import( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, import_params: TypedBody, @@ -2382,7 +2636,7 @@ async fn disk_bulk_write_import( let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let params = import_params.into_inner(); @@ -2395,7 +2649,11 @@ async fn disk_bulk_write_import( Ok(HttpResponseUpdatedNoContent()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Stop importing blocks into disk @@ -2407,14 +2665,14 @@ async fn disk_bulk_write_import( tags = ["disks"], }] async fn disk_bulk_write_import_stop( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); @@ -2426,7 +2684,11 @@ async fn disk_bulk_write_import_stop( Ok(HttpResponseUpdatedNoContent()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Confirm disk block import completion @@ -2436,7 +2698,7 @@ async fn disk_bulk_write_import_stop( tags = ["disks"], }] async fn disk_finalize_import( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, finalize_params: TypedBody, @@ -2444,7 +2706,7 @@ async fn disk_finalize_import( let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let params = finalize_params.into_inner(); @@ -2456,7 +2718,11 @@ async fn disk_finalize_import( Ok(HttpResponseUpdatedNoContent()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Instances @@ -2468,12 +2734,12 @@ async fn disk_finalize_import( tags = ["instances"], }] async fn instance_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -2493,7 +2759,11 @@ async fn instance_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create instance @@ -2503,12 +2773,12 @@ async fn instance_list( tags = ["instances"], }] async fn instance_create( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, new_instance: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let project_selector = query_params.into_inner(); let new_instance_params = &new_instance.into_inner(); let handler = async { @@ -2523,7 +2793,11 @@ async fn instance_create( .await?; Ok(HttpResponseCreated(instance.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch instance @@ -2533,12 +2807,12 @@ async fn instance_create( tags = ["instances"], }] async fn instance_view( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let handler = async { @@ -2557,7 +2831,11 @@ async fn instance_view( .await?; Ok(HttpResponseOk(instance_and_vmm.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete instance @@ -2567,12 +2845,12 @@ async fn instance_view( tags = ["instances"], }] async fn instance_delete( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, path_params: Path, ) -> Result { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let instance_selector = params::InstanceSelector { @@ -2586,7 +2864,11 @@ async fn instance_delete( nexus.project_destroy_instance(&opctx, &instance_lookup).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // TODO should this be in the public API? @@ -2597,13 +2879,13 @@ async fn instance_delete( tags = ["instances"], }] async fn instance_migrate( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, path_params: Path, migrate_params: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let migrate_instance_params = migrate_params.into_inner(); @@ -2624,7 +2906,11 @@ async fn instance_migrate( .await?; Ok(HttpResponseOk(instance.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Reboot an instance @@ -2634,12 +2920,12 @@ async fn instance_migrate( tags = ["instances"], }] async fn instance_reboot( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let instance_selector = params::InstanceSelector { @@ -2653,7 +2939,11 @@ async fn instance_reboot( let instance = nexus.instance_reboot(&opctx, &instance_lookup).await?; Ok(HttpResponseAccepted(instance.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Boot instance @@ -2663,12 +2953,12 @@ async fn instance_reboot( tags = ["instances"], }] async fn instance_start( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let instance_selector = params::InstanceSelector { @@ -2682,7 +2972,11 @@ async fn instance_start( let instance = nexus.instance_start(&opctx, &instance_lookup).await?; Ok(HttpResponseAccepted(instance.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Stop instance @@ -2692,12 +2986,12 @@ async fn instance_start( tags = ["instances"], }] async fn instance_stop( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let instance_selector = params::InstanceSelector { @@ -2711,7 +3005,11 @@ async fn instance_stop( let instance = nexus.instance_stop(&opctx, &instance_lookup).await?; Ok(HttpResponseAccepted(instance.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch instance serial console @@ -2721,14 +3019,14 @@ async fn instance_stop( tags = ["instances"], }] async fn instance_serial_console( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let instance_selector = params::InstanceSelector { @@ -2742,7 +3040,11 @@ async fn instance_serial_console( .await?; Ok(HttpResponseOk(data)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Stream instance serial console @@ -2752,13 +3054,13 @@ async fn instance_serial_console( tags = ["instances"], }] async fn instance_serial_console_stream( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, conn: WebsocketConnection, ) -> WebsocketChannelResult { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -2808,13 +3110,13 @@ async fn instance_serial_console_stream( tags = ["instances"], }] async fn instance_ssh_public_key_list( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; @@ -2839,7 +3141,11 @@ async fn instance_ssh_public_key_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List disks for instance @@ -2849,13 +3155,13 @@ async fn instance_ssh_public_key_list( tags = ["instances"], }] async fn instance_disk_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, path_params: Path, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; @@ -2880,7 +3186,11 @@ async fn instance_disk_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Attach disk to instance @@ -2890,13 +3200,13 @@ async fn instance_disk_list( tags = ["instances"], }] async fn instance_disk_attach( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, disk_to_attach: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let disk = disk_to_attach.into_inner().disk; @@ -2912,7 +3222,11 @@ async fn instance_disk_attach( nexus.instance_attach_disk(&opctx, &instance_lookup, disk).await?; Ok(HttpResponseAccepted(disk.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Detach disk from instance @@ -2922,7 +3236,7 @@ async fn instance_disk_attach( tags = ["instances"], }] async fn instance_disk_detach( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, disk_to_detach: TypedBody, @@ -2930,7 +3244,7 @@ async fn instance_disk_detach( let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let disk = disk_to_detach.into_inner().disk; @@ -2944,7 +3258,11 @@ async fn instance_disk_detach( nexus.instance_detach_disk(&opctx, &instance_lookup, disk).await?; Ok(HttpResponseAccepted(disk.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Certificates @@ -2960,12 +3278,12 @@ async fn instance_disk_detach( tags = ["silos"], }] async fn certificate_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -2983,7 +3301,11 @@ async fn certificate_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create new system-wide x.509 certificate @@ -2996,18 +3318,22 @@ async fn certificate_list( tags = ["silos"] }] async fn certificate_create( - rqctx: RequestContext>, + rqctx: RequestContext, new_cert: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let new_cert_params = new_cert.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let cert = nexus.certificate_create(&opctx, new_cert_params).await?; Ok(HttpResponseCreated(cert.try_into()?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Path parameters for Certificate requests @@ -3025,19 +3351,23 @@ struct CertificatePathParam { tags = ["silos"], }] async fn certificate_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let (.., cert) = nexus.certificate_lookup(&opctx, &path.certificate).fetch().await?; Ok(HttpResponseOk(cert.try_into()?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete certificate @@ -3049,12 +3379,12 @@ async fn certificate_view( tags = ["silos"], }] async fn certificate_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; nexus @@ -3065,7 +3395,11 @@ async fn certificate_delete( .await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create address lot @@ -3075,12 +3409,12 @@ async fn certificate_delete( tags = ["system/networking"], }] async fn networking_address_lot_create( - rqctx: RequestContext>, + rqctx: RequestContext, new_address_lot: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let params = new_address_lot.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let result = nexus.address_lot_create(&opctx, params).await?; @@ -3091,7 +3425,11 @@ async fn networking_address_lot_create( Ok(HttpResponseCreated(AddressLotCreateResponse { lot, blocks })) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete address lot @@ -3101,20 +3439,24 @@ async fn networking_address_lot_create( tags = ["system/networking"], }] async fn networking_address_lot_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let address_lot_lookup = nexus.address_lot_lookup(&opctx, path.address_lot)?; nexus.address_lot_delete(&opctx, &address_lot_lookup).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List address lots @@ -3124,12 +3466,12 @@ async fn networking_address_lot_delete( tags = ["system/networking"], }] async fn networking_address_lot_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -3148,7 +3490,11 @@ async fn networking_address_lot_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List blocks in address lot @@ -3158,13 +3504,13 @@ async fn networking_address_lot_list( tags = ["system/networking"], }] async fn networking_address_lot_block_list( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let path = path_params.into_inner(); let pagparams = data_page_params_for(&rqctx, &query)?; @@ -3184,7 +3530,11 @@ async fn networking_address_lot_block_list( &|_, x: &AddressLotBlock| x.id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create loopback address @@ -3194,12 +3544,12 @@ async fn networking_address_lot_block_list( tags = ["system/networking"], }] async fn networking_loopback_address_create( - rqctx: RequestContext>, + rqctx: RequestContext, new_loopback_address: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let params = new_loopback_address.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let result = nexus.loopback_address_create(&opctx, params).await?; @@ -3208,7 +3558,11 @@ async fn networking_loopback_address_create( Ok(HttpResponseCreated(addr)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } #[derive(Serialize, Deserialize, JsonSchema)] @@ -3235,12 +3589,12 @@ pub struct LoopbackAddressPath { tags = ["system/networking"], }] async fn networking_loopback_address_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path: Path, ) -> Result { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let addr = match IpNetwork::new(path.address, path.subnet_mask) { @@ -3260,7 +3614,11 @@ async fn networking_loopback_address_delete( .await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List loopback addresses @@ -3270,12 +3628,12 @@ async fn networking_loopback_address_delete( tags = ["system/networking"], }] async fn networking_loopback_address_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pagparams = data_page_params_for(&rqctx, &query)?; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -3292,7 +3650,11 @@ async fn networking_loopback_address_list( &|_, x: &LoopbackAddress| x.id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create switch port settings @@ -3302,12 +3664,12 @@ async fn networking_loopback_address_list( tags = ["system/networking"], }] async fn networking_switch_port_settings_create( - rqctx: RequestContext>, + rqctx: RequestContext, new_settings: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let params = new_settings.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let result = nexus.switch_port_settings_post(&opctx, params).await?; @@ -3315,7 +3677,11 @@ async fn networking_switch_port_settings_create( let settings: SwitchPortSettingsView = result.into(); Ok(HttpResponseCreated(settings)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete switch port settings @@ -3325,18 +3691,22 @@ async fn networking_switch_port_settings_create( tags = ["system/networking"], }] async fn networking_switch_port_settings_delete( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let selector = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; nexus.switch_port_settings_delete(&opctx, &selector).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List switch port settings @@ -3346,14 +3716,14 @@ async fn networking_switch_port_settings_delete( tags = ["system/networking"], }] async fn networking_switch_port_settings_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query< PaginatedByNameOrId, >, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -3372,7 +3742,11 @@ async fn networking_switch_port_settings_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Get information about switch port @@ -3382,18 +3756,22 @@ async fn networking_switch_port_settings_list( tags = ["system/networking"], }] async fn networking_switch_port_settings_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = path_params.into_inner().port; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let settings = nexus.switch_port_settings_get(&opctx, &query).await?; Ok(HttpResponseOk(settings.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List switch ports @@ -3403,12 +3781,12 @@ async fn networking_switch_port_settings_view( tags = ["system/hardware"], }] async fn networking_switch_port_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pagparams = data_page_params_for(&rqctx, &query)?; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -3425,7 +3803,11 @@ async fn networking_switch_port_list( &|_, x: &SwitchPort| x.id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Get switch port status @@ -3435,13 +3817,13 @@ async fn networking_switch_port_list( tags = ["system/hardware"], }] async fn networking_switch_port_status( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let path = path_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -3451,7 +3833,11 @@ async fn networking_switch_port_status( .await?, )) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Apply switch port settings @@ -3461,14 +3847,14 @@ async fn networking_switch_port_status( tags = ["system/hardware"], }] async fn networking_switch_port_apply_settings( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, settings_body: TypedBody, ) -> Result { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let port = path_params.into_inner().port; let query = query_params.into_inner(); let settings = settings_body.into_inner(); @@ -3478,7 +3864,11 @@ async fn networking_switch_port_apply_settings( .await?; Ok(HttpResponseUpdatedNoContent {}) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Clear switch port settings @@ -3488,20 +3878,24 @@ async fn networking_switch_port_apply_settings( tags = ["system/hardware"], }] async fn networking_switch_port_clear_settings( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let port = path_params.into_inner().port; let query = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; nexus.switch_port_clear_settings(&opctx, &port, &query).await?; Ok(HttpResponseUpdatedNoContent {}) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create new BGP configuration @@ -3511,18 +3905,22 @@ async fn networking_switch_port_clear_settings( tags = ["system/networking"], }] async fn networking_bgp_config_create( - rqctx: RequestContext>, + rqctx: RequestContext, config: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let config = config.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let result = nexus.bgp_config_set(&opctx, &config).await?; Ok(HttpResponseCreated::(result.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List BGP configurations @@ -3532,12 +3930,12 @@ async fn networking_bgp_config_create( tags = ["system/networking"], }] async fn networking_bgp_config_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -3556,7 +3954,11 @@ async fn networking_bgp_config_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } //TODO pagination? the normal by-name/by-id stuff does not work here @@ -3567,16 +3969,20 @@ async fn networking_bgp_config_list( tags = ["system/networking"], }] async fn networking_bgp_status( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result>, HttpError> { let apictx = rqctx.context(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let result = nexus.bgp_peer_status(&opctx).await?; Ok(HttpResponseOk(result)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Get BGP router message history @@ -3586,18 +3992,22 @@ async fn networking_bgp_status( tags = ["system/networking"], }] async fn networking_bgp_message_history( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let sel = query_params.into_inner(); let result = nexus.bgp_message_history(&opctx, &sel).await?; Ok(HttpResponseOk(AggregateBgpMessageHistory::new(result))) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } //TODO pagination? the normal by-name/by-id stuff does not work here @@ -3608,18 +4018,22 @@ async fn networking_bgp_message_history( tags = ["system/networking"], }] async fn networking_bgp_imported_routes_ipv4( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let sel = query_params.into_inner(); let result = nexus.bgp_imported_routes_ipv4(&opctx, &sel).await?; Ok(HttpResponseOk(result)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete BGP configuration @@ -3629,18 +4043,22 @@ async fn networking_bgp_imported_routes_ipv4( tags = ["system/networking"], }] async fn networking_bgp_config_delete( - rqctx: RequestContext>, + rqctx: RequestContext, sel: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let sel = sel.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; nexus.bgp_config_delete(&opctx, &sel).await?; Ok(HttpResponseUpdatedNoContent {}) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create new BGP announce set @@ -3650,18 +4068,22 @@ async fn networking_bgp_config_delete( tags = ["system/networking"], }] async fn networking_bgp_announce_set_create( - rqctx: RequestContext>, + rqctx: RequestContext, config: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let config = config.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let result = nexus.bgp_create_announce_set(&opctx, &config).await?; Ok(HttpResponseCreated::(result.0.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } //TODO pagination? the normal by-name/by-id stuff does not work here @@ -3672,12 +4094,12 @@ async fn networking_bgp_announce_set_create( tags = ["system/networking"], }] async fn networking_bgp_announce_set_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let sel = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let result = nexus @@ -3688,7 +4110,11 @@ async fn networking_bgp_announce_set_list( .collect(); Ok(HttpResponseOk(result)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete BGP announce set @@ -3698,18 +4124,22 @@ async fn networking_bgp_announce_set_list( tags = ["system/networking"], }] async fn networking_bgp_announce_set_delete( - rqctx: RequestContext>, + rqctx: RequestContext, selector: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let sel = selector.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; nexus.bgp_delete_announce_set(&opctx, &sel).await?; Ok(HttpResponseUpdatedNoContent {}) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Enable a BFD session @@ -3719,18 +4149,22 @@ async fn networking_bgp_announce_set_delete( tags = ["system/networking"], }] async fn networking_bfd_enable( - rqctx: RequestContext>, + rqctx: RequestContext, session: TypedBody, ) -> Result { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; opctx.authorize(authz::Action::ListChildren, &authz::FLEET).await?; nexus.bfd_enable(&opctx, session.into_inner()).await?; Ok(HttpResponseUpdatedNoContent {}) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Disable a BFD session @@ -3740,18 +4174,22 @@ async fn networking_bfd_enable( tags = ["system/networking"], }] async fn networking_bfd_disable( - rqctx: RequestContext>, + rqctx: RequestContext, session: TypedBody, ) -> Result { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; opctx.authorize(authz::Action::ListChildren, &authz::FLEET).await?; nexus.bfd_disable(&opctx, session.into_inner()).await?; Ok(HttpResponseUpdatedNoContent {}) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Get BFD status @@ -3761,17 +4199,21 @@ async fn networking_bfd_disable( tags = ["system/networking"], }] async fn networking_bfd_status( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; opctx.authorize(authz::Action::ListChildren, &authz::FLEET).await?; let status = nexus.bfd_status(&opctx).await?; Ok(HttpResponseOk(status)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Get user-facing services IP allowlist @@ -3781,11 +4223,11 @@ async fn networking_bfd_status( tags = ["system/networking"], }] async fn networking_allow_list_view( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; nexus .allow_list_view(&opctx) @@ -3793,7 +4235,11 @@ async fn networking_allow_list_view( .map(HttpResponseOk) .map_err(HttpError::from) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Update user-facing services IP allowlist @@ -3803,22 +4249,27 @@ async fn networking_allow_list_view( tags = ["system/networking"], }] async fn networking_allow_list_update( - rqctx: RequestContext>, + rqctx: RequestContext, params: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; + let server_kind = apictx.kind; let params = params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let remote_addr = rqctx.request.remote_addr().ip(); nexus - .allow_list_upsert(&opctx, remote_addr, params) + .allow_list_upsert(&opctx, remote_addr, server_kind, params) .await .map(HttpResponseOk) .map_err(HttpError::from) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Images @@ -3833,13 +4284,13 @@ async fn networking_allow_list_update( tags = ["images"], }] async fn image_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -3869,7 +4320,11 @@ async fn image_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create image @@ -3881,14 +4336,14 @@ async fn image_list( tags = ["images"] }] async fn image_create( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, new_image: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let params = &new_image.into_inner(); let parent_lookup = match query.project.clone() { @@ -3907,7 +4362,11 @@ async fn image_create( let image = nexus.image_create(&opctx, &parent_lookup, ¶ms).await?; Ok(HttpResponseCreated(image.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch image @@ -3919,14 +4378,14 @@ async fn image_create( tags = ["images"], }] async fn image_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let image: nexus_db_model::Image = match nexus @@ -3950,7 +4409,11 @@ async fn image_view( }; Ok(HttpResponseOk(image.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete image @@ -3964,14 +4427,14 @@ async fn image_view( tags = ["images"], }] async fn image_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let image_lookup = nexus @@ -3986,7 +4449,11 @@ async fn image_delete( nexus.image_delete(&opctx, &image_lookup).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Promote project image @@ -3998,14 +4465,14 @@ async fn image_delete( tags = ["images"] }] async fn image_promote( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let image_lookup = nexus @@ -4020,7 +4487,11 @@ async fn image_promote( let image = nexus.image_promote(&opctx, &image_lookup).await?; Ok(HttpResponseAccepted(image.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Demote silo image @@ -4032,14 +4503,14 @@ async fn image_promote( tags = ["images"] }] async fn image_demote( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let image_lookup = nexus @@ -4055,7 +4526,11 @@ async fn image_demote( nexus.image_demote(&opctx, &image_lookup, &project_lookup).await?; Ok(HttpResponseAccepted(image.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List network interfaces @@ -4065,13 +4540,13 @@ async fn image_demote( tags = ["instances"], }] async fn instance_network_interface_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -4094,7 +4569,11 @@ async fn instance_network_interface_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create network interface @@ -4104,14 +4583,14 @@ async fn instance_network_interface_list( tags = ["instances"], }] async fn instance_network_interface_create( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, interface_params: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let instance_lookup = nexus.instance_lookup(&opctx, query)?; let iface = nexus @@ -4123,7 +4602,11 @@ async fn instance_network_interface_create( .await?; Ok(HttpResponseCreated(iface.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete network interface @@ -4138,14 +4621,14 @@ async fn instance_network_interface_create( tags = ["instances"], }] async fn instance_network_interface_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let interface_selector = params::InstanceNetworkInterfaceSelector { @@ -4160,7 +4643,11 @@ async fn instance_network_interface_delete( .await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch network interface @@ -4170,14 +4657,14 @@ async fn instance_network_interface_delete( tags = ["instances"], }] async fn instance_network_interface_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let interface_selector = params::InstanceNetworkInterfaceSelector { @@ -4191,7 +4678,11 @@ async fn instance_network_interface_view( .await?; Ok(HttpResponseOk(interface.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Update network interface @@ -4201,7 +4692,7 @@ async fn instance_network_interface_view( tags = ["instances"], }] async fn instance_network_interface_update( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, updated_iface: TypedBody, @@ -4209,7 +4700,7 @@ async fn instance_network_interface_update( let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let updated_iface = updated_iface.into_inner(); @@ -4233,7 +4724,11 @@ async fn instance_network_interface_update( .await?; Ok(HttpResponseOk(InstanceNetworkInterface::from(interface))) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // External IP addresses for instances @@ -4245,13 +4740,13 @@ async fn instance_network_interface_update( tags = ["instances"], }] async fn instance_external_ip_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, path_params: Path, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -4265,7 +4760,11 @@ async fn instance_external_ip_list( nexus.instance_list_external_ips(&opctx, &instance_lookup).await?; Ok(HttpResponseOk(ResultsPage { items: ips, next_page: None })) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Allocate and attach ephemeral IP to instance @@ -4275,7 +4774,7 @@ async fn instance_external_ip_list( tags = ["instances"], }] async fn instance_ephemeral_ip_attach( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ip_to_create: TypedBody, @@ -4283,7 +4782,7 @@ async fn instance_ephemeral_ip_attach( let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let instance_selector = params::InstanceSelector { @@ -4301,7 +4800,11 @@ async fn instance_ephemeral_ip_attach( .await?; Ok(HttpResponseAccepted(ip)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Detach and deallocate ephemeral IP from instance @@ -4311,14 +4814,14 @@ async fn instance_ephemeral_ip_attach( tags = ["instances"], }] async fn instance_ephemeral_ip_detach( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let instance_selector = params::InstanceSelector { @@ -4336,7 +4839,11 @@ async fn instance_ephemeral_ip_detach( .await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Snapshots @@ -4348,13 +4855,13 @@ async fn instance_ephemeral_ip_detach( tags = ["snapshots"], }] async fn snapshot_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -4373,7 +4880,11 @@ async fn snapshot_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create snapshot @@ -4385,14 +4896,14 @@ async fn snapshot_list( tags = ["snapshots"], }] async fn snapshot_create( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, new_snapshot: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let new_snapshot_params = &new_snapshot.into_inner(); let project_lookup = nexus.project_lookup(&opctx, query)?; @@ -4401,7 +4912,11 @@ async fn snapshot_create( .await?; Ok(HttpResponseCreated(snapshot.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch snapshot @@ -4411,14 +4926,14 @@ async fn snapshot_create( tags = ["snapshots"], }] async fn snapshot_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let snapshot_selector = params::SnapshotSelector { @@ -4429,7 +4944,11 @@ async fn snapshot_view( nexus.snapshot_lookup(&opctx, snapshot_selector)?.fetch().await?; Ok(HttpResponseOk(snapshot.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete snapshot @@ -4439,14 +4958,14 @@ async fn snapshot_view( tags = ["snapshots"], }] async fn snapshot_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let snapshot_selector = params::SnapshotSelector { @@ -4458,7 +4977,11 @@ async fn snapshot_delete( nexus.snapshot_delete(&opctx, &snapshot_lookup).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // VPCs @@ -4470,12 +4993,12 @@ async fn snapshot_delete( tags = ["vpcs"], }] async fn vpc_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -4496,7 +5019,11 @@ async fn vpc_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create VPC @@ -4506,12 +5033,12 @@ async fn vpc_list( tags = ["vpcs"], }] async fn vpc_create( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, body: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let new_vpc_params = body.into_inner(); let handler = async { @@ -4522,7 +5049,11 @@ async fn vpc_create( .await?; Ok(HttpResponseCreated(vpc.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch VPC @@ -4532,13 +5063,13 @@ async fn vpc_create( tags = ["vpcs"], }] async fn vpc_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -4547,7 +5078,11 @@ async fn vpc_view( let (.., vpc) = nexus.vpc_lookup(&opctx, vpc_selector)?.fetch().await?; Ok(HttpResponseOk(vpc.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Update a VPC @@ -4557,14 +5092,14 @@ async fn vpc_view( tags = ["vpcs"], }] async fn vpc_update( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, updated_vpc: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let updated_vpc_params = &updated_vpc.into_inner(); @@ -4577,7 +5112,11 @@ async fn vpc_update( .await?; Ok(HttpResponseOk(vpc.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete VPC @@ -4587,13 +5126,13 @@ async fn vpc_update( tags = ["vpcs"], }] async fn vpc_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -4603,7 +5142,11 @@ async fn vpc_delete( nexus.project_delete_vpc(&opctx, &vpc_lookup).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List subnets @@ -4613,12 +5156,12 @@ async fn vpc_delete( tags = ["vpcs"], }] async fn vpc_subnet_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -4638,7 +5181,11 @@ async fn vpc_subnet_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create subnet @@ -4648,13 +5195,13 @@ async fn vpc_subnet_list( tags = ["vpcs"], }] async fn vpc_subnet_create( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, create_params: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let create = create_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -4663,7 +5210,11 @@ async fn vpc_subnet_create( nexus.vpc_create_subnet(&opctx, &vpc_lookup, &create).await?; Ok(HttpResponseCreated(subnet.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch subnet @@ -4673,13 +5224,13 @@ async fn vpc_subnet_create( tags = ["vpcs"], }] async fn vpc_subnet_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -4692,7 +5243,11 @@ async fn vpc_subnet_view( nexus.vpc_subnet_lookup(&opctx, subnet_selector)?.fetch().await?; Ok(HttpResponseOk(subnet.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete subnet @@ -4702,13 +5257,13 @@ async fn vpc_subnet_view( tags = ["vpcs"], }] async fn vpc_subnet_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -4721,7 +5276,11 @@ async fn vpc_subnet_delete( nexus.vpc_delete_subnet(&opctx, &subnet_lookup).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Update subnet @@ -4731,14 +5290,14 @@ async fn vpc_subnet_delete( tags = ["vpcs"], }] async fn vpc_subnet_update( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, subnet_params: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let subnet_params = subnet_params.into_inner(); @@ -4754,7 +5313,11 @@ async fn vpc_subnet_update( .await?; Ok(HttpResponseOk(subnet.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // This endpoint is likely temporary. We would rather list all IPs allocated in @@ -4768,13 +5331,13 @@ async fn vpc_subnet_update( tags = ["vpcs"], }] async fn vpc_subnet_list_network_interfaces( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let path = path_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; @@ -4803,7 +5366,11 @@ async fn vpc_subnet_list_network_interfaces( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // VPC Firewalls @@ -4816,7 +5383,7 @@ async fn vpc_subnet_list_network_interfaces( tags = ["vpcs"], }] async fn vpc_firewall_rules_view( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result, HttpError> { // TODO: Check If-Match and fail if the ETag doesn't match anymore. @@ -4825,7 +5392,7 @@ async fn vpc_firewall_rules_view( let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let vpc_lookup = nexus.vpc_lookup(&opctx, query)?; let rules = nexus.vpc_list_firewall_rules(&opctx, &vpc_lookup).await?; @@ -4833,7 +5400,11 @@ async fn vpc_firewall_rules_view( rules: rules.into_iter().map(|rule| rule.into()).collect(), })) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Replace firewall rules @@ -4843,7 +5414,7 @@ async fn vpc_firewall_rules_view( tags = ["vpcs"], }] async fn vpc_firewall_rules_update( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, router_params: TypedBody, ) -> Result, HttpError> { @@ -4852,7 +5423,7 @@ async fn vpc_firewall_rules_update( let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let router_params = router_params.into_inner(); let vpc_lookup = nexus.vpc_lookup(&opctx, query)?; @@ -4863,7 +5434,11 @@ async fn vpc_firewall_rules_update( rules: rules.into_iter().map(|rule| rule.into()).collect(), })) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // VPC Routers @@ -4876,13 +5451,13 @@ async fn vpc_firewall_rules_update( unpublished = true, }] async fn vpc_router_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -4901,7 +5476,11 @@ async fn vpc_router_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch router @@ -4912,13 +5491,13 @@ async fn vpc_router_list( unpublished = true, }] async fn vpc_router_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -4931,7 +5510,11 @@ async fn vpc_router_view( nexus.vpc_router_lookup(&opctx, router_selector)?.fetch().await?; Ok(HttpResponseOk(vpc_router.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create VPC router @@ -4942,13 +5525,13 @@ async fn vpc_router_view( unpublished = true, }] async fn vpc_router_create( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, create_params: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let create = create_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -4963,7 +5546,11 @@ async fn vpc_router_create( .await?; Ok(HttpResponseCreated(router.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete router @@ -4974,13 +5561,13 @@ async fn vpc_router_create( unpublished = true, }] async fn vpc_router_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -4993,7 +5580,11 @@ async fn vpc_router_delete( nexus.vpc_delete_router(&opctx, &router_lookup).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Update router @@ -5004,14 +5595,14 @@ async fn vpc_router_delete( unpublished = true, }] async fn vpc_router_update( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, router_params: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let router_params = router_params.into_inner(); @@ -5027,7 +5618,11 @@ async fn vpc_router_update( .await?; Ok(HttpResponseOk(router.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List routes @@ -5040,13 +5635,13 @@ async fn vpc_router_update( unpublished = true, }] async fn vpc_router_route_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -5065,7 +5660,11 @@ async fn vpc_router_route_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Vpc Router Routes @@ -5078,14 +5677,14 @@ async fn vpc_router_route_list( unpublished = true, }] async fn vpc_router_route_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let route_selector = params::RouteSelector { @@ -5100,7 +5699,11 @@ async fn vpc_router_route_view( .await?; Ok(HttpResponseOk(route.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create router @@ -5111,14 +5714,14 @@ async fn vpc_router_route_view( unpublished = true, }] async fn vpc_router_route_create( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, create_params: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let create = create_params.into_inner(); let router_lookup = nexus.vpc_router_lookup(&opctx, query)?; @@ -5132,7 +5735,11 @@ async fn vpc_router_route_create( .await?; Ok(HttpResponseCreated(route.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete route @@ -5143,14 +5750,14 @@ async fn vpc_router_route_create( unpublished = true, }] async fn vpc_router_route_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let route_selector = params::RouteSelector { @@ -5164,7 +5771,11 @@ async fn vpc_router_route_delete( nexus.router_delete_route(&opctx, &route_lookup).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Update route @@ -5175,14 +5786,14 @@ async fn vpc_router_route_delete( unpublished = true, }] async fn vpc_router_route_update( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, router_params: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let router_params = router_params.into_inner(); @@ -5200,7 +5811,11 @@ async fn vpc_router_route_update( .await?; Ok(HttpResponseOk(route.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Racks @@ -5212,12 +5827,12 @@ async fn vpc_router_route_update( tags = ["system/hardware"], }] async fn rack_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let racks = nexus @@ -5232,7 +5847,11 @@ async fn rack_list( &|_, rack: &Rack| rack.identity.id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Path parameters for Rack requests @@ -5249,18 +5868,22 @@ struct RackPathParam { tags = ["system/hardware"], }] async fn rack_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let rack_info = nexus.rack_lookup(&opctx, &path.rack_id).await?; Ok(HttpResponseOk(rack_info.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List uninitialized sleds @@ -5270,7 +5893,7 @@ async fn rack_view( tags = ["system/hardware"] }] async fn sled_list_uninitialized( - rqctx: RequestContext>, + rqctx: RequestContext, query: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); @@ -5282,12 +5905,16 @@ async fn sled_list_uninitialized( ); } let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let sleds = nexus.sled_list_uninitialized(&opctx).await?; Ok(HttpResponseOk(ResultsPage { items: sleds, next_page: None })) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// The unique ID of a sled. @@ -5308,11 +5935,11 @@ pub struct SledId { tags = ["system/hardware"] }] async fn sled_add( - rqctx: RequestContext>, + rqctx: RequestContext, sled: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let id = nexus @@ -5321,7 +5948,11 @@ async fn sled_add( .into_untyped_uuid(); Ok(HttpResponseCreated(SledId { id })) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Sleds @@ -5333,12 +5964,12 @@ async fn sled_add( tags = ["system/hardware"], }] async fn sled_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let sleds = nexus @@ -5353,7 +5984,11 @@ async fn sled_list( &|_, sled: &Sled| sled.identity.id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch sled @@ -5363,19 +5998,23 @@ async fn sled_list( tags = ["system/hardware"], }] async fn sled_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let (.., sled) = nexus.sled_lookup(&opctx, &path.sled_id)?.fetch().await?; Ok(HttpResponseOk(sled.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Set sled provision policy @@ -5385,13 +6024,13 @@ async fn sled_view( tags = ["system/hardware"], }] async fn sled_set_provision_policy( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, new_provision_state: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let new_state = new_provision_state.into_inner().state; @@ -5409,7 +6048,11 @@ async fn sled_set_provision_policy( Ok(HttpResponseOk(response)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List instances running on given sled @@ -5419,13 +6062,13 @@ async fn sled_set_provision_policy( tags = ["system/hardware"], }] async fn sled_instance_list( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -5446,7 +6089,11 @@ async fn sled_instance_list( &|_, sled_instance: &views::SledInstance| sled_instance.identity.id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Physical disks @@ -5458,12 +6105,12 @@ async fn sled_instance_list( tags = ["system/hardware"], }] async fn physical_disk_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let disks = nexus @@ -5478,7 +6125,11 @@ async fn physical_disk_list( &|_, disk: &PhysicalDisk| disk.identity.id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Get a physical disk @@ -5488,12 +6139,12 @@ async fn physical_disk_list( tags = ["system/hardware"], }] async fn physical_disk_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -5501,7 +6152,11 @@ async fn physical_disk_view( nexus.physical_disk_lookup(&opctx, &path).await?.fetch().await?; Ok(HttpResponseOk(physical_disk.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Switches @@ -5513,12 +6168,12 @@ async fn physical_disk_view( tags = ["system/hardware"], }] async fn switch_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let switches = nexus @@ -5533,7 +6188,11 @@ async fn switch_list( &|_, switch: &views::Switch| switch.identity.id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch switch @@ -5543,12 +6202,12 @@ async fn switch_list( tags = ["system/hardware"], }] async fn switch_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let (.., switch) = nexus @@ -5560,7 +6219,11 @@ async fn switch_view( .await?; Ok(HttpResponseOk(switch.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List physical disks attached to sleds @@ -5570,13 +6233,13 @@ async fn switch_view( tags = ["system/hardware"], }] async fn sled_physical_disk_list( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let query = query_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -5596,7 +6259,11 @@ async fn sled_physical_disk_list( &|_, disk: &PhysicalDisk| disk.identity.id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Metrics @@ -5637,7 +6304,7 @@ struct SystemMetricsPathParam { tags = ["system/metrics"], }] async fn system_metric( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, pag_params: Query< PaginationParams, @@ -5646,7 +6313,7 @@ async fn system_metric( ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let metric_name = path_params.into_inner().metric_name; let pagination = pag_params.into_inner(); let limit = rqctx.page_limit(&pagination)?; @@ -5669,7 +6336,11 @@ async fn system_metric( Ok(HttpResponseOk(result)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// View metrics @@ -5681,7 +6352,7 @@ async fn system_metric( tags = ["metrics"], }] async fn silo_metric( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, pag_params: Query< PaginationParams, @@ -5690,7 +6361,7 @@ async fn silo_metric( ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let metric_name = path_params.into_inner().metric_name; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -5718,7 +6389,11 @@ async fn silo_metric( Ok(HttpResponseOk(result)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List timeseries schemas @@ -5728,13 +6403,13 @@ async fn silo_metric( tags = ["metrics"], }] async fn timeseries_schema_list( - rqctx: RequestContext>, + rqctx: RequestContext, pag_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let pagination = pag_params.into_inner(); let limit = rqctx.page_limit(&pagination)?; @@ -5744,7 +6419,11 @@ async fn timeseries_schema_list( .map(HttpResponseOk) .map_err(HttpError::from) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // TODO: can we link to an OxQL reference? Do we have one? Can we even do links? @@ -5758,12 +6437,12 @@ async fn timeseries_schema_list( tags = ["metrics"], }] async fn timeseries_query( - rqctx: RequestContext>, + rqctx: RequestContext, body: TypedBody, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let query = body.into_inner().query; nexus @@ -5772,7 +6451,11 @@ async fn timeseries_query( .map(HttpResponseOk) .map_err(HttpError::from) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Updates @@ -5785,12 +6468,12 @@ async fn timeseries_query( unpublished = true, }] async fn system_update_put_repository( - rqctx: RequestContext>, + rqctx: RequestContext, query: Query, body: StreamingBody, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let query = query.into_inner(); @@ -5799,7 +6482,11 @@ async fn system_update_put_repository( nexus.updates_put_repository(&opctx, body, query.file_name).await?; Ok(HttpResponseOk(update)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch TUF repository description @@ -5812,11 +6499,11 @@ async fn system_update_put_repository( unpublished = true, }] async fn system_update_get_repository( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let params = path_params.into_inner(); @@ -5826,7 +6513,11 @@ async fn system_update_get_repository( description: description.into_external(), })) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Silo users @@ -5838,12 +6529,12 @@ async fn system_update_get_repository( tags = ["silos"], }] async fn user_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pagparams = data_page_params_for(&rqctx, &query)?; let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -5867,7 +6558,11 @@ async fn user_list( &|_, user: &User| user.id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Silo groups @@ -5879,11 +6574,11 @@ async fn user_list( tags = ["silos"], }] async fn group_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pagparams = data_page_params_for(&rqctx, &query)?; let handler = async { @@ -5900,7 +6595,11 @@ async fn group_list( &|_, group: &Group| group.id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch group @@ -5910,19 +6609,23 @@ async fn group_list( tags = ["silos"], }] async fn group_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let (.., group) = nexus.silo_group_lookup(&opctx, &path.group_id).fetch().await?; Ok(HttpResponseOk(group.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Built-in (system) users @@ -5934,11 +6637,11 @@ async fn group_view( tags = ["system/silos"], }] async fn user_builtin_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pagparams = data_page_params_for(&rqctx, &query)?.map_name(|n| Name::ref_cast(n)); @@ -5956,7 +6659,11 @@ async fn user_builtin_list( &marker_for_name, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch built-in user @@ -5966,19 +6673,23 @@ async fn user_builtin_list( tags = ["system/silos"], }] async fn user_builtin_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let user_selector = path_params.into_inner(); let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let (.., user) = nexus.user_builtin_lookup(&opctx, &user_selector)?.fetch().await?; Ok(HttpResponseOk(user.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Built-in roles @@ -6004,11 +6715,11 @@ struct RolePathParam { tags = ["roles"], }] async fn role_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; @@ -6038,7 +6749,11 @@ async fn role_list( |role: &Role, _| RolePage { last_seen: role.name.to_string() }, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch built-in role @@ -6048,11 +6763,11 @@ async fn role_list( tags = ["roles"], }] async fn role_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let role_name = &path.role_name; let handler = async { @@ -6060,7 +6775,11 @@ async fn role_view( let role = nexus.role_builtin_fetch(&opctx, &role_name).await?; Ok(HttpResponseOk(role.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Current user @@ -6072,10 +6791,10 @@ async fn role_view( tags = ["session"], }] pub(crate) async fn current_user_view( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result, HttpError> { let apictx = rqctx.context(); - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let user = nexus.silo_user_fetch_self(&opctx).await?; @@ -6085,7 +6804,11 @@ pub(crate) async fn current_user_view( silo_name: silo.name().clone(), })) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch current user's groups @@ -6095,13 +6818,13 @@ pub(crate) async fn current_user_view( tags = ["session"], }] pub(crate) async fn current_user_groups( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let groups = nexus .silo_user_fetch_groups_for_self( @@ -6118,7 +6841,11 @@ pub(crate) async fn current_user_groups( &|_, group: &views::Group| group.id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } // Per-user SSH public keys @@ -6132,13 +6859,13 @@ pub(crate) async fn current_user_groups( tags = ["session"], }] async fn current_user_ssh_key_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -6159,7 +6886,11 @@ async fn current_user_ssh_key_list( &marker_for_name_or_id, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create SSH public key @@ -6171,13 +6902,13 @@ async fn current_user_ssh_key_list( tags = ["session"], }] async fn current_user_ssh_key_create( - rqctx: RequestContext>, + rqctx: RequestContext, new_key: TypedBody, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let &actor = opctx .authn .actor_required() @@ -6187,7 +6918,11 @@ async fn current_user_ssh_key_create( .await?; Ok(HttpResponseCreated(ssh_key.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Fetch SSH public key @@ -6199,13 +6934,13 @@ async fn current_user_ssh_key_create( tags = ["session"], }] async fn current_user_ssh_key_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let &actor = opctx .authn @@ -6221,7 +6956,11 @@ async fn current_user_ssh_key_view( assert_eq!(silo_user.id(), actor.actor_id()); Ok(HttpResponseOk(ssh_key.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete SSH public key @@ -6233,13 +6972,13 @@ async fn current_user_ssh_key_view( tags = ["session"], }] async fn current_user_ssh_key_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let &actor = opctx .authn @@ -6253,7 +6992,11 @@ async fn current_user_ssh_key_delete( nexus.ssh_key_delete(&opctx, actor.actor_id(), &ssh_key_lookup).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// List instrumentation probes @@ -6263,7 +7006,7 @@ async fn current_user_ssh_key_delete( tags = ["system/probes"], }] async fn probe_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query>, ) -> Result>, HttpError> { let apictx = rqctx.context(); @@ -6271,7 +7014,7 @@ async fn probe_list( let opctx = crate::context::op_context_for_external_api(&rqctx).await?; opctx.authorize(authz::Action::ListChildren, &authz::FLEET).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let query = query_params.into_inner(); let pag_params = data_page_params_for(&rqctx, &query)?; let scan_params = ScanByNameOrId::from_query(&query)?; @@ -6291,7 +7034,11 @@ async fn probe_list( }, )?)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// View instrumentation probe @@ -6301,7 +7048,7 @@ async fn probe_list( tags = ["system/probes"], }] async fn probe_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result, HttpError> { @@ -6310,7 +7057,7 @@ async fn probe_view( let opctx = crate::context::op_context_for_external_api(&rqctx).await?; opctx.authorize(authz::Action::ListChildren, &authz::FLEET).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let project_selector = query_params.into_inner(); let project_lookup = nexus.project_lookup(&opctx, project_selector)?; @@ -6318,7 +7065,11 @@ async fn probe_view( nexus.probe_get(&opctx, &project_lookup, &path.probe).await?; Ok(HttpResponseOk(probe)) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Create instrumentation probe @@ -6328,7 +7079,7 @@ async fn probe_view( tags = ["system/probes"], }] async fn probe_create( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, new_probe: TypedBody, ) -> Result, HttpError> { @@ -6337,7 +7088,7 @@ async fn probe_create( let opctx = crate::context::op_context_for_external_api(&rqctx).await?; opctx.authorize(authz::Action::Modify, &authz::FLEET).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let new_probe_params = &new_probe.into_inner(); let project_selector = query_params.into_inner(); let project_lookup = nexus.project_lookup(&opctx, project_selector)?; @@ -6346,7 +7097,11 @@ async fn probe_create( .await?; Ok(HttpResponseCreated(probe.into())) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } /// Delete instrumentation probe @@ -6356,7 +7111,7 @@ async fn probe_create( tags = ["system/probes"], }] async fn probe_delete( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, path_params: Path, ) -> Result { @@ -6365,14 +7120,18 @@ async fn probe_delete( let opctx = crate::context::op_context_for_external_api(&rqctx).await?; opctx.authorize(authz::Action::Modify, &authz::FLEET).await?; - let nexus = &apictx.nexus; + let nexus = &apictx.context.nexus; let path = path_params.into_inner(); let project_selector = query_params.into_inner(); let project_lookup = nexus.project_lookup(&opctx, project_selector)?; nexus.probe_delete(&opctx, &project_lookup, path.probe).await?; Ok(HttpResponseDeleted()) }; - apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await + apictx + .context + .external_latencies + .instrument_dropshot_handler(&rqctx, handler) + .await } #[cfg(test)] diff --git a/nexus/src/internal_api/http_entrypoints.rs b/nexus/src/internal_api/http_entrypoints.rs index 81b63d0d89..ceafe7f103 100644 --- a/nexus/src/internal_api/http_entrypoints.rs +++ b/nexus/src/internal_api/http_entrypoints.rs @@ -5,7 +5,7 @@ //! Handler functions (entrypoints) for HTTP APIs internal to the control plane use super::params::{OximeterInfo, RackInitializationRequest}; -use crate::ServerContext; +use crate::context::ApiContext; use dropshot::endpoint; use dropshot::ApiDescription; use dropshot::FreeformBody; @@ -60,10 +60,9 @@ use serde::Deserialize; use serde::Serialize; use std::collections::BTreeMap; use std::collections::BTreeSet; -use std::sync::Arc; use uuid::Uuid; -type NexusApiDescription = ApiDescription>; +type NexusApiDescription = ApiDescription; /// Returns a description of the internal nexus API pub(crate) fn internal_api() -> NexusApiDescription { @@ -134,10 +133,10 @@ struct SledAgentPathParam { path = "/sled-agents/{sled_id}", }] async fn sled_agent_get( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let nexus = &apictx.nexus; let opctx = crate::context::op_context_for_internal_api(&rqctx).await; let path = path_params.into_inner(); @@ -155,11 +154,11 @@ async fn sled_agent_get( path = "/sled-agents/{sled_id}", }] async fn sled_agent_put( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, sled_info: TypedBody, ) -> Result { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let nexus = &apictx.nexus; let opctx = crate::context::op_context_for_internal_api(&rqctx).await; let path = path_params.into_inner(); @@ -182,10 +181,10 @@ async fn sled_agent_put( path = "/sled-agents/{sled_id}/firewall-rules-update", }] async fn sled_firewall_rules_request( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let nexus = &apictx.nexus; let opctx = crate::context::op_context_for_internal_api(&rqctx).await; let path = path_params.into_inner(); @@ -211,11 +210,11 @@ struct RackPathParam { path = "/racks/{rack_id}/initialization-complete", }] async fn rack_initialization_complete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, info: TypedBody, ) -> Result { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let nexus = &apictx.nexus; let path = path_params.into_inner(); let request = info.into_inner(); @@ -237,11 +236,11 @@ struct SwitchPathParam { path = "/switch/{switch_id}", }] async fn switch_put( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, body: TypedBody, ) -> Result, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let nexus = &apictx.nexus; let path = path_params.into_inner(); @@ -264,11 +263,11 @@ struct InstancePathParam { path = "/instances/{instance_id}", }] async fn cpapi_instances_put( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, new_runtime_state: TypedBody, ) -> Result { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let nexus = &apictx.nexus; let path = path_params.into_inner(); let new_state = new_runtime_state.into_inner(); @@ -294,11 +293,11 @@ struct DiskPathParam { path = "/disks/{disk_id}", }] async fn cpapi_disks_put( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, new_runtime_state: TypedBody, ) -> Result { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let nexus = &apictx.nexus; let path = path_params.into_inner(); let new_state = new_runtime_state.into_inner(); @@ -329,10 +328,10 @@ struct VolumePathParam { path = "/volume/{volume_id}/remove-read-only-parent", }] async fn cpapi_volume_remove_read_only_parent( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let nexus = &apictx.nexus; let path = path_params.into_inner(); @@ -354,10 +353,10 @@ async fn cpapi_volume_remove_read_only_parent( path = "/disk/{disk_id}/remove-read-only-parent", }] async fn cpapi_disk_remove_read_only_parent( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let nexus = &apictx.nexus; let path = path_params.into_inner(); @@ -375,10 +374,10 @@ async fn cpapi_disk_remove_read_only_parent( path = "/metrics/producers", }] async fn cpapi_producers_post( - request_context: RequestContext>, + request_context: RequestContext, producer_info: TypedBody, ) -> Result, HttpError> { - let context = request_context.context(); + let context = &request_context.context().context; let handler = async { let nexus = &context.nexus; let producer_info = producer_info.into_inner(); @@ -413,11 +412,11 @@ pub struct CollectorIdPathParams { path = "/metrics/collectors/{collector_id}/producers", }] async fn cpapi_assigned_producers_list( - request_context: RequestContext>, + request_context: RequestContext, path_params: Path, query_params: Query, ) -> Result>, HttpError> { - let context = request_context.context(); + let context = &request_context.context().context; let handler = async { let nexus = &context.nexus; let collector_id = path_params.into_inner().collector_id; @@ -446,10 +445,10 @@ async fn cpapi_assigned_producers_list( path = "/metrics/collectors", }] async fn cpapi_collectors_post( - request_context: RequestContext>, + request_context: RequestContext, oximeter_info: TypedBody, ) -> Result { - let context = request_context.context(); + let context = &request_context.context().context; let handler = async { let nexus = &context.nexus; let oximeter_info = oximeter_info.into_inner(); @@ -470,10 +469,10 @@ async fn cpapi_collectors_post( path = "/artifacts/{kind}/{name}/{version}", }] async fn cpapi_artifact_download( - request_context: RequestContext>, + request_context: RequestContext, path_params: Path, ) -> Result, HttpError> { - let context = request_context.context(); + let context = &request_context.context().context; let nexus = &context.nexus; let opctx = crate::context::op_context_for_internal_api(&request_context).await; @@ -497,11 +496,11 @@ struct UpstairsPathParam { path = "/crucible/0/upstairs/{upstairs_id}/repair-start", }] async fn cpapi_upstairs_repair_start( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, repair_start_info: TypedBody, ) -> Result { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let nexus = &apictx.nexus; let path = path_params.into_inner(); @@ -525,11 +524,11 @@ async fn cpapi_upstairs_repair_start( path = "/crucible/0/upstairs/{upstairs_id}/repair-finish", }] async fn cpapi_upstairs_repair_finish( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, repair_finish_info: TypedBody, ) -> Result { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let nexus = &apictx.nexus; let path = path_params.into_inner(); @@ -560,11 +559,11 @@ struct UpstairsRepairPathParam { path = "/crucible/0/upstairs/{upstairs_id}/repair/{repair_id}/progress", }] async fn cpapi_upstairs_repair_progress( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, repair_progress: TypedBody, ) -> Result { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let nexus = &apictx.nexus; let path = path_params.into_inner(); @@ -597,11 +596,11 @@ struct UpstairsDownstairsPathParam { path = "/crucible/0/upstairs/{upstairs_id}/downstairs/{downstairs_id}/stop-request", }] async fn cpapi_downstairs_client_stop_request( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, downstairs_client_stop_request: TypedBody, ) -> Result { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let nexus = &apictx.nexus; let path = path_params.into_inner(); @@ -627,11 +626,11 @@ async fn cpapi_downstairs_client_stop_request( path = "/crucible/0/upstairs/{upstairs_id}/downstairs/{downstairs_id}/stopped", }] async fn cpapi_downstairs_client_stopped( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, downstairs_client_stopped: TypedBody, ) -> Result { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let nexus = &apictx.nexus; let path = path_params.into_inner(); @@ -658,10 +657,10 @@ async fn cpapi_downstairs_client_stopped( path = "/sagas", }] async fn saga_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let nexus = &apictx.nexus; let query = query_params.into_inner(); @@ -690,10 +689,10 @@ struct SagaPathParam { path = "/sagas/{saga_id}", }] async fn saga_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let opctx = crate::context::op_context_for_internal_api(&rqctx).await; let nexus = &apictx.nexus; @@ -715,9 +714,9 @@ async fn saga_view( path = "/bgtasks", }] async fn bgtask_list( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result>, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let nexus = &apictx.nexus; let opctx = crate::context::op_context_for_internal_api(&rqctx).await; @@ -747,10 +746,10 @@ struct BackgroundTasksActivateRequest { path = "/bgtasks/view/{bgtask_name}", }] async fn bgtask_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let opctx = crate::context::op_context_for_internal_api(&rqctx).await; let nexus = &apictx.nexus; @@ -768,10 +767,10 @@ async fn bgtask_view( path = "/bgtasks/activate", }] async fn bgtask_activate( - rqctx: RequestContext>, + rqctx: RequestContext, body: TypedBody, ) -> Result { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let opctx = crate::context::op_context_for_internal_api(&rqctx).await; let nexus = &apictx.nexus; @@ -810,11 +809,11 @@ struct RpwNatQueryParam { path = "/nat/ipv4/changeset/{from_gen}" }] async fn ipv4_nat_changeset( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result>, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let opctx = crate::context::op_context_for_internal_api(&rqctx).await; let nexus = &apictx.nexus; @@ -843,10 +842,10 @@ async fn ipv4_nat_changeset( path = "/deployment/blueprints/all", }] async fn blueprint_list( - rqctx: RequestContext>, + rqctx: RequestContext, query_params: Query, ) -> Result>, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let nexus = &apictx.nexus; let query = query_params.into_inner(); @@ -869,10 +868,10 @@ async fn blueprint_list( path = "/deployment/blueprints/all/{blueprint_id}", }] async fn blueprint_view( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let opctx = crate::context::op_context_for_internal_api(&rqctx).await; let nexus = &apictx.nexus; @@ -889,10 +888,10 @@ async fn blueprint_view( path = "/deployment/blueprints/all/{blueprint_id}", }] async fn blueprint_delete( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, ) -> Result { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let opctx = crate::context::op_context_for_internal_api(&rqctx).await; let nexus = &apictx.nexus; @@ -911,9 +910,9 @@ async fn blueprint_delete( path = "/deployment/blueprints/target", }] async fn blueprint_target_view( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let opctx = crate::context::op_context_for_internal_api(&rqctx).await; let nexus = &apictx.nexus; @@ -929,10 +928,10 @@ async fn blueprint_target_view( path = "/deployment/blueprints/target", }] async fn blueprint_target_set( - rqctx: RequestContext>, + rqctx: RequestContext, target: TypedBody, ) -> Result, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let opctx = crate::context::op_context_for_internal_api(&rqctx).await; let nexus = &apictx.nexus; @@ -949,10 +948,10 @@ async fn blueprint_target_set( path = "/deployment/blueprints/target/enabled", }] async fn blueprint_target_set_enabled( - rqctx: RequestContext>, + rqctx: RequestContext, target: TypedBody, ) -> Result, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let opctx = crate::context::op_context_for_internal_api(&rqctx).await; let nexus = &apictx.nexus; @@ -972,9 +971,9 @@ async fn blueprint_target_set_enabled( path = "/deployment/blueprints/regenerate", }] async fn blueprint_regenerate( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let opctx = crate::context::op_context_for_internal_api(&rqctx).await; let nexus = &apictx.nexus; @@ -992,10 +991,10 @@ async fn blueprint_regenerate( path = "/deployment/blueprints/import", }] async fn blueprint_import( - rqctx: RequestContext>, + rqctx: RequestContext, blueprint: TypedBody, ) -> Result { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let opctx = crate::context::op_context_for_internal_api(&rqctx).await; let nexus = &apictx.nexus; @@ -1012,9 +1011,9 @@ async fn blueprint_import( path = "/sleds/uninitialized", }] async fn sled_list_uninitialized( - rqctx: RequestContext>, + rqctx: RequestContext, ) -> Result>, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let nexus = &apictx.nexus; let opctx = crate::context::op_context_for_internal_api(&rqctx).await; @@ -1040,10 +1039,10 @@ pub struct SledId { path = "/sleds/add", }] async fn sled_add( - rqctx: RequestContext>, + rqctx: RequestContext, sled: TypedBody, ) -> Result, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let nexus = &apictx.nexus; let handler = async { let opctx = crate::context::op_context_for_internal_api(&rqctx).await; @@ -1064,10 +1063,10 @@ async fn sled_add( path = "/sleds/expunge", }] async fn sled_expunge( - rqctx: RequestContext>, + rqctx: RequestContext, sled: TypedBody, ) -> Result, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let nexus = &apictx.nexus; let handler = async { let opctx = crate::context::op_context_for_internal_api(&rqctx).await; @@ -1090,11 +1089,11 @@ struct ProbePathParam { path = "/probes/{sled}" }] async fn probes_get( - rqctx: RequestContext>, + rqctx: RequestContext, path_params: Path, query_params: Query, ) -> Result>, HttpError> { - let apictx = rqctx.context(); + let apictx = &rqctx.context().context; let handler = async { let query = query_params.into_inner(); let path = path_params.into_inner(); diff --git a/nexus/src/lib.rs b/nexus/src/lib.rs index e34b694e52..c2e3d8ed59 100644 --- a/nexus/src/lib.rs +++ b/nexus/src/lib.rs @@ -20,6 +20,7 @@ mod saga_interface; pub use app::test_interfaces::TestInterfaces; pub use app::Nexus; +use context::ApiContext; use context::ServerContext; use dropshot::ConfigDropshot; use external_api::http_entrypoints::external_api; @@ -77,11 +78,10 @@ pub fn run_openapi_internal() -> Result<(), String> { /// A partially-initialized Nexus server, which exposes an internal interface, /// but is not ready to receive external requests. pub struct InternalServer { - /// shared state used by API request handlers - apictx: Arc, + /// Shared server state. + apictx: ApiContext, /// dropshot server for internal API - http_server_internal: dropshot::HttpServer>, - + http_server_internal: dropshot::HttpServer, config: NexusConfig, log: Logger, } @@ -97,31 +97,35 @@ impl InternalServer { let ctxlog = log.new(o!("component" => "ServerContext")); - let apictx = - ServerContext::new(config.deployment.rack_id, ctxlog, &config) - .await?; + let context = + ApiContext::new(config.deployment.rack_id, ctxlog, &config).await?; // Launch the internal server. let server_starter_internal = dropshot::HttpServerStarter::new( &config.deployment.dropshot_internal, internal_api(), - Arc::clone(&apictx), + context.clone(), &log.new(o!("component" => "dropshot_internal")), ) .map_err(|error| format!("initializing internal server: {}", error))?; let http_server_internal = server_starter_internal.start(); - Ok(Self { apictx, http_server_internal, config: config.clone(), log }) + Ok(Self { + apictx: context, + http_server_internal, + config: config.clone(), + log, + }) } } -type DropshotServer = dropshot::HttpServer>; +type DropshotServer = dropshot::HttpServer; /// Packages up a [`Nexus`], running both external and internal HTTP API servers /// wired up to Nexus pub struct Server { /// shared state used by API request handlers - apictx: Arc, + apictx: ApiContext, } impl Server { @@ -132,16 +136,17 @@ impl Server { let config = internal.config; // Wait until RSS handoff completes. - let opctx = apictx.nexus.opctx_for_service_balancer(); - apictx.nexus.await_rack_initialization(&opctx).await; + let opctx = apictx.context.nexus.opctx_for_service_balancer(); + apictx.context.nexus.await_rack_initialization(&opctx).await; // While we've started our internal server, we need to wait until we've // definitely implemented our source IP allowlist for making requests to // the external server we're about to start. - apictx.nexus.await_ip_allowlist_plumbing().await; + apictx.context.nexus.await_ip_allowlist_plumbing().await; // Launch the external server. let tls_config = apictx + .context .nexus .external_tls_config(config.deployment.dropshot_external.tls) .await; @@ -167,7 +172,7 @@ impl Server { dropshot::HttpServerStarter::new_with_tls( &config.deployment.dropshot_external.dropshot, external_api(), - Arc::clone(&apictx), + apictx.for_external(), &log.new(o!("component" => "dropshot_external")), tls_config.clone().map(dropshot::ConfigTls::Dynamic), ) @@ -181,7 +186,7 @@ impl Server { dropshot::HttpServerStarter::new_with_tls( &techport_server_config, external_api(), - Arc::clone(&apictx), + apictx.for_techport(), &log.new(o!("component" => "dropshot_external_techport")), tls_config.map(dropshot::ConfigTls::Dynamic), ) @@ -195,11 +200,12 @@ impl Server { // metric data. let producer_server = start_producer_server( &log, - &apictx.producer_registry, + &apictx.context.producer_registry, http_server_internal.local_addr(), )?; apictx + .context .nexus .set_servers( http_server_external, @@ -212,8 +218,8 @@ impl Server { Ok(server) } - pub fn apictx(&self) -> &Arc { - &self.apictx + pub fn server_context(&self) -> &Arc { + &self.apictx.context } /// Wait for the given server to shut down @@ -222,7 +228,7 @@ impl Server { /// immediately after calling `start()`, the program will block indefinitely /// or until something else initiates a graceful shutdown. pub(crate) async fn wait_for_finish(self) -> Result<(), String> { - self.apictx.nexus.wait_for_shutdown().await + self.apictx.context.nexus.wait_for_shutdown().await } } @@ -236,7 +242,7 @@ impl nexus_test_interface::NexusServer for Server { ) -> (InternalServer, SocketAddr) { let internal_server = InternalServer::start(config, &log).await.unwrap(); - internal_server.apictx.nexus.wait_for_populate().await.unwrap(); + internal_server.apictx.context.nexus.wait_for_populate().await.unwrap(); let addr = internal_server.http_server_internal.local_addr(); (internal_server, addr) } @@ -259,7 +265,8 @@ impl nexus_test_interface::NexusServer for Server { // Perform the "handoff from RSS". // // However, RSS isn't running, so we'll do the handoff ourselves. - let opctx = internal_server.apictx.nexus.opctx_for_internal_api(); + let opctx = + internal_server.apictx.context.nexus.opctx_for_internal_api(); // Allocation of the initial Nexus's external IP is a little funny. In // a real system, it'd be allocated by RSS and provided with the rack @@ -290,6 +297,7 @@ impl nexus_test_interface::NexusServer for Server { internal_server .apictx + .context .nexus .rack_initialize( &opctx, @@ -332,7 +340,7 @@ impl nexus_test_interface::NexusServer for Server { // Historically, tests have assumed that there's only one provisionable // sled, and that's convenient for a lot of purposes. Mark our second // sled non-provisionable. - let nexus = &rv.apictx().nexus; + let nexus = &rv.server_context().nexus; nexus .sled_set_provision_policy( &opctx, @@ -349,11 +357,15 @@ impl nexus_test_interface::NexusServer for Server { } async fn get_http_server_external_address(&self) -> SocketAddr { - self.apictx.nexus.get_external_server_address().await.unwrap() + self.apictx.context.nexus.get_external_server_address().await.unwrap() + } + + async fn get_http_server_techport_address(&self) -> SocketAddr { + self.apictx.context.nexus.get_techport_server_address().await.unwrap() } async fn get_http_server_internal_address(&self) -> SocketAddr { - self.apictx.nexus.get_internal_server_address().await.unwrap() + self.apictx.context.nexus.get_internal_server_address().await.unwrap() } async fn upsert_crucible_dataset( @@ -363,8 +375,9 @@ impl nexus_test_interface::NexusServer for Server { dataset_id: Uuid, address: SocketAddrV6, ) { - let opctx = self.apictx.nexus.opctx_for_internal_api(); + let opctx = self.apictx.context.nexus.opctx_for_internal_api(); self.apictx + .context .nexus .upsert_physical_disk(&opctx, physical_disk) .await @@ -372,9 +385,10 @@ impl nexus_test_interface::NexusServer for Server { let zpool_id = zpool.id; - self.apictx.nexus.upsert_zpool(&opctx, zpool).await.unwrap(); + self.apictx.context.nexus.upsert_zpool(&opctx, zpool).await.unwrap(); self.apictx + .context .nexus .upsert_dataset( dataset_id, @@ -389,7 +403,7 @@ impl nexus_test_interface::NexusServer for Server { async fn inventory_collect_and_get_latest_collection( &self, ) -> Result, Error> { - let nexus = &self.apictx.nexus; + let nexus = &self.apictx.context.nexus; nexus.activate_inventory_collection(); @@ -399,6 +413,7 @@ impl nexus_test_interface::NexusServer for Server { async fn close(mut self) { self.apictx + .context .nexus .close_servers() .await diff --git a/nexus/test-interface/src/lib.rs b/nexus/test-interface/src/lib.rs index 2c7f0989ea..06c5570b7b 100644 --- a/nexus/test-interface/src/lib.rs +++ b/nexus/test-interface/src/lib.rs @@ -68,6 +68,7 @@ pub trait NexusServer: Send + Sync + 'static { ) -> Self; async fn get_http_server_external_address(&self) -> SocketAddr; + async fn get_http_server_techport_address(&self) -> SocketAddr; async fn get_http_server_internal_address(&self) -> SocketAddr; // Previously, as a dataset was created (within the sled agent), diff --git a/nexus/test-utils/src/lib.rs b/nexus/test-utils/src/lib.rs index 23d84ee702..8bbb6ef38c 100644 --- a/nexus/test-utils/src/lib.rs +++ b/nexus/test-utils/src/lib.rs @@ -104,6 +104,7 @@ pub const TEST_SUITE_PASSWORD: &str = "oxide"; pub struct ControlPlaneTestContext { pub start_time: chrono::DateTime, pub external_client: ClientTestContext, + pub techport_client: ClientTestContext, pub internal_client: ClientTestContext, pub server: N, pub database: dev::db::CockroachInstance, @@ -257,6 +258,7 @@ pub struct ControlPlaneTestContextBuilder<'a, N: NexusServer> { pub logctx: LogContext, pub external_client: Option, + pub techport_client: Option, pub internal_client: Option, pub server: Option, @@ -307,6 +309,7 @@ impl<'a, N: NexusServer> ControlPlaneTestContextBuilder<'a, N> { start_time, logctx, external_client: None, + techport_client: None, internal_client: None, server: None, database: None, @@ -832,6 +835,8 @@ impl<'a, N: NexusServer> ControlPlaneTestContextBuilder<'a, N> { let external_server_addr = server.get_http_server_external_address().await; + let techport_external_server_addr = + server.get_http_server_techport_address().await; let internal_server_addr = server.get_http_server_internal_address().await; let testctx_external = ClientTestContext::new( @@ -840,6 +845,12 @@ impl<'a, N: NexusServer> ControlPlaneTestContextBuilder<'a, N> { .log .new(o!("component" => "external client test context")), ); + let testctx_techport = ClientTestContext::new( + techport_external_server_addr, + self.logctx.log.new( + o!("component" => "techport external client test context"), + ), + ); let testctx_internal = ClientTestContext::new( internal_server_addr, self.logctx @@ -849,6 +860,7 @@ impl<'a, N: NexusServer> ControlPlaneTestContextBuilder<'a, N> { self.external_dns_zone_name = Some(external_dns_zone_name); self.external_client = Some(testctx_external); + self.techport_client = Some(testctx_techport); self.internal_client = Some(testctx_internal); self.silo_name = Some(silo_name); self.user_name = Some(user_name); @@ -1086,6 +1098,7 @@ impl<'a, N: NexusServer> ControlPlaneTestContextBuilder<'a, N> { start_time: self.start_time, server: self.server.unwrap(), external_client: self.external_client.unwrap(), + techport_client: self.techport_client.unwrap(), internal_client: self.internal_client.unwrap(), database: self.database.unwrap(), clickhouse: self.clickhouse.unwrap(), diff --git a/nexus/tests/integration_tests/allow_list.rs b/nexus/tests/integration_tests/allow_list.rs index 319696b5f5..df322dcf58 100644 --- a/nexus/tests/integration_tests/allow_list.rs +++ b/nexus/tests/integration_tests/allow_list.rs @@ -101,7 +101,7 @@ async fn test_allow_list(cptestctx: &ControlPlaneTestContext) { let addrs = vec![IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1)).into()]; let allowed_ips = AllowedSourceIps::try_from(addrs.clone()) .expect("Expected a valid IP list"); - let new_list = params::AllowListUpdate { allowed_ips }; + let new_list = params::AllowListUpdate { allowed_ips: allowed_ips.clone() }; let err: dropshot::HttpErrorResponseBody = NexusRequest::expect_failure_with_body( client, @@ -119,4 +119,9 @@ async fn test_allow_list(cptestctx: &ControlPlaneTestContext) { assert!(err .message .contains("would prevent access from the current client")); + + // But we _should_ be able to make this self-defeating request through the + // techport proxy server. + let client = &cptestctx.techport_client; + update_list_and_compare(client, allowed_ips).await; } diff --git a/nexus/tests/integration_tests/disks.rs b/nexus/tests/integration_tests/disks.rs index c74cfb5c50..886504a83b 100644 --- a/nexus/tests/integration_tests/disks.rs +++ b/nexus/tests/integration_tests/disks.rs @@ -191,7 +191,7 @@ async fn test_disk_create_attach_detach_delete( let client = &cptestctx.external_client; DiskTest::new(&cptestctx).await; let project_id = create_project_and_pool(client).await; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let disks_url = get_disks_url(); // Create a disk. @@ -365,7 +365,7 @@ async fn test_disk_slot_assignment(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; DiskTest::new(&cptestctx).await; create_project_and_pool(client).await; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let disk_names = ["a", "b", "c", "d"]; let mut disks = Vec::new(); @@ -391,7 +391,7 @@ async fn test_disk_slot_assignment(cptestctx: &ControlPlaneTestContext) { get_disk_attach_url(&instance.identity.id.into()); async fn get_disk_slot(ctx: &ControlPlaneTestContext, disk_id: Uuid) -> u8 { - let apictx = &ctx.server.apictx(); + let apictx = &ctx.server.server_context(); let nexus = &apictx.nexus; let datastore = nexus.datastore(); let opctx = @@ -469,7 +469,7 @@ async fn test_disk_slot_assignment(cptestctx: &ControlPlaneTestContext) { #[nexus_test] async fn test_disk_move_between_instances(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; DiskTest::new(&cptestctx).await; create_project_and_pool(&client).await; let disks_url = get_disks_url(); @@ -1043,7 +1043,7 @@ async fn test_disk_virtual_provisioning_collection( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let _test = DiskTest::new(&cptestctx).await; @@ -1251,7 +1251,7 @@ async fn test_disk_virtual_provisioning_collection_failed_delete( ) { // Confirm that there's no panic deleting a project if a disk deletion fails let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let disk_test = DiskTest::new(&cptestctx).await; @@ -1391,7 +1391,7 @@ async fn test_phantom_disk_rename(cptestctx: &ControlPlaneTestContext) { // faulted let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let _disk_test = DiskTest::new(&cptestctx).await; @@ -1512,7 +1512,7 @@ async fn test_phantom_disk_rename(cptestctx: &ControlPlaneTestContext) { #[nexus_test] async fn test_disk_size_accounting(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); // Create three 10 GiB zpools, each with one dataset. @@ -1973,7 +1973,7 @@ async fn test_project_delete_disk_no_auth_idempotent( // Call project_delete_disk_no_auth twice, ensuring that the disk is either // there before deleting and not afterwards. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone()); @@ -2013,7 +2013,7 @@ async fn test_project_delete_disk_no_auth_idempotent( // Test allocating a single region #[nexus_test] async fn test_single_region_allocate(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone()); @@ -2085,7 +2085,7 @@ async fn test_single_region_allocate(cptestctx: &ControlPlaneTestContext) { async fn test_region_allocation_strategy_random_is_idempotent( cptestctx: &ControlPlaneTestContext, ) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone()); @@ -2152,7 +2152,7 @@ async fn test_region_allocation_strategy_random_is_idempotent( async fn test_region_allocation_strategy_random_is_idempotent_arbitrary( cptestctx: &ControlPlaneTestContext, ) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone()); @@ -2208,7 +2208,7 @@ async fn test_region_allocation_strategy_random_is_idempotent_arbitrary( async fn test_single_region_allocate_for_replace( cptestctx: &ControlPlaneTestContext, ) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone()); @@ -2297,7 +2297,7 @@ async fn test_single_region_allocate_for_replace( async fn test_single_region_allocate_for_replace_not_enough_zpools( cptestctx: &ControlPlaneTestContext, ) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone()); @@ -2387,7 +2387,7 @@ async fn test_single_region_allocate_for_replace_not_enough_zpools( async fn test_region_allocation_after_delete( cptestctx: &ControlPlaneTestContext, ) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let opctx = OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone()); diff --git a/nexus/tests/integration_tests/external_ips.rs b/nexus/tests/integration_tests/external_ips.rs index 9d7ef34b35..396edddc41 100644 --- a/nexus/tests/integration_tests/external_ips.rs +++ b/nexus/tests/integration_tests/external_ips.rs @@ -628,7 +628,7 @@ async fn test_floating_ip_create_attachment( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; create_default_ip_pool(&client).await; @@ -725,7 +725,7 @@ async fn test_external_ip_live_attach_detach( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; create_default_ip_pool(&client).await; @@ -934,7 +934,7 @@ async fn test_floating_ip_attach_fail_between_projects( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let _nexus = &apictx.nexus; create_default_ip_pool(&client).await; @@ -1009,7 +1009,7 @@ async fn test_external_ip_attach_fail_if_in_use_by_other( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; create_default_ip_pool(&client).await; diff --git a/nexus/tests/integration_tests/instances.rs b/nexus/tests/integration_tests/instances.rs index 0b5947ef7e..7ad52b9919 100644 --- a/nexus/tests/integration_tests/instances.rs +++ b/nexus/tests/integration_tests/instances.rs @@ -280,7 +280,7 @@ async fn test_instances_create_reboot_halt( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let instance_name = "just-rainsticks"; @@ -585,7 +585,7 @@ async fn test_instance_start_creates_networking_state( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let instance_name = "series-of-tubes"; @@ -688,7 +688,7 @@ async fn test_instance_start_creates_networking_state( #[nexus_test] async fn test_instance_migrate(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let instance_name = "bird-ecology"; @@ -784,7 +784,7 @@ async fn test_instance_migrate(cptestctx: &ControlPlaneTestContext) { #[nexus_test] async fn test_instance_migrate_v2p(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let datastore = nexus.datastore(); let opctx = @@ -936,7 +936,7 @@ async fn test_instance_failed_after_sled_agent_error( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let instance_name = "losing-is-fun"; @@ -1063,7 +1063,7 @@ async fn assert_metrics( #[nexus_test] async fn test_instance_metrics(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let datastore = nexus.datastore(); @@ -1143,14 +1143,14 @@ async fn test_instance_metrics_with_migration( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let instance_name = "bird-ecology"; // Wait until Nexus registers as a producer with Oximeter. wait_for_producer( &cptestctx.oximeter, - cptestctx.server.apictx().nexus.id(), + cptestctx.server.server_context().nexus.id(), ) .await; @@ -1276,7 +1276,7 @@ async fn test_instances_create_stopped_start( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let instance_name = "just-rainsticks"; @@ -1327,7 +1327,7 @@ async fn test_instances_delete_fails_when_running_succeeds_when_stopped( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let instance_name = "just-rainsticks"; @@ -1849,7 +1849,7 @@ async fn test_instance_create_delete_network_interface( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let instance_name = "nic-attach-test-inst"; create_project_and_pool(&client).await; @@ -2090,7 +2090,7 @@ async fn test_instance_update_network_interfaces( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let instance_name = "nic-update-test-inst"; create_project_and_pool(&client).await; @@ -2710,7 +2710,7 @@ async fn test_instance_create_attach_disks_undo( let faulted_disk = create_disk(&client, PROJECT_NAME, "faulted-disk").await; // set `faulted_disk` to the faulted state - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; assert!(nexus .set_disk_as_faulted(&faulted_disk.identity.id) @@ -2971,7 +2971,7 @@ async fn test_cannot_attach_faulted_disks(cptestctx: &ControlPlaneTestContext) { assert_eq!(disks.len(), 8); // Set the 7th to FAULTED - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; assert!(nexus.set_disk_as_faulted(&disks[6].identity.id).await.unwrap()); @@ -3129,7 +3129,7 @@ async fn test_disks_detached_when_instance_destroyed( // sled. let instance_url = format!("/v1/instances/nfs?project={}", PROJECT_NAME); let instance = instance_get(&client, &instance_url).await; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let sa = nexus .instance_sled_by_id(&instance.identity.id) @@ -3656,7 +3656,7 @@ async fn test_cannot_provision_instance_beyond_cpu_capacity( // Make the started instance transition to Running, shut it down, and verify // that the other reasonably-sized instance can now start. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; instance_simulate(nexus, &instances[1].identity.id).await; instances[1] = instance_post(client, configs[1].0, InstanceOp::Stop).await; instance_simulate(nexus, &instances[1].identity.id).await; @@ -3762,7 +3762,7 @@ async fn test_cannot_provision_instance_beyond_ram_capacity( // Make the started instance transition to Running, shut it down, and verify // that the other reasonably-sized instance can now start. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; instance_simulate(nexus, &instances[1].identity.id).await; instances[1] = instance_post(client, configs[1].0, InstanceOp::Stop).await; instance_simulate(nexus, &instances[1].identity.id).await; @@ -3772,7 +3772,7 @@ async fn test_cannot_provision_instance_beyond_ram_capacity( #[nexus_test] async fn test_instance_serial(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let instance_name = "kris-picks"; @@ -4052,7 +4052,7 @@ async fn stop_and_delete_instance( let client = &cptestctx.external_client; let instance = instance_post(&client, instance_name, InstanceOp::Stop).await; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; instance_simulate(nexus, &instance.identity.id).await; let url = format!("/v1/instances/{}?project={}", instance_name, PROJECT_NAME); @@ -4436,7 +4436,7 @@ async fn test_instance_create_in_silo(cptestctx: &ControlPlaneTestContext) { // Make sure the instance can actually start even though a collaborator // created it. - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let authn = AuthnMode::SiloUser(user_id); let instance_url = get_instance_url(instance_name); @@ -4533,7 +4533,7 @@ async fn test_instance_v2p_mappings(cptestctx: &ControlPlaneTestContext) { // Validate that every sled (except the instance's sled) now has a V2P // mapping for this instance - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let datastore = nexus.datastore(); let opctx = diff --git a/nexus/tests/integration_tests/ip_pools.rs b/nexus/tests/integration_tests/ip_pools.rs index cb5eade735..38cfd25844 100644 --- a/nexus/tests/integration_tests/ip_pools.rs +++ b/nexus/tests/integration_tests/ip_pools.rs @@ -791,7 +791,7 @@ async fn test_ip_pool_utilization_total(cptestctx: &ControlPlaneTestContext) { // allowed. It's worth doing because we want this code to correctly handle // IPv6 ranges when they are allowed again. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let log = cptestctx.logctx.log.new(o!()); let opctx = OpContext::for_tests(log, datastore.clone()); @@ -1147,7 +1147,7 @@ async fn test_ip_range_delete_with_allocated_external_ip_fails( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let ip_pools_url = "/v1/system/ip-pools"; let pool_name = "mypool"; diff --git a/nexus/tests/integration_tests/metrics.rs b/nexus/tests/integration_tests/metrics.rs index ec44c3747a..71d18f95ee 100644 --- a/nexus/tests/integration_tests/metrics.rs +++ b/nexus/tests/integration_tests/metrics.rs @@ -179,7 +179,7 @@ async fn test_metrics( // Wait until Nexus registers as a producer with Oximeter. wait_for_producer( &cptestctx.oximeter, - cptestctx.server.apictx().nexus.id(), + cptestctx.server.server_context().nexus.id(), ) .await; @@ -259,7 +259,7 @@ async fn test_timeseries_schema_list( // Nexus registers itself as a metric producer on startup, with its own UUID // as the producer ID. Wait for this to show up in the registered lists of // producers. - let nexus_id = cptestctx.server.apictx().nexus.id(); + let nexus_id = cptestctx.server.server_context().nexus.id(); wait_for_producer(&cptestctx.oximeter, nexus_id).await; // We should be able to fetch the list of timeseries, and it should include @@ -328,7 +328,7 @@ async fn test_instance_watcher_metrics( let client = &cptestctx.external_client; let internal_client = &cptestctx.internal_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; // TODO(eliza): consider factoring this out to a generic // `activate_background_task` function in `nexus-test-utils` eventually? @@ -445,7 +445,7 @@ async fn test_instance_watcher_metrics( // Wait until Nexus registers as a producer with Oximeter. wait_for_producer( &cptestctx.oximeter, - cptestctx.server.apictx().nexus.id(), + cptestctx.server.server_context().nexus.id(), ) .await; diff --git a/nexus/tests/integration_tests/pantry.rs b/nexus/tests/integration_tests/pantry.rs index 1a3908affa..c5d98709ac 100644 --- a/nexus/tests/integration_tests/pantry.rs +++ b/nexus/tests/integration_tests/pantry.rs @@ -393,7 +393,7 @@ async fn test_cannot_mount_import_ready_disk( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; DiskTest::new(&cptestctx).await; create_project_and_pool(client).await; @@ -424,7 +424,7 @@ async fn test_cannot_mount_import_from_bulk_writes_disk( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; DiskTest::new(&cptestctx).await; create_project_and_pool(client).await; @@ -448,7 +448,7 @@ async fn test_import_blocks_with_bulk_write( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; DiskTest::new(&cptestctx).await; create_project_and_pool(client).await; @@ -489,7 +489,7 @@ async fn test_import_blocks_with_bulk_write_with_snapshot( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; DiskTest::new(&cptestctx).await; create_project_and_pool(client).await; @@ -732,7 +732,7 @@ async fn test_cannot_bulk_write_start_attached_disk( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; DiskTest::new(&cptestctx).await; create_project_and_pool(client).await; @@ -762,7 +762,7 @@ async fn test_cannot_bulk_write_attached_disk( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; DiskTest::new(&cptestctx).await; create_project_and_pool(client).await; @@ -792,7 +792,7 @@ async fn test_cannot_bulk_write_stop_attached_disk( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; DiskTest::new(&cptestctx).await; create_project_and_pool(client).await; @@ -821,7 +821,7 @@ async fn test_cannot_finalize_attached_disk( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; DiskTest::new(&cptestctx).await; create_project_and_pool(client).await; diff --git a/nexus/tests/integration_tests/rack.rs b/nexus/tests/integration_tests/rack.rs index a6c218cea8..a7ebf0f8b6 100644 --- a/nexus/tests/integration_tests/rack.rs +++ b/nexus/tests/integration_tests/rack.rs @@ -35,14 +35,17 @@ async fn test_list_own_rack(cptestctx: &ControlPlaneTestContext) { .all_items; assert_eq!(1, racks.len()); - assert_eq!(cptestctx.server.apictx().nexus.rack_id(), racks[0].identity.id); + assert_eq!( + cptestctx.server.server_context().nexus.rack_id(), + racks[0].identity.id + ); } #[nexus_test] async fn test_get_own_rack(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let expected_id = cptestctx.server.apictx().nexus.rack_id(); + let expected_id = cptestctx.server.server_context().nexus.rack_id(); let rack_url = format!("/v1/system/hardware/racks/{}", expected_id); let rack = NexusRequest::object_get(client, &rack_url) .authn_as(AuthnMode::PrivilegedUser) diff --git a/nexus/tests/integration_tests/saml.rs b/nexus/tests/integration_tests/saml.rs index b1b0429c2e..80816f2ea2 100644 --- a/nexus/tests/integration_tests/saml.rs +++ b/nexus/tests/integration_tests/saml.rs @@ -91,7 +91,7 @@ async fn test_create_a_saml_idp(cptestctx: &ControlPlaneTestContext) { .await; // Assert external authenticator opctx can read it - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let (.., _retrieved_silo_nexus) = nexus .silo_lookup( &nexus.opctx_external_authn(), @@ -1167,7 +1167,7 @@ async fn test_post_saml_response(cptestctx: &ControlPlaneTestContext) { ) .await; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; nexus.set_samael_max_issue_delay( chrono::Utc::now() - "2022-05-04T15:36:12.631Z" @@ -1298,7 +1298,7 @@ async fn test_post_saml_response_with_relay_state( ) .await; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; nexus.set_samael_max_issue_delay( chrono::Utc::now() - "2022-05-04T15:36:12.631Z" diff --git a/nexus/tests/integration_tests/silo_users.rs b/nexus/tests/integration_tests/silo_users.rs index 099a186a2c..598d2a28a4 100644 --- a/nexus/tests/integration_tests/silo_users.rs +++ b/nexus/tests/integration_tests/silo_users.rs @@ -26,10 +26,10 @@ type ControlPlaneTestContext = #[nexus_test] async fn test_silo_group_users(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let opctx = OpContext::for_tests( cptestctx.logctx.log.new(o!()), - cptestctx.server.apictx().nexus.datastore().clone(), + cptestctx.server.server_context().nexus.datastore().clone(), ); // we start out with the two default users diff --git a/nexus/tests/integration_tests/silos.rs b/nexus/tests/integration_tests/silos.rs index 6dfddb12e1..e95b2870ca 100644 --- a/nexus/tests/integration_tests/silos.rs +++ b/nexus/tests/integration_tests/silos.rs @@ -55,7 +55,7 @@ type ControlPlaneTestContext = #[nexus_test] async fn test_silos(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; // Verify that we cannot create a name with the same name as the recovery // Silo that was created during rack initialization. @@ -277,7 +277,7 @@ async fn test_silos(cptestctx: &ControlPlaneTestContext) { #[nexus_test] async fn test_silo_admin_group(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let silo: Silo = object_create( client, @@ -523,7 +523,7 @@ async fn test_deleting_a_silo_deletes_the_idp( .expect("failed to make request"); // Expect that the silo is gone - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let response = IdentityProviderType::lookup( &nexus.datastore(), @@ -747,7 +747,7 @@ struct TestSiloUserProvisionTypes { #[nexus_test] async fn test_silo_user_provision_types(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let test_cases: Vec = vec![ @@ -844,7 +844,7 @@ async fn test_silo_user_fetch_by_external_id( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let silo = create_silo( &client, @@ -1026,7 +1026,7 @@ async fn test_silo_users_list(cptestctx: &ControlPlaneTestContext) { #[nexus_test] async fn test_silo_groups_jit(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let silo = create_silo( @@ -1095,7 +1095,7 @@ async fn test_silo_groups_jit(cptestctx: &ControlPlaneTestContext) { #[nexus_test] async fn test_silo_groups_fixed(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let silo = create_silo( &client, @@ -1156,7 +1156,7 @@ async fn test_silo_groups_remove_from_one_group( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let silo = create_silo( @@ -1269,7 +1269,7 @@ async fn test_silo_groups_remove_from_both_groups( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let silo = create_silo( @@ -1381,7 +1381,7 @@ async fn test_silo_groups_remove_from_both_groups( #[nexus_test] async fn test_silo_delete_clean_up_groups(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; // Create a silo let silo = create_silo( @@ -1463,7 +1463,7 @@ async fn test_silo_delete_clean_up_groups(cptestctx: &ControlPlaneTestContext) { #[nexus_test] async fn test_ensure_same_silo_group(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; // Create a silo let silo = create_silo( @@ -1525,7 +1525,7 @@ async fn test_ensure_same_silo_group(cptestctx: &ControlPlaneTestContext) { #[nexus_test] async fn test_silo_user_views(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let datastore = cptestctx.server.apictx().nexus.datastore(); + let datastore = cptestctx.server.server_context().nexus.datastore(); // Create the two Silos. let silo1 = @@ -1741,7 +1741,7 @@ async fn create_jit_user( #[nexus_test] async fn test_jit_silo_constraints(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let silo = create_silo(&client, "jit", true, shared::SiloIdentityMode::SamlJit) diff --git a/nexus/tests/integration_tests/sleds.rs b/nexus/tests/integration_tests/sleds.rs index bf1e2e4b99..97dbb39bc6 100644 --- a/nexus/tests/integration_tests/sleds.rs +++ b/nexus/tests/integration_tests/sleds.rs @@ -106,7 +106,7 @@ async fn test_physical_disk_create_list_delete( let disks_initial = physical_disks_list(&external_client, &disks_url).await; // Inject a disk into the database, observe it in the external API - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let sled_id = Uuid::from_str(&SLED_AGENT_UUID).unwrap(); let physical_disk = DbPhysicalDisk::new( diff --git a/nexus/tests/integration_tests/snapshots.rs b/nexus/tests/integration_tests/snapshots.rs index 058c59a501..3fb6f8f6ec 100644 --- a/nexus/tests/integration_tests/snapshots.rs +++ b/nexus/tests/integration_tests/snapshots.rs @@ -136,7 +136,7 @@ async fn test_snapshot_basic(cptestctx: &ControlPlaneTestContext) { .await; // cannot snapshot attached disk for instance in state starting - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; instance_simulate(nexus, &instance.identity.id).await; // Issue snapshot request @@ -362,7 +362,7 @@ async fn test_snapshot_stopped_instance(cptestctx: &ControlPlaneTestContext) { #[nexus_test] async fn test_delete_snapshot(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); DiskTest::new(&cptestctx).await; let project_id = create_project_and_pool(client).await; @@ -521,7 +521,7 @@ async fn test_reject_creating_disk_from_snapshot( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let project_id = create_project_and_pool(&client).await; @@ -674,7 +674,7 @@ async fn test_reject_creating_disk_from_illegal_snapshot( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let project_id = create_project_and_pool(&client).await; @@ -770,7 +770,7 @@ async fn test_reject_creating_disk_from_other_project_snapshot( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let project_id = create_project_and_pool(&client).await; @@ -1002,7 +1002,7 @@ async fn test_create_snapshot_record_idempotent( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let project_id = create_project_and_pool(&client).await; @@ -1194,7 +1194,7 @@ async fn test_create_snapshot_record_idempotent( async fn test_region_snapshot_create_idempotent( cptestctx: &ControlPlaneTestContext, ) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let region_snapshot = db::model::RegionSnapshot { @@ -1218,7 +1218,7 @@ async fn test_region_snapshot_create_idempotent( #[nexus_test] async fn test_multiple_deletes_not_sent(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); DiskTest::new(&cptestctx).await; let _project_id = create_project_and_pool(client).await; diff --git a/nexus/tests/integration_tests/subnet_allocation.rs b/nexus/tests/integration_tests/subnet_allocation.rs index d9d015bf26..0efc659890 100644 --- a/nexus/tests/integration_tests/subnet_allocation.rs +++ b/nexus/tests/integration_tests/subnet_allocation.rs @@ -91,8 +91,12 @@ async fn test_subnet_allocation(cptestctx: &ControlPlaneTestContext) { // Create a new, small VPC Subnet, so we don't need to issue many requests // to test address exhaustion. - let subnet_size = - cptestctx.server.apictx().nexus.tunables().max_vpc_ipv4_subnet_prefix; + let subnet_size = cptestctx + .server + .server_context() + .nexus + .tunables() + .max_vpc_ipv4_subnet_prefix; let vpc_selector = format!("project={}&vpc=default", project_name); let subnets_url = format!("/v1/vpc-subnets?{}", vpc_selector); let subnet_name = "small"; diff --git a/nexus/tests/integration_tests/volume_management.rs b/nexus/tests/integration_tests/volume_management.rs index ecfa7cf0f1..ae348e775d 100644 --- a/nexus/tests/integration_tests/volume_management.rs +++ b/nexus/tests/integration_tests/volume_management.rs @@ -1351,7 +1351,7 @@ async fn test_volume_remove_read_only_parent_base( ) { // Test the removal of a volume with a read only parent. // The ROP should end up on the t_vid volume. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let volume_id = Uuid::new_v4(); @@ -1465,7 +1465,7 @@ async fn test_volume_remove_read_only_parent_no_parent( ) { // Test the removal of a read only parent from a volume // without a read only parent. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let volume_id = Uuid::new_v4(); @@ -1483,7 +1483,7 @@ async fn test_volume_remove_read_only_parent_volume_not_volume( ) { // test removal of a read only volume for a volume that is not // of a type to have a read only parent. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let volume_id = Uuid::new_v4(); @@ -1512,7 +1512,7 @@ async fn test_volume_remove_read_only_parent_bad_volume( ) { // Test the removal of a read only parent from a volume // that does not exist - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let volume_id = Uuid::new_v4(); @@ -1528,7 +1528,7 @@ async fn test_volume_remove_read_only_parent_volume_deleted( cptestctx: &ControlPlaneTestContext, ) { // Test the removal of a read_only_parent from a deleted volume. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let volume_id = Uuid::new_v4(); let block_size = 512; @@ -1558,7 +1558,7 @@ async fn test_volume_remove_read_only_parent_volume_deleted( async fn test_volume_remove_rop_saga(cptestctx: &ControlPlaneTestContext) { // Test the saga for removal of a volume with a read only parent. // We create a volume with a read only parent, then call the saga on it. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let volume_id = Uuid::new_v4(); @@ -1621,7 +1621,7 @@ async fn test_volume_remove_rop_saga_twice( // Test calling the saga for removal of a volume with a read only parent // two times, the first will remove the read_only_parent, the second will // do nothing. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let volume_id = Uuid::new_v4(); @@ -1720,7 +1720,7 @@ async fn test_volume_remove_rop_saga_volume_not_volume( ) { // Test saga removal of a read only volume for a volume that is not // of a type to have a read only parent. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let volume_id = Uuid::new_v4(); let datastore = nexus.datastore(); @@ -1759,7 +1759,7 @@ async fn test_volume_remove_rop_saga_deleted_volume( ) { // Test that a saga removal of a read_only_parent from a deleted volume // takes no action on that deleted volume. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let volume_id = Uuid::new_v4(); let block_size = 512; @@ -1823,7 +1823,7 @@ async fn test_volume_remove_rop_saga_deleted_volume( async fn test_volume_checkout(cptestctx: &ControlPlaneTestContext) { // Verify that a volume_checkout will update the generation number in the // database when the volume type is Volume with sub_volume Region. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let volume_id = Uuid::new_v4(); let block_size = 512; @@ -1874,7 +1874,7 @@ async fn test_volume_checkout_updates_nothing( ) { // Verify that a volume_checkout will do nothing for a volume that does // not contain a sub_volume with a generation field. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let volume_id = Uuid::new_v4(); let block_size = 512; @@ -1927,7 +1927,7 @@ async fn test_volume_checkout_updates_multiple_gen( // Verify that a volume_checkout will update the generation number in the // database when the volume type is Volume with multiple sub_volumes of // type Region. - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let volume_id = Uuid::new_v4(); let block_size = 512; @@ -1993,7 +1993,7 @@ async fn test_volume_checkout_updates_sparse_multiple_gen( // database when the volume type is Volume with multiple sub_volumes of // type Region and also verify that a non generation sub_volume won't be a // problem - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let volume_id = Uuid::new_v4(); let block_size = 512; @@ -2054,7 +2054,7 @@ async fn test_volume_checkout_updates_sparse_mid_multiple_gen( // database when the volume type is Volume with multiple sub_volumes of // type Region and also verify that a non generation sub_volume in the // middle of the sub_volumes won't be a problem - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let volume_id = Uuid::new_v4(); let block_size = 512; @@ -2113,7 +2113,7 @@ async fn test_volume_checkout_randomize_ids_only_read_only( ) { // Verify that a volume_checkout_randomize_ids will not work for // non-read-only Regions - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let volume_id = Uuid::new_v4(); let block_size = 512; @@ -2155,7 +2155,7 @@ async fn test_volume_checkout_randomize_ids_only_read_only( /// `[ipv6]:port` targets being reused. #[nexus_test] async fn test_keep_your_targets_straight(cptestctx: &ControlPlaneTestContext) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); // Four zpools, one dataset each @@ -2646,7 +2646,7 @@ fn volume_match_gen( async fn test_volume_hard_delete_idempotent( cptestctx: &ControlPlaneTestContext, ) { - let nexus = &cptestctx.server.apictx().nexus; + let nexus = &cptestctx.server.server_context().nexus; let datastore = nexus.datastore(); let volume_id = Uuid::new_v4(); diff --git a/nexus/tests/integration_tests/vpc_subnets.rs b/nexus/tests/integration_tests/vpc_subnets.rs index 76cff9ac79..0814512cf2 100644 --- a/nexus/tests/integration_tests/vpc_subnets.rs +++ b/nexus/tests/integration_tests/vpc_subnets.rs @@ -31,7 +31,7 @@ async fn test_delete_vpc_subnet_with_interfaces_fails( cptestctx: &ControlPlaneTestContext, ) { let client = &cptestctx.external_client; - let apictx = &cptestctx.server.apictx(); + let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; // Create a project that we'll use for testing.