From 1855275a28db1cf64f875467391cc1583badeecf Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Wed, 20 Jul 2022 16:52:11 -0400 Subject: [PATCH 1/5] nexus shattering: Extract nexus-db-model crate from nexus::db::model --- Cargo.lock | 27 ++++ Cargo.toml | 2 + nexus/Cargo.toml | 1 + nexus/db-macros/src/lib.rs | 4 +- nexus/db-macros/src/lookup.rs | 18 +-- nexus/db-model/Cargo.toml | 29 ++++ .../db/model => db-model/src}/block_size.rs | 2 +- .../db/model => db-model/src}/bytecount.rs | 0 nexus/db-model/src/collection.rs | 153 ++++++++++++++++++ .../model => db-model/src}/console_session.rs | 2 +- .../{src/db/model => db-model/src}/dataset.rs | 4 +- .../db/model => db-model/src}/dataset_kind.rs | 2 +- .../db/model => db-model/src}/device_auth.rs | 2 +- .../{src/db/model => db-model/src}/digest.rs | 0 nexus/{src/db/model => db-model/src}/disk.rs | 6 +- .../db/model => db-model/src}/disk_state.rs | 0 .../db/model => db-model/src}/external_ip.rs | 12 +- .../db/model => db-model/src}/generation.rs | 0 .../db/model => db-model/src}/global_image.rs | 6 +- .../src}/identity_provider.rs | 6 +- nexus/{src/db/model => db-model/src}/image.rs | 6 +- .../db/model => db-model/src}/instance.rs | 8 +- .../src}/instance_cpu_count.rs | 0 .../model => db-model/src}/instance_state.rs | 0 .../{src/db/model => db-model/src}/ip_pool.rs | 14 +- .../{src/db/model => db-model/src}/ipv4net.rs | 0 nexus/{src/db => db-model/src}/ipv6.rs | 0 .../{src/db/model => db-model/src}/ipv6net.rs | 0 .../model => db-model/src}/l4_port_range.rs | 0 .../db/model/mod.rs => db-model/src/lib.rs} | 87 +++------- .../{src/db/model => db-model/src}/macaddr.rs | 6 +- nexus/{src/db/model => db-model/src}/name.rs | 0 .../src}/network_interface.rs | 8 +- .../db/model => db-model/src}/organization.rs | 8 +- .../model => db-model/src}/oximeter_info.rs | 4 +- .../src}/producer_endpoint.rs | 4 +- .../{src/db/model => db-model/src}/project.rs | 5 +- nexus/{src/db/model => db-model/src}/rack.rs | 2 +- .../{src/db/model => db-model/src}/region.rs | 2 +- .../model => db-model/src}/role_assignment.rs | 17 +- .../db/model => db-model/src}/role_builtin.rs | 2 +- nexus/{src/db => db-model/src}/saga_types.rs | 2 +- nexus/{src/db => db-model/src}/schema.rs | 37 +++-- .../{src/db/model => db-model/src}/service.rs | 4 +- .../db/model => db-model/src}/service_kind.rs | 2 +- nexus/{src/db/model => db-model/src}/silo.rs | 10 +- .../db/model => db-model/src}/silo_user.rs | 4 +- nexus/{src/db/model => db-model/src}/sled.rs | 6 +- .../db/model => db-model/src}/snapshot.rs | 6 +- .../{src/db/model => db-model/src}/ssh_key.rs | 6 +- nexus/{src/db/model => db-model/src}/u16.rs | 0 .../model => db-model/src}/update_artifact.rs | 2 +- .../db/model => db-model/src}/user_builtin.rs | 6 +- nexus/{src/db/model => db-model/src}/vni.rs | 0 .../{src/db/model => db-model/src}/volume.rs | 4 +- nexus/{src/db/model => db-model/src}/vpc.rs | 10 +- .../src}/vpc_firewall_rule.rs | 4 +- .../db/model => db-model/src}/vpc_route.rs | 4 +- .../db/model => db-model/src}/vpc_router.rs | 8 +- .../db/model => db-model/src}/vpc_subnet.rs | 5 +- nexus/{src/db/model => db-model/src}/zpool.rs | 6 +- nexus/src/app/instance.rs | 5 +- nexus/src/authz/api_resources.rs | 2 +- nexus/src/cidata.rs | 9 +- nexus/src/db/collection_attach.rs | 85 ++-------- nexus/src/db/collection_detach.rs | 6 +- nexus/src/db/collection_detach_many.rs | 6 +- nexus/src/db/collection_insert.rs | 77 ++------- nexus/src/db/datastore/dataset.rs | 2 +- nexus/src/db/datastore/disk.rs | 2 +- nexus/src/db/datastore/ip_pool.rs | 2 +- nexus/src/db/datastore/organization.rs | 2 +- nexus/src/db/datastore/project.rs | 2 +- nexus/src/db/datastore/rack.rs | 4 +- nexus/src/db/datastore/service.rs | 2 +- nexus/src/db/datastore/vpc.rs | 2 +- nexus/src/db/datastore/zpool.rs | 2 +- nexus/src/db/lookup.rs | 5 +- nexus/src/db/mod.rs | 79 ++++++++- nexus/src/lib.rs | 1 + 80 files changed, 492 insertions(+), 378 deletions(-) create mode 100644 nexus/db-model/Cargo.toml rename nexus/{src/db/model => db-model/src}/block_size.rs (97%) rename nexus/{src/db/model => db-model/src}/bytecount.rs (100%) create mode 100644 nexus/db-model/src/collection.rs rename nexus/{src/db/model => db-model/src}/console_session.rs (95%) rename nexus/{src/db/model => db-model/src}/dataset.rs (95%) rename nexus/{src/db/model => db-model/src}/dataset_kind.rs (97%) rename nexus/{src/db/model => db-model/src}/device_auth.rs (98%) rename nexus/{src/db/model => db-model/src}/digest.rs (100%) rename nexus/{src/db/model => db-model/src}/disk.rs (98%) rename nexus/{src/db/model => db-model/src}/disk_state.rs (100%) rename nexus/{src/db/model => db-model/src}/external_ip.rs (96%) rename nexus/{src/db/model => db-model/src}/generation.rs (100%) rename nexus/{src/db/model => db-model/src}/global_image.rs (91%) rename nexus/{src/db/model => db-model/src}/identity_provider.rs (94%) rename nexus/{src/db/model => db-model/src}/image.rs (92%) rename nexus/{src/db/model => db-model/src}/instance.rs (97%) rename nexus/{src/db/model => db-model/src}/instance_cpu_count.rs (100%) rename nexus/{src/db/model => db-model/src}/instance_state.rs (100%) rename nexus/{src/db/model => db-model/src}/ip_pool.rs (95%) rename nexus/{src/db/model => db-model/src}/ipv4net.rs (100%) rename nexus/{src/db => db-model/src}/ipv6.rs (100%) rename nexus/{src/db/model => db-model/src}/ipv6net.rs (100%) rename nexus/{src/db/model => db-model/src}/l4_port_range.rs (100%) rename nexus/{src/db/model/mod.rs => db-model/src/lib.rs} (81%) rename nexus/{src/db/model => db-model/src}/macaddr.rs (94%) rename nexus/{src/db/model => db-model/src}/name.rs (100%) rename nexus/{src/db/model => db-model/src}/network_interface.rs (95%) rename nexus/{src/db/model => db-model/src}/organization.rs (92%) rename nexus/{src/db/model => db-model/src}/oximeter_info.rs (95%) rename nexus/{src/db/model => db-model/src}/producer_endpoint.rs (95%) rename nexus/{src/db/model => db-model/src}/project.rs (93%) rename nexus/{src/db/model => db-model/src}/rack.rs (96%) rename nexus/{src/db/model => db-model/src}/region.rs (98%) rename nexus/{src/db/model => db-model/src}/role_assignment.rs (93%) rename nexus/{src/db/model => db-model/src}/role_builtin.rs (97%) rename nexus/{src/db => db-model/src}/saga_types.rs (99%) rename nexus/{src/db => db-model/src}/schema.rs (92%) rename nexus/{src/db/model => db-model/src}/service.rs (94%) rename nexus/{src/db/model => db-model/src}/service_kind.rs (97%) rename nexus/{src/db/model => db-model/src}/silo.rs (92%) rename nexus/{src/db/model => db-model/src}/silo_user.rs (94%) rename nexus/{src/db/model => db-model/src}/sled.rs (95%) rename nexus/{src/db/model => db-model/src}/snapshot.rs (90%) rename nexus/{src/db/model => db-model/src}/ssh_key.rs (92%) rename nexus/{src/db/model => db-model/src}/u16.rs (100%) rename nexus/{src/db/model => db-model/src}/update_artifact.rs (96%) rename nexus/{src/db/model => db-model/src}/user_builtin.rs (89%) rename nexus/{src/db/model => db-model/src}/vni.rs (100%) rename nexus/{src/db/model => db-model/src}/volume.rs (92%) rename nexus/{src/db/model => db-model/src}/vpc.rs (94%) rename nexus/{src/db/model => db-model/src}/vpc_firewall_rule.rs (99%) rename nexus/{src/db/model => db-model/src}/vpc_route.rs (98%) rename nexus/{src/db/model => db-model/src}/vpc_router.rs (93%) rename nexus/{src/db/model => db-model/src}/vpc_subnet.rs (96%) rename nexus/{src/db/model => db-model/src}/zpool.rs (92%) diff --git a/Cargo.lock b/Cargo.lock index 20988ff9b28..5bfe8e66e92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2772,6 +2772,32 @@ dependencies = [ "uuid", ] +[[package]] +name = "nexus-db-model" +version = "0.1.0" +dependencies = [ + "anyhow", + "chrono", + "db-macros", + "diesel", + "hex", + "ipnetwork", + "macaddr", + "newtype_derive", + "nexus-defaults", + "nexus-types", + "omicron-common 0.1.0", + "parse-display", + "rand 0.8.5", + "ref-cast", + "schemars", + "serde", + "serde_json", + "sled-agent-client", + "steno", + "uuid", +] + [[package]] name = "nexus-defaults" version = "0.1.0" @@ -3107,6 +3133,7 @@ dependencies = [ "macaddr", "mime_guess", "newtype_derive", + "nexus-db-model", "nexus-defaults", "nexus-test-utils", "nexus-test-utils-macros", diff --git a/Cargo.toml b/Cargo.toml index cb051e78a4b..be188470da9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ members = [ "nexus", "nexus/authz-macros", "nexus/db-macros", + "nexus/db-model", "nexus/defaults", "nexus/test-utils", "nexus/test-utils-macros", @@ -47,6 +48,7 @@ default-members = [ "nexus", "nexus/authz-macros", "nexus/db-macros", + "nexus/db-model", "nexus/defaults", "nexus/types", "package", diff --git a/nexus/Cargo.toml b/nexus/Cargo.toml index 30c305cef01..e7b7b66264f 100644 --- a/nexus/Cargo.toml +++ b/nexus/Cargo.toml @@ -61,6 +61,7 @@ usdt = "0.3.1" authz-macros = { path = "authz-macros" } db-macros = { path = "db-macros" } nexus-defaults = { path = "defaults" } +nexus-db-model = { path = "db-model" } nexus-types = { path = "types" } [dependencies.chrono] diff --git a/nexus/db-macros/src/lib.rs b/nexus/db-macros/src/lib.rs index 8495e0369ad..839b0479eac 100644 --- a/nexus/db-macros/src/lib.rs +++ b/nexus/db-macros/src/lib.rs @@ -334,7 +334,7 @@ fn build_resource_impl( } }; - impl crate::db::identity::Resource for #struct_name { + impl ::nexus_types::identity::Resource for #struct_name { fn id(&self) -> ::uuid::Uuid { self.identity.id } @@ -381,7 +381,7 @@ fn build_asset_impl( } }; - impl crate::db::identity::Asset for #struct_name { + impl ::nexus_types::identity::Asset for #struct_name { fn id(&self) -> ::uuid::Uuid { self.identity.id } diff --git a/nexus/db-macros/src/lookup.rs b/nexus/db-macros/src/lookup.rs index fdc66ef35c8..e0157222595 100644 --- a/nexus/db-macros/src/lookup.rs +++ b/nexus/db-macros/src/lookup.rs @@ -389,7 +389,7 @@ fn generate_misc_helpers(config: &Config) -> TokenStream { /// Build the `authz` object for this resource fn make_authz( authz_parent: &authz::#parent_resource_name, - db_row: &model::#resource_name, + db_row: &nexus_db_model::#resource_name, lookup_type: LookupType, ) -> authz::#resource_name { authz::#resource_name::new( @@ -533,7 +533,7 @@ fn generate_lookup_methods(config: &Config) -> TokenStream { /// This is equivalent to `fetch_for(authz::Action::Read)`. pub async fn fetch( &self, - ) -> LookupResult<(#(authz::#path_types,)* model::#resource_name)> { + ) -> LookupResult<(#(authz::#path_types,)* nexus_db_model::#resource_name)> { self.fetch_for(authz::Action::Read).await } @@ -549,7 +549,7 @@ fn generate_lookup_methods(config: &Config) -> TokenStream { pub async fn fetch_for( &self, action: authz::Action, - ) -> LookupResult<(#(authz::#path_types,)* model::#resource_name)> { + ) -> LookupResult<(#(authz::#path_types,)* nexus_db_model::#resource_name)> { let lookup = self.lookup_root(); let opctx = &lookup.opctx; let datastore = &lookup.datastore; @@ -712,7 +712,7 @@ fn generate_database_functions(config: &Config) -> TokenStream { #parent_lookup_arg_formal name: &Name, action: authz::Action, - ) -> LookupResult<(authz::#resource_name, model::#resource_name)> { + ) -> LookupResult<(authz::#resource_name, nexus_db_model::#resource_name)> { let (#resource_authz_name, db_row) = Self::lookup_by_name_no_authz( opctx, @@ -738,7 +738,7 @@ fn generate_database_functions(config: &Config) -> TokenStream { #parent_lookup_arg_formal name: &Name, ) -> LookupResult< - (authz::#resource_name, model::#resource_name) + (authz::#resource_name, nexus_db_model::#resource_name) > { use db::schema::#resource_as_snake::dsl; @@ -746,7 +746,7 @@ fn generate_database_functions(config: &Config) -> TokenStream { #soft_delete_filter .filter(dsl::name.eq(name.clone())) #lookup_filter - .select(model::#resource_name::as_select()) + .select(nexus_db_model::#resource_name::as_select()) .get_result_async( datastore.pool_authorized(opctx).await? ) @@ -804,7 +804,7 @@ fn generate_database_functions(config: &Config) -> TokenStream { datastore: &DataStore, #(#pkey_names: &#pkey_types,)* action: authz::Action, - ) -> LookupResult<(#(authz::#path_types,)* model::#resource_name)> { + ) -> LookupResult<(#(authz::#path_types,)* nexus_db_model::#resource_name)> { let (#(#path_authz_names,)* db_row) = Self::lookup_by_id_no_authz( opctx, @@ -826,13 +826,13 @@ fn generate_database_functions(config: &Config) -> TokenStream { opctx: &OpContext, datastore: &DataStore, #(#pkey_names: &#pkey_types,)* - ) -> LookupResult<(#(authz::#path_types,)* model::#resource_name)> { + ) -> LookupResult<(#(authz::#path_types,)* nexus_db_model::#resource_name)> { use db::schema::#resource_as_snake::dsl; let db_row = dsl::#resource_as_snake #soft_delete_filter #(.filter(dsl::#pkey_column_names.eq(#pkey_names.clone())))* - .select(model::#resource_name::as_select()) + .select(nexus_db_model::#resource_name::as_select()) .get_result_async(datastore.pool_authorized(opctx).await?) .await .map_err(|e| { diff --git a/nexus/db-model/Cargo.toml b/nexus/db-model/Cargo.toml new file mode 100644 index 00000000000..0578b986f64 --- /dev/null +++ b/nexus/db-model/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "nexus-db-model" +version = "0.1.0" +edition = "2021" +license = "MPL-2.0" + +[dependencies] +anyhow = "1.0" +chrono = { version = "0.4", features = ["serde"] } +diesel = { version = "2.0.0-rc.0", features = ["postgres", "r2d2", "chrono", "serde_json", "network-address", "uuid"] } +hex = "0.4.3" +ipnetwork = "0.18" +macaddr = { version = "1.0.1", features = [ "serde_std" ]} +newtype_derive = "0.1.6" +parse-display = "0.5.4" +rand = "0.8.5" +ref-cast = "1.0" +schemars = { version = "0.8.10", features = ["chrono", "uuid1"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +uuid = { version = "1.1.0", features = ["serde", "v4"] } + +steno = { git = "https://github.com/oxidecomputer/steno", branch = "main" } + +db-macros = { path = "../db-macros" } +omicron-common = { path = "../../common" } +nexus-defaults = { path = "../defaults" } +nexus-types = { path = "../types" } +sled-agent-client = { path = "../../sled-agent-client" } diff --git a/nexus/src/db/model/block_size.rs b/nexus/db-model/src/block_size.rs similarity index 97% rename from nexus/src/db/model/block_size.rs rename to nexus/db-model/src/block_size.rs index cdb3e0130bf..1a090f1e441 100644 --- a/nexus/src/db/model/block_size.rs +++ b/nexus/db-model/src/block_size.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::impl_enum_type; -use crate::external_api::params; +use nexus_types::external_api::params; use omicron_common::api::external; use serde::{Deserialize, Serialize}; diff --git a/nexus/src/db/model/bytecount.rs b/nexus/db-model/src/bytecount.rs similarity index 100% rename from nexus/src/db/model/bytecount.rs rename to nexus/db-model/src/bytecount.rs diff --git a/nexus/db-model/src/collection.rs b/nexus/db-model/src/collection.rs new file mode 100644 index 00000000000..eb3e0350d73 --- /dev/null +++ b/nexus/db-model/src/collection.rs @@ -0,0 +1,153 @@ +// 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::pg::Pg; +use diesel::Column; +use diesel::ExpressionMethods; +use diesel::Selectable; +use std::fmt::Debug; + +/// Trait to be implemented by any structs representing a collection. +/// For example, since Organizations have a one-to-many relationship with +/// Projects, the Organization datatype should implement this trait. +/// ``` +/// # use diesel::prelude::*; +/// # use nexus_db_model::DatastoreCollection; +/// # use nexus_db_model::Generation; +/// # +/// # table! { +/// # test_schema.organization (id) { +/// # id -> Uuid, +/// # time_deleted -> Nullable, +/// # rcgen -> Int8, +/// # } +/// # } +/// # +/// # table! { +/// # test_schema.project (id) { +/// # id -> Uuid, +/// # time_deleted -> Nullable, +/// # organization_id -> Uuid, +/// # } +/// # } +/// +/// #[derive(Queryable, Insertable, Debug, Selectable)] +/// #[diesel(table_name = project)] +/// struct Project { +/// pub id: uuid::Uuid, +/// pub time_deleted: Option>, +/// pub organization_id: uuid::Uuid, +/// } +/// +/// #[derive(Queryable, Insertable, Debug, Selectable)] +/// #[diesel(table_name = organization)] +/// struct Organization { +/// pub id: uuid::Uuid, +/// pub time_deleted: Option>, +/// pub rcgen: Generation, +/// } +/// +/// impl DatastoreCollection for Organization { +/// // Type of Organization::identity::id and Project::organization_id +/// type CollectionId = uuid::Uuid; +/// +/// type GenerationNumberColumn = organization::dsl::rcgen; +/// type CollectionTimeDeletedColumn = organization::dsl::time_deleted; +/// +/// type CollectionIdColumn = project::dsl::organization_id; +/// } +/// ``` +pub trait DatastoreCollection { + /// The Rust type of the collection id (typically Uuid for us) + type CollectionId: Copy + Debug; + + /// The column in the CollectionTable that acts as a generation number. + /// This is the "child-resource-generation-number" in RFD 192. + type GenerationNumberColumn: Column + Default; + + /// The time deleted column in the CollectionTable + // We enforce that this column comes from the same table as + // GenerationNumberColumn when defining insert_resource() below. + type CollectionTimeDeletedColumn: Column + Default; + + /// The column in the ResourceTable that acts as a foreign key into + /// the CollectionTable + type CollectionIdColumn: Column; +} + +/// Trait to be implemented by structs representing an attachable collection. +/// +/// For example, since Instances have a one-to-many relationship with +/// Disks, the Instance datatype should implement this trait. +/// ``` +/// # use diesel::prelude::*; +/// # use nexus_db_model::DatastoreAttachTarget; +/// # +/// # table! { +/// # test_schema.instance (id) { +/// # id -> Uuid, +/// # time_deleted -> Nullable, +/// # } +/// # } +/// # +/// # table! { +/// # test_schema.disk (id) { +/// # id -> Uuid, +/// # time_deleted -> Nullable, +/// # instance_id -> Nullable, +/// # } +/// # } +/// +/// #[derive(Queryable, Debug, Selectable)] +/// #[diesel(table_name = disk)] +/// struct Disk { +/// pub id: uuid::Uuid, +/// pub time_deleted: Option>, +/// pub instance_id: Option, +/// } +/// +/// #[derive(Queryable, Debug, Selectable)] +/// #[diesel(table_name = instance)] +/// struct Instance { +/// pub id: uuid::Uuid, +/// pub time_deleted: Option>, +/// } +/// +/// impl DatastoreAttachTarget for Instance { +/// // Type of instance::id and disk::id. +/// type Id = uuid::Uuid; +/// +/// type CollectionIdColumn = instance::dsl::id; +/// type CollectionTimeDeletedColumn = instance::dsl::time_deleted; +/// +/// type ResourceIdColumn = disk::dsl::id; +/// type ResourceCollectionIdColumn = disk::dsl::instance_id; +/// type ResourceTimeDeletedColumn = disk::dsl::time_deleted; +/// } +/// ``` +pub trait DatastoreAttachTarget: Selectable + Sized { + /// The Rust type of the collection and resource ids (typically Uuid). + type Id: Copy + Debug + PartialEq + Send + 'static; + + /// The primary key column of the collection. + type CollectionIdColumn: Column; + + /// The time deleted column in the CollectionTable + type CollectionTimeDeletedColumn: Column::Table> + + Default + + ExpressionMethods; + + /// The primary key column of the resource + type ResourceIdColumn: Column; + + /// The column in the resource acting as a foreign key into the Collection + type ResourceCollectionIdColumn: Column
::Table> + + Default + + ExpressionMethods; + + /// The time deleted column in the ResourceTable + type ResourceTimeDeletedColumn: Column
::Table> + + Default + + ExpressionMethods; +} diff --git a/nexus/src/db/model/console_session.rs b/nexus/db-model/src/console_session.rs similarity index 95% rename from nexus/src/db/model/console_session.rs rename to nexus/db-model/src/console_session.rs index e22a6d06dc6..35eeafcbec0 100644 --- a/nexus/src/db/model/console_session.rs +++ b/nexus/db-model/src/console_session.rs @@ -2,7 +2,7 @@ // 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 crate::db::schema::console_session; +use crate::schema::console_session; use chrono::{DateTime, Utc}; use uuid::Uuid; diff --git a/nexus/src/db/model/dataset.rs b/nexus/db-model/src/dataset.rs similarity index 95% rename from nexus/src/db/model/dataset.rs rename to nexus/db-model/src/dataset.rs index fd4d24eee40..6ec68a3eb7a 100644 --- a/nexus/src/db/model/dataset.rs +++ b/nexus/db-model/src/dataset.rs @@ -3,8 +3,8 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{DatasetKind, Generation, Region, SqlU16}; -use crate::db::collection_insert::DatastoreCollection; -use crate::db::schema::{dataset, region}; +use crate::collection::DatastoreCollection; +use crate::schema::{dataset, region}; use chrono::{DateTime, Utc}; use db_macros::Asset; use serde::{Deserialize, Serialize}; diff --git a/nexus/src/db/model/dataset_kind.rs b/nexus/db-model/src/dataset_kind.rs similarity index 97% rename from nexus/src/db/model/dataset_kind.rs rename to nexus/db-model/src/dataset_kind.rs index b9d7d1c4b9a..e2c0510ab3d 100644 --- a/nexus/src/db/model/dataset_kind.rs +++ b/nexus/db-model/src/dataset_kind.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::impl_enum_type; -use crate::internal_api; +use nexus_types::internal_api; use serde::{Deserialize, Serialize}; impl_enum_type!( diff --git a/nexus/src/db/model/device_auth.rs b/nexus/db-model/src/device_auth.rs similarity index 98% rename from nexus/src/db/model/device_auth.rs rename to nexus/db-model/src/device_auth.rs index d1137e3672c..67285b809a0 100644 --- a/nexus/src/db/model/device_auth.rs +++ b/nexus/db-model/src/device_auth.rs @@ -6,7 +6,7 @@ //! Device Authorization Grant flow. See the module-level documentation //! on [`nexus::device_auth`] for an overview of how these are used. -use crate::db::schema::{device_access_token, device_auth_request}; +use crate::schema::{device_access_token, device_auth_request}; use chrono::{DateTime, Duration, Utc}; use nexus_types::external_api::views; diff --git a/nexus/src/db/model/digest.rs b/nexus/db-model/src/digest.rs similarity index 100% rename from nexus/src/db/model/digest.rs rename to nexus/db-model/src/digest.rs diff --git a/nexus/src/db/model/disk.rs b/nexus/db-model/src/disk.rs similarity index 98% rename from nexus/src/db/model/disk.rs rename to nexus/db-model/src/disk.rs index d4aa2f20e16..0bea5d272e5 100644 --- a/nexus/src/db/model/disk.rs +++ b/nexus/db-model/src/disk.rs @@ -3,11 +3,11 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{BlockSize, ByteCount, DiskState, Generation}; -use crate::db::identity::Resource; -use crate::db::schema::disk; -use crate::external_api::params; +use crate::schema::disk; use chrono::{DateTime, Utc}; use db_macros::Resource; +use nexus_types::external_api::params; +use nexus_types::identity::Resource; use omicron_common::api::external; use omicron_common::api::internal; use serde::{Deserialize, Serialize}; diff --git a/nexus/src/db/model/disk_state.rs b/nexus/db-model/src/disk_state.rs similarity index 100% rename from nexus/src/db/model/disk_state.rs rename to nexus/db-model/src/disk_state.rs diff --git a/nexus/src/db/model/external_ip.rs b/nexus/db-model/src/external_ip.rs similarity index 96% rename from nexus/src/db/model/external_ip.rs rename to nexus/db-model/src/external_ip.rs index ec83574bcba..969ba50bf80 100644 --- a/nexus/src/db/model/external_ip.rs +++ b/nexus/db-model/src/external_ip.rs @@ -5,17 +5,17 @@ //! Model types for external IPs, both for instances and externally-facing //! services. -use crate::db::model::impl_enum_type; -use crate::db::model::Name; -use crate::db::model::SqlU16; -use crate::db::schema::instance_external_ip; -use crate::external_api::shared; -use crate::external_api::views; +use crate::impl_enum_type; +use crate::schema::instance_external_ip; +use crate::Name; +use crate::SqlU16; use chrono::DateTime; use chrono::Utc; use diesel::Queryable; use diesel::Selectable; use ipnetwork::IpNetwork; +use nexus_types::external_api::shared; +use nexus_types::external_api::views; use omicron_common::api::external::Error; use std::convert::TryFrom; use uuid::Uuid; diff --git a/nexus/src/db/model/generation.rs b/nexus/db-model/src/generation.rs similarity index 100% rename from nexus/src/db/model/generation.rs rename to nexus/db-model/src/generation.rs diff --git a/nexus/src/db/model/global_image.rs b/nexus/db-model/src/global_image.rs similarity index 91% rename from nexus/src/db/model/global_image.rs rename to nexus/db-model/src/global_image.rs index d143623a9f7..4d0174ca173 100644 --- a/nexus/src/db/model/global_image.rs +++ b/nexus/db-model/src/global_image.rs @@ -3,10 +3,10 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{BlockSize, ByteCount, Digest}; -use crate::db::identity::Resource; -use crate::db::schema::global_image; -use crate::external_api::views; +use crate::schema::global_image; use db_macros::Resource; +use nexus_types::external_api::views; +use nexus_types::identity::Resource; use serde::{Deserialize, Serialize}; use uuid::Uuid; diff --git a/nexus/src/db/model/identity_provider.rs b/nexus/db-model/src/identity_provider.rs similarity index 94% rename from nexus/src/db/model/identity_provider.rs rename to nexus/db-model/src/identity_provider.rs index 38427063f8a..3006e80054b 100644 --- a/nexus/src/db/model/identity_provider.rs +++ b/nexus/db-model/src/identity_provider.rs @@ -2,10 +2,10 @@ // 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 crate::db::identity::Resource; -use crate::db::model::impl_enum_type; -use crate::db::schema::{identity_provider, saml_identity_provider}; +use crate::impl_enum_type; +use crate::schema::{identity_provider, saml_identity_provider}; use db_macros::Resource; +use nexus_types::identity::Resource; use nexus_types::external_api::views; use serde::{Deserialize, Serialize}; diff --git a/nexus/src/db/model/image.rs b/nexus/db-model/src/image.rs similarity index 92% rename from nexus/src/db/model/image.rs rename to nexus/db-model/src/image.rs index a8f6fb4cc96..c28537cce1a 100644 --- a/nexus/src/db/model/image.rs +++ b/nexus/db-model/src/image.rs @@ -3,10 +3,10 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{BlockSize, ByteCount, Digest}; -use crate::db::identity::Resource; -use crate::db::schema::image; -use crate::external_api::views; +use crate::schema::image; use db_macros::Resource; +use nexus_types::external_api::views; +use nexus_types::identity::Resource; use serde::{Deserialize, Serialize}; use uuid::Uuid; diff --git a/nexus/src/db/model/instance.rs b/nexus/db-model/src/instance.rs similarity index 97% rename from nexus/src/db/model/instance.rs rename to nexus/db-model/src/instance.rs index 48c047180dc..2f135e5083a 100644 --- a/nexus/src/db/model/instance.rs +++ b/nexus/db-model/src/instance.rs @@ -3,12 +3,12 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{ByteCount, Disk, Generation, InstanceCpuCount, InstanceState}; -use crate::db::collection_attach::DatastoreAttachTarget; -use crate::db::identity::Resource; -use crate::db::schema::{disk, instance}; -use crate::external_api::params; +use crate::collection::DatastoreAttachTarget; +use crate::schema::{disk, instance}; use chrono::{DateTime, Utc}; use db_macros::Resource; +use nexus_types::external_api::params; +use nexus_types::identity::Resource; use omicron_common::address::PROPOLIS_PORT; use omicron_common::api::external; use omicron_common::api::internal; diff --git a/nexus/src/db/model/instance_cpu_count.rs b/nexus/db-model/src/instance_cpu_count.rs similarity index 100% rename from nexus/src/db/model/instance_cpu_count.rs rename to nexus/db-model/src/instance_cpu_count.rs diff --git a/nexus/src/db/model/instance_state.rs b/nexus/db-model/src/instance_state.rs similarity index 100% rename from nexus/src/db/model/instance_state.rs rename to nexus/db-model/src/instance_state.rs diff --git a/nexus/src/db/model/ip_pool.rs b/nexus/db-model/src/ip_pool.rs similarity index 95% rename from nexus/src/db/model/ip_pool.rs rename to nexus/db-model/src/ip_pool.rs index 0aadc87ffb0..b2374759eba 100644 --- a/nexus/src/db/model/ip_pool.rs +++ b/nexus/db-model/src/ip_pool.rs @@ -4,19 +4,19 @@ //! Model types for IP Pools and the CIDR blocks therein. -use crate::db::collection_insert::DatastoreCollection; -use crate::db::identity::Resource; -use crate::db::model::Name; -use crate::db::schema::ip_pool; -use crate::db::schema::ip_pool_range; -use crate::external_api::params; -use crate::external_api::shared::IpRange; +use crate::collection::DatastoreCollection; +use crate::schema::ip_pool; +use crate::schema::ip_pool_range; +use crate::Name; use chrono::DateTime; use chrono::Utc; use db_macros::Resource; use diesel::Selectable; use ipnetwork::IpNetwork; +use nexus_types::external_api::params; +use nexus_types::external_api::shared::IpRange; use nexus_types::external_api::views; +use nexus_types::identity::Resource; use omicron_common::api::external; use std::net::IpAddr; use uuid::Uuid; diff --git a/nexus/src/db/model/ipv4net.rs b/nexus/db-model/src/ipv4net.rs similarity index 100% rename from nexus/src/db/model/ipv4net.rs rename to nexus/db-model/src/ipv4net.rs diff --git a/nexus/src/db/ipv6.rs b/nexus/db-model/src/ipv6.rs similarity index 100% rename from nexus/src/db/ipv6.rs rename to nexus/db-model/src/ipv6.rs diff --git a/nexus/src/db/model/ipv6net.rs b/nexus/db-model/src/ipv6net.rs similarity index 100% rename from nexus/src/db/model/ipv6net.rs rename to nexus/db-model/src/ipv6net.rs diff --git a/nexus/src/db/model/l4_port_range.rs b/nexus/db-model/src/l4_port_range.rs similarity index 100% rename from nexus/src/db/model/l4_port_range.rs rename to nexus/db-model/src/l4_port_range.rs diff --git a/nexus/src/db/model/mod.rs b/nexus/db-model/src/lib.rs similarity index 81% rename from nexus/src/db/model/mod.rs rename to nexus/db-model/src/lib.rs index 9cb8449c701..fe6a01ef751 100644 --- a/nexus/src/db/model/mod.rs +++ b/nexus/db-model/src/lib.rs @@ -4,8 +4,14 @@ //! Structures stored to the database. +#[macro_use] +extern crate diesel; +#[macro_use] +extern crate newtype_derive; + mod block_size; mod bytecount; +mod collection; mod console_session; mod dataset; mod dataset_kind; @@ -23,6 +29,7 @@ mod instance_cpu_count; mod instance_state; mod ip_pool; mod ipv4net; +mod ipv6; mod ipv6net; mod l4_port_range; mod macaddr; @@ -36,6 +43,8 @@ mod rack; mod region; mod role_assignment; mod role_builtin; +pub mod saga_types; +pub mod schema; mod service; mod service_kind; mod silo; @@ -55,10 +64,19 @@ mod vpc_router; mod vpc_subnet; mod zpool; +// This module namespacing is a quirk to allow `db-macros` to refer to +// `crate::db::model::Name` in both this crate and `nexus` proper. +mod db { + pub(crate) mod model { + pub(crate) use crate::Name; + } +} + pub use self::macaddr::*; pub use self::u16::*; pub use block_size::*; pub use bytecount::*; +pub use collection::*; pub use console_session::*; pub use dataset::*; pub use dataset_kind::*; @@ -76,6 +94,7 @@ pub use instance_cpu_count::*; pub use instance_state::*; pub use ip_pool::*; pub use ipv4net::*; +pub use ipv6::*; pub use ipv6net::*; pub use l4_port_range::*; pub use name::*; @@ -252,74 +271,6 @@ pub trait DatabaseString: Sized { fn from_database_string(s: &str) -> Result; } -/// Does some basic smoke checks on an impl of `DatabaseString` -/// -/// This tests: -/// -/// - that for every variant, if we serialize it and deserialize the result, we -/// get back the original variant -/// - that if we attempt to deserialize some _other_ input, we get back an error -/// - that the serialized form for each variant matches what's found in -/// `expected_output_file`. This output file is generated by this test using -/// expectorate. -/// -/// This cannot completely test the correctness of the implementation, but it -/// can catch some basic copy/paste errors and accidental compatibility -/// breakage. -#[cfg(test)] -pub fn test_database_string_impl(expected_output_file: P) -where - T: std::fmt::Debug + PartialEq + DatabaseString + strum::IntoEnumIterator, - P: std::convert::AsRef, -{ - let mut output = String::new(); - let mut maxlen: Option = None; - - for variant in T::iter() { - // Serialize the variant. Verify that we can deserialize the thing we - // just got back. - let serialized = variant.to_database_string(); - let deserialized = - T::from_database_string(serialized).unwrap_or_else(|_| { - panic!( - "failed to deserialize the string {:?}, which we \ - got by serializing {:?}", - serialized, variant - ) - }); - assert_eq!(variant, deserialized); - - // Put the serialized form into "output". At the end, we'll compare - // this to the expected output. This will fail if somebody has - // incompatibly changed things. - output.push_str(&format!( - "variant {:?}: serialized form = {}\n", - variant, serialized - )); - - // Keep track of the maximum length of the serialized strings. We'll - // use this to construct an input to `from_database_string()` that was - // not emitted by any of the variants' `to_database_string()` functions. - match (maxlen, serialized.len()) { - (None, newlen) => maxlen = Some(newlen), - (Some(oldlen), newlen) if newlen > oldlen => maxlen = Some(newlen), - _ => (), - } - } - - // Check that `from_database_string()` fails when given input that doesn't - // match any of the variants' serialized forms. We construct this input by - // providing a string that's longer than all strings emitted by - // `to_database_string()`. - if let Some(maxlen) = maxlen { - let input = String::from_utf8(vec![b'-'; maxlen + 1]).unwrap(); - T::from_database_string(&input) - .expect_err("expected failure to deserialize unknown string"); - } - - expectorate::assert_contents(expected_output_file, &output); -} - #[cfg(test)] mod tests { use super::VpcSubnet; diff --git a/nexus/src/db/model/macaddr.rs b/nexus/db-model/src/macaddr.rs similarity index 94% rename from nexus/src/db/model/macaddr.rs rename to nexus/db-model/src/macaddr.rs index 29dc983d0a9..ff5d91427b9 100644 --- a/nexus/src/db/model/macaddr.rs +++ b/nexus/db-model/src/macaddr.rs @@ -24,8 +24,8 @@ impl MacAddr { // range, and // https://github.com/oxidecomputer/omicron/pull/955#discussion_r856432498 // for an initial discussion of the customer/system address range split. - pub(crate) const MIN_GUEST_ADDR: i64 = 0xA8_40_25_F0_00_00; - pub(crate) const MAX_GUEST_ADDR: i64 = 0xA8_40_25_FE_FF_FF; + pub const MIN_GUEST_ADDR: i64 = 0xA8_40_25_F0_00_00; + pub const MAX_GUEST_ADDR: i64 = 0xA8_40_25_FE_FF_FF; /// Generate a random MAC address for a guest network interface pub fn random_guest() -> Self { @@ -45,7 +45,7 @@ impl MacAddr { /// Convert a MAC address to its i64 big-endian byte representation // NOTE: This is the representation used in the database. - pub(crate) fn to_i64(self) -> i64 { + pub fn to_i64(self) -> i64 { let bytes = self.0.as_bytes(); i64::from_be_bytes([ 0, 0, bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], diff --git a/nexus/src/db/model/name.rs b/nexus/db-model/src/name.rs similarity index 100% rename from nexus/src/db/model/name.rs rename to nexus/db-model/src/name.rs diff --git a/nexus/src/db/model/network_interface.rs b/nexus/db-model/src/network_interface.rs similarity index 95% rename from nexus/src/db/model/network_interface.rs rename to nexus/db-model/src/network_interface.rs index 3f56e5e5db8..5a135ccdf9f 100644 --- a/nexus/src/db/model/network_interface.rs +++ b/nexus/db-model/src/network_interface.rs @@ -3,14 +3,14 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{MacAddr, VpcSubnet}; -use crate::db::identity::Resource; -use crate::db::model::Name; -use crate::db::schema::network_interface; -use crate::external_api::params; +use crate::schema::network_interface; +use crate::Name; use chrono::DateTime; use chrono::Utc; use db_macros::Resource; use diesel::AsChangeset; +use nexus_types::external_api::params; +use nexus_types::identity::Resource; use omicron_common::api::external; use uuid::Uuid; diff --git a/nexus/src/db/model/organization.rs b/nexus/db-model/src/organization.rs similarity index 92% rename from nexus/src/db/model/organization.rs rename to nexus/db-model/src/organization.rs index 10171b147c1..56d27707bf7 100644 --- a/nexus/src/db/model/organization.rs +++ b/nexus/db-model/src/organization.rs @@ -3,13 +3,13 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{Generation, Name, Project}; -use crate::db::collection_insert::DatastoreCollection; -use crate::db::identity::Resource; -use crate::db::schema::{organization, project}; -use crate::external_api::params; +use crate::collection::DatastoreCollection; +use crate::schema::{organization, project}; use chrono::{DateTime, Utc}; use db_macros::Resource; +use nexus_types::external_api::params; use nexus_types::external_api::views; +use nexus_types::identity::Resource; use uuid::Uuid; /// Describes an organization within the database. diff --git a/nexus/src/db/model/oximeter_info.rs b/nexus/db-model/src/oximeter_info.rs similarity index 95% rename from nexus/src/db/model/oximeter_info.rs rename to nexus/db-model/src/oximeter_info.rs index 0ef5fa28614..ac30384c59a 100644 --- a/nexus/src/db/model/oximeter_info.rs +++ b/nexus/db-model/src/oximeter_info.rs @@ -3,9 +3,9 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::SqlU16; -use crate::db::schema::oximeter; -use crate::internal_api; +use crate::schema::oximeter; use chrono::{DateTime, Utc}; +use nexus_types::internal_api; use uuid::Uuid; /// Message used to notify Nexus that this oximeter instance is up and running. diff --git a/nexus/src/db/model/producer_endpoint.rs b/nexus/db-model/src/producer_endpoint.rs similarity index 95% rename from nexus/src/db/model/producer_endpoint.rs rename to nexus/db-model/src/producer_endpoint.rs index 6b5b9f62c1c..29e57b0877e 100644 --- a/nexus/src/db/model/producer_endpoint.rs +++ b/nexus/db-model/src/producer_endpoint.rs @@ -3,9 +3,9 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::SqlU16; -use crate::db::identity::Asset; -use crate::db::schema::metric_producer; +use crate::schema::metric_producer; use db_macros::Asset; +use nexus_types::identity::Asset; use omicron_common::api::internal; use uuid::Uuid; diff --git a/nexus/src/db/model/project.rs b/nexus/db-model/src/project.rs similarity index 93% rename from nexus/src/db/model/project.rs rename to nexus/db-model/src/project.rs index 5e47b424086..ccfacee44bd 100644 --- a/nexus/src/db/model/project.rs +++ b/nexus/db-model/src/project.rs @@ -3,11 +3,12 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::Name; -use crate::db::{identity::Resource, schema::project}; -use crate::external_api::params; +use crate::schema::project; use chrono::{DateTime, Utc}; use db_macros::Resource; +use nexus_types::external_api::params; use nexus_types::external_api::views; +use nexus_types::identity::Resource; use uuid::Uuid; /// Describes a project within the database. diff --git a/nexus/src/db/model/rack.rs b/nexus/db-model/src/rack.rs similarity index 96% rename from nexus/src/db/model/rack.rs rename to nexus/db-model/src/rack.rs index cc6916ee24b..63ce64f996d 100644 --- a/nexus/src/db/model/rack.rs +++ b/nexus/db-model/src/rack.rs @@ -2,7 +2,7 @@ // 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 crate::db::schema::rack; +use crate::schema::rack; use db_macros::Asset; use nexus_types::external_api::views; use uuid::Uuid; diff --git a/nexus/src/db/model/region.rs b/nexus/db-model/src/region.rs similarity index 98% rename from nexus/src/db/model/region.rs rename to nexus/db-model/src/region.rs index 0f4f7d79afc..5fcbaddb4a9 100644 --- a/nexus/src/db/model/region.rs +++ b/nexus/db-model/src/region.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::ByteCount; -use crate::db::schema::region; +use crate::schema::region; use db_macros::Asset; use omicron_common::api::external; use serde::{Deserialize, Serialize}; diff --git a/nexus/src/db/model/role_assignment.rs b/nexus/db-model/src/role_assignment.rs similarity index 93% rename from nexus/src/db/model/role_assignment.rs rename to nexus/db-model/src/role_assignment.rs index a8ecb04fc79..66e563f3dab 100644 --- a/nexus/src/db/model/role_assignment.rs +++ b/nexus/db-model/src/role_assignment.rs @@ -3,9 +3,9 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{impl_enum_type, DatabaseString}; -use crate::db::schema::role_assignment; -use crate::external_api::shared; +use crate::schema::role_assignment; use anyhow::anyhow; +use nexus_types::external_api::shared; use omicron_common::api::external::Error; use serde::{Deserialize, Serialize}; use uuid::Uuid; @@ -117,7 +117,6 @@ where #[cfg(test)] mod tests { use super::*; - use crate::db; use omicron_common::api::external::ResourceType; #[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq)] @@ -126,7 +125,7 @@ mod tests { Bogus, } - impl db::model::DatabaseString for DummyRoles { + impl crate::DatabaseString for DummyRoles { type Error = anyhow::Error; fn to_database_string(&self) -> &str { @@ -149,21 +148,21 @@ mod tests { let resource_id = "9e3e3be8-4051-4ddb-92fa-32cc5294f066".parse().unwrap(); - let ok_input = db::model::RoleAssignment { - identity_type: db::model::IdentityType::SiloUser, + let ok_input = crate::RoleAssignment { + identity_type: crate::IdentityType::SiloUser, identity_id, resource_type: ResourceType::Organization.to_string(), resource_id, role_name: String::from("bogus"), }; - let bad_input_role = db::model::RoleAssignment { + let bad_input_role = crate::RoleAssignment { role_name: String::from("bogosity"), ..ok_input.clone() }; - let bad_input_idtype = db::model::RoleAssignment { - identity_type: db::model::IdentityType::UserBuiltin, + let bad_input_idtype = crate::RoleAssignment { + identity_type: crate::IdentityType::UserBuiltin, ..ok_input.clone() }; diff --git a/nexus/src/db/model/role_builtin.rs b/nexus/db-model/src/role_builtin.rs similarity index 97% rename from nexus/src/db/model/role_builtin.rs rename to nexus/db-model/src/role_builtin.rs index a088a34501b..368cdd88b20 100644 --- a/nexus/src/db/model/role_builtin.rs +++ b/nexus/db-model/src/role_builtin.rs @@ -2,7 +2,7 @@ // 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 crate::db::schema::role_builtin; +use crate::schema::role_builtin; use nexus_types::external_api::views; use omicron_common::api::external::RoleName; diff --git a/nexus/src/db/saga_types.rs b/nexus/db-model/src/saga_types.rs similarity index 99% rename from nexus/src/db/saga_types.rs rename to nexus/db-model/src/saga_types.rs index 9027a354716..68785bba6bd 100644 --- a/nexus/src/db/saga_types.rs +++ b/nexus/db-model/src/saga_types.rs @@ -189,7 +189,7 @@ pub struct Saga { pub saga_params: serde_json::Value, pub saga_state: SagaCachedState, pub current_sec: Option, - pub adopt_generation: super::model::Generation, + pub adopt_generation: super::Generation, pub adopt_time: chrono::DateTime, } diff --git a/nexus/src/db/schema.rs b/nexus/db-model/src/schema.rs similarity index 92% rename from nexus/src/db/schema.rs rename to nexus/db-model/src/schema.rs index 609f021dda0..c5f7406a51e 100644 --- a/nexus/src/db/schema.rs +++ b/nexus/db-model/src/schema.rs @@ -22,7 +22,7 @@ table! { state_generation -> Int8, time_state_updated -> Timestamptz, size_bytes -> Int8, - block_size -> crate::db::model::BlockSizeEnum, + block_size -> crate::BlockSizeEnum, origin_snapshot -> Nullable, origin_image -> Nullable, } @@ -41,7 +41,7 @@ table! { url -> Nullable, version -> Nullable, digest -> Nullable, - block_size -> crate::db::model::BlockSizeEnum, + block_size -> crate::BlockSizeEnum, size_bytes -> Int8, } } @@ -59,7 +59,7 @@ table! { distribution -> Text, version -> Text, digest -> Nullable, - block_size -> crate::db::model::BlockSizeEnum, + block_size -> crate::BlockSizeEnum, size_bytes -> Int8, } } @@ -90,7 +90,7 @@ table! { time_deleted -> Nullable, project_id -> Uuid, user_data -> Binary, - state -> crate::db::model::InstanceStateEnum, + state -> crate::InstanceStateEnum, time_state_updated -> Timestamptz, state_generation -> Int8, active_server_id -> Uuid, @@ -174,7 +174,7 @@ table! { ip_pool_range_id -> Uuid, project_id -> Uuid, instance_id -> Nullable, - kind -> crate::db::model::IpKindEnum, + kind -> crate::IpKindEnum, ip -> Inet, first_port -> Int4, last_port -> Int4, @@ -191,7 +191,7 @@ table! { time_deleted -> Nullable, discoverable -> Bool, - user_provision_type -> crate::db::model::UserProvisionTypeEnum, + user_provision_type -> crate::UserProvisionTypeEnum, rcgen -> Int8, } } @@ -218,7 +218,7 @@ table! { time_deleted -> Nullable, silo_id -> Uuid, - provider_type -> crate::db::model::IdentityProviderTypeEnum, + provider_type -> crate::IdentityProviderTypeEnum, } } @@ -300,7 +300,7 @@ table! { template_name -> Text, time_created -> Timestamptz, saga_params -> Jsonb, - saga_state -> crate::db::saga_types::SagaCachedStateEnum, + saga_state -> crate::saga_types::SagaCachedStateEnum, current_sec -> Nullable, adopt_generation -> Int8, adopt_time -> Timestamptz, @@ -360,7 +360,7 @@ table! { sled_id -> Uuid, ip -> Inet, - kind -> crate::db::model::ServiceKindEnum, + kind -> crate::ServiceKindEnum, } } @@ -391,7 +391,7 @@ table! { ip -> Inet, port -> Int4, - kind -> crate::db::model::DatasetKindEnum, + kind -> crate::DatasetKindEnum, size_used -> Nullable, } @@ -464,7 +464,7 @@ table! { time_created -> Timestamptz, time_modified -> Timestamptz, time_deleted -> Nullable, - kind -> crate::db::model::VpcRouterKindEnum, + kind -> crate::VpcRouterKindEnum, vpc_id -> Uuid, rcgen -> Int8, } @@ -478,7 +478,7 @@ table! { time_created -> Timestamptz, time_modified -> Timestamptz, time_deleted -> Nullable, - kind -> crate::db::model::RouterRouteKindEnum, + kind -> crate::RouterRouteKindEnum, vpc_router_id -> Uuid, target -> Text, destination -> Text, @@ -486,7 +486,6 @@ table! { } table! { - use crate::db::model; use diesel::sql_types::*; vpc_firewall_rule (id) { @@ -497,13 +496,13 @@ table! { time_modified -> Timestamptz, time_deleted -> Nullable, vpc_id -> Uuid, - status -> model::VpcFirewallRuleStatusEnum, - direction -> model::VpcFirewallRuleDirectionEnum, + status -> crate::VpcFirewallRuleStatusEnum, + direction -> crate::VpcFirewallRuleDirectionEnum, targets -> Array, filter_hosts -> Nullable>, filter_ports -> Nullable>, - filter_protocols -> Nullable>, - action -> model::VpcFirewallRuleActionEnum, + filter_protocols -> Nullable>, + action -> crate::VpcFirewallRuleActionEnum, priority -> Int4, } } @@ -557,7 +556,7 @@ table! { resource_id, role_name ) { - identity_type -> crate::db::model::IdentityTypeEnum, + identity_type -> crate::IdentityTypeEnum, identity_id -> Uuid, resource_type -> Text, role_name -> Text, @@ -569,7 +568,7 @@ table! { update_available_artifact (name, version, kind) { name -> Text, version -> Int8, - kind -> crate::db::model::UpdateArtifactKindEnum, + kind -> crate::UpdateArtifactKindEnum, targets_role_version -> Int8, valid_until -> Timestamptz, target_name -> Text, diff --git a/nexus/src/db/model/service.rs b/nexus/db-model/src/service.rs similarity index 94% rename from nexus/src/db/model/service.rs rename to nexus/db-model/src/service.rs index 3501337e42b..3b9e57cfc62 100644 --- a/nexus/src/db/model/service.rs +++ b/nexus/db-model/src/service.rs @@ -3,8 +3,8 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::ServiceKind; -use crate::db::ipv6; -use crate::db::schema::service; +use crate::ipv6; +use crate::schema::service; use db_macros::Asset; use std::net::Ipv6Addr; use uuid::Uuid; diff --git a/nexus/src/db/model/service_kind.rs b/nexus/db-model/src/service_kind.rs similarity index 97% rename from nexus/src/db/model/service_kind.rs rename to nexus/db-model/src/service_kind.rs index e6e9b45bd59..d7230367d45 100644 --- a/nexus/src/db/model/service_kind.rs +++ b/nexus/db-model/src/service_kind.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::impl_enum_type; -use crate::internal_api; +use nexus_types::internal_api; use serde::{Deserialize, Serialize}; impl_enum_type!( diff --git a/nexus/src/db/model/silo.rs b/nexus/db-model/src/silo.rs similarity index 92% rename from nexus/src/db/model/silo.rs rename to nexus/db-model/src/silo.rs index e2f2dcadbf7..83134c4a89f 100644 --- a/nexus/src/db/model/silo.rs +++ b/nexus/db-model/src/silo.rs @@ -3,13 +3,13 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{Generation, Organization}; -use crate::db::collection_insert::DatastoreCollection; -use crate::db::identity::Resource; -use crate::db::model::impl_enum_type; -use crate::db::schema::{organization, silo}; -use crate::external_api::{params, shared}; +use crate::collection::DatastoreCollection; +use crate::impl_enum_type; +use crate::schema::{organization, silo}; use db_macros::Resource; use nexus_types::external_api::views; +use nexus_types::external_api::{params, shared}; +use nexus_types::identity::Resource; use uuid::Uuid; impl_enum_type!( diff --git a/nexus/src/db/model/silo_user.rs b/nexus/db-model/src/silo_user.rs similarity index 94% rename from nexus/src/db/model/silo_user.rs rename to nexus/db-model/src/silo_user.rs index 2365ce45589..16fb6eb32f4 100644 --- a/nexus/src/db/model/silo_user.rs +++ b/nexus/db-model/src/silo_user.rs @@ -2,10 +2,10 @@ // 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 crate::db::identity::Asset; -use crate::db::schema::silo_user; +use crate::schema::silo_user; use db_macros::Asset; use nexus_types::external_api::views; +use nexus_types::identity::Asset; use uuid::Uuid; /// Describes a silo user within the database. diff --git a/nexus/src/db/model/sled.rs b/nexus/db-model/src/sled.rs similarity index 95% rename from nexus/src/db/model/sled.rs rename to nexus/db-model/src/sled.rs index 8bcb122359b..d5d4c89b7a5 100644 --- a/nexus/src/db/model/sled.rs +++ b/nexus/db-model/src/sled.rs @@ -3,9 +3,9 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{Generation, SqlU16}; -use crate::db::collection_insert::DatastoreCollection; -use crate::db::ipv6; -use crate::db::schema::{service, sled, zpool}; +use crate::collection::DatastoreCollection; +use crate::ipv6; +use crate::schema::{service, sled, zpool}; use chrono::{DateTime, Utc}; use db_macros::Asset; use nexus_types::external_api::views; diff --git a/nexus/src/db/model/snapshot.rs b/nexus/db-model/src/snapshot.rs similarity index 90% rename from nexus/src/db/model/snapshot.rs rename to nexus/db-model/src/snapshot.rs index 6ea9b934de9..b3ab2ad95ca 100644 --- a/nexus/src/db/model/snapshot.rs +++ b/nexus/db-model/src/snapshot.rs @@ -3,10 +3,10 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::ByteCount; -use crate::db::identity::Resource; -use crate::db::schema::snapshot; -use crate::external_api::views; +use crate::schema::snapshot; use db_macros::Resource; +use nexus_types::external_api::views; +use nexus_types::identity::Resource; use serde::{Deserialize, Serialize}; use uuid::Uuid; diff --git a/nexus/src/db/model/ssh_key.rs b/nexus/db-model/src/ssh_key.rs similarity index 92% rename from nexus/src/db/model/ssh_key.rs rename to nexus/db-model/src/ssh_key.rs index a0726ebf093..79513ded62b 100644 --- a/nexus/src/db/model/ssh_key.rs +++ b/nexus/db-model/src/ssh_key.rs @@ -2,11 +2,11 @@ // 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 crate::db::identity::Resource; -use crate::db::schema::ssh_key; -use crate::external_api::params; +use crate::schema::ssh_key; use db_macros::Resource; +use nexus_types::external_api::params; use nexus_types::external_api::views; +use nexus_types::identity::Resource; use uuid::Uuid; /// Describes a user's public SSH key within the database. diff --git a/nexus/src/db/model/u16.rs b/nexus/db-model/src/u16.rs similarity index 100% rename from nexus/src/db/model/u16.rs rename to nexus/db-model/src/u16.rs diff --git a/nexus/src/db/model/update_artifact.rs b/nexus/db-model/src/update_artifact.rs similarity index 96% rename from nexus/src/db/model/update_artifact.rs rename to nexus/db-model/src/update_artifact.rs index 1787f171230..13615e045ec 100644 --- a/nexus/src/db/model/update_artifact.rs +++ b/nexus/db-model/src/update_artifact.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::impl_enum_wrapper; -use crate::db::schema::update_available_artifact; +use crate::schema::update_available_artifact; use chrono::{DateTime, Utc}; use omicron_common::api::internal; use parse_display::Display; diff --git a/nexus/src/db/model/user_builtin.rs b/nexus/db-model/src/user_builtin.rs similarity index 89% rename from nexus/src/db/model/user_builtin.rs rename to nexus/db-model/src/user_builtin.rs index 7f046910146..79b6ba91770 100644 --- a/nexus/src/db/model/user_builtin.rs +++ b/nexus/db-model/src/user_builtin.rs @@ -2,11 +2,11 @@ // 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 crate::db::identity::Resource; -use crate::db::schema::user_builtin; -use crate::external_api::params; +use crate::schema::user_builtin; use db_macros::Resource; +use nexus_types::external_api::params; use nexus_types::external_api::views; +use nexus_types::identity::Resource; use uuid::Uuid; /// Describes a built-in user, as stored in the database diff --git a/nexus/src/db/model/vni.rs b/nexus/db-model/src/vni.rs similarity index 100% rename from nexus/src/db/model/vni.rs rename to nexus/db-model/src/vni.rs diff --git a/nexus/src/db/model/volume.rs b/nexus/db-model/src/volume.rs similarity index 92% rename from nexus/src/db/model/volume.rs rename to nexus/db-model/src/volume.rs index e5cdcc8078e..b4d1cc1c141 100644 --- a/nexus/src/db/model/volume.rs +++ b/nexus/db-model/src/volume.rs @@ -3,8 +3,8 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{Generation, Region}; -use crate::db::collection_insert::DatastoreCollection; -use crate::db::schema::{region, volume}; +use crate::collection::DatastoreCollection; +use crate::schema::{region, volume}; use chrono::{DateTime, Utc}; use db_macros::Asset; use serde::{Deserialize, Serialize}; diff --git a/nexus/src/db/model/vpc.rs b/nexus/db-model/src/vpc.rs similarity index 94% rename from nexus/src/db/model/vpc.rs rename to nexus/db-model/src/vpc.rs index 84d55ab7702..016d62707b5 100644 --- a/nexus/src/db/model/vpc.rs +++ b/nexus/db-model/src/vpc.rs @@ -3,16 +3,16 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{Generation, Ipv6Net, Name, VpcFirewallRule}; -use crate::db::collection_insert::DatastoreCollection; -use crate::db::identity::Resource; -use crate::db::model::Vni; -use crate::db::schema::{vpc, vpc_firewall_rule}; -use crate::external_api::params; +use crate::collection::DatastoreCollection; +use crate::schema::{vpc, vpc_firewall_rule}; +use crate::Vni; use chrono::{DateTime, Utc}; use db_macros::Resource; use ipnetwork::IpNetwork; use nexus_defaults as defaults; +use nexus_types::external_api::params; use nexus_types::external_api::views; +use nexus_types::identity::Resource; use omicron_common::api::external; use uuid::Uuid; diff --git a/nexus/src/db/model/vpc_firewall_rule.rs b/nexus/db-model/src/vpc_firewall_rule.rs similarity index 99% rename from nexus/src/db/model/vpc_firewall_rule.rs rename to nexus/db-model/src/vpc_firewall_rule.rs index da37a304b2a..d4228e24e12 100644 --- a/nexus/src/db/model/vpc_firewall_rule.rs +++ b/nexus/db-model/src/vpc_firewall_rule.rs @@ -3,14 +3,14 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{impl_enum_wrapper, L4PortRange, SqlU16}; -use crate::db::identity::Resource; -use crate::db::schema::vpc_firewall_rule; +use crate::schema::vpc_firewall_rule; use db_macros::Resource; use diesel::backend::{Backend, RawValue}; use diesel::deserialize::{self, FromSql}; use diesel::pg::Pg; use diesel::serialize::{self, ToSql}; use diesel::sql_types; +use nexus_types::identity::Resource; use omicron_common::api::external; use std::io::Write; use uuid::Uuid; diff --git a/nexus/src/db/model/vpc_route.rs b/nexus/db-model/src/vpc_route.rs similarity index 98% rename from nexus/src/db/model/vpc_route.rs rename to nexus/db-model/src/vpc_route.rs index 2bfaf09cf82..c8316bef14b 100644 --- a/nexus/src/db/model/vpc_route.rs +++ b/nexus/db-model/src/vpc_route.rs @@ -3,8 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{impl_enum_wrapper, Name}; -use crate::db::identity::Resource; -use crate::db::schema::router_route; +use crate::schema::router_route; use chrono::{DateTime, Utc}; use db_macros::Resource; use diesel::backend::{Backend, RawValue}; @@ -12,6 +11,7 @@ use diesel::deserialize::{self, FromSql}; use diesel::pg::Pg; use diesel::serialize::{self, ToSql}; use diesel::sql_types; +use nexus_types::identity::Resource; use omicron_common::api::external; use std::io::Write; use uuid::Uuid; diff --git a/nexus/src/db/model/vpc_router.rs b/nexus/db-model/src/vpc_router.rs similarity index 93% rename from nexus/src/db/model/vpc_router.rs rename to nexus/db-model/src/vpc_router.rs index e8047332d1f..bde8e5ade7b 100644 --- a/nexus/src/db/model/vpc_router.rs +++ b/nexus/db-model/src/vpc_router.rs @@ -3,13 +3,13 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{impl_enum_type, Generation, Name, RouterRoute}; -use crate::db::collection_insert::DatastoreCollection; -use crate::db::identity::Resource; -use crate::db::schema::{router_route, vpc_router}; -use crate::external_api::params; +use crate::collection::DatastoreCollection; +use crate::schema::{router_route, vpc_router}; use chrono::{DateTime, Utc}; use db_macros::Resource; +use nexus_types::external_api::params; use nexus_types::external_api::views; +use nexus_types::identity::Resource; use uuid::Uuid; impl_enum_type!( diff --git a/nexus/src/db/model/vpc_subnet.rs b/nexus/db-model/src/vpc_subnet.rs similarity index 96% rename from nexus/src/db/model/vpc_subnet.rs rename to nexus/db-model/src/vpc_subnet.rs index d8370ca6c78..21fcf93cc11 100644 --- a/nexus/src/db/model/vpc_subnet.rs +++ b/nexus/db-model/src/vpc_subnet.rs @@ -3,11 +3,12 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{Ipv4Net, Ipv6Net, Name}; -use crate::db::{identity::Resource, schema::vpc_subnet}; -use crate::external_api::params; +use crate::schema::vpc_subnet; use chrono::{DateTime, Utc}; use db_macros::Resource; +use nexus_types::external_api::params; use nexus_types::external_api::views; +use nexus_types::identity::Resource; use omicron_common::api::external; use std::net::IpAddr; use uuid::Uuid; diff --git a/nexus/src/db/model/zpool.rs b/nexus/db-model/src/zpool.rs similarity index 92% rename from nexus/src/db/model/zpool.rs rename to nexus/db-model/src/zpool.rs index 511312a3382..d7636741677 100644 --- a/nexus/src/db/model/zpool.rs +++ b/nexus/db-model/src/zpool.rs @@ -3,11 +3,11 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{ByteCount, Dataset, Generation}; -use crate::db::collection_insert::DatastoreCollection; -use crate::db::schema::{dataset, zpool}; -use crate::internal_api; +use crate::collection::DatastoreCollection; +use crate::schema::{dataset, zpool}; use chrono::{DateTime, Utc}; use db_macros::Asset; +use nexus_types::internal_api; use uuid::Uuid; /// Database representation of a Pool. diff --git a/nexus/src/app/instance.rs b/nexus/src/app/instance.rs index 2c3967c578e..c7418e9a7ac 100644 --- a/nexus/src/app/instance.rs +++ b/nexus/src/app/instance.rs @@ -11,14 +11,15 @@ use crate::app::sagas; use crate::authn; use crate::authz; use crate::authz::ApiResource; +use crate::cidata::InstanceCiData; use crate::context::OpContext; use crate::db; use crate::db::identity::Resource; use crate::db::lookup::LookupPath; -use crate::db::model::IpKind; -use crate::db::model::Name; use crate::db::queries::network_interface; use crate::external_api::params; +use nexus_db_model::IpKind; +use nexus_db_model::Name; use omicron_common::api::external::ByteCount; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DataPageParams; diff --git a/nexus/src/authz/api_resources.rs b/nexus/src/authz/api_resources.rs index 89d3a947ab8..b2c164e8f42 100644 --- a/nexus/src/authz/api_resources.rs +++ b/nexus/src/authz/api_resources.rs @@ -838,7 +838,7 @@ mod test { use super::OrganizationRole; use super::ProjectRole; use super::SiloRole; - use crate::db::model::test_database_string_impl; + use crate::db::test_database_string_impl; #[test] fn test_roles_database_strings() { diff --git a/nexus/src/cidata.rs b/nexus/src/cidata.rs index 5e0190c78da..17e7a4f2060 100644 --- a/nexus/src/cidata.rs +++ b/nexus/src/cidata.rs @@ -8,8 +8,13 @@ use uuid::Uuid; pub use nexus_types::external_api::params::MAX_USER_DATA_BYTES; -impl Instance { - pub fn generate_cidata( +pub trait InstanceCiData { + fn generate_cidata(&self, public_keys: &[String]) + -> Result, Error>; +} + +impl InstanceCiData for Instance { + fn generate_cidata( &self, public_keys: &[String], ) -> Result, Error> { diff --git a/nexus/src/db/collection_attach.rs b/nexus/src/db/collection_attach.rs index e008a06c8a8..33fb40c2c5c 100644 --- a/nexus/src/db/collection_attach.rs +++ b/nexus/src/db/collection_attach.rs @@ -27,6 +27,7 @@ use diesel::query_builder::*; use diesel::query_dsl::methods as query_methods; use diesel::query_source::Table; use diesel::sql_types::{BigInt, Nullable, SingleValue}; +use nexus_db_model::DatastoreAttachTarget; use std::fmt::Debug; /// A collection of type aliases particularly relevant to collection-based CTEs. @@ -77,81 +78,11 @@ pub(crate) mod aliases { use aliases::*; -/// Trait to be implemented by structs representing an attachable collection. -/// -/// For example, since Instances have a one-to-many relationship with -/// Disks, the Instance datatype should implement this trait. -/// ``` -/// # use diesel::prelude::*; -/// # use omicron_nexus::db::collection_attach::DatastoreAttachTarget; -/// # -/// # table! { -/// # test_schema.instance (id) { -/// # id -> Uuid, -/// # time_deleted -> Nullable, -/// # } -/// # } -/// # -/// # table! { -/// # test_schema.disk (id) { -/// # id -> Uuid, -/// # time_deleted -> Nullable, -/// # instance_id -> Nullable, -/// # } -/// # } -/// -/// #[derive(Queryable, Debug, Selectable)] -/// #[diesel(table_name = disk)] -/// struct Disk { -/// pub id: uuid::Uuid, -/// pub time_deleted: Option>, -/// pub instance_id: Option, -/// } -/// -/// #[derive(Queryable, Debug, Selectable)] -/// #[diesel(table_name = instance)] -/// struct Instance { -/// pub id: uuid::Uuid, -/// pub time_deleted: Option>, -/// } -/// -/// impl DatastoreAttachTarget for Instance { -/// // Type of instance::id and disk::id. -/// type Id = uuid::Uuid; -/// -/// type CollectionIdColumn = instance::dsl::id; -/// type CollectionTimeDeletedColumn = instance::dsl::time_deleted; -/// -/// type ResourceIdColumn = disk::dsl::id; -/// type ResourceCollectionIdColumn = disk::dsl::instance_id; -/// type ResourceTimeDeletedColumn = disk::dsl::time_deleted; -/// } -/// ``` -pub trait DatastoreAttachTarget: Selectable + Sized { - /// The Rust type of the collection and resource ids (typically Uuid). - type Id: Copy + Debug + PartialEq + Send + 'static; - - /// The primary key column of the collection. - type CollectionIdColumn: Column; - - /// The time deleted column in the CollectionTable - type CollectionTimeDeletedColumn: Column
::Table> - + Default - + ExpressionMethods; - - /// The primary key column of the resource - type ResourceIdColumn: Column; - - /// The column in the resource acting as a foreign key into the Collection - type ResourceCollectionIdColumn: Column
::Table> - + Default - + ExpressionMethods; - - /// The time deleted column in the ResourceTable - type ResourceTimeDeletedColumn: Column
::Table> - + Default - + ExpressionMethods; - +/// Extension trait adding behavior to types that implement +/// `nexus_db_model::DatastoreAttachTarget`. +pub trait DatastoreAttachTargetExt: + DatastoreAttachTarget +{ /// Creates a statement for attaching a resource to the given collection. /// /// This statement allows callers to atomically check the state of a @@ -325,6 +256,8 @@ pub trait DatastoreAttachTarget: Selectable + Sized { } } +impl DatastoreAttachTargetExt for T where T: DatastoreAttachTarget {} + /// The CTE described in the module docs #[must_use = "Queries must be executed"] pub struct AttachToCollectionStatement @@ -651,7 +584,7 @@ where #[cfg(test)] mod test { - use super::{AttachError, DatastoreAttachTarget}; + use super::*; use crate::db::{ self, error::TransactionError, identity::Resource as IdentityResource, }; diff --git a/nexus/src/db/collection_detach.rs b/nexus/src/db/collection_detach.rs index 62974c41593..9f57028d5a7 100644 --- a/nexus/src/db/collection_detach.rs +++ b/nexus/src/db/collection_detach.rs @@ -16,7 +16,6 @@ use super::cte_utils::{ QueryFromClause, QuerySqlType, }; use super::pool::DbConnection; -use crate::db::collection_attach::DatastoreAttachTarget; use async_bb8_diesel::{AsyncRunQueryDsl, ConnectionManager, PoolError}; use diesel::associations::HasTable; use diesel::expression::{AsExpression, Expression}; @@ -27,6 +26,7 @@ use diesel::query_builder::*; use diesel::query_dsl::methods as query_methods; use diesel::query_source::Table; use diesel::sql_types::{Nullable, SingleValue}; +use nexus_db_model::DatastoreAttachTarget; use std::fmt::Debug; /// Trait to be implemented by structs representing a detachable collection. @@ -500,8 +500,8 @@ where #[cfg(test)] mod test { - use super::{DatastoreDetachTarget, DetachError}; - use crate::db::collection_attach::DatastoreAttachTarget; + use super::*; + use crate::db::collection_attach::DatastoreAttachTargetExt; use crate::db::{ self, error::TransactionError, identity::Resource as IdentityResource, }; diff --git a/nexus/src/db/collection_detach_many.rs b/nexus/src/db/collection_detach_many.rs index 31addf386f2..ab723c92ee5 100644 --- a/nexus/src/db/collection_detach_many.rs +++ b/nexus/src/db/collection_detach_many.rs @@ -16,7 +16,6 @@ use super::cte_utils::{ QueryFromClause, QuerySqlType, }; use super::pool::DbConnection; -use crate::db::collection_attach::DatastoreAttachTarget; use async_bb8_diesel::{AsyncRunQueryDsl, ConnectionManager, PoolError}; use diesel::associations::HasTable; use diesel::expression::{AsExpression, Expression}; @@ -27,6 +26,7 @@ use diesel::query_builder::*; use diesel::query_dsl::methods as query_methods; use diesel::query_source::Table; use diesel::sql_types::{Nullable, SingleValue}; +use nexus_db_model::DatastoreAttachTarget; use std::fmt::Debug; /// Trait to be implemented by structs representing a detachable collection. @@ -494,8 +494,8 @@ where #[cfg(test)] mod test { - use super::{DatastoreDetachManyTarget, DetachManyError}; - use crate::db::collection_attach::DatastoreAttachTarget; + use super::*; + use crate::db::collection_attach::DatastoreAttachTargetExt; use crate::db::{ self, error::TransactionError, identity::Resource as IdentityResource, }; diff --git a/nexus/src/db/collection_insert.rs b/nexus/src/db/collection_insert.rs index f83ba22bae8..f7bdb0ac988 100644 --- a/nexus/src/db/collection_insert.rs +++ b/nexus/src/db/collection_insert.rs @@ -21,76 +21,15 @@ use diesel::query_builder::*; use diesel::query_dsl::methods as query_methods; use diesel::query_source::Table; use diesel::sql_types::SingleValue; +use nexus_db_model::DatastoreCollection; use std::fmt::Debug; use std::marker::PhantomData; -/// Trait to be implemented by any structs representing a collection. -/// For example, since Organizations have a one-to-many relationship with -/// Projects, the Organization datatype should implement this trait. -/// ``` -/// # use diesel::prelude::*; -/// # use omicron_nexus::db::collection_insert::DatastoreCollection; -/// # use omicron_nexus::db::model::Generation; -/// # -/// # table! { -/// # test_schema.organization (id) { -/// # id -> Uuid, -/// # time_deleted -> Nullable, -/// # rcgen -> Int8, -/// # } -/// # } -/// # -/// # table! { -/// # test_schema.project (id) { -/// # id -> Uuid, -/// # time_deleted -> Nullable, -/// # organization_id -> Uuid, -/// # } -/// # } -/// -/// #[derive(Queryable, Insertable, Debug, Selectable)] -/// #[diesel(table_name = project)] -/// struct Project { -/// pub id: uuid::Uuid, -/// pub time_deleted: Option>, -/// pub organization_id: uuid::Uuid, -/// } -/// -/// #[derive(Queryable, Insertable, Debug, Selectable)] -/// #[diesel(table_name = organization)] -/// struct Organization { -/// pub id: uuid::Uuid, -/// pub time_deleted: Option>, -/// pub rcgen: Generation, -/// } -/// -/// impl DatastoreCollection for Organization { -/// // Type of Organization::identity::id and Project::organization_id -/// type CollectionId = uuid::Uuid; -/// -/// type GenerationNumberColumn = organization::dsl::rcgen; -/// type CollectionTimeDeletedColumn = organization::dsl::time_deleted; -/// -/// type CollectionIdColumn = project::dsl::organization_id; -/// } -/// ``` -pub trait DatastoreCollection { - /// The Rust type of the collection id (typically Uuid for us) - type CollectionId: Copy + Debug; - - /// The column in the CollectionTable that acts as a generation number. - /// This is the "child-resource-generation-number" in RFD 192. - type GenerationNumberColumn: Column + Default; - - /// The time deleted column in the CollectionTable - // We enforce that this column comes from the same table as - // GenerationNumberColumn when defining insert_resource() below. - type CollectionTimeDeletedColumn: Column + Default; - - /// The column in the ResourceTable that acts as a foreign key into - /// the CollectionTable - type CollectionIdColumn: Column; - +/// Extension trait adding behavior to types that implement +/// `nexus_db_model::DatastoreCollection`. +pub trait DatastoreCollectionExt: + DatastoreCollection +{ /// Create a statement for inserting a resource into the given collection. /// /// The ISR type is the same type as the second generic argument to @@ -176,6 +115,8 @@ pub trait DatastoreCollection { } } +impl DatastoreCollectionExt for T where T: DatastoreCollection {} + /// Utility type to make trait bounds below easier to read. type CollectionId = >::CollectionId; @@ -504,7 +445,7 @@ where #[cfg(test)] mod test { - use super::{AsyncInsertError, DatastoreCollection, SyncInsertError}; + use super::*; use crate::db::{ self, error::TransactionError, identity::Resource as IdentityResource, }; diff --git a/nexus/src/db/datastore/dataset.rs b/nexus/src/db/datastore/dataset.rs index 0023cbb972e..698ff52c8e4 100644 --- a/nexus/src/db/datastore/dataset.rs +++ b/nexus/src/db/datastore/dataset.rs @@ -9,7 +9,7 @@ use super::RunnableQuery; use super::REGION_REDUNDANCY_THRESHOLD; use crate::db; use crate::db::collection_insert::AsyncInsertError; -use crate::db::collection_insert::DatastoreCollection; +use crate::db::collection_insert::DatastoreCollectionExt; use crate::db::error::public_error_from_diesel_pool; use crate::db::error::ErrorHandler; use crate::db::identity::Asset; diff --git a/nexus/src/db/datastore/disk.rs b/nexus/src/db/datastore/disk.rs index 3b7a421d00e..a83c8922631 100644 --- a/nexus/src/db/datastore/disk.rs +++ b/nexus/src/db/datastore/disk.rs @@ -10,7 +10,7 @@ use crate::authz::ApiResource; use crate::context::OpContext; use crate::db; use crate::db::collection_attach::AttachError; -use crate::db::collection_attach::DatastoreAttachTarget; +use crate::db::collection_attach::DatastoreAttachTargetExt; use crate::db::collection_detach::DatastoreDetachTarget; use crate::db::collection_detach::DetachError; use crate::db::error::public_error_from_diesel_pool; diff --git a/nexus/src/db/datastore/ip_pool.rs b/nexus/src/db/datastore/ip_pool.rs index f9ea58958ab..b1417f3ec27 100644 --- a/nexus/src/db/datastore/ip_pool.rs +++ b/nexus/src/db/datastore/ip_pool.rs @@ -9,7 +9,7 @@ use crate::authz; use crate::context::OpContext; use crate::db; use crate::db::collection_insert::AsyncInsertError; -use crate::db::collection_insert::DatastoreCollection; +use crate::db::collection_insert::DatastoreCollectionExt; use crate::db::error::diesel_pool_result_optional; use crate::db::error::public_error_from_diesel_pool; use crate::db::error::ErrorHandler; diff --git a/nexus/src/db/datastore/organization.rs b/nexus/src/db/datastore/organization.rs index e237aa63819..1f2d8d996a9 100644 --- a/nexus/src/db/datastore/organization.rs +++ b/nexus/src/db/datastore/organization.rs @@ -9,7 +9,7 @@ use crate::authz; use crate::context::OpContext; use crate::db; use crate::db::collection_insert::AsyncInsertError; -use crate::db::collection_insert::DatastoreCollection; +use crate::db::collection_insert::DatastoreCollectionExt; use crate::db::error::diesel_pool_result_optional; use crate::db::error::public_error_from_diesel_pool; use crate::db::error::ErrorHandler; diff --git a/nexus/src/db/datastore/project.rs b/nexus/src/db/datastore/project.rs index b4063d7ad49..c6999e83909 100644 --- a/nexus/src/db/datastore/project.rs +++ b/nexus/src/db/datastore/project.rs @@ -9,7 +9,7 @@ use crate::authz; use crate::context::OpContext; use crate::db; use crate::db::collection_insert::AsyncInsertError; -use crate::db::collection_insert::DatastoreCollection; +use crate::db::collection_insert::DatastoreCollectionExt; use crate::db::error::public_error_from_diesel_pool; use crate::db::error::ErrorHandler; use crate::db::identity::Resource; diff --git a/nexus/src/db/datastore/rack.rs b/nexus/src/db/datastore/rack.rs index 06d298a4261..fc76ca52a58 100644 --- a/nexus/src/db/datastore/rack.rs +++ b/nexus/src/db/datastore/rack.rs @@ -8,7 +8,7 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; use crate::db; -use crate::db::collection_insert::DatastoreCollection; +use crate::db::collection_insert::DatastoreCollectionExt; use crate::db::collection_insert::SyncInsertError; use crate::db::error::public_error_from_diesel_create; use crate::db::error::public_error_from_diesel_lookup; @@ -115,7 +115,7 @@ impl DataStore { // Otherwise, insert services and set rack.initialized = true. for svc in services { let sled_id = svc.sled_id; - >::insert_resource( + >::insert_resource( sled_id, diesel::insert_into(service_dsl::service) .values(svc.clone()) diff --git a/nexus/src/db/datastore/service.rs b/nexus/src/db/datastore/service.rs index b2665b48cdd..e2b7334adee 100644 --- a/nexus/src/db/datastore/service.rs +++ b/nexus/src/db/datastore/service.rs @@ -8,7 +8,7 @@ use super::DataStore; use crate::context::OpContext; use crate::db; use crate::db::collection_insert::AsyncInsertError; -use crate::db::collection_insert::DatastoreCollection; +use crate::db::collection_insert::DatastoreCollectionExt; use crate::db::error::public_error_from_diesel_pool; use crate::db::error::ErrorHandler; use crate::db::identity::Asset; diff --git a/nexus/src/db/datastore/vpc.rs b/nexus/src/db/datastore/vpc.rs index fb570815ae4..bfa95e47054 100644 --- a/nexus/src/db/datastore/vpc.rs +++ b/nexus/src/db/datastore/vpc.rs @@ -9,7 +9,7 @@ use crate::authz; use crate::context::OpContext; use crate::db; use crate::db::collection_insert::AsyncInsertError; -use crate::db::collection_insert::DatastoreCollection; +use crate::db::collection_insert::DatastoreCollectionExt; use crate::db::collection_insert::SyncInsertError; use crate::db::error::public_error_from_diesel_pool; use crate::db::error::ErrorHandler; diff --git a/nexus/src/db/datastore/zpool.rs b/nexus/src/db/datastore/zpool.rs index b2fb6cdf7a2..2a37e7a99ac 100644 --- a/nexus/src/db/datastore/zpool.rs +++ b/nexus/src/db/datastore/zpool.rs @@ -7,7 +7,7 @@ use super::DataStore; use crate::db; use crate::db::collection_insert::AsyncInsertError; -use crate::db::collection_insert::DatastoreCollection; +use crate::db::collection_insert::DatastoreCollectionExt; use crate::db::error::public_error_from_diesel_pool; use crate::db::error::ErrorHandler; use crate::db::identity::Asset; diff --git a/nexus/src/db/lookup.rs b/nexus/src/db/lookup.rs index 97093a81be8..228e4d93903 100644 --- a/nexus/src/db/lookup.rs +++ b/nexus/src/db/lookup.rs @@ -7,18 +7,17 @@ use super::datastore::DataStore; use super::identity::Asset; use super::identity::Resource; -use super::model; use crate::{ authz, context::OpContext, db, db::error::{public_error_from_diesel_pool, ErrorHandler}, - db::model::Name, - db::model::UpdateArtifactKind, }; use async_bb8_diesel::AsyncRunQueryDsl; use db_macros::lookup_resource; use diesel::{ExpressionMethods, QueryDsl, SelectableHelper}; +use nexus_db_model::Name; +use nexus_db_model::UpdateArtifactKind; use omicron_common::api::external::Error; use omicron_common::api::external::InternalContext; use omicron_common::api::external::{LookupResult, LookupType, ResourceType}; diff --git a/nexus/src/db/mod.rs b/nexus/src/db/mod.rs index 1aa79c9427c..02e8198a8a3 100644 --- a/nexus/src/db/mod.rs +++ b/nexus/src/db/mod.rs @@ -17,7 +17,6 @@ pub mod datastore; mod error; mod explain; pub mod fixed_data; -pub mod ipv6; pub mod lookup; mod pagination; mod pool; @@ -25,15 +24,16 @@ mod pool; // sagas. pub(crate) mod queries; mod saga_recovery; -mod saga_types; mod sec_store; mod update_and_check; #[cfg(test)] mod test_utils; -pub mod model; -pub mod schema; +// TODO-jkg +pub use nexus_db_model as model; +use nexus_db_model::saga_types; +pub use nexus_db_model::schema; pub use config::Config; pub use datastore::DataStore; @@ -43,3 +43,74 @@ pub use saga_types::SecId; pub use sec_store::CockroachDbSecStore; pub use nexus_types::identity; + +/// Does some basic smoke checks on an impl of `DatabaseString` +/// +/// This tests: +/// +/// - that for every variant, if we serialize it and deserialize the result, we +/// get back the original variant +/// - that if we attempt to deserialize some _other_ input, we get back an error +/// - that the serialized form for each variant matches what's found in +/// `expected_output_file`. This output file is generated by this test using +/// expectorate. +/// +/// This cannot completely test the correctness of the implementation, but it +/// can catch some basic copy/paste errors and accidental compatibility +/// breakage. +#[cfg(test)] +pub fn test_database_string_impl(expected_output_file: P) +where + T: std::fmt::Debug + + PartialEq + + nexus_db_model::DatabaseString + + strum::IntoEnumIterator, + P: std::convert::AsRef, +{ + let mut output = String::new(); + let mut maxlen: Option = None; + + for variant in T::iter() { + // Serialize the variant. Verify that we can deserialize the thing we + // just got back. + let serialized = variant.to_database_string(); + let deserialized = + T::from_database_string(serialized).unwrap_or_else(|_| { + panic!( + "failed to deserialize the string {:?}, which we \ + got by serializing {:?}", + serialized, variant + ) + }); + assert_eq!(variant, deserialized); + + // Put the serialized form into "output". At the end, we'll compare + // this to the expected output. This will fail if somebody has + // incompatibly changed things. + output.push_str(&format!( + "variant {:?}: serialized form = {}\n", + variant, serialized + )); + + // Keep track of the maximum length of the serialized strings. We'll + // use this to construct an input to `from_database_string()` that was + // not emitted by any of the variants' `to_database_string()` functions. + match (maxlen, serialized.len()) { + (None, newlen) => maxlen = Some(newlen), + (Some(oldlen), newlen) if newlen > oldlen => maxlen = Some(newlen), + _ => (), + } + } + + // Check that `from_database_string()` fails when given input that doesn't + // match any of the variants' serialized forms. We construct this input by + // providing a string that's longer than all strings emitted by + // `to_database_string()`. + if let Some(maxlen) = maxlen { + let input = String::from_utf8(vec![b'-'; maxlen + 1]).unwrap(); + T::from_database_string(&input) + .expect_err("expected failure to deserialize unknown string"); + } + + expectorate::assert_contents(expected_output_file, &output); +} diff --git a/nexus/src/lib.rs b/nexus/src/lib.rs index 7597bfc1e0b..fd7b50802e9 100644 --- a/nexus/src/lib.rs +++ b/nexus/src/lib.rs @@ -40,6 +40,7 @@ use std::sync::Arc; extern crate slog; #[macro_use] extern crate newtype_derive; +#[cfg(test)] #[macro_use] extern crate diesel; From 8f36b4bd6af6f788d6aa72afdbc7d60214a5657a Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Mon, 25 Jul 2022 14:30:02 -0400 Subject: [PATCH 2/5] Rename database collection traits for clarity --- nexus/db-model/src/collection.rs | 6 +++-- nexus/db-model/src/dataset.rs | 4 +-- nexus/db-model/src/instance.rs | 4 +-- nexus/db-model/src/ip_pool.rs | 4 +-- nexus/db-model/src/organization.rs | 4 +-- nexus/db-model/src/silo.rs | 4 +-- nexus/db-model/src/sled.rs | 6 ++--- nexus/db-model/src/volume.rs | 4 +-- nexus/db-model/src/vpc.rs | 4 +-- nexus/db-model/src/vpc_router.rs | 4 +-- nexus/db-model/src/zpool.rs | 4 +-- nexus/src/db/collection_attach.rs | 35 +++++++++++++------------- nexus/src/db/collection_detach.rs | 10 ++++---- nexus/src/db/collection_detach_many.rs | 10 ++++---- nexus/src/db/collection_insert.rs | 32 +++++++++++------------ nexus/src/db/datastore/dataset.rs | 2 +- nexus/src/db/datastore/disk.rs | 2 +- nexus/src/db/datastore/ip_pool.rs | 2 +- nexus/src/db/datastore/organization.rs | 2 +- nexus/src/db/datastore/project.rs | 2 +- nexus/src/db/datastore/rack.rs | 4 +-- nexus/src/db/datastore/service.rs | 2 +- nexus/src/db/datastore/vpc.rs | 2 +- nexus/src/db/datastore/zpool.rs | 2 +- 24 files changed, 79 insertions(+), 76 deletions(-) diff --git a/nexus/db-model/src/collection.rs b/nexus/db-model/src/collection.rs index eb3e0350d73..d285df3d5a7 100644 --- a/nexus/db-model/src/collection.rs +++ b/nexus/db-model/src/collection.rs @@ -58,7 +58,7 @@ use std::fmt::Debug; /// type CollectionIdColumn = project::dsl::organization_id; /// } /// ``` -pub trait DatastoreCollection { +pub trait DatastoreCollectionConfig { /// The Rust type of the collection id (typically Uuid for us) type CollectionId: Copy + Debug; @@ -126,7 +126,9 @@ pub trait DatastoreCollection { /// type ResourceTimeDeletedColumn = disk::dsl::time_deleted; /// } /// ``` -pub trait DatastoreAttachTarget: Selectable + Sized { +pub trait DatastoreAttachTargetConfig: + Selectable + Sized +{ /// The Rust type of the collection and resource ids (typically Uuid). type Id: Copy + Debug + PartialEq + Send + 'static; diff --git a/nexus/db-model/src/dataset.rs b/nexus/db-model/src/dataset.rs index 6ec68a3eb7a..d68097af274 100644 --- a/nexus/db-model/src/dataset.rs +++ b/nexus/db-model/src/dataset.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{DatasetKind, Generation, Region, SqlU16}; -use crate::collection::DatastoreCollection; +use crate::collection::DatastoreCollectionConfig; use crate::schema::{dataset, region}; use chrono::{DateTime, Utc}; use db_macros::Asset; @@ -75,7 +75,7 @@ impl Dataset { } // Datasets contain regions -impl DatastoreCollection for Dataset { +impl DatastoreCollectionConfig for Dataset { type CollectionId = Uuid; type GenerationNumberColumn = dataset::dsl::rcgen; type CollectionTimeDeletedColumn = dataset::dsl::time_deleted; diff --git a/nexus/db-model/src/instance.rs b/nexus/db-model/src/instance.rs index 2f135e5083a..430c8c675bd 100644 --- a/nexus/db-model/src/instance.rs +++ b/nexus/db-model/src/instance.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{ByteCount, Disk, Generation, InstanceCpuCount, InstanceState}; -use crate::collection::DatastoreAttachTarget; +use crate::collection::DatastoreAttachTargetConfig; use crate::schema::{disk, instance}; use chrono::{DateTime, Utc}; use db_macros::Resource; @@ -69,7 +69,7 @@ impl Into for Instance { } } -impl DatastoreAttachTarget for Instance { +impl DatastoreAttachTargetConfig for Instance { type Id = Uuid; type CollectionIdColumn = instance::dsl::id; diff --git a/nexus/db-model/src/ip_pool.rs b/nexus/db-model/src/ip_pool.rs index b2374759eba..137351edd05 100644 --- a/nexus/db-model/src/ip_pool.rs +++ b/nexus/db-model/src/ip_pool.rs @@ -4,7 +4,7 @@ //! Model types for IP Pools and the CIDR blocks therein. -use crate::collection::DatastoreCollection; +use crate::collection::DatastoreCollectionConfig; use crate::schema::ip_pool; use crate::schema::ip_pool_range; use crate::Name; @@ -162,7 +162,7 @@ impl From<&IpPoolRange> for IpRange { } } -impl DatastoreCollection for IpPool { +impl DatastoreCollectionConfig for IpPool { type CollectionId = uuid::Uuid; type GenerationNumberColumn = ip_pool::dsl::rcgen; type CollectionTimeDeletedColumn = ip_pool::dsl::time_deleted; diff --git a/nexus/db-model/src/organization.rs b/nexus/db-model/src/organization.rs index 56d27707bf7..04bfeb560d7 100644 --- a/nexus/db-model/src/organization.rs +++ b/nexus/db-model/src/organization.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{Generation, Name, Project}; -use crate::collection::DatastoreCollection; +use crate::collection::DatastoreCollectionConfig; use crate::schema::{organization, project}; use chrono::{DateTime, Utc}; use db_macros::Resource; @@ -43,7 +43,7 @@ impl From for views::Organization { } } -impl DatastoreCollection for Organization { +impl DatastoreCollectionConfig for Organization { type CollectionId = Uuid; type GenerationNumberColumn = organization::dsl::rcgen; type CollectionTimeDeletedColumn = organization::dsl::time_deleted; diff --git a/nexus/db-model/src/silo.rs b/nexus/db-model/src/silo.rs index 83134c4a89f..4ed28dcb635 100644 --- a/nexus/db-model/src/silo.rs +++ b/nexus/db-model/src/silo.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{Generation, Organization}; -use crate::collection::DatastoreCollection; +use crate::collection::DatastoreCollectionConfig; use crate::impl_enum_type; use crate::schema::{organization, silo}; use db_macros::Resource; @@ -85,7 +85,7 @@ impl From for views::Silo { } } -impl DatastoreCollection for Silo { +impl DatastoreCollectionConfig for Silo { type CollectionId = Uuid; type GenerationNumberColumn = silo::dsl::rcgen; type CollectionTimeDeletedColumn = silo::dsl::time_deleted; diff --git a/nexus/db-model/src/sled.rs b/nexus/db-model/src/sled.rs index d5d4c89b7a5..784bb1b56f6 100644 --- a/nexus/db-model/src/sled.rs +++ b/nexus/db-model/src/sled.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{Generation, SqlU16}; -use crate::collection::DatastoreCollection; +use crate::collection::DatastoreCollectionConfig; use crate::ipv6; use crate::schema::{service, sled, zpool}; use chrono::{DateTime, Utc}; @@ -72,14 +72,14 @@ impl From for views::Sled { } } -impl DatastoreCollection for Sled { +impl DatastoreCollectionConfig for Sled { type CollectionId = Uuid; type GenerationNumberColumn = sled::dsl::rcgen; type CollectionTimeDeletedColumn = sled::dsl::time_deleted; type CollectionIdColumn = zpool::dsl::sled_id; } -impl DatastoreCollection for Sled { +impl DatastoreCollectionConfig for Sled { type CollectionId = Uuid; type GenerationNumberColumn = sled::dsl::rcgen; type CollectionTimeDeletedColumn = sled::dsl::time_deleted; diff --git a/nexus/db-model/src/volume.rs b/nexus/db-model/src/volume.rs index b4d1cc1c141..b53815c10e3 100644 --- a/nexus/db-model/src/volume.rs +++ b/nexus/db-model/src/volume.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{Generation, Region}; -use crate::collection::DatastoreCollection; +use crate::collection::DatastoreCollectionConfig; use crate::schema::{region, volume}; use chrono::{DateTime, Utc}; use db_macros::Asset; @@ -47,7 +47,7 @@ impl Volume { } // Volumes contain regions -impl DatastoreCollection for Volume { +impl DatastoreCollectionConfig for Volume { type CollectionId = Uuid; type GenerationNumberColumn = volume::dsl::rcgen; type CollectionTimeDeletedColumn = volume::dsl::time_deleted; diff --git a/nexus/db-model/src/vpc.rs b/nexus/db-model/src/vpc.rs index 016d62707b5..695b3b52c23 100644 --- a/nexus/db-model/src/vpc.rs +++ b/nexus/db-model/src/vpc.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{Generation, Ipv6Net, Name, VpcFirewallRule}; -use crate::collection::DatastoreCollection; +use crate::collection::DatastoreCollectionConfig; use crate::schema::{vpc, vpc_firewall_rule}; use crate::Vni; use chrono::{DateTime, Utc}; @@ -96,7 +96,7 @@ impl IncompleteVpc { } } -impl DatastoreCollection for Vpc { +impl DatastoreCollectionConfig for Vpc { type CollectionId = Uuid; type GenerationNumberColumn = vpc::dsl::firewall_gen; type CollectionTimeDeletedColumn = vpc::dsl::time_deleted; diff --git a/nexus/db-model/src/vpc_router.rs b/nexus/db-model/src/vpc_router.rs index bde8e5ade7b..676bc17ec49 100644 --- a/nexus/db-model/src/vpc_router.rs +++ b/nexus/db-model/src/vpc_router.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{impl_enum_type, Generation, Name, RouterRoute}; -use crate::collection::DatastoreCollection; +use crate::collection::DatastoreCollectionConfig; use crate::schema::{router_route, vpc_router}; use chrono::{DateTime, Utc}; use db_macros::Resource; @@ -68,7 +68,7 @@ impl From for views::VpcRouter { } } -impl DatastoreCollection for VpcRouter { +impl DatastoreCollectionConfig for VpcRouter { type CollectionId = Uuid; type GenerationNumberColumn = vpc_router::dsl::rcgen; type CollectionTimeDeletedColumn = vpc_router::dsl::time_deleted; diff --git a/nexus/db-model/src/zpool.rs b/nexus/db-model/src/zpool.rs index d7636741677..bad66359131 100644 --- a/nexus/db-model/src/zpool.rs +++ b/nexus/db-model/src/zpool.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::{ByteCount, Dataset, Generation}; -use crate::collection::DatastoreCollection; +use crate::collection::DatastoreCollectionConfig; use crate::schema::{dataset, zpool}; use chrono::{DateTime, Utc}; use db_macros::Asset; @@ -46,7 +46,7 @@ impl Zpool { } } -impl DatastoreCollection for Zpool { +impl DatastoreCollectionConfig for Zpool { type CollectionId = Uuid; type GenerationNumberColumn = zpool::dsl::rcgen; type CollectionTimeDeletedColumn = zpool::dsl::time_deleted; diff --git a/nexus/src/db/collection_attach.rs b/nexus/src/db/collection_attach.rs index 33fb40c2c5c..10ad00b7254 100644 --- a/nexus/src/db/collection_attach.rs +++ b/nexus/src/db/collection_attach.rs @@ -27,23 +27,23 @@ use diesel::query_builder::*; use diesel::query_dsl::methods as query_methods; use diesel::query_source::Table; use diesel::sql_types::{BigInt, Nullable, SingleValue}; -use nexus_db_model::DatastoreAttachTarget; +use nexus_db_model::DatastoreAttachTargetConfig; use std::fmt::Debug; /// A collection of type aliases particularly relevant to collection-based CTEs. pub(crate) mod aliases { use super::{ - Column, DatastoreAttachTarget, Table, TableDefaultWhereClause, + Column, DatastoreAttachTargetConfig, Table, TableDefaultWhereClause, }; /// The table representing the collection. The resource references /// this table. - pub type CollectionTable = < = <>::CollectionIdColumn as Column>::Table; /// The table representing the resource. This table contains an /// ID acting as a foreign key into the collection table. - pub type ResourceTable = < = <>::ResourceIdColumn as Column>::Table; @@ -55,9 +55,9 @@ pub(crate) mod aliases { TableDefaultWhereClause>; pub type CollectionIdColumn = - >::CollectionIdColumn; + >::CollectionIdColumn; pub type ResourceIdColumn = - >::ResourceIdColumn; + >::ResourceIdColumn; /// Representation of Primary Key in Rust. pub type CollectionPrimaryKey = @@ -65,7 +65,7 @@ pub(crate) mod aliases { pub type ResourcePrimaryKey = as Table>::PrimaryKey; pub type ResourceForeignKey = - >::ResourceCollectionIdColumn; + >::ResourceCollectionIdColumn; /// Representation of Primary Key in SQL. pub type SerializedCollectionPrimaryKey = @@ -80,8 +80,8 @@ use aliases::*; /// Extension trait adding behavior to types that implement /// `nexus_db_model::DatastoreAttachTarget`. -pub trait DatastoreAttachTargetExt: - DatastoreAttachTarget +pub trait DatastoreAttachTarget: + DatastoreAttachTargetConfig { /// Creates a statement for attaching a resource to the given collection. /// @@ -256,14 +256,15 @@ pub trait DatastoreAttachTargetExt: } } -impl DatastoreAttachTargetExt for T where T: DatastoreAttachTarget {} +impl DatastoreAttachTarget for T where T: DatastoreAttachTargetConfig +{} /// The CTE described in the module docs #[must_use = "Queries must be executed"] pub struct AttachToCollectionStatement where ResourceType: Selectable, - C: DatastoreAttachTarget, + C: DatastoreAttachTargetConfig, { // Query which answers: "Does the collection exist?" collection_exists_query: Box + Send>, @@ -290,7 +291,7 @@ impl QueryId for AttachToCollectionStatement where ResourceType: Selectable, - C: DatastoreAttachTarget, + C: DatastoreAttachTargetConfig, { type QueryId = (); const HAS_STATIC_QUERY_ID: bool = false; @@ -331,7 +332,7 @@ pub type RawOutput = impl AttachToCollectionStatement where ResourceType: 'static + Debug + Send + Selectable, - C: 'static + Debug + DatastoreAttachTarget + Send, + C: 'static + Debug + DatastoreAttachTargetConfig + Send, ResourceTable: 'static + Table + Send + Copy + Debug, V: 'static + Send, AttachToCollectionStatement: Send, @@ -409,7 +410,7 @@ impl Query for AttachToCollectionStatement where ResourceType: Selectable, - C: DatastoreAttachTarget, + C: DatastoreAttachTargetConfig, { type SqlType = ( // The number of resources attached to the collection before update. @@ -427,7 +428,7 @@ impl RunQueryDsl for AttachToCollectionStatement where ResourceType: Selectable, - C: DatastoreAttachTarget, + C: DatastoreAttachTargetConfig, { } @@ -503,7 +504,7 @@ impl QueryFragment for AttachToCollectionStatement where ResourceType: Selectable, - C: DatastoreAttachTarget, + C: DatastoreAttachTargetConfig, CollectionPrimaryKey: diesel::Column, // Necessary to "walk_ast" over "self.update_resource_statement". BoxedUpdateStatement<'static, Pg, ResourceTable, V>: @@ -675,7 +676,7 @@ mod test { pub identity: CollectionIdentity, } - impl DatastoreAttachTarget for Collection { + impl DatastoreAttachTargetConfig for Collection { type Id = uuid::Uuid; type CollectionIdColumn = collection::dsl::id; diff --git a/nexus/src/db/collection_detach.rs b/nexus/src/db/collection_detach.rs index 9f57028d5a7..531a51500ca 100644 --- a/nexus/src/db/collection_detach.rs +++ b/nexus/src/db/collection_detach.rs @@ -26,7 +26,7 @@ use diesel::query_builder::*; use diesel::query_dsl::methods as query_methods; use diesel::query_source::Table; use diesel::sql_types::{Nullable, SingleValue}; -use nexus_db_model::DatastoreAttachTarget; +use nexus_db_model::DatastoreAttachTargetConfig; use std::fmt::Debug; /// Trait to be implemented by structs representing a detachable collection. @@ -34,7 +34,7 @@ use std::fmt::Debug; /// A blanket implementation is provided for traits that implement /// [`DatastoreAttachTarget`]. pub trait DatastoreDetachTarget: - DatastoreAttachTarget + DatastoreAttachTargetConfig { /// Creates a statement for detaching a resource from the given collection. /// @@ -191,7 +191,7 @@ pub trait DatastoreDetachTarget: } impl DatastoreDetachTarget for T where - T: DatastoreAttachTarget + T: DatastoreAttachTargetConfig { } @@ -501,7 +501,7 @@ where #[cfg(test)] mod test { use super::*; - use crate::db::collection_attach::DatastoreAttachTargetExt; + use crate::db::collection_attach::DatastoreAttachTarget; use crate::db::{ self, error::TransactionError, identity::Resource as IdentityResource, }; @@ -592,7 +592,7 @@ mod test { pub identity: CollectionIdentity, } - impl DatastoreAttachTarget for Collection { + impl DatastoreAttachTargetConfig for Collection { type Id = uuid::Uuid; type CollectionIdColumn = collection::dsl::id; diff --git a/nexus/src/db/collection_detach_many.rs b/nexus/src/db/collection_detach_many.rs index ab723c92ee5..135d3b83b63 100644 --- a/nexus/src/db/collection_detach_many.rs +++ b/nexus/src/db/collection_detach_many.rs @@ -26,7 +26,7 @@ use diesel::query_builder::*; use diesel::query_dsl::methods as query_methods; use diesel::query_source::Table; use diesel::sql_types::{Nullable, SingleValue}; -use nexus_db_model::DatastoreAttachTarget; +use nexus_db_model::DatastoreAttachTargetConfig; use std::fmt::Debug; /// Trait to be implemented by structs representing a detachable collection. @@ -34,7 +34,7 @@ use std::fmt::Debug; /// A blanket implementation is provided for traits that implement /// [`DatastoreAttachTarget`]. pub trait DatastoreDetachManyTarget: - DatastoreAttachTarget + DatastoreAttachTargetConfig { /// Creates a statement for detaching a resource from the given collection. /// @@ -201,7 +201,7 @@ pub trait DatastoreDetachManyTarget: } impl DatastoreDetachManyTarget for T where - T: DatastoreAttachTarget + T: DatastoreAttachTargetConfig { } @@ -495,7 +495,7 @@ where #[cfg(test)] mod test { use super::*; - use crate::db::collection_attach::DatastoreAttachTargetExt; + use crate::db::collection_attach::DatastoreAttachTarget; use crate::db::{ self, error::TransactionError, identity::Resource as IdentityResource, }; @@ -586,7 +586,7 @@ mod test { pub identity: CollectionIdentity, } - impl DatastoreAttachTarget for Collection { + impl DatastoreAttachTargetConfig for Collection { type Id = uuid::Uuid; type CollectionIdColumn = collection::dsl::id; diff --git a/nexus/src/db/collection_insert.rs b/nexus/src/db/collection_insert.rs index f7bdb0ac988..e87c5670168 100644 --- a/nexus/src/db/collection_insert.rs +++ b/nexus/src/db/collection_insert.rs @@ -21,14 +21,14 @@ use diesel::query_builder::*; use diesel::query_dsl::methods as query_methods; use diesel::query_source::Table; use diesel::sql_types::SingleValue; -use nexus_db_model::DatastoreCollection; +use nexus_db_model::DatastoreCollectionConfig; use std::fmt::Debug; use std::marker::PhantomData; /// Extension trait adding behavior to types that implement /// `nexus_db_model::DatastoreCollection`. -pub trait DatastoreCollectionExt: - DatastoreCollection +pub trait DatastoreCollection: + DatastoreCollectionConfig { /// Create a statement for inserting a resource into the given collection. /// @@ -115,25 +115,25 @@ pub trait DatastoreCollectionExt: } } -impl DatastoreCollectionExt for T where T: DatastoreCollection {} +impl DatastoreCollection for T where T: DatastoreCollectionConfig {} /// Utility type to make trait bounds below easier to read. type CollectionId = - >::CollectionId; + >::CollectionId; /// The table representing the collection. The resource references /// this table. -type CollectionTable = < = <>::GenerationNumberColumn as Column>::Table; /// The table representing the resource. This table contains an /// ID acting as a foreign key into the collection table. -type ResourceTable = < = <>::CollectionIdColumn as Column>::Table; type CollectionTimeDeletedColumn = - >::CollectionTimeDeletedColumn; + >::CollectionTimeDeletedColumn; type GenerationNumberColumn = - >::GenerationNumberColumn; + >::GenerationNumberColumn; // Trick to check that columns come from the same table pub trait TypesAreSame {} @@ -144,7 +144,7 @@ impl TypesAreSame for (T, T) {} pub struct InsertIntoCollectionStatement where ResourceType: Selectable, - C: DatastoreCollection, + C: DatastoreCollectionConfig, { insert_statement: InsertStatement, ISR>, filter_subquery: Box + Send>, @@ -156,7 +156,7 @@ where impl QueryId for InsertIntoCollectionStatement where - C: DatastoreCollection, + C: DatastoreCollectionConfig, ResourceType: Selectable, { type QueryId = (); @@ -190,7 +190,7 @@ pub enum SyncInsertError { impl InsertIntoCollectionStatement where ResourceType: 'static + Debug + Send + Selectable, - C: 'static + DatastoreCollection + Send, + C: 'static + DatastoreCollectionConfig + Send, CollectionId: 'static + PartialEq + Send, ResourceTable: 'static + Table + Send + Copy + Debug, ISR: 'static + Send, @@ -317,7 +317,7 @@ impl Query for InsertIntoCollectionStatement where ResourceType: Selectable, - C: DatastoreCollection, + C: DatastoreCollectionConfig, { type SqlType = SelectableSqlType; } @@ -326,7 +326,7 @@ impl RunQueryDsl for InsertIntoCollectionStatement where ResourceType: Selectable, - C: DatastoreCollection, + C: DatastoreCollectionConfig, { } @@ -389,7 +389,7 @@ impl QueryFragment for InsertIntoCollectionStatement where ResourceType: Selectable, - C: DatastoreCollection, + C: DatastoreCollectionConfig, CollectionPrimaryKey: diesel::Column, // Necessary to "walk_ast" over "select.from_clause". as QuerySource>::FromClause: @@ -523,7 +523,7 @@ mod test { } struct Collection; - impl DatastoreCollection for Collection { + impl DatastoreCollectionConfig for Collection { type CollectionId = uuid::Uuid; type GenerationNumberColumn = collection::dsl::rcgen; type CollectionIdColumn = resource::dsl::collection_id; diff --git a/nexus/src/db/datastore/dataset.rs b/nexus/src/db/datastore/dataset.rs index 698ff52c8e4..0023cbb972e 100644 --- a/nexus/src/db/datastore/dataset.rs +++ b/nexus/src/db/datastore/dataset.rs @@ -9,7 +9,7 @@ use super::RunnableQuery; use super::REGION_REDUNDANCY_THRESHOLD; use crate::db; use crate::db::collection_insert::AsyncInsertError; -use crate::db::collection_insert::DatastoreCollectionExt; +use crate::db::collection_insert::DatastoreCollection; use crate::db::error::public_error_from_diesel_pool; use crate::db::error::ErrorHandler; use crate::db::identity::Asset; diff --git a/nexus/src/db/datastore/disk.rs b/nexus/src/db/datastore/disk.rs index a83c8922631..3b7a421d00e 100644 --- a/nexus/src/db/datastore/disk.rs +++ b/nexus/src/db/datastore/disk.rs @@ -10,7 +10,7 @@ use crate::authz::ApiResource; use crate::context::OpContext; use crate::db; use crate::db::collection_attach::AttachError; -use crate::db::collection_attach::DatastoreAttachTargetExt; +use crate::db::collection_attach::DatastoreAttachTarget; use crate::db::collection_detach::DatastoreDetachTarget; use crate::db::collection_detach::DetachError; use crate::db::error::public_error_from_diesel_pool; diff --git a/nexus/src/db/datastore/ip_pool.rs b/nexus/src/db/datastore/ip_pool.rs index b1417f3ec27..f9ea58958ab 100644 --- a/nexus/src/db/datastore/ip_pool.rs +++ b/nexus/src/db/datastore/ip_pool.rs @@ -9,7 +9,7 @@ use crate::authz; use crate::context::OpContext; use crate::db; use crate::db::collection_insert::AsyncInsertError; -use crate::db::collection_insert::DatastoreCollectionExt; +use crate::db::collection_insert::DatastoreCollection; use crate::db::error::diesel_pool_result_optional; use crate::db::error::public_error_from_diesel_pool; use crate::db::error::ErrorHandler; diff --git a/nexus/src/db/datastore/organization.rs b/nexus/src/db/datastore/organization.rs index 1f2d8d996a9..e237aa63819 100644 --- a/nexus/src/db/datastore/organization.rs +++ b/nexus/src/db/datastore/organization.rs @@ -9,7 +9,7 @@ use crate::authz; use crate::context::OpContext; use crate::db; use crate::db::collection_insert::AsyncInsertError; -use crate::db::collection_insert::DatastoreCollectionExt; +use crate::db::collection_insert::DatastoreCollection; use crate::db::error::diesel_pool_result_optional; use crate::db::error::public_error_from_diesel_pool; use crate::db::error::ErrorHandler; diff --git a/nexus/src/db/datastore/project.rs b/nexus/src/db/datastore/project.rs index c6999e83909..b4063d7ad49 100644 --- a/nexus/src/db/datastore/project.rs +++ b/nexus/src/db/datastore/project.rs @@ -9,7 +9,7 @@ use crate::authz; use crate::context::OpContext; use crate::db; use crate::db::collection_insert::AsyncInsertError; -use crate::db::collection_insert::DatastoreCollectionExt; +use crate::db::collection_insert::DatastoreCollection; use crate::db::error::public_error_from_diesel_pool; use crate::db::error::ErrorHandler; use crate::db::identity::Resource; diff --git a/nexus/src/db/datastore/rack.rs b/nexus/src/db/datastore/rack.rs index fc76ca52a58..06d298a4261 100644 --- a/nexus/src/db/datastore/rack.rs +++ b/nexus/src/db/datastore/rack.rs @@ -8,7 +8,7 @@ use super::DataStore; use crate::authz; use crate::context::OpContext; use crate::db; -use crate::db::collection_insert::DatastoreCollectionExt; +use crate::db::collection_insert::DatastoreCollection; use crate::db::collection_insert::SyncInsertError; use crate::db::error::public_error_from_diesel_create; use crate::db::error::public_error_from_diesel_lookup; @@ -115,7 +115,7 @@ impl DataStore { // Otherwise, insert services and set rack.initialized = true. for svc in services { let sled_id = svc.sled_id; - >::insert_resource( + >::insert_resource( sled_id, diesel::insert_into(service_dsl::service) .values(svc.clone()) diff --git a/nexus/src/db/datastore/service.rs b/nexus/src/db/datastore/service.rs index e2b7334adee..b2665b48cdd 100644 --- a/nexus/src/db/datastore/service.rs +++ b/nexus/src/db/datastore/service.rs @@ -8,7 +8,7 @@ use super::DataStore; use crate::context::OpContext; use crate::db; use crate::db::collection_insert::AsyncInsertError; -use crate::db::collection_insert::DatastoreCollectionExt; +use crate::db::collection_insert::DatastoreCollection; use crate::db::error::public_error_from_diesel_pool; use crate::db::error::ErrorHandler; use crate::db::identity::Asset; diff --git a/nexus/src/db/datastore/vpc.rs b/nexus/src/db/datastore/vpc.rs index bfa95e47054..fb570815ae4 100644 --- a/nexus/src/db/datastore/vpc.rs +++ b/nexus/src/db/datastore/vpc.rs @@ -9,7 +9,7 @@ use crate::authz; use crate::context::OpContext; use crate::db; use crate::db::collection_insert::AsyncInsertError; -use crate::db::collection_insert::DatastoreCollectionExt; +use crate::db::collection_insert::DatastoreCollection; use crate::db::collection_insert::SyncInsertError; use crate::db::error::public_error_from_diesel_pool; use crate::db::error::ErrorHandler; diff --git a/nexus/src/db/datastore/zpool.rs b/nexus/src/db/datastore/zpool.rs index 2a37e7a99ac..b2fb6cdf7a2 100644 --- a/nexus/src/db/datastore/zpool.rs +++ b/nexus/src/db/datastore/zpool.rs @@ -7,7 +7,7 @@ use super::DataStore; use crate::db; use crate::db::collection_insert::AsyncInsertError; -use crate::db::collection_insert::DatastoreCollectionExt; +use crate::db::collection_insert::DatastoreCollection; use crate::db::error::public_error_from_diesel_pool; use crate::db::error::ErrorHandler; use crate::db::identity::Asset; From b8ae5eb74a372d4bed4156148aa5bfd37a1ea189 Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Mon, 25 Jul 2022 14:37:35 -0400 Subject: [PATCH 3/5] Remove stray TODO comment --- nexus/src/db/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/nexus/src/db/mod.rs b/nexus/src/db/mod.rs index 02e8198a8a3..e2a4e7f9f73 100644 --- a/nexus/src/db/mod.rs +++ b/nexus/src/db/mod.rs @@ -30,7 +30,6 @@ mod update_and_check; #[cfg(test)] mod test_utils; -// TODO-jkg pub use nexus_db_model as model; use nexus_db_model::saga_types; pub use nexus_db_model::schema; From 66f1e5f8230451e8d37962c05e89ab9213352d6e Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Mon, 25 Jul 2022 16:06:56 -0400 Subject: [PATCH 4/5] Fix failing doctests after trait rename --- nexus/db-model/src/collection.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nexus/db-model/src/collection.rs b/nexus/db-model/src/collection.rs index d285df3d5a7..5fbe789561f 100644 --- a/nexus/db-model/src/collection.rs +++ b/nexus/db-model/src/collection.rs @@ -13,7 +13,7 @@ use std::fmt::Debug; /// Projects, the Organization datatype should implement this trait. /// ``` /// # use diesel::prelude::*; -/// # use nexus_db_model::DatastoreCollection; +/// # use nexus_db_model::DatastoreCollectionConfig; /// # use nexus_db_model::Generation; /// # /// # table! { @@ -48,7 +48,7 @@ use std::fmt::Debug; /// pub rcgen: Generation, /// } /// -/// impl DatastoreCollection for Organization { +/// impl DatastoreCollectionConfig for Organization { /// // Type of Organization::identity::id and Project::organization_id /// type CollectionId = uuid::Uuid; /// @@ -82,7 +82,7 @@ pub trait DatastoreCollectionConfig { /// Disks, the Instance datatype should implement this trait. /// ``` /// # use diesel::prelude::*; -/// # use nexus_db_model::DatastoreAttachTarget; +/// # use nexus_db_model::DatastoreAttachTargetConfig; /// # /// # table! { /// # test_schema.instance (id) { @@ -114,7 +114,7 @@ pub trait DatastoreCollectionConfig { /// pub time_deleted: Option>, /// } /// -/// impl DatastoreAttachTarget for Instance { +/// impl DatastoreAttachTargetConfig for Instance { /// // Type of instance::id and disk::id. /// type Id = uuid::Uuid; /// From 9789e49d973e12be39036102d4c487932b4876b8 Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Tue, 26 Jul 2022 10:34:06 -0400 Subject: [PATCH 5/5] Bump diesel version in nexus-db-model --- nexus/db-model/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nexus/db-model/Cargo.toml b/nexus/db-model/Cargo.toml index 0578b986f64..4b9094421eb 100644 --- a/nexus/db-model/Cargo.toml +++ b/nexus/db-model/Cargo.toml @@ -7,7 +7,7 @@ license = "MPL-2.0" [dependencies] anyhow = "1.0" chrono = { version = "0.4", features = ["serde"] } -diesel = { version = "2.0.0-rc.0", features = ["postgres", "r2d2", "chrono", "serde_json", "network-address", "uuid"] } +diesel = { version = "2.0.0-rc.1", features = ["postgres", "r2d2", "chrono", "serde_json", "network-address", "uuid"] } hex = "0.4.3" ipnetwork = "0.18" macaddr = { version = "1.0.1", features = [ "serde_std" ]}