Skip to content

Commit

Permalink
Add routes to lookup resources by id (#1266)
Browse files Browse the repository at this point in the history
* first pass at implementing /by_id/ routes

* Restore text that failed to get written when I ran out of space

* Add docstrings

* Fixup formatting

* Fix compiler errors

* Update config

* Reverse by_id/resource name order

* reorganize imports

* Reorganize id lookup implementation code

* Reorganize implementations, fix some tags

* by_id to by-id

* Prefix vpc resources

* Add mechanism to valid auth endpoints with ids

* Add coverage for by-id unauthed tests

* Fix comment

* Fix unauth tests

* Restore test that was added by @ahl in #751

* Improve the setup req comment
  • Loading branch information
zephraph authored Jul 12, 2022
1 parent 5760d15 commit 4640dd3
Show file tree
Hide file tree
Showing 17 changed files with 1,180 additions and 40 deletions.
24 changes: 24 additions & 0 deletions nexus/src/app/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,18 @@ impl super::Nexus {
Ok(db_disk)
}

pub async fn disk_fetch_by_id(
&self,
opctx: &OpContext,
disk_id: &Uuid,
) -> LookupResult<db::model::Disk> {
let (.., db_disk) = LookupPath::new(opctx, &self.db_datastore)
.disk_id(*disk_id)
.fetch()
.await?;
Ok(db_disk)
}

/// Modifies the runtime state of the Disk as requested. This generally
/// means attaching or detaching the disk.
// TODO(https://github.com/oxidecomputer/omicron/issues/811):
Expand Down Expand Up @@ -386,6 +398,18 @@ impl super::Nexus {
Err(self.unimplemented_todo(opctx, unimp).await)
}

pub async fn snapshot_fetch_by_id(
&self,
opctx: &OpContext,
snapshot_id: &Uuid,
) -> LookupResult<db::model::Snapshot> {
let lookup_type = LookupType::ById(*snapshot_id);
let not_found_error =
lookup_type.into_not_found(ResourceType::Snapshot);
let unimp = Unimpl::ProtectedLookup(not_found_error);
Err(self.unimplemented_todo(opctx, unimp).await)
}

pub async fn project_delete_snapshot(
self: &Arc<Self>,
opctx: &OpContext,
Expand Down
23 changes: 23 additions & 0 deletions nexus/src/app/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@ impl super::Nexus {
Err(self.unimplemented_todo(opctx, unimp).await)
}

pub async fn project_image_fetch_by_id(
&self,
opctx: &OpContext,
image_id: &Uuid,
) -> LookupResult<db::model::Image> {
let lookup_type = LookupType::ById(*image_id);
let not_found_error = lookup_type.into_not_found(ResourceType::Image);
let unimp = Unimpl::ProtectedLookup(not_found_error);
Err(self.unimplemented_todo(opctx, unimp).await)
}

pub async fn project_delete_image(
self: &Arc<Self>,
opctx: &OpContext,
Expand Down Expand Up @@ -293,6 +304,18 @@ impl super::Nexus {
Ok(db_disk)
}

pub async fn global_image_fetch_by_id(
&self,
opctx: &OpContext,
global_image_id: &Uuid,
) -> LookupResult<db::model::GlobalImage> {
let (.., db_global_image) = LookupPath::new(opctx, &self.db_datastore)
.global_image_id(*global_image_id)
.fetch()
.await?;
Ok(db_global_image)
}

pub async fn global_image_delete(
self: &Arc<Self>,
opctx: &OpContext,
Expand Down
24 changes: 24 additions & 0 deletions nexus/src/app/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,18 @@ impl super::Nexus {
Ok(db_instance)
}

pub async fn instance_fetch_by_id(
&self,
opctx: &OpContext,
instance_id: &Uuid,
) -> LookupResult<db::model::Instance> {
let (.., db_instance) = LookupPath::new(opctx, &self.db_datastore)
.instance_id(*instance_id)
.fetch()
.await?;
Ok(db_instance)
}

// This operation may only occur on stopped instances, which implies that
// the attached disks do not have any running "upstairs" process running
// within the sled.
Expand Down Expand Up @@ -776,6 +788,18 @@ impl super::Nexus {
Ok(db_interface)
}

pub async fn network_interface_fetch_by_id(
&self,
opctx: &OpContext,
interface_id: &Uuid,
) -> LookupResult<db::model::NetworkInterface> {
let (.., db_interface) = LookupPath::new(opctx, &self.db_datastore)
.network_interface_id(*interface_id)
.fetch()
.await?;
Ok(db_interface)
}

/// Update a network interface for the given instance.
pub async fn network_interface_update(
&self,
Expand Down
12 changes: 12 additions & 0 deletions nexus/src/app/organization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ impl super::Nexus {
Ok(db_organization)
}

pub async fn organization_fetch_by_id(
&self,
opctx: &OpContext,
organization_id: &Uuid,
) -> LookupResult<db::model::Organization> {
let (.., db_organization) = LookupPath::new(opctx, &self.db_datastore)
.organization_id(*organization_id)
.fetch()
.await?;
Ok(db_organization)
}

pub async fn organizations_list_by_name(
&self,
opctx: &OpContext,
Expand Down
12 changes: 12 additions & 0 deletions nexus/src/app/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,18 @@ impl super::Nexus {
Ok(db_project)
}

pub async fn project_fetch_by_id(
&self,
opctx: &OpContext,
project_id: &Uuid,
) -> LookupResult<db::model::Project> {
let (.., db_project) = LookupPath::new(opctx, &self.db_datastore)
.project_id(*project_id)
.fetch()
.await?;
Ok(db_project)
}

pub async fn projects_list_by_name(
&self,
opctx: &OpContext,
Expand Down
12 changes: 12 additions & 0 deletions nexus/src/app/vpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,18 @@ impl super::Nexus {
Ok(db_vpc)
}

pub async fn vpc_fetch_by_id(
&self,
opctx: &OpContext,
vpc_id: &Uuid,
) -> LookupResult<db::model::Vpc> {
let (.., db_vpc) = LookupPath::new(opctx, &self.db_datastore)
.vpc_id(*vpc_id)
.fetch()
.await?;
Ok(db_vpc)
}

pub async fn project_update_vpc(
&self,
opctx: &OpContext,
Expand Down
24 changes: 24 additions & 0 deletions nexus/src/app/vpc_router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,18 @@ impl super::Nexus {
Ok(db_router)
}

pub async fn vpc_router_fetch_by_id(
&self,
opctx: &OpContext,
vpc_router_id: &Uuid,
) -> LookupResult<db::model::VpcRouter> {
let (.., db_router) = LookupPath::new(opctx, &self.db_datastore)
.vpc_router_id(*vpc_router_id)
.fetch()
.await?;
Ok(db_router)
}

pub async fn vpc_update_router(
&self,
opctx: &OpContext,
Expand Down Expand Up @@ -223,6 +235,18 @@ impl super::Nexus {
Ok(db_route)
}

pub async fn route_fetch_by_id(
&self,
opctx: &OpContext,
route_id: &Uuid,
) -> LookupResult<db::model::RouterRoute> {
let (.., db_route) = LookupPath::new(opctx, &self.db_datastore)
.router_route_id(*route_id)
.fetch()
.await?;
Ok(db_route)
}

#[allow(clippy::too_many_arguments)]
pub async fn router_update_route(
&self,
Expand Down
12 changes: 12 additions & 0 deletions nexus/src/app/vpc_subnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,18 @@ impl super::Nexus {
Ok(db_vpc)
}

pub async fn vpc_subnet_fetch_by_id(
&self,
opctx: &OpContext,
vpc_subnet_id: &Uuid,
) -> LookupResult<db::model::VpcSubnet> {
let (.., db_vpc) = LookupPath::new(opctx, &self.db_datastore)
.vpc_subnet_id(*vpc_subnet_id)
.fetch()
.await?;
Ok(db_vpc)
}

pub async fn vpc_update_subnet(
&self,
opctx: &OpContext,
Expand Down
16 changes: 16 additions & 0 deletions nexus/src/authz/api_resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,22 @@ authz_resource! {
polar_snippet = InProject,
}

authz_resource! {
name = "Image",
parent = "Project",
primary_key = Uuid,
roles_allowed = false,
polar_snippet = InProject,
}

authz_resource! {
name = "Snapshot",
parent = "Project",
primary_key = Uuid,
roles_allowed = false,
polar_snippet = InProject,
}

authz_resource! {
name = "Instance",
parent = "Project",
Expand Down
40 changes: 40 additions & 0 deletions nexus/src/db/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,28 @@ impl<'a> LookupPath<'a> {
Disk { key: DiskKey::PrimaryKey(Root { lookup_root: self }, id) }
}

/// Select a resource of type Image, identified by its id
pub fn image_id(self, id: Uuid) -> Image<'a> {
Image { key: ImageKey::PrimaryKey(Root { lookup_root: self }, id) }
}

/// Select a resource of type Snapshot, identified by its id
pub fn snapshot_id(self, id: Uuid) -> Snapshot<'a> {
Snapshot {
key: SnapshotKey::PrimaryKey(Root { lookup_root: self }, id),
}
}

/// Select a resource of type NetworkInterface, identified by its id
pub fn network_interface_id(self, id: Uuid) -> NetworkInterface<'a> {
NetworkInterface {
key: NetworkInterfaceKey::PrimaryKey(
Root { lookup_root: self },
id,
),
}
}

/// Select a resource of type Vpc, identified by its id
pub fn vpc_id(self, id: Uuid) -> Vpc<'a> {
Vpc { key: VpcKey::PrimaryKey(Root { lookup_root: self }, id) }
Expand Down Expand Up @@ -533,6 +555,24 @@ lookup_resource! {
primary_key_columns = [ { column_name = "id", rust_type = Uuid } ]
}

lookup_resource! {
name = "Image",
ancestors = [ "Silo", "Organization", "Project" ],
children = [],
lookup_by_name = true,
soft_deletes = true,
primary_key_columns = [ { column_name = "id", rust_type = Uuid } ]
}

lookup_resource! {
name = "Snapshot",
ancestors = [ "Silo", "Organization", "Project" ],
children = [],
lookup_by_name = true,
soft_deletes = true,
primary_key_columns = [ { column_name = "id", rust_type = Uuid } ]
}

lookup_resource! {
name = "Instance",
ancestors = [ "Silo", "Organization", "Project" ],
Expand Down
6 changes: 3 additions & 3 deletions nexus/src/db/model/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ pub struct Snapshot {
#[diesel(embed)]
identity: SnapshotIdentity,

project_id: Uuid,
disk_id: Uuid,
volume_id: Uuid,
pub project_id: Uuid,
pub disk_id: Uuid,
pub volume_id: Uuid,

#[diesel(column_name = size_bytes)]
pub size: ByteCount,
Expand Down
Loading

0 comments on commit 4640dd3

Please sign in to comment.