From 16a32de3f24346d0c06e5206a44f6dedcc200a9b Mon Sep 17 00:00:00 2001 From: Rain Date: Fri, 18 Apr 2025 02:05:34 +0000 Subject: [PATCH 1/2] [spr] changes to main this commit is based on Created using spr 1.3.6-beta.1 [skip ci] --- Cargo.lock | 46 +++++ Cargo.toml | 6 + dev-tools/omdb/Cargo.toml | 2 + dev-tools/omdb/src/bin/omdb/db.rs | 4 +- dev-tools/omdb/src/bin/omdb/nexus.rs | 6 +- nexus/Cargo.toml | 1 + nexus/auth/src/authz/api_resources.rs | 2 +- nexus/db-errors/Cargo.toml | 15 ++ nexus/db-errors/src/lib.rs | 9 + nexus/db-errors/src/optional_error.rs | 70 ++++++++ .../src/transaction_error.rs} | 36 ++-- nexus/db-lookup/Cargo.toml | 38 +++++ nexus/db-lookup/build.rs | 10 ++ nexus/db-lookup/src/datastore_interface.rs | 47 +++++ nexus/db-lookup/src/lib.rs | 16 ++ .../src/db => db-lookup/src}/lookup.rs | 160 ++---------------- nexus/db-lookup/src/lookup_path.rs | 98 +++++++++++ nexus/db-lookup/tests/integration/lookup.rs | 41 +++++ nexus/db-lookup/tests/integration/main.rs | 10 ++ nexus/db-macros/outputs/project.txt | 14 +- nexus/db-macros/outputs/silo_user.txt | 8 +- nexus/db-macros/outputs/sled.txt | 8 +- nexus/db-macros/outputs/update_artifact.txt | 8 +- nexus/db-macros/src/lookup.rs | 15 +- nexus/db-queries/Cargo.toml | 2 + .../src/db/datastore/address_lot.rs | 8 +- nexus/db-queries/src/db/datastore/affinity.rs | 8 +- .../db-queries/src/db/datastore/allow_list.rs | 4 +- nexus/db-queries/src/db/datastore/auth.rs | 4 +- nexus/db-queries/src/db/datastore/bfd.rs | 4 +- nexus/db-queries/src/db/datastore/bgp.rs | 4 +- .../db-queries/src/db/datastore/bootstore.rs | 2 +- .../src/db/datastore/certificate.rs | 4 +- .../src/db/datastore/clickhouse_policy.rs | 4 +- .../src/db/datastore/cockroachdb_node_id.rs | 4 +- .../src/db/datastore/cockroachdb_settings.rs | 4 +- .../src/db/datastore/console_session.rs | 4 +- .../src/db/datastore/crucible_dataset.rs | 8 +- .../src/db/datastore/db_metadata.rs | 4 +- .../db-queries/src/db/datastore/deployment.rs | 8 +- .../src/db/datastore/device_auth.rs | 6 +- nexus/db-queries/src/db/datastore/disk.rs | 14 +- nexus/db-queries/src/db/datastore/dns.rs | 10 +- .../src/db/datastore/external_ip.rs | 10 +- .../src/db/datastore/identity_provider.rs | 6 +- nexus/db-queries/src/db/datastore/image.rs | 4 +- nexus/db-queries/src/db/datastore/instance.rs | 12 +- .../db-queries/src/db/datastore/inventory.rs | 6 +- nexus/db-queries/src/db/datastore/ip_pool.rs | 12 +- .../src/db/datastore/ipv4_nat_entry.rs | 4 +- nexus/db-queries/src/db/datastore/lldp.rs | 4 +- .../src/db/datastore/lookup_interface.rs | 19 +++ .../db-queries/src/db/datastore/migration.rs | 8 +- nexus/db-queries/src/db/datastore/mod.rs | 23 +-- .../src/db/datastore/network_interface.rs | 6 +- nexus/db-queries/src/db/datastore/oximeter.rs | 4 +- .../src/db/datastore/oximeter_read_policy.rs | 4 +- .../src/db/datastore/physical_disk.rs | 13 +- nexus/db-queries/src/db/datastore/probe.rs | 6 +- nexus/db-queries/src/db/datastore/project.rs | 8 +- nexus/db-queries/src/db/datastore/quota.rs | 4 +- nexus/db-queries/src/db/datastore/rack.rs | 16 +- nexus/db-queries/src/db/datastore/region.rs | 10 +- .../src/db/datastore/region_replacement.rs | 8 +- .../src/db/datastore/region_snapshot.rs | 4 +- .../datastore/region_snapshot_replacement.rs | 8 +- .../db/datastore/rendezvous_debug_dataset.rs | 4 +- nexus/db-queries/src/db/datastore/role.rs | 6 +- nexus/db-queries/src/db/datastore/saga.rs | 4 +- nexus/db-queries/src/db/datastore/silo.rs | 8 +- .../db-queries/src/db/datastore/silo_group.rs | 6 +- .../db-queries/src/db/datastore/silo_user.rs | 4 +- nexus/db-queries/src/db/datastore/sled.rs | 12 +- .../src/db/datastore/sled_instance.rs | 4 +- nexus/db-queries/src/db/datastore/snapshot.rs | 6 +- nexus/db-queries/src/db/datastore/ssh_key.rs | 4 +- .../src/db/datastore/support_bundle.rs | 8 +- nexus/db-queries/src/db/datastore/switch.rs | 4 +- .../src/db/datastore/switch_interface.rs | 6 +- .../src/db/datastore/switch_port.rs | 6 +- .../src/db/datastore/target_release.rs | 2 +- .../db-queries/src/db/datastore/test_utils.rs | 6 +- nexus/db-queries/src/db/datastore/update.rs | 4 +- .../src/db/datastore/utilization.rs | 4 +- .../src/db/datastore/v2p_mapping.rs | 2 +- .../virtual_provisioning_collection.rs | 8 +- nexus/db-queries/src/db/datastore/vmm.rs | 6 +- nexus/db-queries/src/db/datastore/volume.rs | 6 +- .../src/db/datastore/volume_repair.rs | 6 +- nexus/db-queries/src/db/datastore/vpc.rs | 30 ++-- nexus/db-queries/src/db/datastore/zpool.rs | 6 +- nexus/db-queries/src/db/mod.rs | 3 - .../src/db/pub_test_utils/helpers.rs | 2 +- .../db-queries/src/db/queries/external_ip.rs | 11 +- .../src/db/queries/network_interface.rs | 51 +++--- .../src/db/queries/region_allocation.rs | 7 +- .../virtual_provisioning_collection_update.rs | 7 +- nexus/db-queries/src/db/queries/vpc_subnet.rs | 20 ++- nexus/db-queries/src/transaction_retry.rs | 63 ------- nexus/networking/Cargo.toml | 1 + nexus/networking/src/firewall_rules.rs | 5 +- nexus/networking/src/sled_client.rs | 4 +- nexus/reconfigurator/execution/Cargo.toml | 1 + .../execution/src/sled_state.rs | 2 +- nexus/src/app/address_lot.rs | 4 +- nexus/src/app/affinity.rs | 4 +- .../tasks/instance_reincarnation.rs | 2 +- .../app/background/tasks/instance_updater.rs | 4 +- .../read_only_region_replacement_start.rs | 4 +- .../region_snapshot_replacement_start.rs | 4 +- .../background/tasks/sync_service_zone_nat.rs | 4 +- nexus/src/app/certificate.rs | 4 +- nexus/src/app/device_auth.rs | 2 +- nexus/src/app/disk.rs | 4 +- nexus/src/app/external_ip.rs | 4 +- nexus/src/app/iam.rs | 3 +- nexus/src/app/image.rs | 8 +- nexus/src/app/instance.rs | 6 +- nexus/src/app/instance_network.rs | 2 +- nexus/src/app/internet_gateway.rs | 4 +- nexus/src/app/ip_pool.rs | 4 +- nexus/src/app/metrics.rs | 6 +- nexus/src/app/mod.rs | 4 +- nexus/src/app/network_interface.rs | 3 +- nexus/src/app/probe.rs | 2 +- nexus/src/app/project.rs | 4 +- nexus/src/app/quota.rs | 2 +- nexus/src/app/rack.rs | 2 +- nexus/src/app/sagas/common_storage.rs | 4 +- nexus/src/app/sagas/disk_create.rs | 44 +++-- nexus/src/app/sagas/finalize_disk.rs | 14 +- nexus/src/app/sagas/image_create.rs | 12 +- nexus/src/app/sagas/instance_common.rs | 4 +- nexus/src/app/sagas/instance_create.rs | 41 +++-- nexus/src/app/sagas/instance_delete.rs | 20 +-- nexus/src/app/sagas/instance_ip_attach.rs | 2 +- nexus/src/app/sagas/instance_ip_detach.rs | 2 +- nexus/src/app/sagas/instance_migrate.rs | 5 +- nexus/src/app/sagas/instance_start.rs | 13 +- nexus/src/app/sagas/instance_update/mod.rs | 15 +- nexus/src/app/sagas/project_create.rs | 2 +- .../src/app/sagas/region_replacement_drive.rs | 13 +- .../src/app/sagas/region_replacement_start.rs | 9 +- .../region_snapshot_replacement_start.rs | 15 +- .../sagas/region_snapshot_replacement_step.rs | 6 +- nexus/src/app/sagas/snapshot_create.rs | 40 ++--- nexus/src/app/sagas/test_helpers.rs | 4 +- nexus/src/app/sagas/vpc_create.rs | 14 +- nexus/src/app/sagas/vpc_subnet_create.rs | 4 +- nexus/src/app/session.rs | 2 +- nexus/src/app/silo.rs | 7 +- nexus/src/app/sled.rs | 6 +- nexus/src/app/sled_instance.rs | 2 +- nexus/src/app/snapshot.rs | 4 +- nexus/src/app/ssh_key.rs | 9 +- nexus/src/app/support_bundles.rs | 2 +- nexus/src/app/switch.rs | 4 +- nexus/src/app/switch_interface.rs | 4 +- nexus/src/app/test_interfaces.rs | 2 +- nexus/src/app/utilization.rs | 2 +- nexus/src/app/vpc.rs | 4 +- nexus/src/app/vpc_router.rs | 4 +- nexus/src/app/vpc_subnet.rs | 4 +- nexus/src/context.rs | 2 +- nexus/src/external_api/http_entrypoints.rs | 4 +- .../crucible_replacements.rs | 26 +-- nexus/tests/integration_tests/disks.rs | 18 +- nexus/tests/integration_tests/instances.rs | 18 +- nexus/tests/integration_tests/silos.rs | 22 +-- nexus/tests/integration_tests/snapshots.rs | 26 +-- .../integration_tests/volume_management.rs | 46 ++--- nexus/tests/integration_tests/vpc_routers.rs | 4 +- 172 files changed, 1078 insertions(+), 831 deletions(-) create mode 100644 nexus/db-errors/Cargo.toml create mode 100644 nexus/db-errors/src/lib.rs create mode 100644 nexus/db-errors/src/optional_error.rs rename nexus/{db-queries/src/db/error.rs => db-errors/src/transaction_error.rs} (90%) create mode 100644 nexus/db-lookup/Cargo.toml create mode 100644 nexus/db-lookup/build.rs create mode 100644 nexus/db-lookup/src/datastore_interface.rs create mode 100644 nexus/db-lookup/src/lib.rs rename nexus/{db-queries/src/db => db-lookup/src}/lookup.rs (81%) create mode 100644 nexus/db-lookup/src/lookup_path.rs create mode 100644 nexus/db-lookup/tests/integration/lookup.rs create mode 100644 nexus/db-lookup/tests/integration/main.rs create mode 100644 nexus/db-queries/src/db/datastore/lookup_interface.rs diff --git a/Cargo.lock b/Cargo.lock index a7e9f54df5f..e454e00af9e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5914,6 +5914,17 @@ dependencies = [ "uuid", ] +[[package]] +name = "nexus-db-errors" +version = "0.1.0" +dependencies = [ + "diesel", + "nexus-auth", + "omicron-common", + "omicron-workspace-hack", + "thiserror 1.0.69", +] + [[package]] name = "nexus-db-fixed-data" version = "0.1.0" @@ -5928,6 +5939,34 @@ dependencies = [ "uuid", ] +[[package]] +name = "nexus-db-lookup" +version = "0.1.0" +dependencies = [ + "async-bb8-diesel", + "async-trait", + "db-macros", + "diesel", + "diesel-dtrace", + "ipnetwork", + "nexus-auth", + "nexus-db-errors", + "nexus-db-model", + "nexus-db-queries", + "nexus-db-schema", + "nexus-types", + "omicron-common", + "omicron-rpaths", + "omicron-test-utils", + "omicron-uuid-kinds", + "omicron-workspace-hack", + "pq-sys", + "qorb", + "slog", + "tokio", + "uuid", +] + [[package]] name = "nexus-db-model" version = "0.1.0" @@ -6007,7 +6046,9 @@ dependencies = [ "macaddr", "nexus-auth", "nexus-config", + "nexus-db-errors", "nexus-db-fixed-data", + "nexus-db-lookup", "nexus-db-model", "nexus-db-schema", "nexus-inventory", @@ -6221,6 +6262,7 @@ version = "0.1.0" dependencies = [ "futures", "ipnetwork", + "nexus-db-lookup", "nexus-db-queries", "omicron-common", "omicron-workspace-hack", @@ -6296,6 +6338,7 @@ dependencies = [ "ipnet", "newtype-uuid", "nexus-config", + "nexus-db-lookup", "nexus-db-model", "nexus-db-queries", "nexus-db-schema", @@ -7254,6 +7297,7 @@ dependencies = [ "nexus-auth", "nexus-client", "nexus-config", + "nexus-db-lookup", "nexus-db-model", "nexus-db-queries", "nexus-db-schema", @@ -7379,6 +7423,8 @@ dependencies = [ "multimap", "nexus-client", "nexus-config", + "nexus-db-errors", + "nexus-db-lookup", "nexus-db-model", "nexus-db-queries", "nexus-db-schema", diff --git a/Cargo.toml b/Cargo.toml index 876560386d2..3dd62b1b0f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -77,7 +77,9 @@ members = [ "nexus-sled-agent-shared", "nexus/authz-macros", "nexus/auth", + "nexus/db-errors", "nexus/db-fixed-data", + "nexus/db-lookup", "nexus/db-macros", "nexus/db-model", "nexus/db-queries", @@ -223,7 +225,9 @@ default-members = [ "nexus-sled-agent-shared", "nexus/authz-macros", "nexus/auth", + "nexus/db-errors", "nexus/db-fixed-data", + "nexus/db-lookup", "nexus/db-macros", "nexus/db-model", "nexus/db-queries", @@ -492,7 +496,9 @@ multimap = "0.10.0" nexus-auth = { path = "nexus/auth" } nexus-client = { path = "clients/nexus-client" } nexus-config = { path = "nexus-config" } +nexus-db-errors = { path = "nexus/db-errors" } nexus-db-fixed-data = { path = "nexus/db-fixed-data" } +nexus-db-lookup = { path = "nexus/db-lookup" } nexus-db-model = { path = "nexus/db-model" } nexus-db-queries = { path = "nexus/db-queries" } nexus-db-schema = { path = "nexus/db-schema" } diff --git a/dev-tools/omdb/Cargo.toml b/dev-tools/omdb/Cargo.toml index e605bd58300..f14e5156ed3 100644 --- a/dev-tools/omdb/Cargo.toml +++ b/dev-tools/omdb/Cargo.toml @@ -33,6 +33,8 @@ internal-dns-types.workspace = true itertools.workspace = true nexus-client.workspace = true nexus-config.workspace = true +nexus-db-errors.workspace = true +nexus-db-lookup.workspace = true nexus-db-model.workspace = true nexus-db-queries.workspace = true nexus-db-schema.workspace = true diff --git a/dev-tools/omdb/src/bin/omdb/db.rs b/dev-tools/omdb/src/bin/omdb/db.rs index 2e29cc41708..550eb82daed 100644 --- a/dev-tools/omdb/src/bin/omdb/db.rs +++ b/dev-tools/omdb/src/bin/omdb/db.rs @@ -56,6 +56,8 @@ use ipnetwork::IpNetwork; use itertools::Itertools; use nexus_config::PostgresConfigWithUrl; use nexus_config::RegionAllocationStrategy; +use nexus_db_errors::OptionalError; +use nexus_db_lookup::LookupPath; use nexus_db_model::CrucibleDataset; use nexus_db_model::Disk; use nexus_db_model::DnsGroup; @@ -113,13 +115,11 @@ use nexus_db_queries::db::datastore::SQL_BATCH_SIZE; use nexus_db_queries::db::datastore::VolumeCookedResult; use nexus_db_queries::db::datastore::read_only_resources_associated_with_volume; use nexus_db_queries::db::identity::Asset; -use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::db::model::ServiceKind; use nexus_db_queries::db::pagination::Paginator; use nexus_db_queries::db::pagination::paginated; use nexus_db_queries::db::queries::ALLOW_FULL_TABLE_SCAN_SQL; use nexus_db_queries::db::queries::region_allocation; -use nexus_db_queries::transaction_retry::OptionalError; use nexus_types::deployment::Blueprint; use nexus_types::deployment::BlueprintZoneDisposition; use nexus_types::deployment::BlueprintZoneType; diff --git a/dev-tools/omdb/src/bin/omdb/nexus.rs b/dev-tools/omdb/src/bin/omdb/nexus.rs index 3dd1d296505..bdba356f04d 100644 --- a/dev-tools/omdb/src/bin/omdb/nexus.rs +++ b/dev-tools/omdb/src/bin/omdb/nexus.rs @@ -35,8 +35,8 @@ use nexus_client::types::PhysicalDiskPath; use nexus_client::types::SagaState; use nexus_client::types::SledSelector; use nexus_client::types::UninitializedSledId; +use nexus_db_lookup::LookupPath; use nexus_db_queries::db::DataStore; -use nexus_db_queries::db::lookup::LookupPath; use nexus_inventory::now_db_precision; use nexus_saga_recovery::LastPass; use nexus_types::deployment::Blueprint; @@ -3167,7 +3167,7 @@ async fn cmd_nexus_sled_expunge_with_datastore( let opctx = &opctx; // First, we need to look up the sled so we know its serial number. - let (_authz_sled, sled) = LookupPath::new(opctx, &datastore) + let (_authz_sled, sled) = LookupPath::new(opctx, datastore) .sled_id(args.sled_id.into_untyped_uuid()) .fetch() .await @@ -3271,7 +3271,7 @@ async fn cmd_nexus_sled_expunge_disk_with_datastore( // First, we need to look up the disk so we can lookup identity information. let (_authz_physical_disk, physical_disk) = - LookupPath::new(opctx, &datastore) + LookupPath::new(opctx, datastore) .physical_disk(args.physical_disk_id) .fetch() .await diff --git a/nexus/Cargo.toml b/nexus/Cargo.toml index 0d6478790ab..eaac2386186 100644 --- a/nexus/Cargo.toml +++ b/nexus/Cargo.toml @@ -106,6 +106,7 @@ uuid.workspace = true nexus-auth.workspace = true nexus-defaults.workspace = true +nexus-db-lookup.workspace = true nexus-db-model.workspace = true nexus-db-queries.workspace = true nexus-db-schema.workspace = true diff --git a/nexus/auth/src/authz/api_resources.rs b/nexus/auth/src/authz/api_resources.rs index e833d1efcda..e6b3b3a6537 100644 --- a/nexus/auth/src/authz/api_resources.rs +++ b/nexus/auth/src/authz/api_resources.rs @@ -5,7 +5,7 @@ //! Authz types for resources in the API hierarchy //! //! The general pattern in Nexus for working with an object is to look it up -//! (see `nexus_db_queries::db::lookup::LookupPath`) and get back a so-called +//! (see `nexus_db_lookup::LookupPath`) and get back a so-called //! `authz` type. This type uniquely identifies the resource regardless of //! any other changes (e.g., name change or moving it to a different parent //! collection). The various datastore functions that modify API resources diff --git a/nexus/db-errors/Cargo.toml b/nexus/db-errors/Cargo.toml new file mode 100644 index 00000000000..a664288a4fc --- /dev/null +++ b/nexus/db-errors/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "nexus-db-errors" +version = "0.1.0" +edition = "2021" +license = "MPL-2.0" + +[lints] +workspace = true + +[dependencies] +diesel.workspace = true +nexus-auth.workspace = true +omicron-common.workspace = true +omicron-workspace-hack.workspace = true +thiserror.workspace = true diff --git a/nexus/db-errors/src/lib.rs b/nexus/db-errors/src/lib.rs new file mode 100644 index 00000000000..f6a50406cb4 --- /dev/null +++ b/nexus/db-errors/src/lib.rs @@ -0,0 +1,9 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +mod optional_error; +mod transaction_error; + +pub use optional_error::*; +pub use transaction_error::*; diff --git a/nexus/db-errors/src/optional_error.rs b/nexus/db-errors/src/optional_error.rs new file mode 100644 index 00000000000..0c894bfb629 --- /dev/null +++ b/nexus/db-errors/src/optional_error.rs @@ -0,0 +1,70 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +use diesel::result::Error as DieselError; +use std::sync::{Arc, Mutex}; + +/// Helper utility for passing non-retryable errors out-of-band from +/// transactions. +/// +/// Transactions prefer to act on the `diesel::result::Error` type, +/// but transaction users may want more meaningful error types. +/// This utility helps callers safely propagate back Diesel errors while +/// retaining auxiliary error info. +pub struct OptionalError(Arc>>); + +impl Clone for OptionalError { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl OptionalError { + #[expect(clippy::new_without_default)] // ehh Default isn't really logical here? + pub fn new() -> Self { + Self(Arc::new(Mutex::new(None))) + } + + /// Sets "Self" to the value of `error` and returns `DieselError::RollbackTransaction`. + pub fn bail(&self, err: E) -> DieselError { + (*self.0.lock().unwrap()).replace(err); + DieselError::RollbackTransaction + } + + /// If `diesel_error` is retryable, returns it without setting Self. + /// + /// Otherwise, sets "Self" to the value of `err`, and returns + /// `DieselError::RollbackTransaction`. + pub fn bail_retryable_or( + &self, + diesel_error: DieselError, + err: E, + ) -> DieselError { + self.bail_retryable_or_else(diesel_error, |_diesel_error| err) + } + + /// If `diesel_error` is retryable, returns it without setting Self. + /// + /// Otherwise, sets "Self" to the value of `f` applied to `diesel_err`, and + /// returns `DieselError::RollbackTransaction`. + pub fn bail_retryable_or_else( + &self, + diesel_error: DieselError, + f: F, + ) -> DieselError + where + F: FnOnce(DieselError) -> E, + { + if crate::retryable(&diesel_error) { + diesel_error + } else { + self.bail(f(diesel_error)) + } + } + + /// If "Self" was previously set to a non-retryable error, return it. + pub fn take(self) -> Option { + (*self.0.lock().unwrap()).take() + } +} diff --git a/nexus/db-queries/src/db/error.rs b/nexus/db-errors/src/transaction_error.rs similarity index 90% rename from nexus/db-queries/src/db/error.rs rename to nexus/db-errors/src/transaction_error.rs index 29607588a4c..15c9e738434 100644 --- a/nexus/db-queries/src/db/error.rs +++ b/nexus/db-errors/src/transaction_error.rs @@ -2,16 +2,17 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -//! Error handling and conversions. - -use crate::transaction_retry::OptionalError; -use diesel::result::DatabaseErrorInformation; -use diesel::result::DatabaseErrorKind as DieselErrorKind; -use diesel::result::Error as DieselError; +use diesel::result::{ + DatabaseErrorInformation, DatabaseErrorKind as DieselErrorKind, + Error as DieselError, +}; +use nexus_auth::authz; use omicron_common::api::external::{ Error as PublicError, LookupType, ResourceType, }; +use crate::OptionalError; + /// Wrapper around an error which may be returned from a Diesel transaction. #[derive(Debug, thiserror::Error)] pub enum TransactionError { @@ -33,11 +34,9 @@ pub fn retryable(error: &DieselError) -> bool { match error { DieselError::DatabaseError(kind, boxed_error_information) => match kind { - DieselErrorKind::SerializationFailure => { - return boxed_error_information - .message() - .starts_with("restart transaction"); - } + DieselErrorKind::SerializationFailure => boxed_error_information + .message() + .starts_with("restart transaction"), _ => false, }, _ => false, @@ -148,16 +147,15 @@ fn format_database_error( /// etc. pub enum ErrorHandler<'a> { /// The operation expected to fetch, update, or delete exactly one resource - /// identified by the [`crate::authz::ApiResource`]. - /// If that row is not found, an appropriate "Not Found" error will be - /// returned. - NotFoundByResource(&'a dyn crate::authz::ApiResource), + /// identified by the [`authz::ApiResource`]. If that row is not found, an + /// appropriate "Not Found" error will be returned. + NotFoundByResource(&'a dyn authz::ApiResource), /// The operation was attempting to lookup or update a resource. /// If that row is not found, an appropriate "Not Found" error will be /// returned. /// - /// NOTE: If you already have an [`crate::authz::ApiResource`] object, you - /// should use the [`ErrorHandler::NotFoundByResource`] variant instead. + /// NOTE: If you already have an [`authz::ApiResource`] object, you should + /// use the [`ErrorHandler::NotFoundByResource`] variant instead. /// Eventually, the only uses of this function should be in the DataStore /// functions that actually look up a record for the first time. NotFoundByLookup(ResourceType, LookupType), @@ -202,7 +200,7 @@ pub fn public_error_from_diesel( /// Converts a Diesel error to an external error, handling "NotFound" using /// `make_not_found_error`. -pub(crate) fn public_error_from_diesel_lookup( +pub fn public_error_from_diesel_lookup( error: DieselError, resource_type: ResourceType, lookup_type: &LookupType, @@ -227,7 +225,7 @@ pub(crate) fn public_error_from_diesel_lookup( /// Converts a Diesel error to an external error, when requested as /// part of a creation operation. -pub(crate) fn public_error_from_diesel_create( +pub fn public_error_from_diesel_create( error: DieselError, resource_type: ResourceType, object_name: &str, diff --git a/nexus/db-lookup/Cargo.toml b/nexus/db-lookup/Cargo.toml new file mode 100644 index 00000000000..bd9bf43e215 --- /dev/null +++ b/nexus/db-lookup/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "nexus-db-lookup" +version = "0.1.0" +edition = "2021" +license = "MPL-2.0" + +[lints] +workspace = true + +[build-dependencies] +omicron-rpaths.workspace = true + +[dependencies] +async-bb8-diesel.workspace = true +async-trait.workspace = true +db-macros.workspace = true +diesel.workspace = true +diesel-dtrace.workspace = true +nexus-auth.workspace = true +nexus-db-errors.workspace = true +nexus-db-model.workspace = true +nexus-db-schema.workspace = true +nexus-types.workspace = true +ipnetwork.workspace = true +omicron-common.workspace = true +omicron-uuid-kinds.workspace = true +omicron-workspace-hack.workspace = true +# See omicron-rpaths for more about the "pq-sys" dependency. +pq-sys = "*" +qorb.workspace = true +slog.workspace = true +tokio.workspace = true +uuid.workspace = true + +[dev-dependencies] +nexus-db-queries = { workspace = true, features = ["testing"] } +omicron-test-utils.workspace = true +tokio.workspace = true diff --git a/nexus/db-lookup/build.rs b/nexus/db-lookup/build.rs new file mode 100644 index 00000000000..1ba9acd41c9 --- /dev/null +++ b/nexus/db-lookup/build.rs @@ -0,0 +1,10 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// See omicron-rpaths for documentation. +// NOTE: This file MUST be kept in sync with the other build.rs files in this +// repository. +fn main() { + omicron_rpaths::configure_default_omicron_rpaths(); +} diff --git a/nexus/db-lookup/src/datastore_interface.rs b/nexus/db-lookup/src/datastore_interface.rs new file mode 100644 index 00000000000..8945bc6905a --- /dev/null +++ b/nexus/db-lookup/src/datastore_interface.rs @@ -0,0 +1,47 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +use std::sync::Arc; + +use diesel::PgConnection; +use diesel_dtrace::DTraceConnection; +use nexus_auth::context::OpContext; +use omicron_common::api::external::Error; + +/// The interface between lookups and the Nexus datastore. +#[async_trait::async_trait] +pub trait LookupDataStore: Send + Sync { + async fn pool_connection_authorized( + &self, + opctx: &OpContext, + ) -> Result; +} + +// Define `From` impls for a couple of types to allow easier coercions from +// `&Arc` and `&T` in `LookupPath::new`. +// +// `AsRef` doesn't work due to lifetime constraints. +impl<'a, D> From<&'a D> for &'a dyn LookupDataStore +where + D: 'a + LookupDataStore, +{ + #[inline] + fn from(datastore: &'a D) -> &'a dyn LookupDataStore { + datastore + } +} + +impl<'a, D> From<&'a Arc> for &'a dyn LookupDataStore +where + D: 'a + LookupDataStore, +{ + fn from(datastore: &'a Arc) -> &'a dyn LookupDataStore { + &**datastore + } +} + +// These are duplicated from nexus-db-queries for now. +pub type DbConnection = DTraceConnection; +pub type DataStoreConnection = + qorb::claim::Handle>; diff --git a/nexus/db-lookup/src/lib.rs b/nexus/db-lookup/src/lib.rs new file mode 100644 index 00000000000..79059a7176d --- /dev/null +++ b/nexus/db-lookup/src/lib.rs @@ -0,0 +1,16 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +//! Types to look up entries in the Nexus database by their primary key. +//! +//! This crate does not depend on the Nexus datastore directly. Rather, it +//! exposes a generic trait that the datastore implements so that more of the +//! build process can be parallelized in the future. + +mod datastore_interface; +pub mod lookup; +mod lookup_path; + +pub use datastore_interface::*; +pub use lookup_path::*; diff --git a/nexus/db-queries/src/db/lookup.rs b/nexus/db-lookup/src/lookup.rs similarity index 81% rename from nexus/db-queries/src/db/lookup.rs rename to nexus/db-lookup/src/lookup.rs index 43ba9e9a02f..c1edfe01c19 100644 --- a/nexus/db-queries/src/db/lookup.rs +++ b/nexus/db-lookup/src/lookup.rs @@ -2,21 +2,27 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -//! Look up API resources from the database - -use super::datastore::DataStore; -use super::identity::Asset; -use super::identity::Resource; -use crate::{ - authz, - context::OpContext, - db::error::{ErrorHandler, public_error_from_diesel}, -}; +//! Defines the specific builder types for each resource. +//! +//! The `lookup_resource` macro defines a struct for the resource, helper +//! functions for selecting child resources, and the publicly-exposed fetch +//! functions (fetch(), fetch_for(), and lookup_for()). +//! +//! This module is called `lookup` rather than something like `resource` so +//! callers can customarily refer to types in here via `lookup::Instance`, +//! `lookup::Project` etc without needing to say `use nexus_db_lookup::resource +//! as lookup`. + use async_bb8_diesel::AsyncRunQueryDsl; use db_macros::lookup_resource; use diesel::{ExpressionMethods, QueryDsl, SelectableHelper}; use ipnetwork::IpNetwork; +use nexus_auth::authz; +use nexus_auth::context::OpContext; +use nexus_db_errors::{ErrorHandler, public_error_from_diesel}; use nexus_db_model::Name; +use nexus_types::identity::Asset; +use nexus_types::identity::Resource; use omicron_common::api::external::Error; use omicron_common::api::external::InternalContext; use omicron_common::api::external::{LookupResult, LookupType, ResourceType}; @@ -25,94 +31,12 @@ use omicron_uuid_kinds::SupportBundleUuid; use omicron_uuid_kinds::TufArtifactKind; use omicron_uuid_kinds::TufRepoKind; use omicron_uuid_kinds::TypedUuid; +use slog::{error, trace}; use uuid::Uuid; -/// Look up an API resource in the database -/// -/// `LookupPath` provides a builder-like interface for identifying a resource by -/// id or a path of names. Once you've selected a resource, you can use one of -/// a few different functions to get information about it from the database: -/// -/// * `fetch()`: fetches the database record and `authz` objects for all parents -/// in the path to this object. This function checks that the caller has -/// permission to `authz::Action::Read` the resoure. -/// * `fetch_for(authz::Action)`: like `fetch()`, but allows you to specify some -/// other action that will be checked rather than `authz::Action::Read`. -/// * `lookup_for(authz::Action)`: fetch just the `authz` objects for a resource -/// and its parents. This function checks that the caller has permissions to -/// perform the specified action. -// Implementation notes -// -// We say that a caller using `LookupPath` is building a _selection path_ for a -// resource. They use this builder interface to _select_ a specific resource. -// Example selection paths: -// -// - From the root, select Project with name "proj1", then Instance with name -// "instance1". -// -// - From the root, select Project with id 123, then Instance "instance1". -// -// A selection path always starts at the root, then _may_ contain a lookup-by-id -// node, and then _may_ contain any number of lookup-by-name nodes. It must -// include at least one lookup-by-id or lookup-by-name node. -// -// Once constructed, it looks like this: -// -// Instance::Name(p, "instance1") -// | -// +----------+ -// | -// v -// Project::Name(o, "proj") -// | -// +-----+ -// | -// v -// Silo::PrimaryKey(r, id) -// | -// +------------+ -// | -// v -// Root -// lookup_root: LookupPath (references OpContext and -// DataStore) -// -// This is essentially a singly-linked list, except that each node _owns_ -// (rather than references) the previous node. This is important: the caller's -// going to do something like this: -// -// let (authz_silo, authz_org, authz_project, authz_instance, db_instance) = -// LookupPath::new(opctx, datastore) // returns LookupPath -// .project_name("proj1") // consumes LookupPath, -// returns Project -// .instance_name("instance1") // consumes Project, -// returns Instance -// .fetch().await?; -// -// As you can see, at each step, a selection function (like "project_name") -// consumes the current tail of the list and returns a new tail. We don't want -// the caller to have to keep track of multiple objects, so that implies that -// the tail must own all the state that we're building up as we go. -pub struct LookupPath<'a> { - opctx: &'a OpContext, - datastore: &'a DataStore, -} +use crate::{LookupDataStore, LookupPath}; impl<'a> LookupPath<'a> { - /// Begin selecting a resource for lookup - /// - /// Authorization checks will be applied to the caller in `opctx`. - pub fn new<'b, 'c>( - opctx: &'b OpContext, - datastore: &'c DataStore, - ) -> LookupPath<'a> - where - 'b: 'a, - 'c: 'a, - { - LookupPath { opctx, datastore } - } - // The top-level selection functions are implemented by hand because the // macro is not in a great position to do this. @@ -565,11 +489,6 @@ impl<'a> Root<'a> { } } -// Define the specific builder types for each resource. The `lookup_resource` -// macro defines a struct for the resource, helper functions for selecting child -// resources, and the publicly-exposed fetch functions (fetch(), fetch_for(), -// and lookup_for()). - // Main resource hierarchy: Organizations, Projects, and their resources lookup_resource! { @@ -943,46 +862,3 @@ pub enum ImageParentLookup<'a> { Project(Project<'a>), Silo(Silo<'a>), } - -#[cfg(test)] -mod test { - use super::Instance; - use super::LookupPath; - use super::Project; - use crate::db::model::Name; - use crate::db::pub_test_utils::TestDatabase; - use omicron_test_utils::dev; - - /* This is a smoke test that things basically appear to work. */ - #[tokio::test] - async fn test_lookup() { - let logctx = dev::test_setup_log("test_lookup"); - let db = TestDatabase::new_with_datastore(&logctx.log).await; - let (opctx, datastore) = (db.opctx(), db.datastore()); - let project_name: Name = Name("my-project".parse().unwrap()); - let instance_name: Name = Name("my-instance".parse().unwrap()); - - let leaf = LookupPath::new(&opctx, &datastore) - .project_name(&project_name) - .instance_name(&instance_name); - assert!(matches!(&leaf, - Instance::Name(Project::Name(_, p), i) - if **p == project_name && **i == instance_name)); - - let leaf = - LookupPath::new(&opctx, &datastore).project_name(&project_name); - assert!(matches!(&leaf, - Project::Name(_, p) - if **p == project_name)); - - let project_id = - "006f29d9-0ff0-e2d2-a022-87e152440122".parse().unwrap(); - let leaf = LookupPath::new(&opctx, &datastore).project_id(project_id); - assert!(matches!(&leaf, - Project::PrimaryKey(_, p) - if *p == project_id)); - - db.terminate().await; - logctx.cleanup_successful(); - } -} diff --git a/nexus/db-lookup/src/lookup_path.rs b/nexus/db-lookup/src/lookup_path.rs new file mode 100644 index 00000000000..00725fab476 --- /dev/null +++ b/nexus/db-lookup/src/lookup_path.rs @@ -0,0 +1,98 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +//! Look up API resources from the database + +use nexus_auth::context::OpContext; + +use crate::LookupDataStore; + +/// Look up an API resource in the database +/// +/// `LookupPath` provides a builder-like interface for identifying a resource by +/// id or a path of names. Once you've selected a resource, you can use one of +/// a few different functions to get information about it from the database: +/// +/// * `fetch()`: fetches the database record and `authz` objects for all parents +/// in the path to this object. This function checks that the caller has +/// permission to `authz::Action::Read` the resoure. +/// * `fetch_for(authz::Action)`: like `fetch()`, but allows you to specify some +/// other action that will be checked rather than `authz::Action::Read`. +/// * `lookup_for(authz::Action)`: fetch just the `authz` objects for a resource +/// and its parents. This function checks that the caller has permissions to +/// perform the specified action. +// Implementation notes +// +// We say that a caller using `LookupPath` is building a _selection path_ for a +// resource. They use this builder interface to _select_ a specific resource. +// Example selection paths: +// +// - From the root, select Project with name "proj1", then Instance with name +// "instance1". +// +// - From the root, select Project with id 123, then Instance "instance1". +// +// A selection path always starts at the root, then _may_ contain a lookup-by-id +// node, and then _may_ contain any number of lookup-by-name nodes. It must +// include at least one lookup-by-id or lookup-by-name node. +// +// Once constructed, it looks like this: +// +// Instance::Name(p, "instance1") +// | +// +----------+ +// | +// v +// Project::Name(o, "proj") +// | +// +-----+ +// | +// v +// Silo::PrimaryKey(r, id) +// | +// +------------+ +// | +// v +// Root +// lookup_root: LookupPath (references OpContext and +// DataStore) +// +// This is essentially a singly-linked list, except that each node _owns_ +// (rather than references) the previous node. This is important: the caller's +// going to do something like this: +// +// let (authz_silo, authz_org, authz_project, authz_instance, db_instance) = +// LookupPath::new(opctx, datastore) // returns LookupPath +// .project_name("proj1") // consumes LookupPath, +// returns Project +// .instance_name("instance1") // consumes Project, +// returns Instance +// .fetch().await?; +// +// As you can see, at each step, a selection function (like "project_name") +// consumes the current tail of the list and returns a new tail. We don't want +// the caller to have to keep track of multiple objects, so that implies that +// the tail must own all the state that we're building up as we go. +pub struct LookupPath<'a> { + pub(crate) opctx: &'a OpContext, + pub(crate) datastore: &'a dyn LookupDataStore, +} + +impl<'a> LookupPath<'a> { + /// Begin selecting a resource for lookup + /// + /// Authorization checks will be applied to the caller in `opctx`. + /// + /// `datastore` is generic to allow a variety of input types to be passed in + /// (particularly `&T` and `&Arc`). If we just accepted `&'a dyn + /// LookupDataStore`, callers with a `&Arc` would have to write + /// `&**datastore`, which is somewhat ugly. + pub fn new(opctx: &'a OpContext, datastore: D) -> LookupPath<'a> + where + D: Into<&'a dyn LookupDataStore>, + { + let datastore = datastore.into(); + LookupPath { opctx, datastore } + } +} diff --git a/nexus/db-lookup/tests/integration/lookup.rs b/nexus/db-lookup/tests/integration/lookup.rs new file mode 100644 index 00000000000..97a9cb88b44 --- /dev/null +++ b/nexus/db-lookup/tests/integration/lookup.rs @@ -0,0 +1,41 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup::Instance; +use nexus_db_lookup::lookup::Project; +use nexus_db_model::Name; +use nexus_db_queries::db::pub_test_utils::TestDatabase; +use omicron_test_utils::dev; + +/* This is a smoke test that things basically appear to work. */ +#[tokio::test] +async fn test_lookup() { + let logctx = dev::test_setup_log("test_lookup"); + let db = TestDatabase::new_with_datastore(&logctx.log).await; + let (opctx, datastore) = (db.opctx(), db.datastore()); + let project_name: Name = Name("my-project".parse().unwrap()); + let instance_name: Name = Name("my-instance".parse().unwrap()); + + let leaf = LookupPath::new(&opctx, datastore) + .project_name(&project_name) + .instance_name(&instance_name); + assert!(matches!(&leaf, + Instance::Name(Project::Name(_, p), i) + if **p == project_name && **i == instance_name)); + + let leaf = LookupPath::new(&opctx, datastore).project_name(&project_name); + assert!(matches!(&leaf, + Project::Name(_, p) + if **p == project_name)); + + let project_id = "006f29d9-0ff0-e2d2-a022-87e152440122".parse().unwrap(); + let leaf = LookupPath::new(&opctx, datastore).project_id(project_id); + assert!(matches!(&leaf, + Project::PrimaryKey(_, p) + if *p == project_id)); + + db.terminate().await; + logctx.cleanup_successful(); +} diff --git a/nexus/db-lookup/tests/integration/main.rs b/nexus/db-lookup/tests/integration/main.rs new file mode 100644 index 00000000000..69f9c891195 --- /dev/null +++ b/nexus/db-lookup/tests/integration/main.rs @@ -0,0 +1,10 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +//! Integration tests for nexus-db-lookup. +//! +//! Note: all integration tests for a crate live in a single binary for build +//! speed reasons. + +mod lookup; diff --git a/nexus/db-macros/outputs/project.txt b/nexus/db-macros/outputs/project.txt index 25f9c370509..490f0606a4d 100644 --- a/nexus/db-macros/outputs/project.txt +++ b/nexus/db-macros/outputs/project.txt @@ -44,7 +44,7 @@ impl<'a> Project<'a> { ) -> LookupResult<(authz::Silo, authz::Project, nexus_db_model::Project)> { let lookup = self.lookup_root(); let opctx = &lookup.opctx; - let datastore = &lookup.datastore; + let datastore = lookup.datastore; match &self { Project::Error(_, error) => Err(error.clone()), Project::Name(parent, &ref name) | Project::OwnedName(parent, ref name) => { @@ -124,7 +124,7 @@ impl<'a> Project<'a> { async fn lookup(&self) -> LookupResult<(authz::Silo, authz::Project)> { let lookup = self.lookup_root(); let opctx = &lookup.opctx; - let datastore = &lookup.datastore; + let datastore = lookup.datastore; match &self { Project::Error(_, error) => Err(error.clone()), Project::Name(parent, &ref name) | Project::OwnedName(parent, ref name) => { @@ -223,7 +223,7 @@ impl<'a> Project<'a> { }; let resource_silo_id = authz_silo.id(); if resource_silo_id != actor_silo_id { - use crate::authz::ApiResource; + use nexus_auth::authz::ApiResource; error!( log, "unexpected successful lookup of siloed resource \ @@ -244,7 +244,7 @@ impl<'a> Project<'a> { /// used outside this module. See `fetch_for(authz::Action)`. async fn fetch_by_name_for( opctx: &OpContext, - datastore: &DataStore, + datastore: &dyn LookupDataStore, authz_silo: &authz::Silo, name: &Name, action: authz::Action, @@ -268,7 +268,7 @@ impl<'a> Project<'a> { /// `lookup_for(authz::Action)`. async fn lookup_by_name_no_authz( opctx: &OpContext, - datastore: &DataStore, + datastore: &dyn LookupDataStore, authz_silo: &authz::Silo, name: &Name, ) -> LookupResult<(authz::Project, nexus_db_model::Project)> { @@ -307,7 +307,7 @@ impl<'a> Project<'a> { /// outside this module. See `fetch_for(authz::Action)`. async fn fetch_by_id_for( opctx: &OpContext, - datastore: &DataStore, + datastore: &dyn LookupDataStore, v0: &Uuid, action: authz::Action, ) -> LookupResult<(authz::Silo, authz::Project, nexus_db_model::Project)> { @@ -328,7 +328,7 @@ impl<'a> Project<'a> { /// this module, you want `fetch()` or `lookup_for(authz::Action)`. async fn lookup_by_id_no_authz( opctx: &OpContext, - datastore: &DataStore, + datastore: &dyn LookupDataStore, v0: &Uuid, ) -> LookupResult<(authz::Silo, authz::Project, nexus_db_model::Project)> { use ::nexus_db_schema::schema::project::dsl; diff --git a/nexus/db-macros/outputs/silo_user.txt b/nexus/db-macros/outputs/silo_user.txt index 09b5ca058b0..690ec1ce625 100644 --- a/nexus/db-macros/outputs/silo_user.txt +++ b/nexus/db-macros/outputs/silo_user.txt @@ -39,7 +39,7 @@ impl<'a> SiloUser<'a> { ) -> LookupResult<(authz::SiloUser, nexus_db_model::SiloUser)> { let lookup = self.lookup_root(); let opctx = &lookup.opctx; - let datastore = &lookup.datastore; + let datastore = lookup.datastore; match &self { SiloUser::Error(_, error) => Err(error.clone()), SiloUser::PrimaryKey(_, v0) => { @@ -97,7 +97,7 @@ impl<'a> SiloUser<'a> { async fn lookup(&self) -> LookupResult<(authz::SiloUser,)> { let lookup = self.lookup_root(); let opctx = &lookup.opctx; - let datastore = &lookup.datastore; + let datastore = lookup.datastore; match &self { SiloUser::Error(_, error) => Err(error.clone()), SiloUser::PrimaryKey(_, v0) => { @@ -137,7 +137,7 @@ impl<'a> SiloUser<'a> { /// outside this module. See `fetch_for(authz::Action)`. async fn fetch_by_id_for( opctx: &OpContext, - datastore: &DataStore, + datastore: &dyn LookupDataStore, v0: &Uuid, action: authz::Action, ) -> LookupResult<(authz::SiloUser, nexus_db_model::SiloUser)> { @@ -154,7 +154,7 @@ impl<'a> SiloUser<'a> { /// this module, you want `fetch()` or `lookup_for(authz::Action)`. async fn lookup_by_id_no_authz( opctx: &OpContext, - datastore: &DataStore, + datastore: &dyn LookupDataStore, v0: &Uuid, ) -> LookupResult<(authz::SiloUser, nexus_db_model::SiloUser)> { use ::nexus_db_schema::schema::silo_user::dsl; diff --git a/nexus/db-macros/outputs/sled.txt b/nexus/db-macros/outputs/sled.txt index a29d114f4b1..f7173a01eb7 100644 --- a/nexus/db-macros/outputs/sled.txt +++ b/nexus/db-macros/outputs/sled.txt @@ -40,7 +40,7 @@ impl<'a> Sled<'a> { ) -> LookupResult<(authz::Sled, nexus_db_model::Sled)> { let lookup = self.lookup_root(); let opctx = &lookup.opctx; - let datastore = &lookup.datastore; + let datastore = lookup.datastore; match &self { Sled::Error(_, error) => Err(error.clone()), Sled::PrimaryKey(_, v0) => { @@ -98,7 +98,7 @@ impl<'a> Sled<'a> { async fn lookup(&self) -> LookupResult<(authz::Sled,)> { let lookup = self.lookup_root(); let opctx = &lookup.opctx; - let datastore = &lookup.datastore; + let datastore = lookup.datastore; match &self { Sled::Error(_, error) => Err(error.clone()), Sled::PrimaryKey(_, v0) => { @@ -134,7 +134,7 @@ impl<'a> Sled<'a> { /// outside this module. See `fetch_for(authz::Action)`. async fn fetch_by_id_for( opctx: &OpContext, - datastore: &DataStore, + datastore: &dyn LookupDataStore, v0: &::omicron_uuid_kinds::TypedUuid<::omicron_uuid_kinds::SledKind>, action: authz::Action, ) -> LookupResult<(authz::Sled, nexus_db_model::Sled)> { @@ -151,7 +151,7 @@ impl<'a> Sled<'a> { /// this module, you want `fetch()` or `lookup_for(authz::Action)`. async fn lookup_by_id_no_authz( opctx: &OpContext, - datastore: &DataStore, + datastore: &dyn LookupDataStore, v0: &::omicron_uuid_kinds::TypedUuid<::omicron_uuid_kinds::SledKind>, ) -> LookupResult<(authz::Sled, nexus_db_model::Sled)> { use ::nexus_db_schema::schema::sled::dsl; diff --git a/nexus/db-macros/outputs/update_artifact.txt b/nexus/db-macros/outputs/update_artifact.txt index 08bece04a77..4da34360b0a 100644 --- a/nexus/db-macros/outputs/update_artifact.txt +++ b/nexus/db-macros/outputs/update_artifact.txt @@ -39,7 +39,7 @@ impl<'a> UpdateArtifact<'a> { ) -> LookupResult<(authz::UpdateArtifact, nexus_db_model::UpdateArtifact)> { let lookup = self.lookup_root(); let opctx = &lookup.opctx; - let datastore = &lookup.datastore; + let datastore = lookup.datastore; match &self { UpdateArtifact::Error(_, error) => Err(error.clone()), UpdateArtifact::PrimaryKey(_, v0, v1, v2) => { @@ -97,7 +97,7 @@ impl<'a> UpdateArtifact<'a> { async fn lookup(&self) -> LookupResult<(authz::UpdateArtifact,)> { let lookup = self.lookup_root(); let opctx = &lookup.opctx; - let datastore = &lookup.datastore; + let datastore = lookup.datastore; match &self { UpdateArtifact::Error(_, error) => Err(error.clone()), UpdateArtifact::PrimaryKey(_, v0, v1, v2) => { @@ -143,7 +143,7 @@ impl<'a> UpdateArtifact<'a> { /// outside this module. See `fetch_for(authz::Action)`. async fn fetch_by_id_for( opctx: &OpContext, - datastore: &DataStore, + datastore: &dyn LookupDataStore, v0: &String, v1: &i64, v2: &KnownArtifactKind, @@ -168,7 +168,7 @@ impl<'a> UpdateArtifact<'a> { /// this module, you want `fetch()` or `lookup_for(authz::Action)`. async fn lookup_by_id_no_authz( opctx: &OpContext, - datastore: &DataStore, + datastore: &dyn LookupDataStore, v0: &String, v1: &i64, v2: &KnownArtifactKind, diff --git a/nexus/db-macros/src/lookup.rs b/nexus/db-macros/src/lookup.rs index 4817acba759..0e0f61cbd41 100644 --- a/nexus/db-macros/src/lookup.rs +++ b/nexus/db-macros/src/lookup.rs @@ -93,7 +93,6 @@ impl InputPrimaryKeyColumn { } } -// // MACRO STATE // @@ -419,7 +418,7 @@ fn generate_misc_helpers(config: &Config) -> TokenStream { let resource_silo_id = authz_silo.id(); if resource_silo_id != actor_silo_id { - use crate::authz::ApiResource; + use nexus_auth::authz::ApiResource; error!( log, "unexpected successful lookup of siloed resource \ @@ -613,7 +612,7 @@ fn generate_lookup_methods(config: &Config) -> TokenStream { ) -> LookupResult<(#(authz::#path_types,)* nexus_db_model::#resource_name)> { let lookup = self.lookup_root(); let opctx = &lookup.opctx; - let datastore = &lookup.datastore; + let datastore = lookup.datastore; match &self { #resource_name::Error(_, error) => Err(error.clone()), @@ -704,7 +703,7 @@ fn generate_lookup_methods(config: &Config) -> TokenStream { ) -> LookupResult<(#(authz::#path_types,)*)> { let lookup = self.lookup_root(); let opctx = &lookup.opctx; - let datastore = &lookup.datastore; + let datastore = lookup.datastore; match &self { #resource_name::Error(_, error) => Err(error.clone()), @@ -815,7 +814,7 @@ fn generate_database_functions(config: &Config) -> TokenStream { // Do NOT make this function public. async fn fetch_by_name_for( opctx: &OpContext, - datastore: &DataStore, + datastore: &dyn LookupDataStore, #parent_lookup_arg_formal name: &Name, action: authz::Action, @@ -841,7 +840,7 @@ fn generate_database_functions(config: &Config) -> TokenStream { // Do NOT make this function public. async fn lookup_by_name_no_authz( opctx: &OpContext, - datastore: &DataStore, + datastore: &dyn LookupDataStore, #parent_lookup_arg_formal name: &Name, ) -> LookupResult< @@ -912,7 +911,7 @@ fn generate_database_functions(config: &Config) -> TokenStream { // Do NOT make this function public. async fn fetch_by_id_for( opctx: &OpContext, - datastore: &DataStore, + datastore: &dyn LookupDataStore, #(#pkey_names: &#pkey_types,)* action: authz::Action, ) -> LookupResult<(#(authz::#path_types,)* nexus_db_model::#resource_name)> { @@ -935,7 +934,7 @@ fn generate_database_functions(config: &Config) -> TokenStream { // Do NOT make this function public. async fn lookup_by_id_no_authz( opctx: &OpContext, - datastore: &DataStore, + datastore: &dyn LookupDataStore, #(#pkey_names: &#pkey_types,)* ) -> LookupResult<(#(authz::#path_types,)* nexus_db_model::#resource_name)> { use ::nexus_db_schema::schema::#resource_as_snake::dsl; diff --git a/nexus/db-queries/Cargo.toml b/nexus/db-queries/Cargo.toml index cbff5591754..5b40b7b271b 100644 --- a/nexus/db-queries/Cargo.toml +++ b/nexus/db-queries/Cargo.toml @@ -57,8 +57,10 @@ uuid.workspace = true db-macros.workspace = true nexus-auth.workspace = true nexus-config.workspace = true +nexus-db-errors.workspace = true nexus-db-fixed-data.workspace = true nexus-db-model.workspace = true +nexus-db-lookup.workspace = true nexus-db-schema.workspace = true nexus-sled-agent-shared.workspace = true nexus-types.workspace = true diff --git a/nexus/db-queries/src/db/datastore/address_lot.rs b/nexus/db-queries/src/db/datastore/address_lot.rs index 716de67c12a..e8d8a18c683 100644 --- a/nexus/db-queries/src/db/datastore/address_lot.rs +++ b/nexus/db-queries/src/db/datastore/address_lot.rs @@ -6,18 +6,18 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; use crate::db::datastore::PgConnection; -use crate::db::error::ErrorHandler; -use crate::db::error::TransactionError; -use crate::db::error::public_error_from_diesel; use crate::db::model::Name; use crate::db::model::{AddressLot, AddressLotBlock, AddressLotReservedBlock}; use crate::db::pagination::paginated; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::{AsyncRunQueryDsl, Connection}; use chrono::Utc; use diesel::{ExpressionMethods, QueryDsl, SelectableHelper}; use diesel_dtrace::DTraceConnection; use ipnetwork::IpNetwork; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::TransactionError; +use nexus_db_errors::public_error_from_diesel; use nexus_types::external_api::params; use nexus_types::identity::Resource; use omicron_common::api::external::http_pagination::PaginatedBy; diff --git a/nexus/db-queries/src/db/datastore/affinity.rs b/nexus/db-queries/src/db/datastore/affinity.rs index 4a4bc7e5ee9..d9a8486e8c8 100644 --- a/nexus/db-queries/src/db/datastore/affinity.rs +++ b/nexus/db-queries/src/db/datastore/affinity.rs @@ -12,8 +12,6 @@ use crate::db::collection_insert::DatastoreCollection; use crate::db::column_walker::AllColumnsOf; use crate::db::datastore::InstanceStateComputer; use crate::db::datastore::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::identity::Resource; use crate::db::model::AffinityGroup; use crate::db::model::AffinityGroupInstanceMembership; @@ -27,12 +25,14 @@ use crate::db::model::Project; use crate::db::model::VmmState; use crate::db::pagination::RawPaginator; use crate::db::pagination::paginated; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::helper_types::AsSelect; use diesel::pg::Pg; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::public_error_from_diesel; use nexus_db_schema::enums::InstanceStateEnum; use nexus_db_schema::enums::VmmStateEnum; use omicron_common::api::external; @@ -1228,10 +1228,10 @@ impl DataStore { mod tests { use super::*; - use crate::db::lookup::LookupPath; use crate::db::pub_test_utils::TestDatabase; use crate::db::pub_test_utils::helpers::create_project; use crate::db::pub_test_utils::helpers::create_stopped_instance_record; + use nexus_db_lookup::LookupPath; use nexus_db_model::Resources; use nexus_db_model::SledResourceVmm; use nexus_types::external_api::params; diff --git a/nexus/db-queries/src/db/datastore/allow_list.rs b/nexus/db-queries/src/db/datastore/allow_list.rs index c02fab8be49..c10e38d3343 100644 --- a/nexus/db-queries/src/db/datastore/allow_list.rs +++ b/nexus/db-queries/src/db/datastore/allow_list.rs @@ -7,12 +7,12 @@ use crate::authz; use crate::context::OpContext; use crate::db::DbConnection; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::ExpressionMethods; use diesel::QueryDsl; use diesel::SelectableHelper; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use nexus_db_fixed_data::allow_list::USER_FACING_SERVICES_ALLOW_LIST_ID; use nexus_db_model::AllowList; use nexus_db_schema::schema::allow_list; diff --git a/nexus/db-queries/src/db/datastore/auth.rs b/nexus/db-queries/src/db/datastore/auth.rs index 2aa8b336c40..2b351670c67 100644 --- a/nexus/db-queries/src/db/datastore/auth.rs +++ b/nexus/db-queries/src/db/datastore/auth.rs @@ -4,8 +4,8 @@ //! Implements the [Storage] interface for [nexus_auth] integration. -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::prelude::*; diff --git a/nexus/db-queries/src/db/datastore/bfd.rs b/nexus/db-queries/src/db/datastore/bfd.rs index bcb4665194a..ae24f3ce80b 100644 --- a/nexus/db-queries/src/db/datastore/bfd.rs +++ b/nexus/db-queries/src/db/datastore/bfd.rs @@ -4,12 +4,12 @@ use super::DataStore; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::pagination::paginated; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::{ExpressionMethods, QueryDsl, SelectableHelper}; use ipnetwork::IpNetwork; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::BfdSession; use nexus_db_model::SqlU32; use nexus_types::external_api::params; diff --git a/nexus/db-queries/src/db/datastore/bgp.rs b/nexus/db-queries/src/db/datastore/bgp.rs index 93ee2fc5a3d..19fe1dc1ef4 100644 --- a/nexus/db-queries/src/db/datastore/bgp.rs +++ b/nexus/db-queries/src/db/datastore/bgp.rs @@ -4,14 +4,14 @@ use super::DataStore; use crate::context::OpContext; -use crate::db::error::{ErrorHandler, public_error_from_diesel}; use crate::db::model::{BgpAnnounceSet, BgpAnnouncement, BgpConfig, Name}; use crate::db::pagination::paginated; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::{ExpressionMethods, QueryDsl, SelectableHelper}; use ipnetwork::IpNetwork; +use nexus_db_errors::OptionalError; +use nexus_db_errors::{ErrorHandler, public_error_from_diesel}; use nexus_db_model::{ BgpPeerView, SwitchPortBgpPeerConfigAllowExport, SwitchPortBgpPeerConfigAllowImport, SwitchPortBgpPeerConfigCommunity, diff --git a/nexus/db-queries/src/db/datastore/bootstore.rs b/nexus/db-queries/src/db/datastore/bootstore.rs index 3292c2ea9d5..4f576b9888e 100644 --- a/nexus/db-queries/src/db/datastore/bootstore.rs +++ b/nexus/db-queries/src/db/datastore/bootstore.rs @@ -1,10 +1,10 @@ use super::DataStore; use crate::context::OpContext; -use crate::db::error::{ErrorHandler, public_error_from_diesel}; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::ExpressionMethods; use diesel::SelectableHelper; use diesel::prelude::*; +use nexus_db_errors::{ErrorHandler, public_error_from_diesel}; use nexus_db_model::{BootstoreConfig, BootstoreKeys}; use omicron_common::api::external::{CreateResult, LookupResult}; diff --git a/nexus/db-queries/src/db/datastore/certificate.rs b/nexus/db-queries/src/db/datastore/certificate.rs index 969045ae2d0..8629e66b72f 100644 --- a/nexus/db-queries/src/db/datastore/certificate.rs +++ b/nexus/db-queries/src/db/datastore/certificate.rs @@ -7,8 +7,6 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::Certificate; use crate::db::model::Name; use crate::db::model::ServiceKind; @@ -16,6 +14,8 @@ use crate::db::pagination::paginated; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use nexus_types::identity::Resource; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DeleteResult; diff --git a/nexus/db-queries/src/db/datastore/clickhouse_policy.rs b/nexus/db-queries/src/db/datastore/clickhouse_policy.rs index 07775d38a2b..03e62cf9a94 100644 --- a/nexus/db-queries/src/db/datastore/clickhouse_policy.rs +++ b/nexus/db-queries/src/db/datastore/clickhouse_policy.rs @@ -7,8 +7,6 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::pagination::paginated; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::ExpressionMethods; @@ -17,6 +15,8 @@ use diesel::QueryDsl; use diesel::dsl::sql_query; use diesel::expression::SelectableHelper; use diesel::sql_types; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::ClickhousePolicy as DbClickhousePolicy; use nexus_db_model::DbClickhouseMode; use nexus_db_model::SqlU8; diff --git a/nexus/db-queries/src/db/datastore/cockroachdb_node_id.rs b/nexus/db-queries/src/db/datastore/cockroachdb_node_id.rs index 61fb792556c..9e74bd6c1a5 100644 --- a/nexus/db-queries/src/db/datastore/cockroachdb_node_id.rs +++ b/nexus/db-queries/src/db/datastore/cockroachdb_node_id.rs @@ -5,14 +5,14 @@ //! Datastore methods involving CockroachDB node IDs. use super::DataStore; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::ExpressionMethods; use diesel::OptionalExtension; use diesel::QueryDsl; use nexus_auth::authz; use nexus_auth::context::OpContext; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::CockroachZoneIdToNodeId; use nexus_db_model::to_db_typed_uuid; use omicron_common::api::external::Error; diff --git a/nexus/db-queries/src/db/datastore/cockroachdb_settings.rs b/nexus/db-queries/src/db/datastore/cockroachdb_settings.rs index fa73e4a78b4..c05fa47efaa 100644 --- a/nexus/db-queries/src/db/datastore/cockroachdb_settings.rs +++ b/nexus/db-queries/src/db/datastore/cockroachdb_settings.rs @@ -7,12 +7,12 @@ use super::DataStore; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::raw_query_builder::QueryBuilder; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::deserialize::Queryable; use diesel::sql_types; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use nexus_types::deployment::CockroachDbSettings; use omicron_common::api::external::Error; use omicron_common::api::external::LookupResult; diff --git a/nexus/db-queries/src/db/datastore/console_session.rs b/nexus/db-queries/src/db/datastore/console_session.rs index f7d7adc7232..c2dd14e5815 100644 --- a/nexus/db-queries/src/db/datastore/console_session.rs +++ b/nexus/db-queries/src/db/datastore/console_session.rs @@ -8,11 +8,11 @@ use super::DataStore; use crate::authn; use crate::authz; use crate::context::OpContext; -use crate::db::lookup::LookupPath; use crate::db::model::ConsoleSession; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; +use nexus_db_lookup::LookupPath; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DeleteResult; use omicron_common::api::external::Error; @@ -76,7 +76,7 @@ impl DataStore { )) })?; - let (.., db_silo_user) = LookupPath::new(opctx, &self) + let (.., db_silo_user) = LookupPath::new(opctx, self) .silo_user_id(console_session.silo_user_id) .fetch() .await diff --git a/nexus/db-queries/src/db/datastore/crucible_dataset.rs b/nexus/db-queries/src/db/datastore/crucible_dataset.rs index 38820c3f203..9f9cdfa0b12 100644 --- a/nexus/db-queries/src/db/datastore/crucible_dataset.rs +++ b/nexus/db-queries/src/db/datastore/crucible_dataset.rs @@ -9,12 +9,8 @@ use super::SQL_BATCH_SIZE; use crate::authz; use crate::context::OpContext; use crate::db; -use crate::db::TransactionError; use crate::db::collection_insert::AsyncInsertError; use crate::db::collection_insert::DatastoreCollection; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; -use crate::db::error::retryable; use crate::db::identity::Asset; use crate::db::model::CrucibleDataset; use crate::db::model::PhysicalDisk; @@ -27,6 +23,10 @@ use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; use diesel::upsert::excluded; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::TransactionError; +use nexus_db_errors::public_error_from_diesel; +use nexus_db_errors::retryable; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DataPageParams; use omicron_common::api::external::Error; diff --git a/nexus/db-queries/src/db/datastore/db_metadata.rs b/nexus/db-queries/src/db/datastore/db_metadata.rs index d8669c3a2bd..dbc1de58571 100644 --- a/nexus/db-queries/src/db/datastore/db_metadata.rs +++ b/nexus/db-queries/src/db/datastore/db_metadata.rs @@ -5,12 +5,12 @@ //! [`DataStore`] methods on Database Metadata. use super::DataStore; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use anyhow::{Context, bail, ensure}; use async_bb8_diesel::{AsyncRunQueryDsl, AsyncSimpleConnection}; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::AllSchemaVersions; use nexus_db_model::EARLIEST_SUPPORTED_VERSION; use nexus_db_model::SchemaUpgradeStep; diff --git a/nexus/db-queries/src/db/datastore/deployment.rs b/nexus/db-queries/src/db/datastore/deployment.rs index 1edd34d6102..3ec15788320 100644 --- a/nexus/db-queries/src/db/datastore/deployment.rs +++ b/nexus/db-queries/src/db/datastore/deployment.rs @@ -7,13 +7,9 @@ use crate::authz; use crate::authz::ApiResource; use crate::context::OpContext; use crate::db::DbConnection; -use crate::db::TransactionError; use crate::db::datastore::SQL_BATCH_SIZE; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::pagination::Paginator; use crate::db::pagination::paginated; -use crate::transaction_retry::OptionalError; use anyhow::Context; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::DateTime; @@ -41,6 +37,10 @@ use diesel::result::Error as DieselError; use diesel::sql_types; use futures::FutureExt; use id_map::IdMap; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::TransactionError; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::Blueprint as DbBlueprint; use nexus_db_model::BpClickhouseClusterConfig; use nexus_db_model::BpClickhouseKeeperZoneIdToNodeId; diff --git a/nexus/db-queries/src/db/datastore/device_auth.rs b/nexus/db-queries/src/db/datastore/device_auth.rs index 8becf5b69ad..25b6e7c73c8 100644 --- a/nexus/db-queries/src/db/datastore/device_auth.rs +++ b/nexus/db-queries/src/db/datastore/device_auth.rs @@ -7,12 +7,12 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::DeviceAccessToken; use crate::db::model::DeviceAuthRequest; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use omicron_common::api::external::CreateResult; use omicron_common::api::external::Error; use omicron_common::api::external::LookupResult; @@ -73,7 +73,7 @@ impl DataStore { TooManyRequests, } - let err = crate::transaction_retry::OptionalError::new(); + let err = nexus_db_errors::OptionalError::new(); let conn = self.pool_connection_authorized(opctx).await?; self.transaction_retry_wrapper("device_access_token_create") diff --git a/nexus/db-queries/src/db/datastore/disk.rs b/nexus/db-queries/src/db/datastore/disk.rs index e5a1e8d918b..3f98aef0f23 100644 --- a/nexus/db-queries/src/db/datastore/disk.rs +++ b/nexus/db-queries/src/db/datastore/disk.rs @@ -15,10 +15,7 @@ use crate::db::collection_detach::DatastoreDetachTarget; use crate::db::collection_detach::DetachError; use crate::db::collection_insert::AsyncInsertError; use crate::db::collection_insert::DatastoreCollection; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::identity::Resource; -use crate::db::lookup::LookupPath; use crate::db::model::Disk; use crate::db::model::DiskRuntimeState; use crate::db::model::DiskUpdate; @@ -36,6 +33,9 @@ use async_bb8_diesel::AsyncRunQueryDsl; use chrono::DateTime; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; +use nexus_db_lookup::LookupPath; use omicron_common::api; use omicron_common::api::external::CreateResult; use omicron_common::api::external::Error; @@ -903,7 +903,7 @@ mod tests { .await .unwrap(); - let (.., authz_disk, db_disk) = LookupPath::new(&opctx, &db_datastore) + let (.., authz_disk, db_disk) = LookupPath::new(&opctx, db_datastore) .disk_id(disk.id()) .fetch() .await @@ -929,7 +929,7 @@ mod tests { // Assert initial state - deleting the Disk will make LookupPath::fetch // not work. { - LookupPath::new(&opctx, &db_datastore) + LookupPath::new(&opctx, db_datastore) .disk_id(disk.id()) .fetch() .await @@ -946,7 +946,7 @@ mod tests { // Assert state change { - let (.., db_disk) = LookupPath::new(&opctx, &db_datastore) + let (.., db_disk) = LookupPath::new(&opctx, db_datastore) .disk_id(disk.id()) .fetch() .await @@ -967,7 +967,7 @@ mod tests { // Assert state is the same after the second call { - let (.., db_disk) = LookupPath::new(&opctx, &db_datastore) + let (.., db_disk) = LookupPath::new(&opctx, db_datastore) .disk_id(disk.id()) .fetch() .await diff --git a/nexus/db-queries/src/db/datastore/dns.rs b/nexus/db-queries/src/db/datastore/dns.rs index 2915cf1243e..3f88b6bc0a1 100644 --- a/nexus/db-queries/src/db/datastore/dns.rs +++ b/nexus/db-queries/src/db/datastore/dns.rs @@ -5,10 +5,7 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; -use crate::db::TransactionError; use crate::db::datastore::SQL_BATCH_SIZE; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::DnsGroup; use crate::db::model::DnsName; use crate::db::model::DnsVersion; @@ -18,11 +15,14 @@ use crate::db::model::InitialDnsGroup; use crate::db::pagination::Paginator; use crate::db::pagination::paginated; use crate::db::pool::DbConnection; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::prelude::*; use futures::FutureExt; use futures::future::BoxFuture; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::TransactionError; +use nexus_db_errors::public_error_from_diesel; use nexus_types::internal_api::params::DnsConfigParams; use nexus_types::internal_api::params::DnsConfigZone; use nexus_types::internal_api::params::DnsRecord; @@ -745,7 +745,6 @@ impl DataStoreDnsTest for DataStore { #[cfg(test)] mod test { use crate::db::DataStore; - use crate::db::TransactionError; use crate::db::datastore::DnsVersionUpdateBuilder; use crate::db::pub_test_utils::TestDatabase; use assert_matches::assert_matches; @@ -753,6 +752,7 @@ mod test { use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use futures::FutureExt; + use nexus_db_errors::TransactionError; use nexus_db_model::DnsGroup; use nexus_db_model::DnsName; use nexus_db_model::DnsVersion; diff --git a/nexus/db-queries/src/db/datastore/external_ip.rs b/nexus/db-queries/src/db/datastore/external_ip.rs index 85dec957a26..bf38e9df9a1 100644 --- a/nexus/db-queries/src/db/datastore/external_ip.rs +++ b/nexus/db-queries/src/db/datastore/external_ip.rs @@ -13,11 +13,6 @@ use crate::db::collection_attach::AttachError; use crate::db::collection_attach::DatastoreAttachTarget; use crate::db::collection_detach::DatastoreDetachTarget; use crate::db::collection_detach::DetachError; -use crate::db::error::ErrorHandler; -use crate::db::error::TransactionError; -use crate::db::error::public_error_from_diesel; -use crate::db::error::retryable; -use crate::db::lookup::LookupPath; use crate::db::model::ExternalIp; use crate::db::model::FloatingIp; use crate::db::model::IncompleteExternalIp; @@ -36,6 +31,11 @@ use crate::db::update_and_check::UpdateStatus; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::TransactionError; +use nexus_db_errors::public_error_from_diesel; +use nexus_db_errors::retryable; +use nexus_db_lookup::LookupPath; use nexus_db_model::FloatingIpUpdate; use nexus_db_model::Instance; use nexus_db_model::IpAttachState; diff --git a/nexus/db-queries/src/db/datastore/identity_provider.rs b/nexus/db-queries/src/db/datastore/identity_provider.rs index 5bbecee488e..cb5268f22f2 100644 --- a/nexus/db-queries/src/db/datastore/identity_provider.rs +++ b/nexus/db-queries/src/db/datastore/identity_provider.rs @@ -8,10 +8,7 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; use crate::db; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::identity::Resource; -use crate::db::lookup::LookupPath; use crate::db::model; use crate::db::model::IdentityProvider; use crate::db::model::Name; @@ -19,6 +16,9 @@ use crate::db::pagination::paginated; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::prelude::*; use nexus_auth::authn::silos::IdentityProviderType; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; +use nexus_db_lookup::LookupPath; use omicron_common::api::external::CreateResult; use omicron_common::api::external::ListResultVec; use omicron_common::api::external::LookupResult; diff --git a/nexus/db-queries/src/db/datastore/image.rs b/nexus/db-queries/src/db/datastore/image.rs index 414e04fd7b0..b48bcf2912b 100644 --- a/nexus/db-queries/src/db/datastore/image.rs +++ b/nexus/db-queries/src/db/datastore/image.rs @@ -3,8 +3,6 @@ use crate::authz::ApiResource; use crate::context::OpContext; use crate::db::collection_insert::AsyncInsertError; use crate::db::collection_insert::DatastoreCollection; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::Image; use crate::db::model::Project; use crate::db::model::ProjectImage; @@ -14,6 +12,8 @@ use crate::db::pagination::paginated; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::Name; use nexus_types::identity::Resource; use omicron_common::api::external::CreateResult; diff --git a/nexus/db-queries/src/db/datastore/instance.rs b/nexus/db-queries/src/db/datastore/instance.rs index 96c4140e1da..ff4dd9d8001 100644 --- a/nexus/db-queries/src/db/datastore/instance.rs +++ b/nexus/db-queries/src/db/datastore/instance.rs @@ -14,10 +14,7 @@ use crate::db::collection_detach_many::DetachManyError; use crate::db::collection_detach_many::DetachManyFromCollectionStatement; use crate::db::collection_insert::AsyncInsertError; use crate::db::collection_insert::DatastoreCollection; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::identity::Resource; -use crate::db::lookup::LookupPath; use crate::db::model::ByteCount; use crate::db::model::Generation; use crate::db::model::Instance; @@ -40,10 +37,13 @@ use crate::db::pool::DbConnection; use crate::db::update_and_check::UpdateAndCheck; use crate::db::update_and_check::UpdateAndQueryResult; use crate::db::update_and_check::UpdateStatus; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::public_error_from_diesel; +use nexus_db_lookup::LookupPath; use nexus_db_model::Disk; use nexus_types::internal_api::background::ReincarnationReason; use omicron_common::api; @@ -2116,9 +2116,9 @@ impl DataStore { mod tests { use super::*; use crate::db::datastore::sled; - use crate::db::lookup::LookupPath; use crate::db::pagination::Paginator; use crate::db::pub_test_utils::TestDatabase; + use nexus_db_lookup::LookupPath; use nexus_db_model::InstanceState; use nexus_db_model::Project; use nexus_db_model::VmmRuntimeState; @@ -2194,7 +2194,7 @@ mod tests { .await .expect("instance must be created successfully"); - let (.., authz_instance) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::Modify) .await diff --git a/nexus/db-queries/src/db/datastore/inventory.rs b/nexus/db-queries/src/db/datastore/inventory.rs index 4f1225c617e..0d5242bee32 100644 --- a/nexus/db-queries/src/db/datastore/inventory.rs +++ b/nexus/db-queries/src/db/datastore/inventory.rs @@ -5,9 +5,6 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; -use crate::db::error::public_error_from_diesel_lookup; use crate::db::pagination::{Paginator, paginated, paginated_multicolumn}; use crate::db::queries::ALLOW_FULL_TABLE_SCAN_SQL; use anyhow::Context; @@ -27,6 +24,9 @@ use diesel::expression::SelectableHelper; use diesel::sql_types::Nullable; use futures::FutureExt; use futures::future::BoxFuture; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; +use nexus_db_errors::public_error_from_diesel_lookup; use nexus_db_model::HwBaseboardId; use nexus_db_model::HwPowerState; use nexus_db_model::HwRotSlot; diff --git a/nexus/db-queries/src/db/datastore/ip_pool.rs b/nexus/db-queries/src/db/datastore/ip_pool.rs index 3187efd5efc..e62852ac020 100644 --- a/nexus/db-queries/src/db/datastore/ip_pool.rs +++ b/nexus/db-queries/src/db/datastore/ip_pool.rs @@ -8,15 +8,10 @@ use super::DataStore; use super::SQL_BATCH_SIZE; use crate::authz; use crate::context::OpContext; -use crate::db::TransactionError; use crate::db::collection_insert::AsyncInsertError; use crate::db::collection_insert::DatastoreCollection; use crate::db::datastore::SERVICE_IP_POOL_NAME; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; -use crate::db::error::public_error_from_diesel_lookup; use crate::db::identity::Resource; -use crate::db::lookup::LookupPath; use crate::db::model::ExternalIp; use crate::db::model::IpKind; use crate::db::model::IpPool; @@ -29,12 +24,17 @@ use crate::db::pagination::Paginator; use crate::db::pagination::paginated; use crate::db::pool::DbConnection; use crate::db::queries::ip_pool::FilterOverlappingIpRanges; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; use diesel::result::Error as DieselError; use ipnetwork::IpNetwork; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::TransactionError; +use nexus_db_errors::public_error_from_diesel; +use nexus_db_errors::public_error_from_diesel_lookup; +use nexus_db_lookup::LookupPath; use nexus_db_model::InternetGateway; use nexus_db_model::InternetGatewayIpPool; use nexus_db_model::Project; diff --git a/nexus/db-queries/src/db/datastore/ipv4_nat_entry.rs b/nexus/db-queries/src/db/datastore/ipv4_nat_entry.rs index 95e6d9118f5..5603ee3c269 100644 --- a/nexus/db-queries/src/db/datastore/ipv4_nat_entry.rs +++ b/nexus/db-queries/src/db/datastore/ipv4_nat_entry.rs @@ -1,12 +1,12 @@ use super::DataStore; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::{Ipv4NatEntry, Ipv4NatValues}; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::{DateTime, Utc}; use diesel::prelude::*; use diesel::sql_types::BigInt; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::ExternalIp; use nexus_db_model::Ipv4NatChange; use nexus_types::internal_api::views::Ipv4NatEntryView; diff --git a/nexus/db-queries/src/db/datastore/lldp.rs b/nexus/db-queries/src/db/datastore/lldp.rs index 2f90f9d31af..4e74e68f41b 100644 --- a/nexus/db-queries/src/db/datastore/lldp.rs +++ b/nexus/db-queries/src/db/datastore/lldp.rs @@ -6,8 +6,6 @@ use super::DataStore; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::LldpLinkConfig; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; @@ -15,6 +13,8 @@ use diesel::ExpressionMethods; use diesel::QueryDsl; use diesel::SelectableHelper; use ipnetwork::IpNetwork; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use omicron_common::api::external; use omicron_common::api::external::Error; use omicron_common::api::external::LookupResult; diff --git a/nexus/db-queries/src/db/datastore/lookup_interface.rs b/nexus/db-queries/src/db/datastore/lookup_interface.rs new file mode 100644 index 00000000000..e61edfde2a7 --- /dev/null +++ b/nexus/db-queries/src/db/datastore/lookup_interface.rs @@ -0,0 +1,19 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +use nexus_auth::context::OpContext; +use nexus_db_lookup::{DataStoreConnection, LookupDataStore}; +use omicron_common::api::external::Error; + +use super::DataStore; + +#[async_trait::async_trait] +impl LookupDataStore for DataStore { + async fn pool_connection_authorized( + &self, + opctx: &OpContext, + ) -> Result { + self.pool_connection_authorized(opctx).await + } +} diff --git a/nexus/db-queries/src/db/datastore/migration.rs b/nexus/db-queries/src/db/datastore/migration.rs index d5fd4077ec2..dd1bb5f8432 100644 --- a/nexus/db-queries/src/db/datastore/migration.rs +++ b/nexus/db-queries/src/db/datastore/migration.rs @@ -7,8 +7,6 @@ use super::DataStore; use crate::context::OpContext; use crate::db; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::Generation; use crate::db::model::Migration; use crate::db::model::MigrationState; @@ -19,6 +17,8 @@ use crate::db::update_and_check::UpdateStatus; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use nexus_db_schema::schema::migration::dsl; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DataPageParams; @@ -178,9 +178,9 @@ impl DataStore { mod tests { use super::*; use crate::authz; - use crate::db::lookup::LookupPath; use crate::db::model::Instance; use crate::db::pub_test_utils::TestDatabase; + use nexus_db_lookup::LookupPath; use nexus_db_model::Project; use nexus_types::external_api::params; use nexus_types::silo::DEFAULT_SILO_ID; @@ -245,7 +245,7 @@ mod tests { .await .expect("instance must be created successfully"); - let (.., authz_instance) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::Modify) .await diff --git a/nexus/db-queries/src/db/datastore/mod.rs b/nexus/db-queries/src/db/datastore/mod.rs index d5d6f33905e..ce122477d6d 100644 --- a/nexus/db-queries/src/db/datastore/mod.rs +++ b/nexus/db-queries/src/db/datastore/mod.rs @@ -22,7 +22,6 @@ use super::Pool; use super::pool::DbConnection; use crate::authz; use crate::context::OpContext; -use crate::db::error::{ErrorHandler, public_error_from_diesel}; use ::oximeter::types::ProducerRegistry; use anyhow::{Context, bail}; use async_bb8_diesel::AsyncRunQueryDsl; @@ -31,6 +30,7 @@ use diesel::prelude::*; use diesel::query_builder::{QueryFragment, QueryId}; use diesel::query_dsl::methods::LoadQuery; use diesel::{ExpressionMethods, QueryDsl}; +use nexus_db_errors::{ErrorHandler, public_error_from_diesel}; use omicron_common::api::external::Error; use omicron_common::api::external::IdentityMetadataCreateParams; use omicron_common::api::external::LookupType; @@ -70,6 +70,7 @@ mod inventory; mod ip_pool; mod ipv4_nat_entry; mod lldp; +mod lookup_interface; mod migration; mod network_interface; mod oximeter; @@ -456,7 +457,6 @@ mod test { }; use crate::db::explain::ExplainableAsync; use crate::db::identity::Asset; - use crate::db::lookup::LookupPath; use crate::db::model::{ BlockSize, ConsoleSession, CrucibleDataset, ExternalIp, PhysicalDisk, PhysicalDiskKind, PhysicalDiskPolicy, PhysicalDiskState, Project, Rack, @@ -470,6 +470,7 @@ mod test { use futures::stream; use nexus_config::RegionAllocationStrategy; use nexus_db_fixed_data::silo::DEFAULT_SILO; + use nexus_db_lookup::LookupPath; use nexus_db_model::IpAttachState; use nexus_db_model::to_db_typed_uuid; use nexus_types::deployment::Blueprint; @@ -529,7 +530,7 @@ mod test { let authz_silo = opctx.authn.silo_required().unwrap(); - let (.., silo) = LookupPath::new(&opctx, &datastore) + let (.., silo) = LookupPath::new(&opctx, datastore) .silo_id(authz_silo.id()) .fetch() .await @@ -547,7 +548,7 @@ mod test { datastore.project_create(&opctx, project).await.unwrap(); let (.., silo_after_project_create) = - LookupPath::new(&opctx, &datastore) + LookupPath::new(&opctx, datastore) .silo_id(authz_silo.id()) .fetch() .await @@ -603,7 +604,7 @@ mod test { .await .unwrap(); - let (.., db_silo_user) = LookupPath::new(&opctx, &datastore) + let (.., db_silo_user) = LookupPath::new(&opctx, datastore) .silo_user_id(session.silo_user_id) .fetch() .await @@ -611,7 +612,7 @@ mod test { assert_eq!(DEFAULT_SILO_ID, db_silo_user.silo_id); // fetch the one we just created - let (.., fetched) = LookupPath::new(&opctx, &datastore) + let (.., fetched) = LookupPath::new(&opctx, datastore) .console_session_token(&token) .fetch() .await @@ -641,7 +642,7 @@ mod test { ); // time_last_used change persists in DB - let (.., fetched) = LookupPath::new(&opctx, &datastore) + let (.., fetched) = LookupPath::new(&opctx, datastore) .console_session_token(&token) .fetch() .await @@ -654,7 +655,7 @@ mod test { let delete = datastore.session_hard_delete(&opctx, &authz_session).await; assert_eq!(delete, Ok(())); - let fetched = LookupPath::new(&opctx, &datastore) + let fetched = LookupPath::new(&opctx, datastore) .console_session_token(&token) .fetch() .await; @@ -675,7 +676,7 @@ mod test { .session_hard_delete(&silo_user_opctx, &authz_session) .await; assert_eq!(delete, Ok(())); - let fetched = LookupPath::new(&opctx, &datastore) + let fetched = LookupPath::new(&opctx, datastore) .console_session_token(&token) .fetch() .await; @@ -1743,7 +1744,7 @@ mod test { .await .unwrap(); - let (.., authz_user) = LookupPath::new(&opctx, &datastore) + let (.., authz_user) = LookupPath::new(&opctx, datastore) .silo_user_id(silo_user_id) .lookup_for(authz::Action::CreateChild) .await @@ -1772,7 +1773,7 @@ mod test { // Lookup the key we just created. let (authz_silo, authz_silo_user, authz_ssh_key, found) = - LookupPath::new(&opctx, &datastore) + LookupPath::new(&opctx, datastore) .silo_user_id(silo_user_id) .ssh_key_name(&key_name.into()) .fetch() diff --git a/nexus/db-queries/src/db/datastore/network_interface.rs b/nexus/db-queries/src/db/datastore/network_interface.rs index efb4d299d38..ac15a4b12f5 100644 --- a/nexus/db-queries/src/db/datastore/network_interface.rs +++ b/nexus/db-queries/src/db/datastore/network_interface.rs @@ -12,8 +12,6 @@ use crate::db; use crate::db::collection_insert::AsyncInsertError; use crate::db::collection_insert::DatastoreCollection; use crate::db::cte_utils::BoxedQuery; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::IncompleteNetworkInterface; use crate::db::model::Instance; use crate::db::model::InstanceNetworkInterface; @@ -26,11 +24,13 @@ use crate::db::pagination::Paginator; use crate::db::pagination::paginated; use crate::db::pool::DbConnection; use crate::db::queries::network_interface; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; use diesel::result::Error as DieselError; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::ServiceNetworkInterface; use nexus_types::identity::Resource; use omicron_common::api::external::DataPageParams; diff --git a/nexus/db-queries/src/db/datastore/oximeter.rs b/nexus/db-queries/src/db/datastore/oximeter.rs index cdff44cd5b8..e9b1b82e967 100644 --- a/nexus/db-queries/src/db/datastore/oximeter.rs +++ b/nexus/db-queries/src/db/datastore/oximeter.rs @@ -7,8 +7,6 @@ use super::DataStore; use super::SQL_BATCH_SIZE; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::identity::Asset; use crate::db::model::OximeterInfo; use crate::db::model::ProducerEndpoint; @@ -21,6 +19,8 @@ use chrono::Utc; use diesel::prelude::*; use diesel::result::DatabaseErrorKind; use diesel::result::Error as DieselError; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use omicron_common::api::external::DataPageParams; use omicron_common::api::external::Error; use omicron_common::api::external::ListResultVec; diff --git a/nexus/db-queries/src/db/datastore/oximeter_read_policy.rs b/nexus/db-queries/src/db/datastore/oximeter_read_policy.rs index 9d972da488b..7c20a1fee4d 100644 --- a/nexus/db-queries/src/db/datastore/oximeter_read_policy.rs +++ b/nexus/db-queries/src/db/datastore/oximeter_read_policy.rs @@ -7,8 +7,6 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::pagination::paginated; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::ExpressionMethods; @@ -16,6 +14,8 @@ use diesel::QueryDsl; use diesel::dsl::sql_query; use diesel::expression::SelectableHelper; use diesel::sql_types; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::DbOximeterReadMode; use nexus_db_model::OximeterReadPolicy as DbOximeterReadPolicy; use nexus_db_model::SqlU32; diff --git a/nexus/db-queries/src/db/datastore/physical_disk.rs b/nexus/db-queries/src/db/datastore/physical_disk.rs index ccfa6c46133..a37f6df92cb 100644 --- a/nexus/db-queries/src/db/datastore/physical_disk.rs +++ b/nexus/db-queries/src/db/datastore/physical_disk.rs @@ -8,11 +8,8 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; use crate::db; -use crate::db::TransactionError; use crate::db::collection_insert::AsyncInsertError; use crate::db::collection_insert::DatastoreCollection; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::ApplySledFilterExt; use crate::db::model::InvPhysicalDisk; use crate::db::model::PhysicalDisk; @@ -23,10 +20,13 @@ use crate::db::model::Sled; use crate::db::model::Zpool; use crate::db::model::to_db_typed_uuid; use crate::db::pagination::paginated; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::TransactionError; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::ApplyPhysicalDiskFilterExt; use nexus_types::deployment::{DiskFilter, SledFilter}; use omicron_common::api::external::CreateResult; @@ -333,11 +333,11 @@ impl DataStore { #[cfg(test)] mod test { use super::*; - use crate::db::lookup::LookupPath; use crate::db::model::{PhysicalDiskKind, Sled}; use crate::db::pub_test_utils::TestDatabase; use crate::db::pub_test_utils::helpers::SledUpdateBuilder; use dropshot::PaginationOrder; + use nexus_db_lookup::LookupPath; use nexus_sled_agent_shared::inventory::{ Baseboard, Inventory, InventoryDisk, OmicronZonesConfig, SledRole, }; @@ -793,8 +793,7 @@ mod test { .unwrap(); // Mark the sled as expunged - let sled_lookup = - LookupPath::new(&opctx, &datastore).sled_id(sled.id()); + let sled_lookup = LookupPath::new(&opctx, datastore).sled_id(sled.id()); let (authz_sled,) = sled_lookup.lookup_for(authz::Action::Modify).await.unwrap(); datastore diff --git a/nexus/db-queries/src/db/datastore/probe.rs b/nexus/db-queries/src/db/datastore/probe.rs index ca3c43aaf35..ce44c1ea368 100644 --- a/nexus/db-queries/src/db/datastore/probe.rs +++ b/nexus/db-queries/src/db/datastore/probe.rs @@ -2,14 +2,14 @@ use crate::authz; use crate::context::OpContext; use crate::db; use crate::db::datastore::DataStoreConnection; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; -use crate::db::lookup::LookupPath; use crate::db::model::Name; use crate::db::pagination::paginated; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::{ExpressionMethods, QueryDsl, SelectableHelper}; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; +use nexus_db_lookup::LookupPath; use nexus_db_model::IncompleteNetworkInterface; use nexus_db_model::Probe; use nexus_db_model::VpcSubnet; diff --git a/nexus/db-queries/src/db/datastore/project.rs b/nexus/db-queries/src/db/datastore/project.rs index 6a28b85a879..a80b1a92acc 100644 --- a/nexus/db-queries/src/db/datastore/project.rs +++ b/nexus/db-queries/src/db/datastore/project.rs @@ -11,8 +11,6 @@ use crate::context::OpContext; use crate::db; use crate::db::collection_insert::AsyncInsertError; use crate::db::collection_insert::DatastoreCollection; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::identity::Resource; use crate::db::model::CollectionTypeProvisioned; use crate::db::model::Name; @@ -21,10 +19,12 @@ use crate::db::model::ProjectUpdate; use crate::db::model::Silo; use crate::db::model::VirtualProvisioningCollection; use crate::db::pagination::paginated; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::public_error_from_diesel; use nexus_db_fixed_data::project::SERVICES_PROJECT; use nexus_types::silo::INTERNAL_SILO_ID; use omicron_common::api::external::CreateResult; @@ -102,7 +102,7 @@ impl DataStore { debug!(opctx.log, "attempting to create built-in projects"); - let (authz_silo,) = db::lookup::LookupPath::new(&opctx, self) + let (authz_silo,) = nexus_db_lookup::LookupPath::new(&opctx, self) .silo_id(INTERNAL_SILO_ID) .lookup_for(authz::Action::CreateChild) .await?; diff --git a/nexus/db-queries/src/db/datastore/quota.rs b/nexus/db-queries/src/db/datastore/quota.rs index 36c97faa90d..1c47c90877f 100644 --- a/nexus/db-queries/src/db/datastore/quota.rs +++ b/nexus/db-queries/src/db/datastore/quota.rs @@ -1,12 +1,12 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::pagination::paginated; use crate::db::pool::DbConnection; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::SiloQuotas; use nexus_db_model::SiloQuotasUpdate; use omicron_common::api::external::DataPageParams; diff --git a/nexus/db-queries/src/db/datastore/rack.rs b/nexus/db-queries/src/db/datastore/rack.rs index 5bfcf4418d7..1454663d549 100644 --- a/nexus/db-queries/src/db/datastore/rack.rs +++ b/nexus/db-queries/src/db/datastore/rack.rs @@ -10,15 +10,9 @@ use super::dns::DnsVersionUpdateBuilder; use crate::authz; use crate::context::OpContext; use crate::db; -use crate::db::TransactionError; use crate::db::collection_insert::AsyncInsertError; use crate::db::collection_insert::DatastoreCollection; -use crate::db::error::ErrorHandler; -use crate::db::error::MaybeRetryable::*; -use crate::db::error::public_error_from_diesel; -use crate::db::error::retryable; use crate::db::identity::Asset; -use crate::db::lookup::LookupPath; use crate::db::model::CrucibleDataset; use crate::db::model::IncompleteExternalIp; use crate::db::model::PhysicalDisk; @@ -32,9 +26,15 @@ use diesel::prelude::*; use diesel::result::Error as DieselError; use diesel::upsert::excluded; use ipnetwork::IpNetwork; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::MaybeRetryable::*; +use nexus_db_errors::TransactionError; +use nexus_db_errors::public_error_from_diesel; +use nexus_db_errors::retryable; use nexus_db_fixed_data::vpc_subnet::DNS_VPC_SUBNET; use nexus_db_fixed_data::vpc_subnet::NEXUS_VPC_SUBNET; use nexus_db_fixed_data::vpc_subnet::NTP_VPC_SUBNET; +use nexus_db_lookup::LookupPath; use nexus_db_model::IncompleteNetworkInterface; use nexus_db_model::InitialDnsGroup; use nexus_db_model::PasswordHashString; @@ -1177,7 +1177,7 @@ mod test { .expect("Failed to list Silos"); // It should *not* show up in the list because it's not discoverable. assert_eq!(silos.len(), 0); - let (authz_silo, db_silo) = LookupPath::new(&opctx, &datastore) + let (authz_silo, db_silo) = LookupPath::new(&opctx, datastore) .silo_name(&nexus_db_model::Name( rack_init.recovery_silo.identity.name.clone(), )) @@ -2415,7 +2415,7 @@ mod test { } // Decommission the sled. - let (authz_sled,) = LookupPath::new(&opctx, &datastore) + let (authz_sled,) = LookupPath::new(&opctx, datastore) .sled_id(sled.id()) .lookup_for(authz::Action::Modify) .await diff --git a/nexus/db-queries/src/db/datastore/region.rs b/nexus/db-queries/src/db/datastore/region.rs index f1ced5c515e..2c6cd7e84e0 100644 --- a/nexus/db-queries/src/db/datastore/region.rs +++ b/nexus/db-queries/src/db/datastore/region.rs @@ -10,9 +10,6 @@ use crate::context::OpContext; use crate::db; use crate::db::datastore::REGION_REDUNDANCY_THRESHOLD; use crate::db::datastore::SQL_BATCH_SIZE; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; -use crate::db::lookup::LookupPath; use crate::db::model::CrucibleDataset; use crate::db::model::PhysicalDiskPolicy; use crate::db::model::Region; @@ -27,6 +24,9 @@ use crate::db::update_and_check::UpdateStatus; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::prelude::*; use nexus_config::RegionAllocationStrategy; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; +use nexus_db_lookup::LookupPath; use nexus_types::external_api::params; use omicron_common::api::external; use omicron_common::api::external::DeleteResult; @@ -134,7 +134,7 @@ impl DataStore { .map_err(|e| Error::invalid_request(&e.to_string()))?) } params::DiskSource::Snapshot { snapshot_id } => { - let (.., db_snapshot) = LookupPath::new(opctx, &self) + let (.., db_snapshot) = LookupPath::new(opctx, self) .snapshot_id(*snapshot_id) .fetch() .await?; @@ -142,7 +142,7 @@ impl DataStore { Ok(db_snapshot.block_size) } params::DiskSource::Image { image_id } => { - let (.., db_image) = LookupPath::new(opctx, &self) + let (.., db_image) = LookupPath::new(opctx, self) .image_id(*image_id) .fetch() .await?; diff --git a/nexus/db-queries/src/db/datastore/region_replacement.rs b/nexus/db-queries/src/db/datastore/region_replacement.rs index 5b922bb22da..38823407df9 100644 --- a/nexus/db-queries/src/db/datastore/region_replacement.rs +++ b/nexus/db-queries/src/db/datastore/region_replacement.rs @@ -6,10 +6,7 @@ use super::DataStore; use crate::context::OpContext; -use crate::db::TransactionError; use crate::db::datastore::SQL_BATCH_SIZE; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::Region; use crate::db::model::RegionReplacement; use crate::db::model::RegionReplacementState; @@ -21,9 +18,12 @@ use crate::db::pagination::Paginator; use crate::db::pagination::paginated; use crate::db::update_and_check::UpdateAndCheck; use crate::db::update_and_check::UpdateStatus; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::TransactionError; +use nexus_db_errors::public_error_from_diesel; use omicron_common::api::external::Error; use omicron_uuid_kinds::DownstairsRegionKind; use omicron_uuid_kinds::TypedUuid; diff --git a/nexus/db-queries/src/db/datastore/region_snapshot.rs b/nexus/db-queries/src/db/datastore/region_snapshot.rs index 23242c3e394..5d56b6d4302 100644 --- a/nexus/db-queries/src/db/datastore/region_snapshot.rs +++ b/nexus/db-queries/src/db/datastore/region_snapshot.rs @@ -6,14 +6,14 @@ use super::DataStore; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::PhysicalDiskPolicy; use crate::db::model::RegionSnapshot; use crate::db::model::to_db_typed_uuid; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::OptionalExtension; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DeleteResult; use omicron_common::api::external::LookupResult; diff --git a/nexus/db-queries/src/db/datastore/region_snapshot_replacement.rs b/nexus/db-queries/src/db/datastore/region_snapshot_replacement.rs index 220619e7d6c..9d868be842c 100644 --- a/nexus/db-queries/src/db/datastore/region_snapshot_replacement.rs +++ b/nexus/db-queries/src/db/datastore/region_snapshot_replacement.rs @@ -7,10 +7,7 @@ use super::DataStore; use crate::context::OpContext; -use crate::db::TransactionError; use crate::db::datastore::SQL_BATCH_SIZE; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::ReadOnlyTargetReplacement; use crate::db::model::ReadOnlyTargetReplacementType; use crate::db::model::RegionSnapshot; @@ -23,9 +20,12 @@ use crate::db::pagination::Paginator; use crate::db::pagination::paginated; use crate::db::update_and_check::UpdateAndCheck; use crate::db::update_and_check::UpdateStatus; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::TransactionError; +use nexus_db_errors::public_error_from_diesel; use omicron_common::api::external::Error; use omicron_uuid_kinds::VolumeUuid; use std::net::SocketAddrV6; diff --git a/nexus/db-queries/src/db/datastore/rendezvous_debug_dataset.rs b/nexus/db-queries/src/db/datastore/rendezvous_debug_dataset.rs index 883c68c5108..a4f741355d3 100644 --- a/nexus/db-queries/src/db/datastore/rendezvous_debug_dataset.rs +++ b/nexus/db-queries/src/db/datastore/rendezvous_debug_dataset.rs @@ -8,13 +8,13 @@ use super::DataStore; use super::SQL_BATCH_SIZE; use crate::authz; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::pagination::Paginator; use crate::db::pagination::paginated; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::RendezvousDebugDataset; use nexus_db_model::to_db_typed_uuid; use omicron_common::api::external::CreateResult; diff --git a/nexus/db-queries/src/db/datastore/role.rs b/nexus/db-queries/src/db/datastore/role.rs index 96e54f97dda..13c7441f2a8 100644 --- a/nexus/db-queries/src/db/datastore/role.rs +++ b/nexus/db-queries/src/db/datastore/role.rs @@ -11,9 +11,6 @@ use crate::context::OpContext; use crate::db; use crate::db::datastore::RunnableQuery; use crate::db::datastore::RunnableQueryNoReturn; -use crate::db::error::ErrorHandler; -use crate::db::error::TransactionError; -use crate::db::error::public_error_from_diesel; use crate::db::model::DatabaseString; use crate::db::model::IdentityType; use crate::db::model::RoleAssignment; @@ -22,6 +19,9 @@ use crate::db::pagination::paginated_multicolumn; use crate::db::pool::DbConnection; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::TransactionError; +use nexus_db_errors::public_error_from_diesel; use nexus_db_fixed_data::role_assignment::BUILTIN_ROLE_ASSIGNMENTS; use nexus_db_fixed_data::role_builtin::BUILTIN_ROLES; use nexus_types::external_api::shared; diff --git a/nexus/db-queries/src/db/datastore/saga.rs b/nexus/db-queries/src/db/datastore/saga.rs index 54e299e6138..54e4224eabe 100644 --- a/nexus/db-queries/src/db/datastore/saga.rs +++ b/nexus/db-queries/src/db/datastore/saga.rs @@ -7,8 +7,6 @@ use super::DataStore; use super::SQL_BATCH_SIZE; use crate::db; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::pagination::Paginator; use crate::db::pagination::paginated; use crate::db::pagination::paginated_multicolumn; @@ -18,6 +16,8 @@ use async_bb8_diesel::AsyncRunQueryDsl; use diesel::prelude::*; use nexus_auth::authz; use nexus_auth::context::OpContext; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::SagaState; use omicron_common::api::external::Error; use omicron_common::api::external::LookupType; diff --git a/nexus/db-queries/src/db/datastore/silo.rs b/nexus/db-queries/src/db/datastore/silo.rs index cdbc5892283..8216f986022 100644 --- a/nexus/db-queries/src/db/datastore/silo.rs +++ b/nexus/db-queries/src/db/datastore/silo.rs @@ -11,10 +11,6 @@ use crate::authz; use crate::context::OpContext; use crate::db; use crate::db::datastore::RunnableQuery; -use crate::db::error::ErrorHandler; -use crate::db::error::TransactionError; -use crate::db::error::public_error_from_diesel; -use crate::db::error::retryable; use crate::db::identity::Resource; use crate::db::model::CollectionTypeProvisioned; use crate::db::model::IpPoolResourceType; @@ -27,6 +23,10 @@ use crate::db::pool::DbConnection; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::TransactionError; +use nexus_db_errors::public_error_from_diesel; +use nexus_db_errors::retryable; use nexus_db_fixed_data::silo::{DEFAULT_SILO, INTERNAL_SILO}; use nexus_db_model::Certificate; use nexus_db_model::ServiceKind; diff --git a/nexus/db-queries/src/db/datastore/silo_group.rs b/nexus/db-queries/src/db/datastore/silo_group.rs index c92f77fc50e..e6cf139bb23 100644 --- a/nexus/db-queries/src/db/datastore/silo_group.rs +++ b/nexus/db-queries/src/db/datastore/silo_group.rs @@ -10,15 +10,15 @@ use crate::context::OpContext; use crate::db; use crate::db::IncompleteOnConflictExt; use crate::db::datastore::RunnableQueryNoReturn; -use crate::db::error::ErrorHandler; -use crate::db::error::TransactionError; -use crate::db::error::public_error_from_diesel; use crate::db::model::SiloGroup; use crate::db::model::SiloGroupMembership; use crate::db::pagination::paginated; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::TransactionError; +use nexus_db_errors::public_error_from_diesel; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DataPageParams; use omicron_common::api::external::DeleteResult; diff --git a/nexus/db-queries/src/db/datastore/silo_user.rs b/nexus/db-queries/src/db/datastore/silo_user.rs index b9299406d75..8b19c1886f8 100644 --- a/nexus/db-queries/src/db/datastore/silo_user.rs +++ b/nexus/db-queries/src/db/datastore/silo_user.rs @@ -9,8 +9,6 @@ use crate::authn; use crate::authz; use crate::context::OpContext; use crate::db::datastore::IdentityMetadataCreateParams; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::Name; use crate::db::model::Silo; use crate::db::model::SiloUser; @@ -23,6 +21,8 @@ use crate::db::update_and_check::UpdateAndCheck; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use nexus_types::external_api::params; use nexus_types::identity::Asset; use nexus_types::identity::Resource; diff --git a/nexus/db-queries/src/db/datastore/sled.rs b/nexus/db-queries/src/db/datastore/sled.rs index 6c3d41226b5..bdf0263822c 100644 --- a/nexus/db-queries/src/db/datastore/sled.rs +++ b/nexus/db-queries/src/db/datastore/sled.rs @@ -9,10 +9,7 @@ use super::SQL_BATCH_SIZE; use crate::authz; use crate::context::OpContext; use crate::db; -use crate::db::TransactionError; use crate::db::datastore::ValidateTransition; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::AffinityPolicy; use crate::db::model::Sled; use crate::db::model::SledResourceVmm; @@ -25,10 +22,13 @@ use crate::db::pool::DbConnection; use crate::db::queries::sled_reservation::sled_find_targets_query; use crate::db::queries::sled_reservation::sled_insert_resource_query; use crate::db::update_and_check::{UpdateAndCheck, UpdateStatus}; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::TransactionError; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::ApplySledFilterExt; use nexus_types::deployment::SledFilter; use nexus_types::external_api::views::SledPolicy; @@ -1068,7 +1068,6 @@ pub(in crate::db::datastore) mod test { use crate::db::datastore::test_utils::{ Expected, IneligibleSleds, sled_set_policy, sled_set_state, }; - use crate::db::lookup::LookupPath; use crate::db::model::ByteCount; use crate::db::model::SqlU32; use crate::db::model::to_db_typed_uuid; @@ -1080,6 +1079,7 @@ pub(in crate::db::datastore) mod test { use crate::db::pub_test_utils::helpers::small_resource_request; use anyhow::{Context, Result}; use itertools::Itertools; + use nexus_db_lookup::LookupPath; use nexus_db_model::Generation; use nexus_db_model::PhysicalDisk; use nexus_db_model::PhysicalDiskKind; @@ -1217,7 +1217,7 @@ pub(in crate::db::datastore) mod test { assert!(datastore.sled_upsert(sled_update.clone()).await.is_err()); // The sled should not have been updated. - let (_, observed_sled_2) = LookupPath::new(&opctx, &datastore) + let (_, observed_sled_2) = LookupPath::new(&opctx, datastore) .sled_id(observed_sled.id()) .fetch_for(authz::Action::Modify) .await diff --git a/nexus/db-queries/src/db/datastore/sled_instance.rs b/nexus/db-queries/src/db/datastore/sled_instance.rs index 5ab5170d52d..eeeb6dd9ca1 100644 --- a/nexus/db-queries/src/db/datastore/sled_instance.rs +++ b/nexus/db-queries/src/db/datastore/sled_instance.rs @@ -2,11 +2,11 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::pagination::paginated; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::SledInstance; use omicron_common::api::external::DataPageParams; use omicron_common::api::external::ListResultVec; diff --git a/nexus/db-queries/src/db/datastore/snapshot.rs b/nexus/db-queries/src/db/datastore/snapshot.rs index f9c52f2c5e0..ed765659861 100644 --- a/nexus/db-queries/src/db/datastore/snapshot.rs +++ b/nexus/db-queries/src/db/datastore/snapshot.rs @@ -10,8 +10,6 @@ use crate::context::OpContext; use crate::db::IncompleteOnConflictExt; use crate::db::collection_insert::AsyncInsertError; use crate::db::collection_insert::DatastoreCollection; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::Generation; use crate::db::model::Name; use crate::db::model::Project; @@ -21,11 +19,13 @@ use crate::db::model::to_db_typed_uuid; use crate::db::pagination::paginated; use crate::db::update_and_check::UpdateAndCheck; use crate::db::update_and_check::UpdateStatus; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::OptionalExtension; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::public_error_from_diesel; use nexus_types::identity::Resource; use omicron_common::api::external::CreateResult; use omicron_common::api::external::Error; diff --git a/nexus/db-queries/src/db/datastore/ssh_key.rs b/nexus/db-queries/src/db/datastore/ssh_key.rs index 7a4fe148062..37e2f939ff6 100644 --- a/nexus/db-queries/src/db/datastore/ssh_key.rs +++ b/nexus/db-queries/src/db/datastore/ssh_key.rs @@ -8,8 +8,6 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; use crate::db; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::identity::Resource; use crate::db::model::Name; use crate::db::model::SshKey; @@ -18,6 +16,8 @@ use crate::db::update_and_check::UpdateAndCheck; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DeleteResult; use omicron_common::api::external::Error; diff --git a/nexus/db-queries/src/db/datastore/support_bundle.rs b/nexus/db-queries/src/db/datastore/support_bundle.rs index 9cefefdae1f..f45b3508f42 100644 --- a/nexus/db-queries/src/db/datastore/support_bundle.rs +++ b/nexus/db-queries/src/db/datastore/support_bundle.rs @@ -7,18 +7,18 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; -use crate::db::lookup::LookupPath; use crate::db::model::RendezvousDebugDataset; use crate::db::model::SupportBundle; use crate::db::model::SupportBundleState; use crate::db::pagination::paginated; use crate::db::update_and_check::{UpdateAndCheck, UpdateStatus}; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::prelude::*; use futures::FutureExt; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::public_error_from_diesel; +use nexus_db_lookup::LookupPath; use nexus_types::deployment::BlueprintDatasetDisposition; use nexus_types::deployment::BlueprintZoneDisposition; use omicron_common::api::external; diff --git a/nexus/db-queries/src/db/datastore/switch.rs b/nexus/db-queries/src/db/datastore/switch.rs index 7b2980549a8..232526f2917 100644 --- a/nexus/db-queries/src/db/datastore/switch.rs +++ b/nexus/db-queries/src/db/datastore/switch.rs @@ -1,14 +1,14 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::identity::Asset; use crate::db::model::Switch; use crate::db::pagination::paginated; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DataPageParams; use omicron_common::api::external::ListResultVec; diff --git a/nexus/db-queries/src/db/datastore/switch_interface.rs b/nexus/db-queries/src/db/datastore/switch_interface.rs index 9094bb6e9ea..7254dcf6fa5 100644 --- a/nexus/db-queries/src/db/datastore/switch_interface.rs +++ b/nexus/db-queries/src/db/datastore/switch_interface.rs @@ -8,14 +8,14 @@ use crate::context::OpContext; use crate::db::datastore::address_lot::{ ReserveBlockError, ReserveBlockTxnError, }; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::LoopbackAddress; use crate::db::pagination::paginated; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::{ExpressionMethods, QueryDsl, SelectableHelper}; use ipnetwork::IpNetwork; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::to_db_typed_uuid; use nexus_types::external_api::params::LoopbackAddressCreate; use omicron_common::api::external::{ diff --git a/nexus/db-queries/src/db/datastore/switch_port.rs b/nexus/db-queries/src/db/datastore/switch_port.rs index beff302f24b..b892a03f7b8 100644 --- a/nexus/db-queries/src/db/datastore/switch_port.rs +++ b/nexus/db-queries/src/db/datastore/switch_port.rs @@ -11,8 +11,6 @@ use crate::db::datastore::UpdatePrecondition; use crate::db::datastore::address_lot::{ ReserveBlockError, ReserveBlockTxnError, }; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::{ LldpLinkConfig, Name, SwitchInterfaceConfig, SwitchPort, SwitchPortAddressConfig, SwitchPortBgpPeerConfig, SwitchPortConfig, @@ -21,7 +19,6 @@ use crate::db::model::{ SwitchVlanInterfaceConfig, TxEqConfig, }; use crate::db::pagination::paginated; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::{AsyncRunQueryDsl, Connection}; use diesel::{ CombineDsl, ExpressionMethods, JoinOnDsl, NullableExpressionMethods, @@ -29,6 +26,9 @@ use diesel::{ }; use diesel_dtrace::DTraceConnection; use ipnetwork::IpNetwork; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::{ BgpConfig, SqlU8, SqlU16, SqlU32, SwitchPortBgpPeerConfigAllowExport, SwitchPortBgpPeerConfigAllowImport, SwitchPortBgpPeerConfigCommunity, diff --git a/nexus/db-queries/src/db/datastore/target_release.rs b/nexus/db-queries/src/db/datastore/target_release.rs index a41f63f8b02..e98a5ce5209 100644 --- a/nexus/db-queries/src/db/datastore/target_release.rs +++ b/nexus/db-queries/src/db/datastore/target_release.rs @@ -7,11 +7,11 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; -use crate::db::error::{ErrorHandler, public_error_from_diesel}; use crate::db::model::{SemverVersion, TargetRelease, TargetReleaseSource}; use async_bb8_diesel::AsyncRunQueryDsl as _; use diesel::insert_into; use diesel::prelude::*; +use nexus_db_errors::{ErrorHandler, public_error_from_diesel}; use nexus_db_schema::schema::target_release::dsl; use nexus_types::external_api::views; use omicron_common::api::external::{CreateResult, Error, LookupResult}; diff --git a/nexus/db-queries/src/db/datastore/test_utils.rs b/nexus/db-queries/src/db/datastore/test_utils.rs index 4dc870ae1d7..fce23ea560a 100644 --- a/nexus/db-queries/src/db/datastore/test_utils.rs +++ b/nexus/db-queries/src/db/datastore/test_utils.rs @@ -8,12 +8,12 @@ use crate::authz; use crate::context::OpContext; use crate::db::DataStore; use crate::db::datastore::ValidateTransition; -use crate::db::lookup::LookupPath; use anyhow::Context; use anyhow::Result; use anyhow::bail; use anyhow::ensure; use futures::future::try_join_all; +use nexus_db_lookup::LookupPath; use nexus_db_model::SledState; use nexus_types::external_api::views::SledPolicy; use nexus_types::external_api::views::SledProvisionPolicy; @@ -252,7 +252,7 @@ pub(super) async fn sled_set_policy( check: ValidateTransition, expected_old_policy: Expected, ) -> Result<()> { - let (authz_sled, _) = LookupPath::new(&opctx, &datastore) + let (authz_sled, _) = LookupPath::new(&opctx, datastore) .sled_id(sled_id.into_untyped_uuid()) .fetch_for(authz::Action::Modify) .await @@ -300,7 +300,7 @@ pub(super) async fn sled_set_state( check: ValidateTransition, expected_old_state: Expected, ) -> Result<()> { - let (authz_sled, _) = LookupPath::new(&opctx, &datastore) + let (authz_sled, _) = LookupPath::new(&opctx, datastore) .sled_id(sled_id.into_untyped_uuid()) .fetch_for(authz::Action::Modify) .await diff --git a/nexus/db-queries/src/db/datastore/update.rs b/nexus/db-queries/src/db/datastore/update.rs index bf283649576..499b0aafc08 100644 --- a/nexus/db-queries/src/db/datastore/update.rs +++ b/nexus/db-queries/src/db/datastore/update.rs @@ -9,13 +9,13 @@ use std::collections::HashMap; use super::DataStore; use crate::authz; use crate::context::OpContext; -use crate::db::error::{ErrorHandler, public_error_from_diesel}; use crate::db::model::SemverVersion; use crate::db::pagination::paginated; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::prelude::*; use diesel::result::Error as DieselError; +use nexus_db_errors::OptionalError; +use nexus_db_errors::{ErrorHandler, public_error_from_diesel}; use nexus_db_model::{ArtifactHash, TufArtifact, TufRepo, TufRepoDescription}; use omicron_common::api::external::{ self, CreateResult, DataPageParams, Generation, ListResultVec, diff --git a/nexus/db-queries/src/db/datastore/utilization.rs b/nexus/db-queries/src/db/datastore/utilization.rs index a2578a6f4c7..68fe7a8ff46 100644 --- a/nexus/db-queries/src/db/datastore/utilization.rs +++ b/nexus/db-queries/src/db/datastore/utilization.rs @@ -1,14 +1,14 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::Name; use crate::db::model::SiloUtilization; use crate::db::pagination::paginated; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::BoolExpressionMethods; use diesel::{ExpressionMethods, QueryDsl, SelectableHelper}; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use omicron_common::api::external::Error; use omicron_common::api::external::ListResultVec; use omicron_common::api::external::http_pagination::PaginatedBy; diff --git a/nexus/db-queries/src/db/datastore/v2p_mapping.rs b/nexus/db-queries/src/db/datastore/v2p_mapping.rs index b7523a9441c..2b2c1103962 100644 --- a/nexus/db-queries/src/db/datastore/v2p_mapping.rs +++ b/nexus/db-queries/src/db/datastore/v2p_mapping.rs @@ -5,7 +5,6 @@ use super::DataStore; use crate::context::OpContext; use crate::db::datastore::SQL_BATCH_SIZE; -use crate::db::error::{ErrorHandler, public_error_from_diesel}; use crate::db::model::ApplySledFilterExt; use crate::db::model::V2PMappingView; use crate::db::pagination::Paginator; @@ -13,6 +12,7 @@ use crate::db::pagination::paginated; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::{ExpressionMethods, QueryDsl, SelectableHelper}; use diesel::{JoinOnDsl, NullableExpressionMethods}; +use nexus_db_errors::{ErrorHandler, public_error_from_diesel}; use nexus_db_model::{NetworkInterface, NetworkInterfaceKind, Sled, Vpc}; use nexus_types::deployment::SledFilter; use omicron_common::api::external::ListResultVec; diff --git a/nexus/db-queries/src/db/datastore/virtual_provisioning_collection.rs b/nexus/db-queries/src/db/datastore/virtual_provisioning_collection.rs index 7afbbef1b1b..72113f7f7a2 100644 --- a/nexus/db-queries/src/db/datastore/virtual_provisioning_collection.rs +++ b/nexus/db-queries/src/db/datastore/virtual_provisioning_collection.rs @@ -7,8 +7,6 @@ use super::DataStore; use crate::context::OpContext; use crate::db; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::ByteCount; use crate::db::model::VirtualProvisioningCollection; use crate::db::pool::DbConnection; @@ -16,6 +14,8 @@ use crate::db::queries::virtual_provisioning_collection_update::VirtualProvision use async_bb8_diesel::AsyncRunQueryDsl; use diesel::prelude::*; use diesel::result::Error as DieselError; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::public_error_from_diesel; use omicron_common::api::external::{DeleteResult, Error}; use omicron_uuid_kinds::InstanceUuid; use uuid::Uuid; @@ -326,8 +326,8 @@ impl DataStore { mod test { use super::*; - use crate::db::lookup::LookupPath; use crate::db::pub_test_utils::TestDatabase; + use nexus_db_lookup::LookupPath; use nexus_db_model::Instance; use nexus_db_model::Project; use nexus_db_model::SiloQuotasUpdate; @@ -411,7 +411,7 @@ mod test { storage: Some(1 << 50), time_modified: chrono::Utc::now(), }; - let authz_silo = LookupPath::new(&opctx, &datastore) + let authz_silo = LookupPath::new(&opctx, datastore) .silo_id(silo_id) .lookup_for(crate::authz::Action::Modify) .await diff --git a/nexus/db-queries/src/db/datastore/vmm.rs b/nexus/db-queries/src/db/datastore/vmm.rs index 1218daa6cd6..0d2cf76ee91 100644 --- a/nexus/db-queries/src/db/datastore/vmm.rs +++ b/nexus/db-queries/src/db/datastore/vmm.rs @@ -7,8 +7,6 @@ use super::DataStore; use crate::context::OpContext; use crate::db; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::Vmm; use crate::db::model::VmmRuntimeState; use crate::db::model::VmmState as DbVmmState; @@ -16,10 +14,12 @@ use crate::db::pagination::paginated; use crate::db::update_and_check::UpdateAndCheck; use crate::db::update_and_check::UpdateAndQueryResult; use crate::db::update_and_check::UpdateStatus; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::public_error_from_diesel; use nexus_db_schema::schema::vmm::dsl; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DataPageParams; diff --git a/nexus/db-queries/src/db/datastore/volume.rs b/nexus/db-queries/src/db/datastore/volume.rs index 50da32b157b..a294651be1d 100644 --- a/nexus/db-queries/src/db/datastore/volume.rs +++ b/nexus/db-queries/src/db/datastore/volume.rs @@ -11,8 +11,6 @@ use crate::db::datastore::OpContext; use crate::db::datastore::REGION_REDUNDANCY_THRESHOLD; use crate::db::datastore::RunnableQuery; use crate::db::datastore::SQL_BATCH_SIZE; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::identity::Asset; use crate::db::model::CrucibleDataset; use crate::db::model::Disk; @@ -31,13 +29,15 @@ use crate::db::model::VolumeResourceUsageType; use crate::db::model::to_db_typed_uuid; use crate::db::pagination::Paginator; use crate::db::pagination::paginated; -use crate::transaction_retry::OptionalError; use anyhow::anyhow; use anyhow::bail; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::OptionalExtension; use diesel::prelude::*; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::public_error_from_diesel; use nexus_types::identity::Resource; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DeleteResult; diff --git a/nexus/db-queries/src/db/datastore/volume_repair.rs b/nexus/db-queries/src/db/datastore/volume_repair.rs index 8742a1c0059..2cb55b6f0c6 100644 --- a/nexus/db-queries/src/db/datastore/volume_repair.rs +++ b/nexus/db-queries/src/db/datastore/volume_repair.rs @@ -9,15 +9,15 @@ use crate::db; use crate::db::DbConnection; use crate::db::datastore::OpContext; use crate::db::datastore::RunnableQuery; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::model::VolumeRepair; use crate::db::model::to_db_typed_uuid; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use diesel::prelude::*; use diesel::result::DatabaseErrorKind; use diesel::result::Error as DieselError; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::public_error_from_diesel; use omicron_common::api::external::Error; use omicron_uuid_kinds::VolumeUuid; use uuid::Uuid; diff --git a/nexus/db-queries/src/db/datastore/vpc.rs b/nexus/db-queries/src/db/datastore/vpc.rs index 6fdafddcefe..5b776ae811a 100644 --- a/nexus/db-queries/src/db/datastore/vpc.rs +++ b/nexus/db-queries/src/db/datastore/vpc.rs @@ -13,8 +13,6 @@ use crate::db::collection_attach::AttachError; use crate::db::collection_attach::DatastoreAttachTarget; use crate::db::collection_insert::AsyncInsertError; use crate::db::collection_insert::DatastoreCollection; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::identity::Resource; use crate::db::model::ApplySledFilterExt; use crate::db::model::IncompleteVpc; @@ -41,7 +39,6 @@ use crate::db::queries::vpc::InsertVpcQuery; use crate::db::queries::vpc::VniSearchIter; use crate::db::queries::vpc_subnet::InsertVpcSubnetError; use crate::db::queries::vpc_subnet::InsertVpcSubnetQuery; -use crate::transaction_retry::OptionalError; use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; @@ -51,6 +48,9 @@ use futures::TryStreamExt; use futures::stream::{self, StreamExt}; use ipnetwork::IpNetwork; use nexus_auth::authz::ApiResource; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::OptionalError; +use nexus_db_errors::public_error_from_diesel; use nexus_db_fixed_data::vpc::SERVICES_INTERNET_GATEWAY_DEFAULT_ROUTE_V4; use nexus_db_fixed_data::vpc::SERVICES_INTERNET_GATEWAY_DEFAULT_ROUTE_V6; use nexus_db_fixed_data::vpc::SERVICES_INTERNET_GATEWAY_ID; @@ -104,7 +104,7 @@ impl DataStore { // Create built-in VPC for Oxide Services - let (_, authz_project) = db::lookup::LookupPath::new(opctx, self) + let (_, authz_project) = nexus_db_lookup::LookupPath::new(opctx, self) .project_id(*SERVICES_PROJECT_ID) .lookup_for(authz::Action::CreateChild) .await @@ -152,7 +152,7 @@ impl DataStore { // Also add the system router and internet gateway route - let system_router = db::lookup::LookupPath::new(opctx, self) + let system_router = nexus_db_lookup::LookupPath::new(opctx, self) .vpc_router_id(SERVICES_VPC.system_router_id) .lookup_for(authz::Action::CreateChild) .await; @@ -240,7 +240,7 @@ impl DataStore { // Create firewall rules for Oxide Services - let (_, _, authz_vpc) = db::lookup::LookupPath::new(opctx, self) + let (_, _, authz_vpc) = nexus_db_lookup::LookupPath::new(opctx, self) .vpc_id(*SERVICES_VPC_ID) .lookup_for(authz::Action::CreateChild) .await @@ -303,7 +303,7 @@ impl DataStore { // Create built-in VPC Subnets for Oxide Services - let (_, _, authz_vpc) = db::lookup::LookupPath::new(opctx, self) + let (_, _, authz_vpc) = nexus_db_lookup::LookupPath::new(opctx, self) .vpc_id(*SERVICES_VPC_ID) .lookup_for(authz::Action::CreateChild) .await @@ -313,7 +313,7 @@ impl DataStore { (&*NEXUS_VPC_SUBNET, *NEXUS_VPC_SUBNET_ROUTE_ID), (&*NTP_VPC_SUBNET, *NTP_VPC_SUBNET_ROUTE_ID), ] { - if let Ok(_) = db::lookup::LookupPath::new(opctx, self) + if let Ok(_) = nexus_db_lookup::LookupPath::new(opctx, self) .vpc_subnet_id(vpc_subnet.id()) .fetch() .await @@ -2497,7 +2497,7 @@ impl DataStore { opctx.check_complex_operations_allowed()?; let (.., authz_project, authz_vpc, authz_router) = - db::lookup::LookupPath::new(opctx, self) + nexus_db_lookup::LookupPath::new(opctx, self) .vpc_router_id(vpc_router_id) .lookup_for(authz::Action::Read) .await @@ -2586,7 +2586,7 @@ impl DataStore { // complete set if we're a system router? We'll need it anyway. let mut subnets_by_id = stream::iter(subnet_ids) .filter_map(|id| async move { - db::lookup::LookupPath::new(opctx, self) + nexus_db_lookup::LookupPath::new(opctx, self) .vpc_subnet_id(id) .fetch() .await @@ -2608,7 +2608,7 @@ impl DataStore { continue; } - let Some(res) = db::lookup::LookupPath::new(opctx, self) + let Some(res) = nexus_db_lookup::LookupPath::new(opctx, self) .vpc_id(vpc_id) .vpc_subnet_name(Name::ref_cast(name)) .fetch() @@ -2627,7 +2627,7 @@ impl DataStore { // TODO: unused until VPC peering. let _vpcs = stream::iter(vpc_names) .filter_map(|name| async { - db::lookup::LookupPath::new(opctx, self) + nexus_db_lookup::LookupPath::new(opctx, self) .project_id(authz_project.id()) .vpc_name(Name::ref_cast(&name)) .fetch() @@ -2641,7 +2641,7 @@ impl DataStore { let inetgws = stream::iter(inetgw_names) .filter_map(|name| async { - db::lookup::LookupPath::new(opctx, self) + nexus_db_lookup::LookupPath::new(opctx, self) .vpc_id(vpc_id) .internet_gateway_name(Name::ref_cast(&name)) .fetch() @@ -2655,7 +2655,7 @@ impl DataStore { let instances = stream::iter(instance_names) .filter_map(|name| async { - db::lookup::LookupPath::new(opctx, self) + nexus_db_lookup::LookupPath::new(opctx, self) .project_id(authz_project.id()) .instance_name(Name::ref_cast(&name)) .fetch() @@ -3884,7 +3884,7 @@ mod tests { .await .unwrap(); let (.., authz_instance) = - db::lookup::LookupPath::new(&opctx, &datastore) + nexus_db_lookup::LookupPath::new(&opctx, datastore) .instance_id(db_inst.id()) .lookup_for(authz::Action::CreateChild) .await diff --git a/nexus/db-queries/src/db/datastore/zpool.rs b/nexus/db-queries/src/db/datastore/zpool.rs index 6aa8245bc51..cadd916d76b 100644 --- a/nexus/db-queries/src/db/datastore/zpool.rs +++ b/nexus/db-queries/src/db/datastore/zpool.rs @@ -8,12 +8,9 @@ use super::DataStore; use super::SQL_BATCH_SIZE; use crate::authz; use crate::db; -use crate::db::TransactionError; use crate::db::collection_insert::AsyncInsertError; use crate::db::collection_insert::DatastoreCollection; use crate::db::datastore::OpContext; -use crate::db::error::ErrorHandler; -use crate::db::error::public_error_from_diesel; use crate::db::identity::Asset; use crate::db::model::PhysicalDisk; use crate::db::model::PhysicalDiskPolicy; @@ -26,6 +23,9 @@ use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; use diesel::upsert::excluded; +use nexus_db_errors::ErrorHandler; +use nexus_db_errors::TransactionError; +use nexus_db_errors::public_error_from_diesel; use nexus_db_model::PhysicalDiskKind; use nexus_db_model::to_db_typed_uuid; use omicron_common::api::external::CreateResult; diff --git a/nexus/db-queries/src/db/mod.rs b/nexus/db-queries/src/db/mod.rs index b7ae1e19ead..cabb3cffefb 100644 --- a/nexus/db-queries/src/db/mod.rs +++ b/nexus/db-queries/src/db/mod.rs @@ -15,9 +15,7 @@ mod config; mod cte_utils; // This is marked public for use by the integration tests pub mod datastore; -pub(crate) mod error; mod explain; -pub mod lookup; mod on_conflict_ext; // Public for doctests. pub mod pagination; @@ -44,7 +42,6 @@ pub use nexus_db_fixed_data as fixed_data; pub use nexus_db_model as model; use nexus_db_model::saga_types; -pub use crate::db::error::TransactionError; pub use config::Config; pub use datastore::DataStore; pub use on_conflict_ext::IncompleteOnConflictExt; diff --git a/nexus/db-queries/src/db/pub_test_utils/helpers.rs b/nexus/db-queries/src/db/pub_test_utils/helpers.rs index 5ac35e8537b..0ebc3af2f58 100644 --- a/nexus/db-queries/src/db/pub_test_utils/helpers.rs +++ b/nexus/db-queries/src/db/pub_test_utils/helpers.rs @@ -7,7 +7,7 @@ use crate::authz; use crate::context::OpContext; use crate::db::DataStore; -use crate::db::lookup::LookupPath; +use nexus_db_lookup::LookupPath; use anyhow::Result; use chrono::Utc; diff --git a/nexus/db-queries/src/db/queries/external_ip.rs b/nexus/db-queries/src/db/queries/external_ip.rs index 8928a06e639..8f15ea6b776 100644 --- a/nexus/db-queries/src/db/queries/external_ip.rs +++ b/nexus/db-queries/src/db/queries/external_ip.rs @@ -70,8 +70,6 @@ const REALLOCATION_WITH_DIFFERENT_IP_SENTINEL: &'static str = /// Translates a generic pool error to an external error. pub fn from_diesel(e: DieselError) -> external::Error { - use crate::db::error; - let sentinels = [REALLOCATION_WITH_DIFFERENT_IP_SENTINEL]; if let Some(sentinel) = matches_sentinel(&e, &sentinels) { match sentinel { @@ -85,7 +83,10 @@ pub fn from_diesel(e: DieselError) -> external::Error { } } - error::public_error_from_diesel(e, error::ErrorHandler::Server) + nexus_db_errors::public_error_from_diesel( + e, + nexus_db_errors::ErrorHandler::Server, + ) } const MAX_PORT: u16 = u16::MAX; @@ -867,7 +868,6 @@ mod tests { use crate::authz; use crate::db::datastore::SERVICE_IP_POOL_NAME; use crate::db::identity::Resource; - use crate::db::lookup::LookupPath; use crate::db::model::IpKind; use crate::db::model::IpPool; use crate::db::model::IpPoolRange; @@ -875,6 +875,7 @@ mod tests { use async_bb8_diesel::AsyncRunQueryDsl; use diesel::{ExpressionMethods, QueryDsl, SelectableHelper}; use dropshot::test_util::LogContext; + use nexus_db_lookup::LookupPath; use nexus_db_model::ByteCount; use nexus_db_model::Instance; use nexus_db_model::InstanceCpuCount; @@ -945,7 +946,7 @@ mod tests { self.initialize_ip_pool(name, range).await; - LookupPath::new(self.db.opctx(), &self.db.datastore()) + LookupPath::new(self.db.opctx(), self.db.datastore()) .ip_pool_id(pool.id()) .lookup_for(authz::Action::Read) .await diff --git a/nexus/db-queries/src/db/queries/network_interface.rs b/nexus/db-queries/src/db/queries/network_interface.rs index 95654747cf1..854a56e69c7 100644 --- a/nexus/db-queries/src/db/queries/network_interface.rs +++ b/nexus/db-queries/src/db/queries/network_interface.rs @@ -5,7 +5,6 @@ //! Queries for inserting and deleting network interfaces. use crate::db; -use crate::db::error::{ErrorHandler, public_error_from_diesel, retryable}; use crate::db::model::IncompleteNetworkInterface; use crate::db::pool::DbConnection; use crate::db::queries::next_item::DefaultShiftGenerator; @@ -26,6 +25,7 @@ use diesel::sql_types::{self, Nullable}; use ipnetwork::IpNetwork; use ipnetwork::Ipv4Network; use nexus_config::NUM_INITIAL_RESERVED_IP_ADDRESSES; +use nexus_db_errors::{ErrorHandler, public_error_from_diesel, retryable}; use nexus_db_model::SqlU8; use nexus_db_model::{MAX_NICS_PER_INSTANCE, NetworkInterfaceKind}; use nexus_db_schema::enums::NetworkInterfaceKindEnum; @@ -249,7 +249,6 @@ fn decode_database_error( err: DieselError, interface: &IncompleteNetworkInterface, ) -> InsertError { - use crate::db::error; use diesel::result::DatabaseErrorKind; // Error message generated when we attempt to insert an interface in a @@ -426,13 +425,15 @@ fn decode_database_error( external::ResourceType::ProbeNetworkInterface } }; - InsertError::External(error::public_error_from_diesel( - err, - error::ErrorHandler::Conflict( - resource_type, - interface.identity.name.as_str(), + InsertError::External( + nexus_db_errors::public_error_from_diesel( + err, + nexus_db_errors::ErrorHandler::Conflict( + resource_type, + interface.identity.name.as_str(), + ), ), - )) + ) } // Constraint violated if the user-requested UUID has already // been inserted. @@ -443,16 +444,18 @@ fn decode_database_error( ) } // Any other constraint violation is a bug - _ => InsertError::External(error::public_error_from_diesel( - err, - error::ErrorHandler::Server, - )), + _ => InsertError::External( + nexus_db_errors::public_error_from_diesel( + err, + nexus_db_errors::ErrorHandler::Server, + ), + ), }, // Any other error at all is a bug - _ => InsertError::External(error::public_error_from_diesel( + _ => InsertError::External(nexus_db_errors::public_error_from_diesel( err, - error::ErrorHandler::Server, + nexus_db_errors::ErrorHandler::Server, )), } } @@ -1699,7 +1702,6 @@ impl DeleteError { /// either the instance is still running, or that the instance has one or /// more secondary interfaces. pub fn from_diesel(e: DieselError, query: &DeleteQuery) -> Self { - use crate::db::error; match e { // Catch the specific errors designed to communicate the failures we // want to distinguish @@ -1728,10 +1730,12 @@ impl DeleteError { }) } // Any other error at all is a bug - _ => DeleteError::External(error::public_error_from_diesel( - e, - error::ErrorHandler::Server, - )), + _ => DeleteError::External( + nexus_db_errors::public_error_from_diesel( + e, + nexus_db_errors::ErrorHandler::Server, + ), + ), } } @@ -1772,7 +1776,6 @@ fn decode_delete_network_interface_database_error( err: DieselError, parent_id: Uuid, ) -> DeleteError { - use crate::db::error; use diesel::result::DatabaseErrorKind; // Error message generated when we're attempting to delete a primary @@ -1809,9 +1812,9 @@ fn decode_delete_network_interface_database_error( } // Any other error at all is a bug - _ => DeleteError::External(error::public_error_from_diesel( + _ => DeleteError::External(nexus_db_errors::public_error_from_diesel( err, - error::ErrorHandler::Server, + nexus_db_errors::ErrorHandler::Server, )), } } @@ -1827,7 +1830,6 @@ mod tests { use crate::context::OpContext; use crate::db::datastore::DataStore; use crate::db::identity::Resource; - use crate::db::lookup::LookupPath; use crate::db::model; use crate::db::model::IncompleteNetworkInterface; use crate::db::model::Instance; @@ -1840,6 +1842,7 @@ mod tests { use async_bb8_diesel::AsyncRunQueryDsl; use dropshot::test_util::LogContext; use model::NetworkInterfaceKind; + use nexus_db_lookup::LookupPath; use nexus_types::external_api::params; use nexus_types::external_api::params::InstanceCreate; use nexus_types::external_api::params::InstanceNetworkInterfaceAttachment; @@ -1893,7 +1896,7 @@ mod tests { let instance = Instance::new(instance_id, project_id, ¶ms); - let (.., authz_project) = LookupPath::new(&opctx, &db_datastore) + let (.., authz_project) = LookupPath::new(&opctx, db_datastore) .project_id(project_id) .lookup_for(authz::Action::CreateChild) .await diff --git a/nexus/db-queries/src/db/queries/region_allocation.rs b/nexus/db-queries/src/db/queries/region_allocation.rs index ee9449d50f4..d155258c216 100644 --- a/nexus/db-queries/src/db/queries/region_allocation.rs +++ b/nexus/db-queries/src/db/queries/region_allocation.rs @@ -31,8 +31,6 @@ const NOT_ENOUGH_UNIQUE_ZPOOLS_SENTINEL: &'static str = /// Translates a generic pool error to an external error based /// on messages which may be emitted during region provisioning. pub fn from_diesel(e: DieselError) -> external::Error { - use crate::db::error; - let sentinels = [ NOT_ENOUGH_DATASETS_SENTINEL, NOT_ENOUGH_ZPOOL_SPACE_SENTINEL, @@ -68,7 +66,10 @@ pub fn from_diesel(e: DieselError) -> external::Error { } } - error::public_error_from_diesel(e, error::ErrorHandler::Server) + nexus_db_errors::public_error_from_diesel( + e, + nexus_db_errors::ErrorHandler::Server, + ) } type SelectableSql = < diff --git a/nexus/db-queries/src/db/queries/virtual_provisioning_collection_update.rs b/nexus/db-queries/src/db/queries/virtual_provisioning_collection_update.rs index 5a522a3a02f..ff113378424 100644 --- a/nexus/db-queries/src/db/queries/virtual_provisioning_collection_update.rs +++ b/nexus/db-queries/src/db/queries/virtual_provisioning_collection_update.rs @@ -35,8 +35,6 @@ const NOT_ENOUGH_STORAGE_SENTINEL: &'static str = "Not enough storage"; /// on messages which may be emitted when provisioning virtual resources /// such as instances and disks. pub fn from_diesel(e: DieselError) -> external::Error { - use crate::db::error; - let sentinels = [ NOT_ENOUGH_CPUS_SENTINEL, NOT_ENOUGH_MEMORY_SENTINEL, @@ -71,7 +69,10 @@ pub fn from_diesel(e: DieselError) -> external::Error { _ => {} } } - error::public_error_from_diesel(e, error::ErrorHandler::Server) + nexus_db_errors::public_error_from_diesel( + e, + nexus_db_errors::ErrorHandler::Server, + ) } /// The virtual resource collection is only updated when a resource is inserted diff --git a/nexus/db-queries/src/db/queries/vpc_subnet.rs b/nexus/db-queries/src/db/queries/vpc_subnet.rs index 9e511824313..5ea3e5b38d5 100644 --- a/nexus/db-queries/src/db/queries/vpc_subnet.rs +++ b/nexus/db-queries/src/db/queries/vpc_subnet.rs @@ -217,7 +217,6 @@ impl InsertVpcSubnetError { /// Construct an `InsertError` from a Diesel error, catching the desired /// cases and building useful errors. pub fn from_diesel(e: DieselError, subnet: &VpcSubnet) -> Self { - use crate::db::error; use diesel::result::DatabaseErrorKind; match e { // Attempt to insert an overlapping IPv4 subnet @@ -251,18 +250,23 @@ impl InsertVpcSubnetError { ) if info.constraint_name() == Some(Self::NAME_CONFLICT_CONSTRAINT) => { - InsertVpcSubnetError::External(error::public_error_from_diesel( - e, - error::ErrorHandler::Conflict( - external::ResourceType::VpcSubnet, - subnet.identity().name.as_str(), + InsertVpcSubnetError::External( + nexus_db_errors::public_error_from_diesel( + e, + nexus_db_errors::ErrorHandler::Conflict( + external::ResourceType::VpcSubnet, + subnet.identity().name.as_str(), + ), ), - )) + ) } // Any other error at all is a bug _ => InsertVpcSubnetError::External( - error::public_error_from_diesel(e, error::ErrorHandler::Server), + nexus_db_errors::public_error_from_diesel( + e, + nexus_db_errors::ErrorHandler::Server, + ), ), } } diff --git a/nexus/db-queries/src/transaction_retry.rs b/nexus/db-queries/src/transaction_retry.rs index 09cf8c240f6..9fa1de595a1 100644 --- a/nexus/db-queries/src/transaction_retry.rs +++ b/nexus/db-queries/src/transaction_retry.rs @@ -227,69 +227,6 @@ impl NonRetryHelper { } } -/// Helper utility for passing non-retryable errors out-of-band from -/// transactions. -/// -/// Transactions prefer to act on the `diesel::result::Error` type, -/// but transaction users may want more meaningful error types. -/// This utility helps callers safely propagate back Diesel errors while -/// retaining auxiliary error info. -pub struct OptionalError(Arc>>); - -impl Clone for OptionalError { - fn clone(&self) -> Self { - Self(self.0.clone()) - } -} - -impl OptionalError { - pub fn new() -> Self { - Self(Arc::new(Mutex::new(None))) - } - - /// Sets "Self" to the value of `error` and returns `DieselError::RollbackTransaction`. - pub fn bail(&self, err: E) -> DieselError { - (*self.0.lock().unwrap()).replace(err); - DieselError::RollbackTransaction - } - - /// If `diesel_error` is retryable, returns it without setting Self. - /// - /// Otherwise, sets "Self" to the value of `err`, and returns - /// `DieselError::RollbackTransaction`. - pub fn bail_retryable_or( - &self, - diesel_error: DieselError, - err: E, - ) -> DieselError { - self.bail_retryable_or_else(diesel_error, |_diesel_error| err) - } - - /// If `diesel_error` is retryable, returns it without setting Self. - /// - /// Otherwise, sets "Self" to the value of `f` applied to `diesel_err`, and - /// returns `DieselError::RollbackTransaction`. - pub fn bail_retryable_or_else( - &self, - diesel_error: DieselError, - f: F, - ) -> DieselError - where - F: FnOnce(DieselError) -> E, - { - if crate::db::error::retryable(&diesel_error) { - return diesel_error; - } else { - self.bail(f(diesel_error)) - } - } - - /// If "Self" was previously set to a non-retryable error, return it. - pub fn take(self) -> Option { - (*self.0.lock().unwrap()).take() - } -} - #[cfg(test)] mod test { use super::*; diff --git a/nexus/networking/Cargo.toml b/nexus/networking/Cargo.toml index 510fd6ca27c..ef6cff6055c 100644 --- a/nexus/networking/Cargo.toml +++ b/nexus/networking/Cargo.toml @@ -10,6 +10,7 @@ workspace = true [dependencies] futures.workspace = true ipnetwork.workspace = true +nexus-db-lookup.workspace = true nexus-db-queries.workspace = true omicron-common.workspace = true oxnet.workspace = true diff --git a/nexus/networking/src/firewall_rules.rs b/nexus/networking/src/firewall_rules.rs index ea51ec8f710..5dba6d3bfbf 100644 --- a/nexus/networking/src/firewall_rules.rs +++ b/nexus/networking/src/firewall_rules.rs @@ -6,6 +6,7 @@ use futures::future::join_all; use ipnetwork::IpNetwork; +use nexus_db_lookup::LookupPath; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; @@ -14,8 +15,6 @@ use nexus_db_queries::db::fixed_data::vpc::SERVICES_VPC_ID; use nexus_db_queries::db::fixed_data::vpc_firewall_rule::NEXUS_VPC_FW_RULE_NAME; use nexus_db_queries::db::identity::Asset; use nexus_db_queries::db::identity::Resource; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::db::model::Name; use omicron_common::api::external; use omicron_common::api::external::AllowedSourceIps; @@ -36,7 +35,7 @@ use uuid::Uuid; pub async fn vpc_list_firewall_rules( datastore: &DataStore, opctx: &OpContext, - vpc_lookup: &lookup::Vpc<'_>, + vpc_lookup: &nexus_db_lookup::lookup::Vpc<'_>, ) -> ListResultVec { let (.., authz_vpc) = vpc_lookup.lookup_for(authz::Action::Read).await?; let rules = datastore.vpc_list_firewall_rules(&opctx, &authz_vpc).await?; diff --git a/nexus/networking/src/sled_client.rs b/nexus/networking/src/sled_client.rs index 98edd3d5619..8d3b1765b4f 100644 --- a/nexus/networking/src/sled_client.rs +++ b/nexus/networking/src/sled_client.rs @@ -4,10 +4,10 @@ //! Functionality for constructing sled-agent clients. +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::DataStore; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use omicron_common::api::external::Error; use omicron_common::api::external::LookupResult; use sled_agent_client::Client as SledAgentClient; diff --git a/nexus/reconfigurator/execution/Cargo.toml b/nexus/reconfigurator/execution/Cargo.toml index 9439adcc8f5..77edcb35276 100644 --- a/nexus/reconfigurator/execution/Cargo.toml +++ b/nexus/reconfigurator/execution/Cargo.toml @@ -24,6 +24,7 @@ internal-dns-resolver.workspace = true internal-dns-types.workspace = true newtype-uuid.workspace = true nexus-config.workspace = true +nexus-db-lookup.workspace = true nexus-db-model.workspace = true nexus-db-queries.workspace = true nexus-mgs-updates.workspace = true diff --git a/nexus/reconfigurator/execution/src/sled_state.rs b/nexus/reconfigurator/execution/src/sled_state.rs index 59b4bdf5df8..df63eefbad9 100644 --- a/nexus/reconfigurator/execution/src/sled_state.rs +++ b/nexus/reconfigurator/execution/src/sled_state.rs @@ -5,12 +5,12 @@ //! Updates sled states required by a given blueprint use anyhow::Context; +use nexus_db_lookup::LookupPath; use nexus_db_model::SledState as DbSledState; use nexus_db_queries::authz::Action; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::DataStore; use nexus_db_queries::db::datastore::TransitionError; -use nexus_db_queries::db::lookup::LookupPath; use nexus_types::deployment::Blueprint; use nexus_types::external_api::views::SledState; use omicron_uuid_kinds::GenericUuid; diff --git a/nexus/src/app/address_lot.rs b/nexus/src/app/address_lot.rs index ec0d97c1f0d..08e5f5d4443 100644 --- a/nexus/src/app/address_lot.rs +++ b/nexus/src/app/address_lot.rs @@ -4,12 +4,12 @@ use crate::external_api::params; use db::model::{AddressLot, AddressLotBlock}; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; use nexus_db_queries::db::datastore::AddressLotCreateResult; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use omicron_common::api::external::DataPageParams; use omicron_common::api::external::LookupResult; use omicron_common::api::external::NameOrId; diff --git a/nexus/src/app/affinity.rs b/nexus/src/app/affinity.rs index e55795a19db..be2edd4ff73 100644 --- a/nexus/src/app/affinity.rs +++ b/nexus/src/app/affinity.rs @@ -4,12 +4,12 @@ //! Affinity groups +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_model::AffinityGroup; use nexus_db_model::AntiAffinityGroup; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use nexus_types::external_api::params; use nexus_types::external_api::views; use nexus_types::identity::Resource; diff --git a/nexus/src/app/background/tasks/instance_reincarnation.rs b/nexus/src/app/background/tasks/instance_reincarnation.rs index c6ca375a936..68c411d6e74 100644 --- a/nexus/src/app/background/tasks/instance_reincarnation.rs +++ b/nexus/src/app/background/tasks/instance_reincarnation.rs @@ -307,6 +307,7 @@ mod test { use crate::app::sagas::test_helpers; use crate::external_api::params; use chrono::Utc; + use nexus_db_lookup::LookupPath; use nexus_db_model::Generation; use nexus_db_model::InstanceRuntimeState; use nexus_db_model::InstanceState; @@ -314,7 +315,6 @@ mod test { use nexus_db_model::VmmRuntimeState; use nexus_db_model::VmmState; use nexus_db_queries::authz; - use nexus_db_queries::db::lookup::LookupPath; use nexus_test_utils::resource_helpers::{ create_default_ip_pool, create_project, object_create, }; diff --git a/nexus/src/app/background/tasks/instance_updater.rs b/nexus/src/app/background/tasks/instance_updater.rs index b9a1f6ee495..0cf68083509 100644 --- a/nexus/src/app/background/tasks/instance_updater.rs +++ b/nexus/src/app/background/tasks/instance_updater.rs @@ -10,11 +10,11 @@ use crate::app::sagas::NexusSaga; use crate::app::sagas::instance_update; use futures::FutureExt; use futures::future::BoxFuture; +use nexus_db_lookup::LookupPath; use nexus_db_model::Instance; use nexus_db_model::VmmState; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::DataStore; -use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::{authn, authz}; use nexus_types::identity::Resource; use nexus_types::internal_api::background::InstanceUpdaterStatus; @@ -169,7 +169,7 @@ impl InstanceUpdater { let instance_id = instance.id(); let saga = async { let (.., authz_instance) = - LookupPath::new(&opctx, &self.datastore) + LookupPath::new(&opctx, &*self.datastore) .instance_id(instance_id) .lookup_for(authz::Action::Modify) .await?; diff --git a/nexus/src/app/background/tasks/read_only_region_replacement_start.rs b/nexus/src/app/background/tasks/read_only_region_replacement_start.rs index e6080e68c96..a2b510e5812 100644 --- a/nexus/src/app/background/tasks/read_only_region_replacement_start.rs +++ b/nexus/src/app/background/tasks/read_only_region_replacement_start.rs @@ -165,6 +165,7 @@ mod test { use crate::app::RegionAllocationStrategy; use crate::external_api::params; use chrono::Utc; + use nexus_db_lookup::LookupPath; use nexus_db_model::BlockSize; use nexus_db_model::Generation; use nexus_db_model::PhysicalDiskPolicy; @@ -175,7 +176,6 @@ mod test { use nexus_db_queries::authz; use nexus_db_queries::db::datastore::RegionAllocationFor; use nexus_db_queries::db::datastore::RegionAllocationParameters; - use nexus_db_queries::db::lookup::LookupPath; use nexus_test_utils::resource_helpers::create_project; use nexus_test_utils_macros::nexus_test; use omicron_common::api::external; @@ -257,7 +257,7 @@ mod test { // Create the fake snapshot - let (.., authz_project) = LookupPath::new(&opctx, &datastore) + let (.., authz_project) = LookupPath::new(&opctx, datastore) .project_id(project_id) .lookup_for(authz::Action::CreateChild) .await diff --git a/nexus/src/app/background/tasks/region_snapshot_replacement_start.rs b/nexus/src/app/background/tasks/region_snapshot_replacement_start.rs index 025617ce1f6..5e470cdbdf1 100644 --- a/nexus/src/app/background/tasks/region_snapshot_replacement_start.rs +++ b/nexus/src/app/background/tasks/region_snapshot_replacement_start.rs @@ -310,6 +310,7 @@ mod test { use crate::app::MIN_DISK_SIZE_BYTES; use crate::app::background::init::test::NoopStartSaga; use chrono::Utc; + use nexus_db_lookup::LookupPath; use nexus_db_model::BlockSize; use nexus_db_model::Generation; use nexus_db_model::PhysicalDiskPolicy; @@ -321,7 +322,6 @@ mod test { use nexus_db_model::SnapshotState; use nexus_db_model::VolumeResourceUsage; use nexus_db_queries::authz; - use nexus_db_queries::db::lookup::LookupPath; use nexus_test_utils::resource_helpers::create_project; use nexus_test_utils_macros::nexus_test; use omicron_common::api::external; @@ -469,7 +469,7 @@ mod test { // Create the fake snapshot - let (.., authz_project) = LookupPath::new(&opctx, &datastore) + let (.., authz_project) = LookupPath::new(&opctx, datastore) .project_id(project_id) .lookup_for(authz::Action::CreateChild) .await diff --git a/nexus/src/app/background/tasks/sync_service_zone_nat.rs b/nexus/src/app/background/tasks/sync_service_zone_nat.rs index dde963a7601..02d49e7f590 100644 --- a/nexus/src/app/background/tasks/sync_service_zone_nat.rs +++ b/nexus/src/app/background/tasks/sync_service_zone_nat.rs @@ -13,10 +13,10 @@ use anyhow::Context; use futures::FutureExt; use futures::future::BoxFuture; use internal_dns_resolver::Resolver; +use nexus_db_lookup::LookupPath; use nexus_db_model::Ipv4NatValues; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::DataStore; -use nexus_db_queries::db::lookup::LookupPath; use nexus_sled_agent_shared::inventory::{ OmicronZoneConfig, OmicronZoneType, OmicronZonesConfig, }; @@ -107,7 +107,7 @@ impl BackgroundTask for ServiceZoneNatTracker { let mut dns_count = 0; for (sled_id, sa) in collection.sled_agents { - let (_, sled) = match LookupPath::new(opctx, &self.datastore) + let (_, sled) = match LookupPath::new(opctx, &*self.datastore) .sled_id(sled_id.into_untyped_uuid()) .fetch() .await diff --git a/nexus/src/app/certificate.rs b/nexus/src/app/certificate.rs index 410799e71e5..f4fabf241d8 100644 --- a/nexus/src/app/certificate.rs +++ b/nexus/src/app/certificate.rs @@ -6,11 +6,11 @@ use crate::external_api::params; use crate::external_api::shared; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::db::model::Name; use nexus_db_queries::db::model::ServiceKind; use omicron_common::api::external::CreateResult; diff --git a/nexus/src/app/device_auth.rs b/nexus/src/app/device_auth.rs index 3b6d8ba436d..6a48ce3d672 100644 --- a/nexus/src/app/device_auth.rs +++ b/nexus/src/app/device_auth.rs @@ -46,10 +46,10 @@ use dropshot::{Body, HttpError}; use http::{Response, StatusCode, header}; +use nexus_db_lookup::LookupPath; use nexus_db_queries::authn::{Actor, Reason}; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; -use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::db::model::{DeviceAccessToken, DeviceAuthRequest}; use nexus_types::external_api::params::DeviceAccessTokenRequest; diff --git a/nexus/src/app/disk.rs b/nexus/src/app/disk.rs index 69e41b33754..aac95a375db 100644 --- a/nexus/src/app/disk.rs +++ b/nexus/src/app/disk.rs @@ -6,12 +6,12 @@ use crate::app::sagas; use crate::external_api::params; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_queries::authn; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use omicron_common::api::external::ByteCount; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DeleteResult; diff --git a/nexus/src/app/external_ip.rs b/nexus/src/app/external_ip.rs index 106237ffe99..d91d8e351c3 100644 --- a/nexus/src/app/external_ip.rs +++ b/nexus/src/app/external_ip.rs @@ -8,11 +8,11 @@ use std::sync::Arc; use crate::external_api::views::ExternalIp; use crate::external_api::views::FloatingIp; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_model::IpAttachState; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::db::model::IpKind; use nexus_types::external_api::params; use nexus_types::external_api::views; diff --git a/nexus/src/app/iam.rs b/nexus/src/app/iam.rs index fe772fc4602..9ad69319447 100644 --- a/nexus/src/app/iam.rs +++ b/nexus/src/app/iam.rs @@ -6,10 +6,11 @@ use crate::external_api::shared; use anyhow::Context; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup::{self, LookupPath}; use nexus_db_queries::db::model::Name; use nexus_types::external_api::params; use omicron_common::api::external::DataPageParams; diff --git a/nexus/src/app/image.rs b/nexus/src/app/image.rs index 35c9bcb94ea..9f54d436dbb 100644 --- a/nexus/src/app/image.rs +++ b/nexus/src/app/image.rs @@ -5,14 +5,14 @@ //! Images (both project and silo scoped) use crate::external_api::params; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; +use nexus_db_lookup::lookup::ImageLookup; +use nexus_db_lookup::lookup::ImageParentLookup; use nexus_db_queries::authn; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::ImageLookup; -use nexus_db_queries::db::lookup::ImageParentLookup; -use nexus_db_queries::db::lookup::LookupPath; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DeleteResult; use omicron_common::api::external::Error; diff --git a/nexus/src/app/instance.rs b/nexus/src/app/instance.rs index 23499117dfe..bcaa81d899e 100644 --- a/nexus/src/app/instance.rs +++ b/nexus/src/app/instance.rs @@ -19,6 +19,8 @@ use crate::external_api::params; use cancel_safe_futures::prelude::*; use futures::future::Fuse; use futures::{FutureExt, SinkExt, StreamExt}; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_model::InstanceUpdate; use nexus_db_model::IpAttachState; use nexus_db_model::IpKind; @@ -33,8 +35,6 @@ use nexus_db_queries::db::DataStore; use nexus_db_queries::db::datastore::InstanceAndActiveVmm; use nexus_db_queries::db::datastore::InstanceStateComputer; use nexus_db_queries::db::identity::Resource; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use nexus_types::external_api::views; use omicron_common::api::external::ByteCount; use omicron_common::api::external::CreateResult; @@ -273,7 +273,7 @@ async fn normalize_ssh_keys( .authn .actor_required() .internal_context("loading current user's ssh keys for new Instance")?; - let (.., authz_user) = LookupPath::new(opctx, &datastore) + let (.., authz_user) = LookupPath::new(opctx, datastore) .silo_user_id(actor.actor_id()) .lookup_for(authz::Action::ListChildren) .await?; diff --git a/nexus/src/app/instance_network.rs b/nexus/src/app/instance_network.rs index 5472383b8d3..649dd870d7e 100644 --- a/nexus/src/app/instance_network.rs +++ b/nexus/src/app/instance_network.rs @@ -6,6 +6,7 @@ use crate::app::switch_port; use ipnetwork::IpNetwork; +use nexus_db_lookup::LookupPath; use nexus_db_model::ExternalIp; use nexus_db_model::IpAttachState; use nexus_db_model::Ipv4NatEntry; @@ -14,7 +15,6 @@ use nexus_db_model::Vni as DbVni; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::DataStore; -use nexus_db_queries::db::lookup::LookupPath; use omicron_common::api::external::Error; use omicron_common::api::internal::shared::NetworkInterface; use omicron_common::api::internal::shared::SwitchLocation; diff --git a/nexus/src/app/internet_gateway.rs b/nexus/src/app/internet_gateway.rs index 610e6e86d1e..23bb9d3bcac 100644 --- a/nexus/src/app/internet_gateway.rs +++ b/nexus/src/app/internet_gateway.rs @@ -7,9 +7,9 @@ use crate::external_api::params; use nexus_auth::authz; use nexus_auth::context::OpContext; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_queries::db; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use nexus_types::identity::Resource; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DeleteResult; diff --git a/nexus/src/app/ip_pool.rs b/nexus/src/app/ip_pool.rs index f51b1184c90..07b3ea8b7d9 100644 --- a/nexus/src/app/ip_pool.rs +++ b/nexus/src/app/ip_pool.rs @@ -7,12 +7,12 @@ use crate::external_api::params; use crate::external_api::shared::IpRange; use ipnetwork::IpNetwork; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_queries::authz; use nexus_db_queries::authz::ApiResource; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::db::model::Name; use nexus_types::identity::Resource; use omicron_common::api::external::CreateResult; diff --git a/nexus/src/app/metrics.rs b/nexus/src/app/metrics.rs index 040c070168f..23afb3be986 100644 --- a/nexus/src/app/metrics.rs +++ b/nexus/src/app/metrics.rs @@ -6,11 +6,9 @@ use crate::external_api::params::ResourceMetrics; use dropshot::PaginationParams; +use nexus_db_lookup::lookup; use nexus_db_queries::authz; -use nexus_db_queries::{ - context::OpContext, - db::{fixed_data::FLEET_ID, lookup}, -}; +use nexus_db_queries::{context::OpContext, db::fixed_data::FLEET_ID}; use nexus_external_api::TimeseriesSchemaPaginationParams; use nexus_types::external_api::params::SystemMetricName; use omicron_common::api::external::{Error, InternalContext}; diff --git a/nexus/src/app/mod.rs b/nexus/src/app/mod.rs index 2a74c77bdc1..e7bb96ff46f 100644 --- a/nexus/src/app/mod.rs +++ b/nexus/src/app/mod.rs @@ -819,9 +819,9 @@ impl Nexus { /// underneath Organizations: /// /// ``` + /// use nexus_db_lookup::LookupPath; /// use nexus_db_queries::authz; /// use nexus_db_queries::context::OpContext; - /// use nexus_db_queries::db::lookup::LookupPath; /// use nexus_db_queries::db::model::Name; /// use nexus_db_queries::db::DataStore; /// use omicron_nexus::app::Nexus; @@ -849,9 +849,9 @@ impl Nexus { /// example stub for the "get" endpoint for that same resource: /// /// ``` + /// use nexus_db_lookup::LookupPath; /// use nexus_db_queries::authz; /// use nexus_db_queries::context::OpContext; - /// use nexus_db_queries::db::lookup::LookupPath; /// use nexus_db_queries::db::model::Name; /// use nexus_db_queries::db::DataStore; /// use omicron_nexus::app::Nexus; diff --git a/nexus/src/app/network_interface.rs b/nexus/src/app/network_interface.rs index 7ce35aa4154..b869fa85dbe 100644 --- a/nexus/src/app/network_interface.rs +++ b/nexus/src/app/network_interface.rs @@ -1,3 +1,4 @@ +use nexus_db_lookup::lookup; use nexus_db_queries::authz::ApiResource; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::queries::network_interface; @@ -15,9 +16,9 @@ use omicron_uuid_kinds::InstanceUuid; use oxnet::IpNet; use uuid::Uuid; +use nexus_db_lookup::{self, LookupPath}; use nexus_db_queries::authz; use nexus_db_queries::db; -use nexus_db_queries::db::lookup::{self, LookupPath}; impl super::Nexus { pub fn instance_network_interface_lookup<'a>( diff --git a/nexus/src/app/probe.rs b/nexus/src/app/probe.rs index f4b5602a7d0..7653006fb0f 100644 --- a/nexus/src/app/probe.rs +++ b/nexus/src/app/probe.rs @@ -1,7 +1,7 @@ +use nexus_db_lookup::lookup; use nexus_db_model::Probe; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; -use nexus_db_queries::db::lookup; use nexus_types::external_api::params; use nexus_types::external_api::shared::ProbeInfo; use nexus_types::identity::Resource; diff --git a/nexus/src/app/project.rs b/nexus/src/app/project.rs index 531fad4fb22..0f994a8c58e 100644 --- a/nexus/src/app/project.rs +++ b/nexus/src/app/project.rs @@ -8,12 +8,12 @@ use crate::app::sagas; use crate::external_api::params; use crate::external_api::shared; use anyhow::Context; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_queries::authn; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DeleteResult; use omicron_common::api::external::Error; diff --git a/nexus/src/app/quota.rs b/nexus/src/app/quota.rs index f59069a9abb..ee131171ce8 100644 --- a/nexus/src/app/quota.rs +++ b/nexus/src/app/quota.rs @@ -4,10 +4,10 @@ //! Resource limits and system quotas +use nexus_db_lookup::lookup; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup; use nexus_types::external_api::params; use omicron_common::api::external::DataPageParams; use omicron_common::api::external::Error; diff --git a/nexus/src/app/rack.rs b/nexus/src/app/rack.rs index a509b1b5599..3db5e46f967 100644 --- a/nexus/src/app/rack.rs +++ b/nexus/src/app/rack.rs @@ -12,6 +12,7 @@ use crate::internal_api::params::RackInitializationRequest; use gateway_client::types::SpType; use internal_dns_types::names::DNS_ZONE; use ipnetwork::{IpNetwork, Ipv6Network}; +use nexus_db_lookup::LookupPath; use nexus_db_model::DnsGroup; use nexus_db_model::INFRA_LOT; use nexus_db_model::InitialDnsGroup; @@ -21,7 +22,6 @@ use nexus_db_queries::db; use nexus_db_queries::db::datastore::DnsVersionUpdateBuilder; use nexus_db_queries::db::datastore::RackInit; use nexus_db_queries::db::datastore::SledUnderlayAllocationResult; -use nexus_db_queries::db::lookup::LookupPath; use nexus_types::deployment::BlueprintZoneDisposition; use nexus_types::deployment::BlueprintZoneType; use nexus_types::deployment::CockroachDbClusterVersion; diff --git a/nexus/src/app/sagas/common_storage.rs b/nexus/src/app/sagas/common_storage.rs index a0f62a2c0e7..81852cebd97 100644 --- a/nexus/src/app/sagas/common_storage.rs +++ b/nexus/src/app/sagas/common_storage.rs @@ -10,10 +10,10 @@ use crate::Nexus; use crucible_pantry_client::types::Error as CruciblePantryClientError; use crucible_pantry_client::types::VolumeConstructionRequest; use internal_dns_types::names::ServiceName; +use nexus_db_lookup::LookupPath; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup::LookupPath; use omicron_common::api::external::Error; use omicron_common::progenitor_operation_retry::ProgenitorOperationRetry; use omicron_common::progenitor_operation_retry::ProgenitorOperationRetryError; @@ -77,7 +77,7 @@ pub(crate) async fn call_pantry_attach_for_disk( disk_id: Uuid, pantry_address: SocketAddrV6, ) -> Result<(), ActionError> { - let (.., disk) = LookupPath::new(opctx, &nexus.datastore()) + let (.., disk) = LookupPath::new(opctx, nexus.datastore()) .disk_id(disk_id) .fetch_for(authz::Action::Modify) .await diff --git a/nexus/src/app/sagas/disk_create.rs b/nexus/src/app/sagas/disk_create.rs index 701fdae63b7..42eec4a4bd9 100644 --- a/nexus/src/app/sagas/disk_create.rs +++ b/nexus/src/app/sagas/disk_create.rs @@ -12,8 +12,8 @@ use super::{ use crate::app::sagas::declare_saga_actions; use crate::app::{authn, authz, db}; use crate::external_api::params; +use nexus_db_lookup::LookupPath; use nexus_db_queries::db::identity::{Asset, Resource}; -use nexus_db_queries::db::lookup::LookupPath; use omicron_common::api::external::DiskState; use omicron_common::api::external::Error; use omicron_uuid_kinds::VolumeUuid; @@ -154,7 +154,7 @@ async fn sdc_create_disk_record( } params::DiskSource::Snapshot { snapshot_id } => { let (.., db_snapshot) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .snapshot_id(*snapshot_id) .fetch() .await @@ -167,16 +167,15 @@ async fn sdc_create_disk_record( db_snapshot.block_size } params::DiskSource::Image { image_id } => { - let (.., image) = - LookupPath::new(&opctx, &osagactx.datastore()) - .image_id(*image_id) - .fetch() - .await - .map_err(|e| { - ActionError::action_failed(Error::internal_error( - &e.to_string(), - )) - })?; + let (.., image) = LookupPath::new(&opctx, osagactx.datastore()) + .image_id(*image_id) + .fetch() + .await + .map_err(|e| { + ActionError::action_failed(Error::internal_error( + &e.to_string(), + )) + })?; image.block_size } @@ -201,7 +200,7 @@ async fn sdc_create_disk_record( ActionError::action_failed(Error::invalid_request(&e.to_string())) })?; - let (.., authz_project) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., authz_project) = LookupPath::new(&opctx, osagactx.datastore()) .project_id(params.project_id) .lookup_for(authz::Action::CreateChild) .await @@ -380,7 +379,7 @@ async fn sdc_regions_ensure( debug!(log, "grabbing snapshot {}", snapshot_id); let (.., db_snapshot) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .snapshot_id(*snapshot_id) .fetch() .await @@ -423,12 +422,11 @@ async fn sdc_regions_ensure( params::DiskSource::Image { image_id } => { debug!(log, "grabbing image {}", image_id); - let (.., image) = - LookupPath::new(&opctx, &osagactx.datastore()) - .image_id(*image_id) - .fetch() - .await - .map_err(ActionError::action_failed)?; + let (.., image) = LookupPath::new(&opctx, osagactx.datastore()) + .image_id(*image_id) + .fetch() + .await + .map_err(ActionError::action_failed)?; debug!(log, "retrieved project image {}", image.id()); @@ -575,7 +573,7 @@ async fn sdc_regions_ensure_undo( ); let disk_id = sagactx.lookup::("disk_id")?; - let (.., authz_disk, db_disk) = LookupPath::new(&opctx, &datastore) + let (.., authz_disk, db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk_id) .fetch_for(authz::Action::Modify) .await @@ -647,7 +645,7 @@ async fn sdc_finalize_disk_record( let disk_id = sagactx.lookup::("disk_id")?; let disk_created = sagactx.lookup::("created_disk")?; - let (.., authz_disk) = LookupPath::new(&opctx, &datastore) + let (.., authz_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk_id) .lookup_for(authz::Action::Modify) .await @@ -713,7 +711,7 @@ async fn sdc_get_pantry_address( "using pantry at {} for importing to disk {}", pantry_address, disk_id ); - let (.., authz_disk) = LookupPath::new(&opctx, &datastore) + let (.., authz_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk_id) .lookup_for(authz::Action::Modify) .await diff --git a/nexus/src/app/sagas/finalize_disk.rs b/nexus/src/app/sagas/finalize_disk.rs index 1729746ffe8..91d336dfcc9 100644 --- a/nexus/src/app/sagas/finalize_disk.rs +++ b/nexus/src/app/sagas/finalize_disk.rs @@ -13,8 +13,8 @@ use super::declare_saga_actions; use crate::app::sagas::common_storage::call_pantry_detach; use crate::app::sagas::snapshot_create; use crate::external_api::params; +use nexus_db_lookup::LookupPath; use nexus_db_model::Generation; -use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::{authn, authz}; use omicron_common::api::external; use omicron_common::api::external::Error; @@ -144,7 +144,7 @@ async fn sfd_set_finalizing_state( ); let (.., authz_disk, db_disk) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch_for(authz::Action::Modify) .await @@ -167,7 +167,7 @@ async fn sfd_set_finalizing_state( // Record the disk's new generation number as this saga node's output. It // will be important later to *only* transition this disk out of finalizing // if the generation number matches what *this* saga is doing. - let (.., db_disk) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., db_disk) = LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch_for(authz::Action::Read) .await @@ -195,7 +195,7 @@ async fn sfd_set_finalizing_state_undo( ); let (.., authz_disk, db_disk) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch_for(authz::Action::Modify) .await @@ -260,7 +260,7 @@ async fn sfd_get_pantry_address( ¶ms.serialized_authn, ); - let (.., db_disk) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., db_disk) = LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch_for(authz::Action::Modify) .await @@ -316,7 +316,7 @@ async fn sfd_clear_pantry_address( info!(log, "setting disk {} pantry to None", params.disk_id); - let (.., authz_disk) = LookupPath::new(&opctx, &datastore) + let (.., authz_disk) = LookupPath::new(&opctx, datastore) .disk_id(params.disk_id) .lookup_for(authz::Action::Modify) .await @@ -342,7 +342,7 @@ async fn sfd_set_detached_state( ); let (.., authz_disk, db_disk) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch_for(authz::Action::Modify) .await diff --git a/nexus/src/app/sagas/image_create.rs b/nexus/src/app/sagas/image_create.rs index 0ed362c3dbc..60e09b3381c 100644 --- a/nexus/src/app/sagas/image_create.rs +++ b/nexus/src/app/sagas/image_create.rs @@ -9,7 +9,7 @@ use super::{ use crate::app::sagas::declare_saga_actions; use crate::app::{authn, authz, db}; use crate::external_api::params; -use nexus_db_queries::db::lookup::LookupPath; +use nexus_db_lookup::LookupPath; use omicron_common::api::external; use omicron_common::api::external::Error; use omicron_uuid_kinds::GenericUuid; @@ -139,7 +139,7 @@ async fn simc_get_source_volume( match ¶ms.create_params.source { params::ImageSource::Snapshot { id } => { let (.., db_snapshot) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .snapshot_id(*id) .fetch() .await @@ -324,7 +324,7 @@ async fn simc_create_image_record_undo( match ¶ms.image_type { ImageType::Project { .. } => { let (.., authz_image, db_image) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .project_image_id(image_id) .fetch() .await?; @@ -337,7 +337,7 @@ async fn simc_create_image_record_undo( ImageType::Silo { .. } => { let (.., authz_image, db_image) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .silo_image_id(image_id) .fetch() .await?; @@ -386,7 +386,7 @@ pub(crate) mod test { let datastore = cptestctx.server.server_context().nexus.datastore(); let (.., authz_silo, _authz_project) = - LookupPath::new(&opctx, &datastore) + LookupPath::new(&opctx, datastore) .project_id(project_id) .lookup_for(nexus_db_queries::authz::Action::Modify) .await @@ -437,7 +437,7 @@ pub(crate) mod test { let opctx = test_opctx(cptestctx); let (.., authz_silo, authz_project) = - LookupPath::new(&opctx, &datastore) + LookupPath::new(&opctx, datastore) .project_id(project_id) .lookup_for(nexus_db_queries::authz::Action::Modify) .await diff --git a/nexus/src/app/sagas/instance_common.rs b/nexus/src/app/sagas/instance_common.rs index 7569f9d7072..b4644201e0c 100644 --- a/nexus/src/app/sagas/instance_common.rs +++ b/nexus/src/app/sagas/instance_common.rs @@ -7,12 +7,12 @@ use std::net::{IpAddr, Ipv6Addr}; use crate::Nexus; +use nexus_db_lookup::LookupPath; use nexus_db_model::{ ByteCount, ExternalIp, InstanceState, IpAttachState, Ipv4NatEntry, SledReservationConstraints, SledResourceVmm, VmmState, }; use nexus_db_queries::authz; -use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::{authn, context::OpContext, db, db::DataStore}; use omicron_common::api::external::{Error, NameOrId}; use omicron_uuid_kinds::{GenericUuid, InstanceUuid, PropolisUuid, SledUuid}; @@ -355,7 +355,7 @@ pub async fn instance_ip_add_nat( // Querying sleds requires fleet access; use the instance allocator context // for this. - let (.., sled) = LookupPath::new(&osagactx.nexus().opctx_alloc, &datastore) + let (.., sled) = LookupPath::new(&osagactx.nexus().opctx_alloc, datastore) .sled_id(sled_uuid.into_untyped_uuid()) .fetch() .await diff --git a/nexus/src/app/sagas/instance_create.rs b/nexus/src/app/sagas/instance_create.rs index 942e0a29596..7242379ee8a 100644 --- a/nexus/src/app/sagas/instance_create.rs +++ b/nexus/src/app/sagas/instance_create.rs @@ -10,8 +10,8 @@ use crate::app::{ MAX_NICS_PER_INSTANCE, }; use crate::external_api::params; +use nexus_db_lookup::LookupPath; use nexus_db_model::{ExternalIp, NetworkInterfaceKind}; -use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::db::queries::network_interface::InsertError as InsertNicError; use nexus_db_queries::{authn, authz, db}; use nexus_defaults::DEFAULT_PRIMARY_NIC_NAME; @@ -390,7 +390,7 @@ async fn sic_associate_ssh_keys( .internal_context("loading current user's ssh keys for new Instance") .map_err(ActionError::action_failed)?; - let (.., authz_user) = LookupPath::new(&opctx, &datastore) + let (.., authz_user) = LookupPath::new(&opctx, datastore) .silo_user_id(actor.actor_id()) .lookup_for(authz::Action::ListChildren) .await @@ -520,13 +520,13 @@ async fn sic_create_network_interface_undo( &saga_params.serialized_authn, ); let interface_id = repeat_saga_params.new_id; - let (.., authz_instance) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::Modify) .await .map_err(ActionError::action_failed)?; - let interface_deleted = match LookupPath::new(&opctx, &datastore) + let interface_deleted = match LookupPath::new(&opctx, datastore) .instance_network_interface_id(interface_id) .lookup_for(authz::Action::Delete) .await @@ -579,12 +579,12 @@ async fn create_custom_network_interface( ); // Lookup authz objects, used in the call to create the NIC itself. - let (.., authz_instance) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::CreateChild) .await .map_err(ActionError::action_failed)?; - let (.., authz_vpc) = LookupPath::new(&opctx, &datastore) + let (.., authz_vpc) = LookupPath::new(&opctx, datastore) .project_id(saga_params.project_id) .vpc_name(&db::model::Name::from(interface_params.vpc_name.clone())) .lookup_for(authz::Action::Read) @@ -596,7 +596,7 @@ async fn create_custom_network_interface( // should probably either be in a transaction, or the // `instance_create_network_interface` function/query needs some JOIN // on the `vpc_subnet` table. - let (.., authz_subnet, db_subnet) = LookupPath::new(&opctx, &datastore) + let (.., authz_subnet, db_subnet) = LookupPath::new(&opctx, datastore) .vpc_id(authz_vpc.id()) .vpc_subnet_name(&db::model::Name::from( interface_params.subnet_name.clone(), @@ -685,12 +685,12 @@ async fn create_default_primary_network_interface( }; // Lookup authz objects, used in the call to actually create the NIC. - let (.., authz_instance) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::CreateChild) .await .map_err(ActionError::action_failed)?; - let (.., authz_subnet, db_subnet) = LookupPath::new(&opctx, &datastore) + let (.., authz_subnet, db_subnet) = LookupPath::new(&opctx, datastore) .project_id(saga_params.project_id) .vpc_name(&internal_default_name) .vpc_subnet_name(&internal_default_name) @@ -911,7 +911,7 @@ async fn sic_allocate_instance_external_ip_undo( datastore.deallocate_external_ip(&opctx, ip.id).await?; } params::ExternalIpCreate::Floating { .. } => { - let (.., authz_fip) = LookupPath::new(&opctx, &datastore) + let (.., authz_fip) = LookupPath::new(&opctx, datastore) .floating_ip_id(ip.id) .lookup_for(authz::Action::Modify) .await?; @@ -984,16 +984,15 @@ async fn ensure_instance_disk_attach_state( } }; - let (.., authz_instance, _db_instance) = - LookupPath::new(&opctx, &datastore) - .instance_id(instance_id.into_untyped_uuid()) - .fetch() - .await - .map_err(ActionError::action_failed)?; + let (.., authz_instance, _db_instance) = LookupPath::new(&opctx, datastore) + .instance_id(instance_id.into_untyped_uuid()) + .fetch() + .await + .map_err(ActionError::action_failed)?; // TODO-correctness TODO-security It's not correct to re-resolve the // disk name now. See oxidecomputer/omicron#1536. - let (.., authz_disk, _db_disk) = LookupPath::new(&opctx, &datastore) + let (.., authz_disk, _db_disk) = LookupPath::new(&opctx, datastore) .project_id(project_id) .disk_name(&disk_name) .fetch() @@ -1037,7 +1036,7 @@ async fn sic_create_instance_record( ¶ms.create_params, ); - let (.., authz_project) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., authz_project) = LookupPath::new(&opctx, osagactx.datastore()) .project_id(params.project_id) .lookup_for(authz::Action::CreateChild) .await @@ -1065,7 +1064,7 @@ async fn sic_delete_instance_record( let instance_id = sagactx.lookup::("instance_id")?; - let result = LookupPath::new(&opctx, &datastore) + let result = LookupPath::new(&opctx, datastore) .instance_id(instance_id.into_untyped_uuid()) .fetch() .await; @@ -1141,7 +1140,7 @@ async fn sic_set_boot_disk( let instance_id = sagactx.lookup::("instance_id")?; - let (.., authz_instance) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::Modify) .await @@ -1175,7 +1174,7 @@ async fn sic_set_boot_disk_undo( let instance_id = sagactx.lookup::("instance_id")?; - let (.., authz_instance) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::Modify) .await diff --git a/nexus/src/app/sagas/instance_delete.rs b/nexus/src/app/sagas/instance_delete.rs index b15fbf26410..2056a14784c 100644 --- a/nexus/src/app/sagas/instance_delete.rs +++ b/nexus/src/app/sagas/instance_delete.rs @@ -8,7 +8,7 @@ use super::ActionRegistry; use super::NexusActionContext; use super::NexusSaga; use crate::app::sagas::declare_saga_actions; -use nexus_db_queries::db::lookup::LookupPath; +use nexus_db_lookup::LookupPath; use nexus_db_queries::{authn, authz, db}; use omicron_common::api::internal::shared::SwitchLocation; use serde::Deserialize; @@ -117,7 +117,7 @@ async fn sid_delete_nat( ¶ms.serialized_authn, ); - let (.., authz_instance) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., authz_instance) = LookupPath::new(&opctx, osagactx.datastore()) .instance_id(instance_id) .lookup_for(authz::Action::Modify) .await @@ -166,9 +166,8 @@ mod test { app::sagas::instance_delete::SagaInstanceDelete, external_api::params, }; use dropshot::test_util::ClientTestContext; - use nexus_db_queries::{ - authn::saga::Serialized, context::OpContext, db, db::lookup::LookupPath, - }; + use nexus_db_lookup::LookupPath; + use nexus_db_queries::{authn::saga::Serialized, context::OpContext, db}; use nexus_test_utils::resource_helpers::DiskTest; use nexus_test_utils::resource_helpers::create_default_ip_pool; use nexus_test_utils::resource_helpers::create_disk; @@ -203,12 +202,11 @@ mod test { let opctx = test_opctx(&cptestctx); let datastore = cptestctx.server.server_context().nexus.datastore(); - let (.., authz_instance, instance) = - LookupPath::new(&opctx, &datastore) - .instance_id(instance_id) - .fetch() - .await - .expect("Failed to lookup instance"); + let (.., authz_instance, instance) = LookupPath::new(&opctx, datastore) + .instance_id(instance_id) + .fetch() + .await + .expect("Failed to lookup instance"); Params { serialized_authn: Serialized::for_opctx(&opctx), authz_instance, diff --git a/nexus/src/app/sagas/instance_ip_attach.rs b/nexus/src/app/sagas/instance_ip_attach.rs index a58bc8d4efc..f34d63b9ec6 100644 --- a/nexus/src/app/sagas/instance_ip_attach.rs +++ b/nexus/src/app/sagas/instance_ip_attach.rs @@ -330,9 +330,9 @@ pub(crate) mod test { ExpressionMethods, OptionalExtension, QueryDsl, SelectableHelper, }; use dropshot::test_util::ClientTestContext; + use nexus_db_lookup::LookupPath; use nexus_db_model::{ExternalIp, IpKind}; use nexus_db_queries::context::OpContext; - use nexus_db_queries::db::lookup::LookupPath; use nexus_test_utils::resource_helpers::{ create_default_ip_pool, create_floating_ip, create_instance, create_project, diff --git a/nexus/src/app/sagas/instance_ip_detach.rs b/nexus/src/app/sagas/instance_ip_detach.rs index d23bdd5a293..355a4f21d42 100644 --- a/nexus/src/app/sagas/instance_ip_detach.rs +++ b/nexus/src/app/sagas/instance_ip_detach.rs @@ -11,8 +11,8 @@ use super::{ActionRegistry, NexusActionContext, NexusSaga}; use crate::app::sagas::declare_saga_actions; use crate::app::{authn, authz, db}; use crate::external_api::params; +use nexus_db_lookup::LookupPath; use nexus_db_model::IpAttachState; -use nexus_db_queries::db::lookup::LookupPath; use nexus_types::external_api::views; use omicron_common::api::external::NameOrId; use omicron_uuid_kinds::{GenericUuid, InstanceUuid}; diff --git a/nexus/src/app/sagas/instance_migrate.rs b/nexus/src/app/sagas/instance_migrate.rs index b0217b75ae1..96349960dc8 100644 --- a/nexus/src/app/sagas/instance_migrate.rs +++ b/nexus/src/app/sagas/instance_migrate.rs @@ -10,7 +10,8 @@ use crate::app::instance::{ use crate::app::sagas::{ declare_saga_actions, instance_common::allocate_vmm_ipv6, }; -use nexus_db_queries::db::{identity::Resource, lookup::LookupPath}; +use nexus_db_lookup::LookupPath; +use nexus_db_queries::db::identity::Resource; use nexus_db_queries::{authn, authz, db}; use nexus_types::internal_api::params::InstanceMigrateRequest; use omicron_common::api::external::Error; @@ -399,7 +400,7 @@ async fn sim_ensure_destination_propolis( "dst_vmm_state" => ?vmm); let (authz_silo, authz_project, authz_instance) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .instance_id(db_instance.id()) .lookup_for(authz::Action::Modify) .await diff --git a/nexus/src/app/sagas/instance_start.rs b/nexus/src/app/sagas/instance_start.rs index 4685421c58f..4045f55984a 100644 --- a/nexus/src/app/sagas/instance_start.rs +++ b/nexus/src/app/sagas/instance_start.rs @@ -16,7 +16,8 @@ use crate::app::instance::{ }; use crate::app::sagas::declare_saga_actions; use chrono::Utc; -use nexus_db_queries::db::{identity::Resource, lookup::LookupPath}; +use nexus_db_lookup::LookupPath; +use nexus_db_queries::db::identity::Resource; use nexus_db_queries::{authn, authz, db}; use omicron_common::api::external::Error; use omicron_uuid_kinds::{GenericUuid, InstanceUuid, PropolisUuid, SledUuid}; @@ -295,7 +296,7 @@ async fn sis_move_to_starting( // For idempotency, refetch the instance to see if this step already applied // its desired update. - let (_, _, authz_instance, ..) = LookupPath::new(&opctx, &datastore) + let (_, _, authz_instance, ..) = LookupPath::new(&opctx, datastore) .instance_id(instance_id.into_untyped_uuid()) .fetch_for(authz::Action::Modify) .await @@ -491,7 +492,7 @@ async fn sis_dpd_ensure( // Querying sleds requires fleet access; use the instance allocator context // for this. let sled_uuid = sagactx.lookup::("sled_id")?; - let (.., sled) = LookupPath::new(&osagactx.nexus().opctx_alloc, &datastore) + let (.., sled) = LookupPath::new(&osagactx.nexus().opctx_alloc, datastore) .sled_id(sled_uuid.into_untyped_uuid()) .fetch() .await @@ -522,7 +523,7 @@ async fn sis_dpd_ensure_undo( "instance_id" => %instance_id, "start_reason" => ?params.reason); - let (.., authz_instance) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., authz_instance) = LookupPath::new(&opctx, osagactx.datastore()) .instance_id(instance_id) .lookup_for(authz::Action::Modify) .await @@ -576,7 +577,7 @@ async fn sis_ensure_registered( "start_reason" => ?params.reason); let (authz_silo, authz_project, authz_instance) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .instance_id(instance_id) .lookup_for(authz::Action::Modify) .await @@ -646,7 +647,7 @@ async fn sis_ensure_registered_undo( // Fetch the latest record so that this callee can drive the instance into // a Failed state if the unregister call fails. - let (.., authz_instance, _) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance, _) = LookupPath::new(&opctx, datastore) .instance_id(instance_id.into_untyped_uuid()) .fetch() .await diff --git a/nexus/src/app/sagas/instance_update/mod.rs b/nexus/src/app/sagas/instance_update/mod.rs index 5c1697583d2..3dc1465e08f 100644 --- a/nexus/src/app/sagas/instance_update/mod.rs +++ b/nexus/src/app/sagas/instance_update/mod.rs @@ -347,7 +347,6 @@ use super::{ use crate::app::db::datastore::InstanceGestalt; use crate::app::db::datastore::VmmStateUpdateResult; use crate::app::db::datastore::instance; -use crate::app::db::lookup::LookupPath; use crate::app::db::model::ByteCount; use crate::app::db::model::Generation; use crate::app::db::model::InstanceRuntimeState; @@ -358,6 +357,7 @@ use crate::app::db::model::VmmState; use crate::app::sagas::declare_saga_actions; use anyhow::Context; use chrono::Utc; +use nexus_db_lookup::LookupPath; use nexus_db_queries::{authn, authz}; use nexus_types::identity::Resource; use omicron_common::api::external::Error; @@ -1478,8 +1478,8 @@ mod test { use crate::external_api::params; use chrono::Utc; use dropshot::test_util::ClientTestContext; + use nexus_db_lookup::LookupPath; use nexus_db_queries::db::datastore::InstanceAndActiveVmm; - use nexus_db_queries::db::lookup::LookupPath; use nexus_test_utils::resource_helpers::{ create_default_ip_pool, create_project, object_create, }; @@ -2466,12 +2466,11 @@ mod test { ) .await; - let (_, _, authz_instance, ..) = - LookupPath::new(&opctx, &datastore) - .instance_id(instance_id.into_untyped_uuid()) - .fetch() - .await - .expect("test instance should be present in datastore"); + let (_, _, authz_instance, ..) = LookupPath::new(&opctx, datastore) + .instance_id(instance_id.into_untyped_uuid()) + .fetch() + .await + .expect("test instance should be present in datastore"); let initial_state = datastore .instance_fetch_all(&opctx, &authz_instance) .await diff --git a/nexus/src/app/sagas/project_create.rs b/nexus/src/app/sagas/project_create.rs index bc358f96b78..37434275c02 100644 --- a/nexus/src/app/sagas/project_create.rs +++ b/nexus/src/app/sagas/project_create.rs @@ -104,7 +104,7 @@ async fn spc_create_record_undo( sagactx.lookup::<(authz::Project, db::model::Project)>("project")?; let (.., authz_project, project) = - db::lookup::LookupPath::new(&opctx, osagactx.datastore()) + nexus_db_lookup::LookupPath::new(&opctx, osagactx.datastore()) .project_id(project.id()) .fetch_for(authz::Action::Delete) .await?; diff --git a/nexus/src/app/sagas/region_replacement_drive.rs b/nexus/src/app/sagas/region_replacement_drive.rs index 71c2f125471..b0989bbf75f 100644 --- a/nexus/src/app/sagas/region_replacement_drive.rs +++ b/nexus/src/app/sagas/region_replacement_drive.rs @@ -141,12 +141,12 @@ use super::{ SagaInitError, }; use crate::app::db::datastore::InstanceAndActiveVmm; -use crate::app::db::lookup::LookupPath; use crate::app::sagas::common_storage::get_pantry_address; use crate::app::sagas::declare_saga_actions; use crate::app::{authn, authz, db}; use chrono::DateTime; use chrono::Utc; +use nexus_db_lookup::LookupPath; use nexus_db_model::VmmState; use omicron_common::api::external::Error; use omicron_uuid_kinds::VolumeUuid; @@ -375,7 +375,7 @@ async fn srrd_drive_region_replacement_check( }; let (.., authz_instance) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .instance_id(step_instance_id) .lookup_for(authz::Action::Read) .await @@ -874,7 +874,7 @@ async fn srrd_drive_region_replacement_prepare( Some(instance_id) => { // The region's volume is attached to an instance let (.., authz_instance) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .instance_id(*instance_id) .lookup_for(authz::Action::Read) .await @@ -1187,7 +1187,7 @@ async fn srrd_drive_region_replacement_execute( }; let (.., authz_instance) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .instance_id(instance_id) .lookup_for(authz::Action::Read) .await @@ -1245,9 +1245,8 @@ async fn srrd_drive_region_replacement_execute( } }; - let instance_lookup = - LookupPath::new(&opctx, &osagactx.datastore()) - .instance_id(instance_id); + let instance_lookup = LookupPath::new(&opctx, osagactx.datastore()) + .instance_id(instance_id); let (vmm, client) = osagactx .nexus() diff --git a/nexus/src/app/sagas/region_replacement_start.rs b/nexus/src/app/sagas/region_replacement_start.rs index b1fe3c5a27b..cf04906eda4 100644 --- a/nexus/src/app/sagas/region_replacement_start.rs +++ b/nexus/src/app/sagas/region_replacement_start.rs @@ -764,13 +764,14 @@ async fn srrs_update_request_record( pub(crate) mod test { use crate::{ app::RegionAllocationStrategy, app::db::DataStore, - app::db::lookup::LookupPath, app::saga::create_saga_dag, + app::saga::create_saga_dag, app::sagas::region_replacement_start::Params, app::sagas::region_replacement_start::SagaRegionReplacementStart, app::sagas::region_replacement_start::find_only_new_region, app::sagas::test_helpers::test_opctx, }; use chrono::Utc; + use nexus_db_lookup::LookupPath; use nexus_db_model::CrucibleDataset; use nexus_db_model::Region; use nexus_db_model::RegionReplacement; @@ -816,7 +817,7 @@ pub(crate) mod test { // Assert disk has three allocated regions let disk_id = disk.identity.id; - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk_id) .fetch() .await @@ -1137,7 +1138,7 @@ pub(crate) mod test { let disk = create_disk(&client, PROJECT_NAME, DISK_NAME).await; let disk_id = disk.identity.id; - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk_id) .fetch() .await @@ -1212,7 +1213,7 @@ pub(crate) mod test { let disk = create_disk(&client, PROJECT_NAME, DISK_NAME).await; let disk_id = disk.identity.id; - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk_id) .fetch() .await diff --git a/nexus/src/app/sagas/region_snapshot_replacement_start.rs b/nexus/src/app/sagas/region_snapshot_replacement_start.rs index def3d6ac919..aeb78baf9e2 100644 --- a/nexus/src/app/sagas/region_snapshot_replacement_start.rs +++ b/nexus/src/app/sagas/region_snapshot_replacement_start.rs @@ -1219,10 +1219,11 @@ async fn rsrss_update_request_record( pub(crate) mod test { use crate::{ app::RegionAllocationStrategy, app::db::DataStore, - app::db::lookup::LookupPath, app::saga::create_saga_dag, + app::saga::create_saga_dag, app::sagas::region_snapshot_replacement_start::*, app::sagas::test_helpers::test_opctx, }; + use nexus_db_lookup::LookupPath; use nexus_db_model::PhysicalDiskPolicy; use nexus_db_model::RegionSnapshotReplacement; use nexus_db_model::RegionSnapshotReplacementState; @@ -1274,7 +1275,7 @@ pub(crate) mod test { assert_eq!(region_allocations(&datastore).await, 3); let disk_id = disk.identity.id; - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk_id) .fetch() .await @@ -1288,7 +1289,7 @@ pub(crate) mod test { assert_eq!(region_allocations(&datastore).await, 6); let snapshot_id = snapshot.identity.id; - let (.., db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot_id) .fetch() .await @@ -1856,13 +1857,13 @@ pub(crate) mod test { create_snapshot(&client, PROJECT_NAME, "disk", "snap").await; // Before expunging any physical disk, save some DB models - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await .unwrap(); - let (.., db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot.identity.id) .fetch() .await @@ -2014,13 +2015,13 @@ pub(crate) mod test { create_snapshot(&client, PROJECT_NAME, "disk", "snap").await; // Before expunging any physical disk, save some DB models - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await .unwrap(); - let (.., db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot.identity.id) .fetch() .await diff --git a/nexus/src/app/sagas/region_snapshot_replacement_step.rs b/nexus/src/app/sagas/region_snapshot_replacement_step.rs index 5a3fdaed93e..f5cbd08b581 100644 --- a/nexus/src/app/sagas/region_snapshot_replacement_step.rs +++ b/nexus/src/app/sagas/region_snapshot_replacement_step.rs @@ -52,9 +52,9 @@ use crate::app::db::datastore::ReplacementTarget; use crate::app::db::datastore::VolumeReplaceResult; use crate::app::db::datastore::VolumeToDelete; use crate::app::db::datastore::VolumeWithTarget; -use crate::app::db::lookup::LookupPath; use crate::app::sagas::declare_saga_actions; use crate::app::{authn, authz, db}; +use nexus_db_lookup::LookupPath; use nexus_db_model::VmmState; use omicron_common::api::external::Error; use omicron_uuid_kinds::GenericUuid; @@ -443,7 +443,7 @@ async fn rsrss_notify_upstairs( ¶ms.serialized_authn, ); - let (.., authz_instance) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., authz_instance) = LookupPath::new(&opctx, osagactx.datastore()) .instance_id(instance_id) .lookup_for(authz::Action::Read) .await @@ -510,7 +510,7 @@ async fn rsrss_notify_upstairs( }; let instance_lookup = - LookupPath::new(&opctx, &osagactx.datastore()).instance_id(instance_id); + LookupPath::new(&opctx, osagactx.datastore()).instance_id(instance_id); let (vmm, client) = osagactx .nexus() diff --git a/nexus/src/app/sagas/snapshot_create.rs b/nexus/src/app/sagas/snapshot_create.rs index 091e937eb46..c6d019becb7 100644 --- a/nexus/src/app/sagas/snapshot_create.rs +++ b/nexus/src/app/sagas/snapshot_create.rs @@ -100,9 +100,9 @@ use crate::app::sagas::declare_saga_actions; use crate::app::{authn, authz, db}; use crate::external_api::params; use anyhow::anyhow; +use nexus_db_lookup::LookupPath; use nexus_db_model::Generation; use nexus_db_queries::db::identity::{Asset, Resource}; -use nexus_db_queries::db::lookup::LookupPath; use omicron_common::api::external::Error; use omicron_common::progenitor_operation_retry::ProgenitorOperationRetryError; use omicron_common::{ @@ -384,7 +384,7 @@ async fn ssc_take_volume_lock( // is blocked by a snapshot being created, and snapshot creation is blocked // by region replacement. - let (.., disk) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., disk) = LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch() .await @@ -411,7 +411,7 @@ async fn ssc_take_volume_lock_undo( ¶ms.serialized_authn, ); - let (.., disk) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., disk) = LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch() .await?; @@ -448,7 +448,7 @@ async fn ssc_alloc_regions( ¶ms.serialized_authn, ); - let (.., disk) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., disk) = LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch() .await @@ -660,7 +660,7 @@ async fn ssc_create_snapshot_record( info!(log, "grabbing disk by name {}", params.create_params.disk); - let (.., disk) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., disk) = LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch() .await @@ -685,7 +685,7 @@ async fn ssc_create_snapshot_record( size: disk.size, }; - let (.., authz_project) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., authz_project) = LookupPath::new(&opctx, osagactx.datastore()) .project_id(params.project_id) .lookup_for(authz::Action::CreateChild) .await @@ -717,7 +717,7 @@ async fn ssc_create_snapshot_record_undo( info!(log, "deleting snapshot {}", snapshot_id); let (.., authz_snapshot, db_snapshot) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .snapshot_id(snapshot_id) .fetch_for(authz::Action::Delete) .await @@ -814,7 +814,7 @@ async fn ssc_send_snapshot_request_to_sled_agent( ¶ms.serialized_authn, ); - let (.., authz_instance) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., authz_instance) = LookupPath::new(&opctx, osagactx.datastore()) .instance_id(attach_instance_id) .lookup_for(authz::Action::Read) .await @@ -896,7 +896,7 @@ async fn ssc_send_snapshot_request_to_sled_agent_undo( info!(log, "Undoing snapshot request for {snapshot_id}"); // Lookup the regions used by the source disk... - let (.., disk) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., disk) = LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch() .await?; @@ -928,7 +928,7 @@ async fn ssc_get_pantry_address( // If the disk is already attached to a Pantry, use that, otherwise get a // random one. Return boolean indicating if additional saga nodes need to // attach this disk to that random pantry. - let (.., disk) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., disk) = LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch() .await @@ -968,7 +968,7 @@ async fn ssc_attach_disk_to_pantry( ); let (.., authz_disk, db_disk) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch_for(authz::Action::Modify) .await @@ -1029,7 +1029,7 @@ async fn ssc_attach_disk_to_pantry( // Record the disk's new generation number as this saga node's output. It // will be important later to *only* transition this disk out of maintenance // if the generation number matches what *this* saga is doing. - let (.., db_disk) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., db_disk) = LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch_for(authz::Action::Read) .await @@ -1050,7 +1050,7 @@ async fn ssc_attach_disk_to_pantry_undo( ); let (.., authz_disk, db_disk) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch_for(authz::Action::Modify) .await @@ -1244,7 +1244,7 @@ async fn ssc_call_pantry_snapshot_for_disk_undo( info!(log, "Undoing pantry snapshot request for {snapshot_id}"); // Lookup the regions used by the source disk... - let (.., disk) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., disk) = LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch() .await?; @@ -1308,7 +1308,7 @@ async fn ssc_detach_disk_from_pantry( ); let (.., authz_disk, db_disk) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch_for(authz::Action::Modify) .await @@ -1385,7 +1385,7 @@ async fn ssc_start_running_snapshot( let snapshot_id = sagactx.lookup::("snapshot_id")?; info!(log, "starting running snapshot"; "snapshot_id" => %snapshot_id); - let (.., disk) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., disk) = LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch() .await @@ -1476,7 +1476,7 @@ async fn ssc_start_running_snapshot_undo( info!(log, "Undoing snapshot start running request for {snapshot_id}"); // Lookup the regions used by the source disk... - let (.., disk) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., disk) = LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch() .await?; @@ -1520,7 +1520,7 @@ async fn ssc_create_volume_record( ¶ms.serialized_authn, ); - let (.., disk) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., disk) = LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch() .await @@ -1614,7 +1614,7 @@ async fn ssc_finalize_snapshot_record( let snapshot_id = sagactx.lookup::("snapshot_id")?; let (.., authz_snapshot, db_snapshot) = - LookupPath::new(&opctx, &osagactx.datastore()) + LookupPath::new(&opctx, osagactx.datastore()) .snapshot_id(snapshot_id) .fetch_for(authz::Action::Modify) .await @@ -1650,7 +1650,7 @@ async fn ssc_release_volume_lock( ¶ms.serialized_authn, ); - let (.., disk) = LookupPath::new(&opctx, &osagactx.datastore()) + let (.., disk) = LookupPath::new(&opctx, osagactx.datastore()) .disk_id(params.disk_id) .fetch() .await diff --git a/nexus/src/app/sagas/test_helpers.rs b/nexus/src/app/sagas/test_helpers.rs index 2b08081fd65..0e2f76d9ee5 100644 --- a/nexus/src/app/sagas/test_helpers.rs +++ b/nexus/src/app/sagas/test_helpers.rs @@ -12,6 +12,7 @@ use diesel::{ BoolExpressionMethods, ExpressionMethods, QueryDsl, SelectableHelper, }; use futures::future::BoxFuture; +use nexus_db_lookup::LookupPath; use nexus_db_model::InstanceState; use nexus_db_queries::{ authz, @@ -19,7 +20,6 @@ use nexus_db_queries::{ db::{ DataStore, datastore::{InstanceAndActiveVmm, InstanceGestalt}, - lookup::LookupPath, }, }; use nexus_types::identity::Resource; @@ -299,7 +299,7 @@ pub(crate) async fn instance_wait_for_state( ) -> InstanceAndActiveVmm { let opctx = test_opctx(&cptestctx); let datastore = cptestctx.server.server_context().nexus.datastore(); - let (.., authz_instance) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::Read) .await diff --git a/nexus/src/app/sagas/vpc_create.rs b/nexus/src/app/sagas/vpc_create.rs index 616fa01f354..b79cbf3063f 100644 --- a/nexus/src/app/sagas/vpc_create.rs +++ b/nexus/src/app/sagas/vpc_create.rs @@ -656,11 +656,11 @@ pub(crate) mod test { ExpressionMethods, OptionalExtension, QueryDsl, SelectableHelper, }; use dropshot::test_util::ClientTestContext; + use nexus_db_lookup::LookupPath; use nexus_db_queries::db::fixed_data::vpc::SERVICES_INTERNET_GATEWAY_ID; use nexus_db_queries::{ authn::saga::Serialized, authz, context::OpContext, db::datastore::DataStore, db::fixed_data::vpc::SERVICES_VPC_ID, - db::lookup::LookupPath, }; use nexus_test_utils::resource_helpers::create_default_ip_pool; use nexus_test_utils::resource_helpers::create_project; @@ -735,7 +735,7 @@ pub(crate) mod test { let system_name = Name::try_from("system".to_string()).unwrap(); // Default Subnet - let (.., authz_subnet, subnet) = LookupPath::new(&opctx, &datastore) + let (.., authz_subnet, subnet) = LookupPath::new(&opctx, datastore) .project_id(project_id) .vpc_name(&default_name.clone().into()) .vpc_subnet_name(&default_name.clone().into()) @@ -748,7 +748,7 @@ pub(crate) mod test { .expect("Failed to delete default Subnet"); // Default gateway routes - let (.., authz_route, _route) = LookupPath::new(&opctx, &datastore) + let (.., authz_route, _route) = LookupPath::new(&opctx, datastore) .project_id(project_id) .vpc_name(&default_name.clone().into()) .vpc_router_name(&system_name.clone().into()) @@ -761,7 +761,7 @@ pub(crate) mod test { .await .expect("Failed to delete default route"); - let (.., authz_route, _route) = LookupPath::new(&opctx, &datastore) + let (.., authz_route, _route) = LookupPath::new(&opctx, datastore) .project_id(project_id) .vpc_name(&default_name.clone().into()) .vpc_router_name(&system_name.clone().into()) @@ -775,7 +775,7 @@ pub(crate) mod test { .expect("Failed to delete default route"); // System router - let (.., authz_router, _router) = LookupPath::new(&opctx, &datastore) + let (.., authz_router, _router) = LookupPath::new(&opctx, datastore) .project_id(project_id) .vpc_name(&default_name.clone().into()) .vpc_router_name(&system_name.into()) @@ -789,7 +789,7 @@ pub(crate) mod test { // Default gateway let (.., authz_vpc, authz_igw, _igw) = - LookupPath::new(&opctx, &datastore) + LookupPath::new(&opctx, datastore) .project_id(project_id) .vpc_name(&default_name.clone().into()) .internet_gateway_name(&default_name.clone().into()) @@ -807,7 +807,7 @@ pub(crate) mod test { .expect("Failed to delete default gateway"); // Default VPC & Firewall Rules - let (.., authz_vpc, vpc) = LookupPath::new(&opctx, &datastore) + let (.., authz_vpc, vpc) = LookupPath::new(&opctx, datastore) .project_id(project_id) .vpc_name(&default_name.into()) .fetch() diff --git a/nexus/src/app/sagas/vpc_subnet_create.rs b/nexus/src/app/sagas/vpc_subnet_create.rs index d205d2343d2..6da5ad0f09c 100644 --- a/nexus/src/app/sagas/vpc_subnet_create.rs +++ b/nexus/src/app/sagas/vpc_subnet_create.rs @@ -8,7 +8,7 @@ use super::NexusActionContext; use super::NexusSaga; use crate::app::sagas::declare_saga_actions; use crate::external_api::params; -use nexus_db_queries::db::lookup::LookupPath; +use nexus_db_lookup::LookupPath; use nexus_db_queries::db::queries::vpc_subnet::InsertVpcSubnetError; use nexus_db_queries::{authn, authz, db}; use omicron_common::api::external; @@ -350,12 +350,12 @@ pub(crate) mod test { use async_bb8_diesel::AsyncRunQueryDsl; use diesel::{ExpressionMethods, QueryDsl, SelectableHelper}; use dropshot::test_util::ClientTestContext; + use nexus_db_lookup::LookupPath; use nexus_db_model::RouterRouteKind; use nexus_db_queries::db; use nexus_db_queries::{ authn::saga::Serialized, authz, context::OpContext, db::datastore::DataStore, db::fixed_data::vpc::SERVICES_VPC_ID, - db::lookup::LookupPath, }; use nexus_test_utils::resource_helpers::create_default_ip_pool; use nexus_test_utils::resource_helpers::create_project; diff --git a/nexus/src/app/session.rs b/nexus/src/app/session.rs index 30489112b35..1418576b738 100644 --- a/nexus/src/app/session.rs +++ b/nexus/src/app/session.rs @@ -5,13 +5,13 @@ //! Console session management. use hex; +use nexus_db_lookup::LookupPath; use nexus_db_queries::authn; use nexus_db_queries::authn::Reason; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; use nexus_db_queries::db::identity::Asset; -use nexus_db_queries::db::lookup::LookupPath; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DeleteResult; use omicron_common::api::external::Error; diff --git a/nexus/src/app/silo.rs b/nexus/src/app/silo.rs index 2a28b005215..09995c73da4 100644 --- a/nexus/src/app/silo.rs +++ b/nexus/src/app/silo.rs @@ -7,14 +7,15 @@ use crate::external_api::params; use crate::external_api::shared; use anyhow::Context; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_model::{DnsGroup, UserProvisionType}; use nexus_db_queries::authz::ApiResource; use nexus_db_queries::context::OpContext; +use nexus_db_queries::db; use nexus_db_queries::db::datastore::Discoverability; use nexus_db_queries::db::datastore::DnsVersionUpdateBuilder; use nexus_db_queries::db::identity::{Asset, Resource}; -use nexus_db_queries::db::lookup::LookupPath; -use nexus_db_queries::db::{self, lookup}; use nexus_db_queries::{authn, authz}; use nexus_types::deployment::execution::blueprint_nexus_external_ips; use nexus_types::internal_api::params::DnsRecord; @@ -900,7 +901,7 @@ impl super::Nexus { &'a self, opctx: &'a OpContext, group_id: &'a Uuid, - ) -> db::lookup::SiloGroup<'a> { + ) -> lookup::SiloGroup<'a> { LookupPath::new(opctx, &self.db_datastore).silo_group_id(*group_id) } } diff --git a/nexus/src/app/sled.rs b/nexus/src/app/sled.rs index bf3a3ef2956..42cf16c762e 100644 --- a/nexus/src/app/sled.rs +++ b/nexus/src/app/sled.rs @@ -8,11 +8,11 @@ use crate::external_api::params; use crate::internal_api::params::{ PhysicalDiskPutRequest, SledAgentInfo, ZpoolPutRequest, }; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use nexus_sled_agent_shared::inventory::SledRole; use nexus_types::deployment::DiskFilter; use nexus_types::deployment::SledFilter; @@ -214,7 +214,7 @@ impl super::Nexus { disk_selector: ¶ms::PhysicalDiskPath, ) -> Result, Error> { // XXX how to do typed UUID as part of dropshot path? - Ok(lookup::LookupPath::new(&opctx, &self.db_datastore).physical_disk( + Ok(LookupPath::new(&opctx, &self.db_datastore).physical_disk( PhysicalDiskUuid::from_untyped_uuid(disk_selector.disk_id), )) } diff --git a/nexus/src/app/sled_instance.rs b/nexus/src/app/sled_instance.rs index 1f8295fced9..95c064e3669 100644 --- a/nexus/src/app/sled_instance.rs +++ b/nexus/src/app/sled_instance.rs @@ -1,7 +1,7 @@ +use nexus_db_lookup::lookup; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup; use omicron_common::api::external::DataPageParams; use omicron_common::api::external::ListResultVec; use uuid::Uuid; diff --git a/nexus/src/app/snapshot.rs b/nexus/src/app/snapshot.rs index c045e4997f8..5b8c59040a6 100644 --- a/nexus/src/app/snapshot.rs +++ b/nexus/src/app/snapshot.rs @@ -1,11 +1,11 @@ use std::sync::Arc; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_queries::authn; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use nexus_types::external_api::params; use nexus_types::external_api::params::DiskSelector; use omicron_common::api::external::CreateResult; diff --git a/nexus/src/app/ssh_key.rs b/nexus/src/app/ssh_key.rs index 15264a5dbda..a0b77da5713 100644 --- a/nexus/src/app/ssh_key.rs +++ b/nexus/src/app/ssh_key.rs @@ -1,10 +1,11 @@ use crate::external_api::params; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; -use nexus_db_queries::db::lookup::LookupPath; +use nexus_db_queries::db; use nexus_db_queries::db::model::Name; use nexus_db_queries::db::model::SshKey; -use nexus_db_queries::db::{self, lookup}; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DeleteResult; use omicron_common::api::external::ListResultVec; @@ -49,7 +50,7 @@ impl super::Nexus { params: params::SshKeyCreate, ) -> CreateResult { let ssh_key = db::model::SshKey::new(silo_user_id, params); - let (.., authz_user) = LookupPath::new(opctx, &self.datastore()) + let (.., authz_user) = LookupPath::new(opctx, self.datastore()) .silo_user_id(silo_user_id) .lookup_for(authz::Action::CreateChild) .await?; @@ -63,7 +64,7 @@ impl super::Nexus { silo_user_id: Uuid, page_params: &PaginatedBy<'_>, ) -> ListResultVec { - let (.., authz_user) = LookupPath::new(opctx, &self.datastore()) + let (.., authz_user) = LookupPath::new(opctx, self.datastore()) .silo_user_id(silo_user_id) .lookup_for(authz::Action::ListChildren) .await?; diff --git a/nexus/src/app/support_bundles.rs b/nexus/src/app/support_bundles.rs index 2d7f3882ef1..7b1e07e8e1d 100644 --- a/nexus/src/app/support_bundles.rs +++ b/nexus/src/app/support_bundles.rs @@ -7,11 +7,11 @@ use dropshot::Body; use futures::TryStreamExt; use http::Response; +use nexus_db_lookup::LookupPath; use nexus_db_model::SupportBundle; use nexus_db_model::SupportBundleState; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; -use nexus_db_queries::db::lookup::LookupPath; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DataPageParams; use omicron_common::api::external::DeleteResult; diff --git a/nexus/src/app/switch.rs b/nexus/src/app/switch.rs index cea16ba7af6..ec1c5e8a470 100644 --- a/nexus/src/app/switch.rs +++ b/nexus/src/app/switch.rs @@ -1,9 +1,9 @@ +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_model::Switch; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use nexus_types::external_api::params; use nexus_types::internal_api::params::SwitchPutRequest; use omicron_common::api::external::DataPageParams; diff --git a/nexus/src/app/switch_interface.rs b/nexus/src/app/switch_interface.rs index c4e69d1e3ea..5c4ebd6b117 100644 --- a/nexus/src/app/switch_interface.rs +++ b/nexus/src/app/switch_interface.rs @@ -4,11 +4,11 @@ use crate::external_api::params; use db::model::{LoopbackAddress, Name}; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use omicron_common::api::external::LookupResult; use omicron_common::api::external::{ CreateResult, DataPageParams, DeleteResult, Error, ListResultVec, diff --git a/nexus/src/app/test_interfaces.rs b/nexus/src/app/test_interfaces.rs index dd8ae6af8c8..acd234e4ddc 100644 --- a/nexus/src/app/test_interfaces.rs +++ b/nexus/src/app/test_interfaces.rs @@ -3,8 +3,8 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use async_trait::async_trait; +use nexus_db_lookup::LookupPath; use nexus_db_queries::context::OpContext; -use nexus_db_queries::db::lookup::LookupPath; use omicron_common::api::external::Error; use omicron_uuid_kinds::{GenericUuid, InstanceUuid, PropolisUuid, SledUuid}; use sled_agent_client::Client as SledAgentClient; diff --git a/nexus/src/app/utilization.rs b/nexus/src/app/utilization.rs index 395e83cfd6d..b343c71dd64 100644 --- a/nexus/src/app/utilization.rs +++ b/nexus/src/app/utilization.rs @@ -4,13 +4,13 @@ //! Insights into capacity and utilization +use nexus_db_lookup::lookup; use nexus_db_model::IpPoolUtilization; use nexus_db_model::Ipv4Utilization; use nexus_db_model::Ipv6Utilization; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup; use omicron_common::api::external::Error; use omicron_common::api::external::ListResultVec; use omicron_common::api::external::http_pagination::PaginatedBy; diff --git a/nexus/src/app/vpc.rs b/nexus/src/app/vpc.rs index 9396c1843fa..23a03bb3574 100644 --- a/nexus/src/app/vpc.rs +++ b/nexus/src/app/vpc.rs @@ -6,12 +6,12 @@ use crate::app::sagas; use crate::external_api::params; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_queries::authn; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::db::model::Name; use nexus_defaults as defaults; use omicron_common::api::external; diff --git a/nexus/src/app/vpc_router.rs b/nexus/src/app/vpc_router.rs index 4d345904eb7..b08de606b71 100644 --- a/nexus/src/app/vpc_router.rs +++ b/nexus/src/app/vpc_router.rs @@ -5,11 +5,11 @@ //! VPC routers and routes use crate::external_api::params; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::db::model::RouterRoute; use nexus_db_queries::db::model::VpcRouter; use nexus_db_queries::db::model::VpcRouterKind; diff --git a/nexus/src/app/vpc_subnet.rs b/nexus/src/app/vpc_subnet.rs index 2ae5ee0cc8a..f1c40c86ed7 100644 --- a/nexus/src/app/vpc_subnet.rs +++ b/nexus/src/app/vpc_subnet.rs @@ -8,11 +8,11 @@ use super::sagas; use crate::external_api::params; use nexus_auth::authn; use nexus_config::MIN_VPC_IPV4_SUBNET_PREFIX; +use nexus_db_lookup::LookupPath; +use nexus_db_lookup::lookup; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::lookup; -use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::db::model::VpcSubnet; use omicron_common::api::external; use omicron_common::api::external::CreateResult; diff --git a/nexus/src/context.rs b/nexus/src/context.rs index 36afa1d8129..a351adb80e6 100644 --- a/nexus/src/context.rs +++ b/nexus/src/context.rs @@ -13,10 +13,10 @@ use camino::Utf8PathBuf; use chrono::Duration; use nexus_config::NexusConfig; use nexus_config::SchemeName; +use nexus_db_lookup::LookupPath; use nexus_db_queries::authn::ConsoleSessionWithSiloId; use nexus_db_queries::authn::external::session_cookie::SessionStore; use nexus_db_queries::context::{OpContext, OpKind}; -use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::{authn, authz, db}; use omicron_common::address::{AZ_PREFIX, Ipv6Subnet}; use omicron_uuid_kinds::GenericUuid; diff --git a/nexus/src/external_api/http_entrypoints.rs b/nexus/src/external_api/http_entrypoints.rs index 258aebce25e..1e9b407aed1 100644 --- a/nexus/src/external_api/http_entrypoints.rs +++ b/nexus/src/external_api/http_entrypoints.rs @@ -38,12 +38,12 @@ use dropshot::{WebsocketChannelResult, WebsocketConnection}; use dropshot::{http_response_found, http_response_see_other}; use http::{Response, StatusCode, header}; use ipnetwork::IpNetwork; +use nexus_db_lookup::lookup::ImageLookup; +use nexus_db_lookup::lookup::ImageParentLookup; use nexus_db_queries::authn::external::session_cookie::{self, SessionStore}; use nexus_db_queries::authz; use nexus_db_queries::db; use nexus_db_queries::db::identity::Resource; -use nexus_db_queries::db::lookup::ImageLookup; -use nexus_db_queries::db::lookup::ImageParentLookup; use nexus_db_queries::db::model::Name; use nexus_external_api::*; use nexus_types::{ diff --git a/nexus/tests/integration_tests/crucible_replacements.rs b/nexus/tests/integration_tests/crucible_replacements.rs index 5b5e7fcae2c..201a2d78c12 100644 --- a/nexus/tests/integration_tests/crucible_replacements.rs +++ b/nexus/tests/integration_tests/crucible_replacements.rs @@ -9,6 +9,7 @@ use diesel::ExpressionMethods; use diesel::QueryDsl; use dropshot::test_util::ClientTestContext; use nexus_client::types::LastResult; +use nexus_db_lookup::LookupPath; use nexus_db_model::PhysicalDiskPolicy; use nexus_db_model::ReadOnlyTargetReplacement; use nexus_db_model::RegionReplacementState; @@ -16,7 +17,6 @@ use nexus_db_model::RegionSnapshotReplacementState; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::DataStore; use nexus_db_queries::db::datastore::region_snapshot_replacement::*; -use nexus_db_queries::db::lookup::LookupPath; use nexus_test_utils::background::*; use nexus_test_utils::http_testing::AuthnMode; use nexus_test_utils::http_testing::NexusRequest; @@ -236,7 +236,7 @@ async fn test_region_replacement_does_not_create_freed_region( let disk = create_disk(&client, PROJECT_NAME, "disk").await; // Before expunging the physical disk, save the DB model - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await @@ -767,7 +767,7 @@ async fn test_racing_replacements_for_soft_deleted_disk_volume( .await; // Before deleting the disk, save the DB model - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await @@ -2000,7 +2000,7 @@ async fn test_replacement_sanity(cptestctx: &ControlPlaneTestContext) { .await; // Before expunging the physical disk, save the DB model - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await @@ -2111,13 +2111,13 @@ async fn test_region_replacement_triple_sanity( .await; // Before expunging any physical disk, save some DB models - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await .unwrap(); - let (.., db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot.identity.id) .fetch() .await @@ -2237,13 +2237,13 @@ async fn test_region_replacement_triple_sanity_2( .await; // Before expunging any physical disk, save some DB models - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await .unwrap(); - let (.., db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot.identity.id) .fetch() .await @@ -2399,7 +2399,7 @@ async fn test_replacement_sanity_twice(cptestctx: &ControlPlaneTestContext) { // Manually create region snapshot replacement requests for each region // snapshot. - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await @@ -2434,7 +2434,7 @@ async fn test_replacement_sanity_twice(cptestctx: &ControlPlaneTestContext) { // Now, do it again, except this time specifying the read-only regions - let (.., db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot.identity.id) .fetch() .await @@ -2506,7 +2506,7 @@ async fn test_read_only_replacement_sanity( // Manually create region snapshot replacement requests for each region // snapshot. - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await @@ -2541,7 +2541,7 @@ async fn test_read_only_replacement_sanity( // Now expunge a sled with read-only regions on it. - let (.., db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot.identity.id) .fetch() .await @@ -2674,7 +2674,7 @@ async fn test_replacement_sanity_twice_after_snapshot_delete( // Manually create region snapshot replacement requests for each region // snapshot. - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await diff --git a/nexus/tests/integration_tests/disks.rs b/nexus/tests/integration_tests/disks.rs index b38bd059007..786d4816fdb 100644 --- a/nexus/tests/integration_tests/disks.rs +++ b/nexus/tests/integration_tests/disks.rs @@ -13,13 +13,13 @@ use dropshot::test_util::ClientTestContext; use http::StatusCode; use http::method::Method; use nexus_config::RegionAllocationStrategy; +use nexus_db_lookup::LookupPath; use nexus_db_model::PhysicalDiskPolicy; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::datastore::REGION_REDUNDANCY_THRESHOLD; use nexus_db_queries::db::datastore::RegionAllocationFor; use nexus_db_queries::db::datastore::RegionAllocationParameters; use nexus_db_queries::db::fixed_data::FLEET_ID; -use nexus_db_queries::db::lookup::LookupPath; use nexus_test_utils::SLED_AGENT_UUID; use nexus_test_utils::http_testing::AuthnMode; use nexus_test_utils::http_testing::Collection; @@ -417,7 +417,7 @@ async fn test_disk_slot_assignment(cptestctx: &ControlPlaneTestContext) { let opctx = OpContext::for_tests(ctx.logctx.log.new(o!()), datastore.clone()); - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk_id) .fetch() .await @@ -2054,7 +2054,7 @@ async fn test_project_delete_disk_no_auth_idempotent( let opctx = OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone()); - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await @@ -2070,7 +2070,7 @@ async fn test_project_delete_disk_no_auth_idempotent( .await .unwrap(); - let r = LookupPath::new(&opctx, &datastore) + let r = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await; @@ -2180,7 +2180,7 @@ async fn test_region_allocation_strategy_random_is_idempotent( // Assert disk has three allocated regions let disk_id = disk.identity.id; - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk_id) .fetch() .await @@ -2310,7 +2310,7 @@ async fn test_single_region_allocate_for_replace( // Assert disk has three allocated regions let disk_id = disk.identity.id; - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk_id) .fetch() .await @@ -2394,7 +2394,7 @@ async fn test_single_region_allocate_for_replace_not_enough_zpools( // Assert disk has three allocated regions let disk_id = disk.identity.id; - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk_id) .fetch() .await @@ -2562,7 +2562,7 @@ async fn test_disk_expunge(cptestctx: &ControlPlaneTestContext) { // Assert disk has three allocated regions let disk_id = disk.identity.id; - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk_id) .fetch() .await @@ -2625,7 +2625,7 @@ async fn test_do_not_provision_on_dataset(cptestctx: &ControlPlaneTestContext) { // Assert no region was allocated to the marked dataset let disk_id = disk.identity.id; - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk_id) .fetch() .await diff --git a/nexus/tests/integration_tests/instances.rs b/nexus/tests/integration_tests/instances.rs index ae6044712fc..b6c27ebfed9 100644 --- a/nexus/tests/integration_tests/instances.rs +++ b/nexus/tests/integration_tests/instances.rs @@ -12,10 +12,10 @@ use http::StatusCode; use http::method::Method; use itertools::Itertools; use nexus_auth::authz::Action; +use nexus_db_lookup::LookupPath; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::DataStore; use nexus_db_queries::db::fixed_data::silo::DEFAULT_SILO; -use nexus_db_queries::db::lookup::LookupPath; use nexus_test_utils::http_testing::AuthnMode; use nexus_test_utils::http_testing::NexusRequest; use nexus_test_utils::http_testing::RequestBuilder; @@ -657,7 +657,7 @@ async fn test_instance_start_creates_networking_state( let opctx = OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone()); - let (.., authz_instance) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance.identity.id) .lookup_for(nexus_db_queries::authz::Action::Read) .await @@ -807,7 +807,7 @@ async fn test_instance_migrate(cptestctx: &ControlPlaneTestContext) { cptestctx.logctx.log.new(o!()), datastore.clone(), ); - let (.., authz_instance) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance.identity.id) .lookup_for(nexus_db_queries::authz::Action::Read) .await @@ -947,7 +947,7 @@ async fn test_instance_migrate_v2p_and_routes( assert_eq!(instance_next.runtime.run_state, InstanceState::Running); // Ensure that all of the V2P information is correct. - let (.., authz_instance) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance_id.into_untyped_uuid()) .lookup_for(nexus_db_queries::authz::Action::Read) .await @@ -1000,7 +1000,7 @@ async fn test_instance_migrate_v2p_and_routes( cptestctx.logctx.log.new(o!()), datastore.clone(), ); - let (.., authz_instance) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance.identity.id) .lookup_for(nexus_db_queries::authz::Action::Read) .await @@ -1797,7 +1797,7 @@ async fn test_instance_metrics_with_migration( cptestctx.logctx.log.new(o!()), datastore.clone(), ); - let (.., authz_instance) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance.identity.id) .lookup_for(nexus_db_queries::authz::Action::Read) .await @@ -5922,7 +5922,7 @@ async fn test_instance_serial(cptestctx: &ControlPlaneTestContext) { let datastore = nexus.datastore(); let opctx = OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone()); - let (.., db_instance) = LookupPath::new(&opctx, &datastore) + let (.., db_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance.identity.id) .fetch() .await @@ -6637,7 +6637,7 @@ async fn test_instance_v2p_mappings(cptestctx: &ControlPlaneTestContext) { let opctx = OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone()); - let (.., authz_instance) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance.identity.id) .lookup_for(nexus_db_queries::authz::Action::Read) .await @@ -6811,7 +6811,7 @@ pub async fn instance_wait_for_vmm_registration( let datastore = cptestctx.server.server_context().nexus.datastore(); let log = &cptestctx.logctx.log; let opctx = OpContext::for_tests(log.clone(), datastore.clone()); - let (.., authz_instance) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance_id.into_untyped_uuid()) .lookup_for(nexus_db_queries::authz::Action::Read) .await diff --git a/nexus/tests/integration_tests/silos.rs b/nexus/tests/integration_tests/silos.rs index 587c4b69387..025c06a615a 100644 --- a/nexus/tests/integration_tests/silos.rs +++ b/nexus/tests/integration_tests/silos.rs @@ -4,6 +4,7 @@ use crate::integration_tests::saml::SAML_IDP_DESCRIPTOR; use dropshot::ResultsPage; +use nexus_db_lookup::LookupPath; use nexus_db_queries::authn::silos::AuthenticatedSubject; use nexus_db_queries::authn::{USER_TEST_PRIVILEGED, USER_TEST_UNPRIVILEGED}; use nexus_db_queries::authz::{self}; @@ -11,7 +12,6 @@ use nexus_db_queries::context::OpContext; use nexus_db_queries::db; use nexus_db_queries::db::fixed_data::silo::DEFAULT_SILO; use nexus_db_queries::db::identity::Asset; -use nexus_db_queries::db::lookup::LookupPath; use nexus_test_utils::http_testing::{AuthnMode, NexusRequest, RequestBuilder}; use nexus_test_utils::resource_helpers::{ create_ip_pool, create_local_user, create_project, create_silo, grant_iam, @@ -299,7 +299,7 @@ async fn test_silo_admin_group(cptestctx: &ControlPlaneTestContext) { let authn_opctx = nexus.opctx_external_authn(); let (authz_silo, db_silo) = - LookupPath::new(&authn_opctx, &nexus.datastore()) + LookupPath::new(&authn_opctx, nexus.datastore()) .silo_name(&silo.identity.name.into()) .fetch() .await @@ -807,7 +807,7 @@ async fn test_silo_user_provision_types(cptestctx: &ControlPlaneTestContext) { let authn_opctx = nexus.opctx_external_authn(); let (authz_silo, db_silo) = - LookupPath::new(&authn_opctx, &nexus.datastore()) + LookupPath::new(&authn_opctx, nexus.datastore()) .silo_name(&silo.identity.name.into()) .fetch() .await @@ -860,7 +860,7 @@ async fn test_silo_user_fetch_by_external_id( nexus.datastore().clone(), ); - let (authz_silo, _) = LookupPath::new(&opctx, &nexus.datastore()) + let (authz_silo, _) = LookupPath::new(&opctx, nexus.datastore()) .silo_name(&Name::try_from("test-silo".to_string()).unwrap().into()) .fetch_for(authz::Action::Read) .await @@ -1043,7 +1043,7 @@ async fn test_silo_groups_jit(cptestctx: &ControlPlaneTestContext) { let authn_opctx = nexus.opctx_external_authn(); let (authz_silo, db_silo) = - LookupPath::new(&authn_opctx, &nexus.datastore()) + LookupPath::new(&authn_opctx, nexus.datastore()) .silo_name(&silo.identity.name.into()) .fetch() .await @@ -1116,7 +1116,7 @@ async fn test_silo_groups_fixed(cptestctx: &ControlPlaneTestContext) { let authn_opctx = nexus.opctx_external_authn(); let (authz_silo, db_silo) = - LookupPath::new(&authn_opctx, &nexus.datastore()) + LookupPath::new(&authn_opctx, nexus.datastore()) .silo_name(&silo.identity.name.into()) .fetch() .await @@ -1171,7 +1171,7 @@ async fn test_silo_groups_remove_from_one_group( let authn_opctx = nexus.opctx_external_authn(); let (authz_silo, db_silo) = - LookupPath::new(&authn_opctx, &nexus.datastore()) + LookupPath::new(&authn_opctx, nexus.datastore()) .silo_name(&silo.identity.name.into()) .fetch() .await @@ -1282,7 +1282,7 @@ async fn test_silo_groups_remove_from_both_groups( let authn_opctx = nexus.opctx_external_authn(); let (authz_silo, db_silo) = - LookupPath::new(&authn_opctx, &nexus.datastore()) + LookupPath::new(&authn_opctx, nexus.datastore()) .silo_name(&silo.identity.name.into()) .fetch() .await @@ -1392,7 +1392,7 @@ async fn test_silo_delete_clean_up_groups(cptestctx: &ControlPlaneTestContext) { nexus.datastore().clone(), ); - let (authz_silo, db_silo) = LookupPath::new(&opctx, &nexus.datastore()) + let (authz_silo, db_silo) = LookupPath::new(&opctx, nexus.datastore()) .silo_name(&silo.identity.name.into()) .fetch() .await @@ -1447,7 +1447,7 @@ async fn test_silo_delete_clean_up_groups(cptestctx: &ControlPlaneTestContext) { assert!(memberships.is_empty()); // Expect the user is gone - LookupPath::new(&opctx_external_authn, &nexus.datastore()) + LookupPath::new(&opctx_external_authn, nexus.datastore()) .silo_user_id(silo_user.id()) .fetch() .await @@ -1474,7 +1474,7 @@ async fn test_ensure_same_silo_group(cptestctx: &ControlPlaneTestContext) { nexus.datastore().clone(), ); - let (authz_silo, db_silo) = LookupPath::new(&opctx, &nexus.datastore()) + let (authz_silo, db_silo) = LookupPath::new(&opctx, nexus.datastore()) .silo_name(&silo.identity.name.into()) .fetch() .await diff --git a/nexus/tests/integration_tests/snapshots.rs b/nexus/tests/integration_tests/snapshots.rs index e4ccb18aed6..babac7cf44a 100644 --- a/nexus/tests/integration_tests/snapshots.rs +++ b/nexus/tests/integration_tests/snapshots.rs @@ -10,6 +10,7 @@ use dropshot::test_util::ClientTestContext; use http::StatusCode; use http::method::Method; use nexus_config::RegionAllocationStrategy; +use nexus_db_lookup::LookupPath; use nexus_db_model::to_db_typed_uuid; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; @@ -18,7 +19,6 @@ use nexus_db_queries::db::datastore::REGION_REDUNDANCY_THRESHOLD; use nexus_db_queries::db::datastore::RegionAllocationFor; use nexus_db_queries::db::datastore::RegionAllocationParameters; use nexus_db_queries::db::identity::Resource; -use nexus_db_queries::db::lookup::LookupPath; use nexus_test_utils::SLED_AGENT_UUID; use nexus_test_utils::http_testing::AuthnMode; use nexus_test_utils::http_testing::NexusRequest; @@ -552,7 +552,7 @@ async fn test_reject_creating_disk_from_snapshot( let opctx = OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone()); - let (.., authz_project) = LookupPath::new(&opctx, &datastore) + let (.., authz_project) = LookupPath::new(&opctx, datastore) .project_id(project_id) .lookup_for(authz::Action::CreateChild) .await @@ -705,7 +705,7 @@ async fn test_reject_creating_disk_from_illegal_snapshot( let opctx = OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone()); - let (.., authz_project) = LookupPath::new(&opctx, &datastore) + let (.., authz_project) = LookupPath::new(&opctx, datastore) .project_id(project_id) .lookup_for(authz::Action::CreateChild) .await @@ -801,7 +801,7 @@ async fn test_reject_creating_disk_from_other_project_snapshot( let opctx = OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone()); - let (.., authz_project) = LookupPath::new(&opctx, &datastore) + let (.., authz_project) = LookupPath::new(&opctx, datastore) .project_id(project_id) .lookup_for(authz::Action::CreateChild) .await @@ -1056,7 +1056,7 @@ async fn test_create_snapshot_record_idempotent( let opctx = OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone()); - let (.., authz_project) = LookupPath::new(&opctx, &datastore) + let (.., authz_project) = LookupPath::new(&opctx, datastore) .project_id(project_id) .lookup_for(authz::Action::CreateChild) .await @@ -1115,7 +1115,7 @@ async fn test_create_snapshot_record_idempotent( // Move snapshot from Creating to Ready - let (.., authz_snapshot, db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., authz_snapshot, db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot_created_1.id()) .fetch_for(authz::Action::Modify) .await @@ -1133,7 +1133,7 @@ async fn test_create_snapshot_record_idempotent( // Grab the new snapshot (so generation number is updated) - let (.., authz_snapshot, db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., authz_snapshot, db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot_created_1.id()) .fetch_for(authz::Action::Delete) .await @@ -1158,7 +1158,7 @@ async fn test_create_snapshot_record_idempotent( { // Ensure the snapshot is gone - let r = LookupPath::new(&opctx, &datastore) + let r = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot_created_1.id()) .fetch_for(authz::Action::Read) .await; @@ -1324,7 +1324,7 @@ async fn test_multiple_deletes_not_sent(cptestctx: &ControlPlaneTestContext) { OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone()); let (.., authz_snapshot_1, db_snapshot_1) = - LookupPath::new(&opctx, &datastore) + LookupPath::new(&opctx, datastore) .snapshot_id(snapshot_1.identity.id) .fetch_for(authz::Action::Delete) .await @@ -1346,7 +1346,7 @@ async fn test_multiple_deletes_not_sent(cptestctx: &ControlPlaneTestContext) { .unwrap(); let (.., authz_snapshot_2, db_snapshot_2) = - LookupPath::new(&opctx, &datastore) + LookupPath::new(&opctx, datastore) .snapshot_id(snapshot_2.identity.id) .fetch_for(authz::Action::Delete) .await @@ -1368,7 +1368,7 @@ async fn test_multiple_deletes_not_sent(cptestctx: &ControlPlaneTestContext) { .unwrap(); let (.., authz_snapshot_3, db_snapshot_3) = - LookupPath::new(&opctx, &datastore) + LookupPath::new(&opctx, datastore) .snapshot_id(snapshot_3.identity.id) .fetch_for(authz::Action::Delete) .await @@ -1480,7 +1480,7 @@ async fn test_region_allocation_for_snapshot( // Assert disk has three allocated regions let disk_id = disk.identity.id; - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk_id) .fetch() .await @@ -1513,7 +1513,7 @@ async fn test_region_allocation_for_snapshot( // There shouldn't be any regions for the snapshot volume let snapshot_id = snapshot.identity.id; - let (.., db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot_id) .fetch() .await diff --git a/nexus/tests/integration_tests/volume_management.rs b/nexus/tests/integration_tests/volume_management.rs index e5641d2f91a..2029b1d2998 100644 --- a/nexus/tests/integration_tests/volume_management.rs +++ b/nexus/tests/integration_tests/volume_management.rs @@ -16,6 +16,7 @@ use dropshot::test_util::ClientTestContext; use http::StatusCode; use http::method::Method; use nexus_config::RegionAllocationStrategy; +use nexus_db_lookup::LookupPath; use nexus_db_model::CrucibleDataset; use nexus_db_model::RegionSnapshotReplacement; use nexus_db_model::RegionSnapshotReplacementState; @@ -37,7 +38,6 @@ use nexus_db_queries::db::datastore::SourceVolume; use nexus_db_queries::db::datastore::VolumeReplaceResult; use nexus_db_queries::db::datastore::VolumeToDelete; use nexus_db_queries::db::datastore::VolumeWithTarget; -use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::db::pagination::Paginator; use nexus_db_queries::db::pagination::paginated; use nexus_test_utils::http_testing::AuthnMode; @@ -3510,7 +3510,7 @@ async fn test_cte_returns_regions(cptestctx: &ControlPlaneTestContext) { let disk_id = disk.identity.id; - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk_id) .fetch() .await @@ -4096,7 +4096,7 @@ async fn test_read_only_region_reference_counting( // Perform region snapshot replacement for one of the snapshot's regions, // causing a read-only region to be created. - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await @@ -4124,7 +4124,7 @@ async fn test_read_only_region_reference_counting( // The snapshot's allocated regions should have the one read-only region - let (.., db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot.identity.id) .fetch() .await @@ -4146,7 +4146,7 @@ async fn test_read_only_region_reference_counting( // The disk-from-snap VCR should also reference that read-only region - let (.., db_disk_from_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_disk_from_snapshot) = LookupPath::new(&opctx, datastore) .disk_id(disk_from_snapshot.identity.id) .fetch() .await @@ -4366,7 +4366,7 @@ async fn test_read_only_region_reference_counting_layers( // Perform region snapshot replacement for one of the snapshot's regions, // causing a read-only region to be created. - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await @@ -4394,7 +4394,7 @@ async fn test_read_only_region_reference_counting_layers( // Grab the read-only region in the snapshot volume - let (.., db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot.identity.id) .fetch() .await @@ -4411,7 +4411,7 @@ async fn test_read_only_region_reference_counting_layers( // The disk-from-snap VCR should also reference that read-only region - let (.., db_disk_from_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_disk_from_snapshot) = LookupPath::new(&opctx, datastore) .disk_id(disk_from_snapshot.identity.id) .fetch() .await @@ -4469,7 +4469,7 @@ async fn test_read_only_region_reference_counting_layers( // Assert correct volume usage records - let (.., db_double_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_double_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(double_snapshot.identity.id) .fetch() .await @@ -4599,7 +4599,7 @@ async fn test_volume_replace_snapshot_respects_accounting( let disk = create_disk(&client, PROJECT_NAME, "disk").await; - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await @@ -4613,7 +4613,7 @@ async fn test_volume_replace_snapshot_respects_accounting( let snapshot = create_snapshot(&client, PROJECT_NAME, "disk", "snapshot").await; - let (.., db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot.identity.id) .fetch() .await @@ -4805,7 +4805,7 @@ async fn test_volume_remove_rop_respects_accounting( let disk = create_disk(&client, PROJECT_NAME, "disk").await; - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await @@ -4819,7 +4819,7 @@ async fn test_volume_remove_rop_respects_accounting( let snapshot = create_snapshot(&client, PROJECT_NAME, "disk", "snapshot").await; - let (.., db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot.identity.id) .fetch() .await @@ -4835,7 +4835,7 @@ async fn test_volume_remove_rop_respects_accounting( ) .await; - let (.., db_disk_from_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_disk_from_snapshot) = LookupPath::new(&opctx, datastore) .disk_id(disk_from_snapshot.identity.id) .fetch() .await @@ -4968,7 +4968,7 @@ async fn test_volume_remove_rop_respects_accounting_no_modify_others( let disk = create_disk(&client, PROJECT_NAME, "disk").await; - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await @@ -4982,7 +4982,7 @@ async fn test_volume_remove_rop_respects_accounting_no_modify_others( let snapshot = create_snapshot(&client, PROJECT_NAME, "disk", "snapshot").await; - let (.., db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot.identity.id) .fetch() .await @@ -4998,7 +4998,7 @@ async fn test_volume_remove_rop_respects_accounting_no_modify_others( ) .await; - let (.., db_disk_from_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_disk_from_snapshot) = LookupPath::new(&opctx, datastore) .disk_id(disk_from_snapshot.identity.id) .fetch() .await @@ -5018,7 +5018,7 @@ async fn test_volume_remove_rop_respects_accounting_no_modify_others( .await; let (.., db_another_disk_from_snapshot) = - LookupPath::new(&opctx, &datastore) + LookupPath::new(&opctx, datastore) .disk_id(another_disk_from_snapshot.identity.id) .fetch() .await @@ -5359,7 +5359,7 @@ async fn test_migrate_to_ref_count_with_records_soft_delete_volume( // Soft-delete the snapshot's volume - let (.., db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot.identity.id) .fetch() .await @@ -5624,7 +5624,7 @@ async fn test_double_layer_with_read_only_region_delete( // Perform region snapshot replacement for one of the snapshot's targets, // causing a read-only region to be created. - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await @@ -5733,7 +5733,7 @@ async fn test_double_layer_snapshot_with_read_only_region_delete_2( // Perform region snapshot replacement for two of the snapshot's targets, // causing two read-only regions to be created. - let (.., db_disk) = LookupPath::new(&opctx, &datastore) + let (.., db_disk) = LookupPath::new(&opctx, datastore) .disk_id(disk.identity.id) .fetch() .await @@ -5917,7 +5917,7 @@ async fn test_no_zombie_region_snapshots(cptestctx: &ControlPlaneTestContext) { // Create a volume that uses the snapshot volume as a read-only parent - let (.., db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot.identity.id) .fetch() .await @@ -6495,7 +6495,7 @@ async fn test_volume_create_wont_use_deleted_region_snapshots( // // 3) pass the disk volume to volume_create - let (.., db_snapshot) = LookupPath::new(&opctx, &datastore) + let (.., db_snapshot) = LookupPath::new(&opctx, datastore) .snapshot_id(snapshot.identity.id) .fetch() .await diff --git a/nexus/tests/integration_tests/vpc_routers.rs b/nexus/tests/integration_tests/vpc_routers.rs index 205b2fde689..2c11e5a9c23 100644 --- a/nexus/tests/integration_tests/vpc_routers.rs +++ b/nexus/tests/integration_tests/vpc_routers.rs @@ -7,8 +7,8 @@ use crate::integration_tests::instances::instance_simulate; use dropshot::test_util::ClientTestContext; use http::StatusCode; use http::method::Method; +use nexus_db_lookup::LookupPath; use nexus_db_queries::context::OpContext; -use nexus_db_queries::db::lookup::LookupPath; use nexus_test_utils::http_testing::AuthnMode; use nexus_test_utils::http_testing::NexusRequest; use nexus_test_utils::http_testing::RequestBuilder; @@ -524,7 +524,7 @@ async fn test_vpc_routers_custom_delivered_to_instance( ) .await; - let (.., authz_instance) = LookupPath::new(&opctx, &datastore) + let (.., authz_instance) = LookupPath::new(&opctx, datastore) .instance_id(instance.identity.id) .lookup_for(nexus_db_queries::authz::Action::Read) .await From cd1ed71784142fda4f7a4267ac5825c256451ce5 Mon Sep 17 00:00:00 2001 From: Rain Date: Fri, 18 Apr 2025 03:05:37 +0000 Subject: [PATCH 2/2] doc fixes Created using spr 1.3.6-beta.1 --- Cargo.lock | 1 + nexus/background-task-interface/Cargo.toml | 1 + .../src/activator.rs | 46 +++++++++++++------ nexus/src/app/background/driver.rs | 8 ++-- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7bf0d1f47f8..dffc8eff53a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5874,6 +5874,7 @@ name = "nexus-background-task-interface" version = "0.1.0" dependencies = [ "omicron-workspace-hack", + "thiserror 1.0.69", "tokio", ] diff --git a/nexus/background-task-interface/Cargo.toml b/nexus/background-task-interface/Cargo.toml index 1f98153b51a..b91bba0a00d 100644 --- a/nexus/background-task-interface/Cargo.toml +++ b/nexus/background-task-interface/Cargo.toml @@ -9,4 +9,5 @@ workspace = true [dependencies] omicron-workspace-hack.workspace = true +thiserror.workspace = true tokio.workspace = true diff --git a/nexus/background-task-interface/src/activator.rs b/nexus/background-task-interface/src/activator.rs index e69e7d74f0e..da8d12f49c0 100644 --- a/nexus/background-task-interface/src/activator.rs +++ b/nexus/background-task-interface/src/activator.rs @@ -7,23 +7,24 @@ use std::sync::{ atomic::{AtomicBool, Ordering}, }; +use thiserror::Error; use tokio::sync::Notify; /// Activates a background task /// -/// See `nexus/src/app/background/mod.rs` documentation for more on what that -/// means. +/// For more on what this means, see the documentation at +/// `nexus/src/app/background/mod.rs`. /// /// Activators are created with [`Activator::new()`] and then wired up to -/// specific background tasks using [`Driver::register()`]. If you call +/// specific background tasks using Nexus's `Driver::register()`. If you call /// `Activator::activate()` before the activator is wired up to a background /// task, then once the Activator _is_ wired up to a task, that task will /// immediately be activated. /// /// Activators are designed specifically so they can be created before the /// corresponding task has been created and then wired up with just an -/// `&Activator` (not a `&mut Activator`). See the [`super::init`] module-level -/// documentation for more on why. +/// `&Activator` (not a `&mut Activator`). See the +/// `nexus/src/app/background/mod.rs` documentation for more on why. #[derive(Clone)] pub struct Activator(Arc); @@ -44,8 +45,8 @@ impl Activator { /// Activate the background task that this Activator has been wired up to /// - /// If this Activator has not yet been wired up with [`Driver::register()`], - /// then whenever it _is_ wired up, that task will be immediately activated. + /// If this Activator has not yet been wired up, then whenever it _is_ wired + /// up, that task will be immediately activated. pub fn activate(&self) { self.0.notify.notify_one(); } @@ -53,21 +54,31 @@ impl Activator { /// Sets the task as wired up. /// /// Returns an error if the task was already wired up. - // XXX return a proper error type here - pub fn mark_wired_up(&self) -> Result { - self.0.wired_up.compare_exchange( + pub fn mark_wired_up(&self) -> Result<(), AlreadyWiredUpError> { + match self.0.wired_up.compare_exchange( false, true, Ordering::SeqCst, Ordering::SeqCst, - ) + ) { + Ok(false) => Ok(()), + Ok(true) => unreachable!( + "on success, the return value is always \ + the previous value (false)" + ), + Err(true) => Err(AlreadyWiredUpError {}), + Err(false) => unreachable!( + "on failure, the return value is always \ + the previous and current value (true)" + ), + } } - /// Blocks until the background task that this Activator has been wired up to - /// is activated. + /// Blocks until the background task that this Activator has been wired up + /// to is activated. /// - /// If this Activator has not yet been wired up with [`Driver::register()`], - /// then whenever it _is_ wired up, that task will be immediately activated. + /// If this Activator has not yet been wired up, then whenever it _is_ wired + /// up, that task will be immediately activated. pub async fn activated(&self) { debug_assert!( self.0.wired_up.load(Ordering::SeqCst), @@ -77,3 +88,8 @@ impl Activator { self.0.notify.notified().await } } + +/// Indicates that an activator was wired up more than once. +#[derive(Debug, Error)] +#[error("activator was already wired up")] +pub struct AlreadyWiredUpError {} diff --git a/nexus/src/app/background/driver.rs b/nexus/src/app/background/driver.rs index f27fb778a47..853ba798bbd 100644 --- a/nexus/src/app/background/driver.rs +++ b/nexus/src/app/background/driver.rs @@ -115,12 +115,10 @@ impl Driver { // requested. The caller provides their own Activator, which just // provides a specific Notify for us to use here. let activator = taskdef.activator; - if let Err(previous) = activator.mark_wired_up() { + if let Err(error) = activator.mark_wired_up() { panic!( - "attempted to wire up the same background task handle \ - twice (previous \"wired_up\" = {}): currently attempting \ - to wire it up to task {:?}", - previous, name + "{error}: currently attempting to wire it up to task {:?}", + name ); }