Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
8d51dbb
Revamp selectors (again), convert organizations
just-be-dev Dec 13, 2022
129011e
Add project APIs, update routes
just-be-dev Dec 13, 2022
c29c67d
Fix clippy failures
just-be-dev Dec 14, 2022
599e6eb
Require less conversions when going from NameOrId to name
just-be-dev Dec 14, 2022
114d39a
Revamp selectors (again x2), convert projects
just-be-dev Dec 14, 2022
6ae7da3
Update nexus.json
just-be-dev Dec 14, 2022
63eddd7
Skip deprecated endpoints in auth check; update test to assert contents
just-be-dev Dec 14, 2022
8db8fa2
Fix authz test
just-be-dev Dec 14, 2022
bd1fafe
Merge branch 'main' into rfd-322-orgs-n-projs
just-be-dev Dec 14, 2022
f949c6c
Update nexus.json
just-be-dev Dec 14, 2022
bd033a0
format -_-
just-be-dev Dec 15, 2022
ae4ddcd
Merge branch 'main' into rfd-322-orgs-n-projs
just-be-dev Dec 15, 2022
69ac008
Add expanded error checking
just-be-dev Dec 15, 2022
83768b1
Start networking v1 apis
just-be-dev Dec 16, 2022
52db40c
Start on subnets
just-be-dev Dec 16, 2022
1176211
Update nexus.json
just-be-dev Dec 16, 2022
5580d22
Merge branch 'main' into rfd-322-orgs-n-projs
just-be-dev Dec 19, 2022
5ceccc4
Merge branch 'rfd-322-orgs-n-projs' into rfd-322-networking
just-be-dev Dec 19, 2022
e18b5b8
Add v1 subnet create
just-be-dev Dec 19, 2022
96786b3
Added deleted; Added deprecations; Updated nexus.json
just-be-dev Dec 19, 2022
341dbd1
Add subnet update
just-be-dev Dec 19, 2022
f34aaf6
Merge branch 'main' into rfd-322-networking
just-be-dev Dec 21, 2022
5518c43
Merge branch 'main' into rfd-322-networking
just-be-dev Jan 17, 2023
bbf0f36
Update pagination strategy
just-be-dev Jan 17, 2023
f3c1d85
Update authz tests
just-be-dev Jan 17, 2023
12396b5
Update api spec
just-be-dev Jan 17, 2023
653df3d
Merge branch 'main' into rfd-322-networking
just-be-dev Jan 18, 2023
a336a5b
Update vpc tests
just-be-dev Jan 18, 2023
99c0466
Merge branch 'main' into rfd-322-networking
just-be-dev Jan 24, 2023
6cff4f9
Add comments, housekeeping
just-be-dev Jan 25, 2023
88cff99
Update vpc router and routes
just-be-dev Jan 26, 2023
7a2ddbc
Update API spec with new routes
just-be-dev Jan 26, 2023
507ffb0
Merge branch 'main' into rfd-322-networking
just-be-dev Jan 26, 2023
c0d325f
Update authz tests
just-be-dev Jan 26, 2023
ba1b8b8
WIP subnet tests
just-be-dev Jan 26, 2023
76c15dc
Merge branch 'main' into rfd-322-networking
just-be-dev Jan 30, 2023
92f9fda
WIP: progress on network interfaces
just-be-dev Jan 30, 2023
a226674
Merge branch 'main' into rfd-322-networking
just-be-dev Jan 31, 2023
7d19f04
Merge branch 'main' into rfd-322-networking
just-be-dev Feb 1, 2023
45427c1
Add nic update
just-be-dev Feb 3, 2023
35c9881
Move network interfaces into their own file
just-be-dev Feb 8, 2023
5f4d1b3
Fix type failures
just-be-dev Feb 8, 2023
6ef30f0
Remove unncessary into
just-be-dev Feb 8, 2023
2be9970
Remove unused imports
just-be-dev Feb 8, 2023
706df91
Merge branch 'main' into rfd-322-networking
just-be-dev Feb 8, 2023
7aeab07
Ensure selectors can be flattened
just-be-dev Feb 8, 2023
0b2f882
Fix remaining path issues; update nexus spec
just-be-dev Feb 8, 2023
9985ba2
Remove unused URLs
just-be-dev Feb 9, 2023
d6acd22
Fix doctest failure
just-be-dev Feb 9, 2023
b14dba6
Fix vpc subnets test
just-be-dev Feb 9, 2023
267ecc4
Fix authz test
just-be-dev Feb 9, 2023
b51834b
Merge branch 'main' into rfd-322-networking
just-be-dev Feb 10, 2023
dc7de20
Add authz coverage for network interfaces
just-be-dev Feb 10, 2023
e9818c2
Merge branch 'main' into rfd-322-networking
just-be-dev Feb 13, 2023
e30a398
Fix conflicts after merge
just-be-dev Feb 13, 2023
8876986
Merge branch 'main' into rfd-322-networking
just-be-dev Feb 15, 2023
1ea7279
Merge branch 'main' into rfd-322-networking
just-be-dev Feb 15, 2023
c832346
PR feedback
just-be-dev Feb 15, 2023
388dcd8
Add missed docstring
just-be-dev Feb 15, 2023
fd06033
Add missing deprecation
just-be-dev Feb 15, 2023
735255d
Add other missing deprecations
just-be-dev Feb 15, 2023
0ec1eeb
Update spec
just-be-dev Feb 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions common/src/api/external/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1557,24 +1557,6 @@ pub struct RouterRoute {
pub destination: RouteDestination,
}

/// Create-time parameters for a [`RouterRoute`]
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
pub struct RouterRouteCreateParams {
#[serde(flatten)]
pub identity: IdentityMetadataCreateParams,
pub target: RouteTarget,
pub destination: RouteDestination,
}

/// Updateable properties of a [`RouterRoute`]
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
pub struct RouterRouteUpdateParams {
#[serde(flatten)]
pub identity: IdentityMetadataUpdateParams,
pub target: RouteTarget,
pub destination: RouteDestination,
}

Comment on lines -1560 to -1577
Copy link
Contributor Author

@just-be-dev just-be-dev Feb 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved this over to the params file to be co-located with the other resource params that were already there.

/// A single rule in a VPC firewall
#[derive(ObjectIdentity, Clone, Debug, Deserialize, Serialize, JsonSchema)]
pub struct VpcFirewallRule {
Expand Down
7 changes: 4 additions & 3 deletions nexus/db-model/src/vpc_route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use diesel::deserialize::{self, FromSql};
use diesel::pg::Pg;
use diesel::serialize::{self, ToSql};
use diesel::sql_types;
use nexus_types::external_api::params;
use nexus_types::identity::Resource;
use omicron_common::api::external;
use std::io::Write;
Expand Down Expand Up @@ -115,7 +116,7 @@ impl RouterRoute {
route_id: Uuid,
vpc_router_id: Uuid,
kind: external::RouterRouteKind,
params: external::RouterRouteCreateParams,
params: params::RouterRouteCreate,
) -> Self {
let identity = RouterRouteIdentity::new(route_id, params.identity);
Self {
Expand Down Expand Up @@ -150,8 +151,8 @@ pub struct RouterRouteUpdate {
pub destination: RouteDestination,
}

impl From<external::RouterRouteUpdateParams> for RouterRouteUpdate {
fn from(params: external::RouterRouteUpdateParams) -> Self {
impl From<params::RouterRouteUpdate> for RouterRouteUpdate {
fn from(params: params::RouterRouteUpdate) -> Self {
Self {
name: params.identity.name.map(Name),
description: params.identity.description,
Expand Down
216 changes: 0 additions & 216 deletions nexus/src/app/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ use super::MAX_NICS_PER_INSTANCE;
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;
use crate::db::lookup::LookupPath;
use crate::db::queries::network_interface;
use crate::external_api::params;
use futures::future::Fuse;
use futures::{FutureExt, SinkExt, StreamExt};
Expand Down Expand Up @@ -799,220 +797,6 @@ impl super::Nexus {
Ok(disk)
}

/// Create a network interface attached to the provided instance.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I relocated the network interface logic in its own file. We break this resource at the data store layer, might as well be consistent with it.

// TODO-performance: Add a version of this that accepts the instance ID
// directly. This will avoid all the internal database lookups in the event
// that we create many NICs for the same instance, such as in a saga.
pub async fn instance_create_network_interface(
&self,
opctx: &OpContext,
organization_name: &Name,
project_name: &Name,
instance_name: &Name,
params: &params::NetworkInterfaceCreate,
) -> CreateResult<db::model::NetworkInterface> {
let (.., authz_project, authz_instance) =
LookupPath::new(opctx, &self.db_datastore)
.organization_name(organization_name)
.project_name(project_name)
.instance_name(instance_name)
.lookup_for(authz::Action::Modify)
.await?;

// NOTE: We need to lookup the VPC and VPC Subnet, since we need both
// IDs for creating the network interface.
//
// TODO-correctness: There are additional races here. The VPC and VPC
// Subnet could both be deleted between the time we fetch them and
// actually insert the record for the interface. The solution is likely
// to make both objects implement `DatastoreCollection` for their
// children, and then use `VpcSubnet::insert_resource` inside the
// `instance_create_network_interface` method. See
// https://github.com/oxidecomputer/omicron/issues/738.
let vpc_name = db::model::Name(params.vpc_name.clone());
let subnet_name = db::model::Name(params.subnet_name.clone());
let (.., authz_vpc, authz_subnet, db_subnet) =
LookupPath::new(opctx, &self.db_datastore)
.project_id(authz_project.id())
.vpc_name(&vpc_name)
.vpc_subnet_name(&subnet_name)
.fetch()
.await?;
let interface_id = Uuid::new_v4();
let interface = db::model::IncompleteNetworkInterface::new(
interface_id,
authz_instance.id(),
authz_vpc.id(),
db_subnet,
params.identity.clone(),
params.ip,
)?;
self.db_datastore
.instance_create_network_interface(
opctx,
&authz_subnet,
&authz_instance,
interface,
)
.await
.map_err(|e| {
debug!(
self.log,
"failed to create network interface";
"instance_id" => ?authz_instance.id(),
"interface_id" => ?interface_id,
"error" => ?e,
);
if matches!(
e,
network_interface::InsertError::InstanceNotFound(_)
) {
// Return the not-found message of the authz interface
// object, so that the message reflects how the caller
// originally looked it up
authz_instance.not_found()
} else {
// Convert other errors into an appropriate client error
network_interface::InsertError::into_external(e)
}
})
}

/// Lists network interfaces attached to the instance.
pub async fn instance_list_network_interfaces(
&self,
opctx: &OpContext,
organization_name: &Name,
project_name: &Name,
instance_name: &Name,
pagparams: &DataPageParams<'_, Name>,
) -> ListResultVec<db::model::NetworkInterface> {
let (.., authz_instance) = LookupPath::new(opctx, &self.db_datastore)
.organization_name(organization_name)
.project_name(project_name)
.instance_name(instance_name)
.lookup_for(authz::Action::ListChildren)
.await?;
self.db_datastore
.instance_list_network_interfaces(opctx, &authz_instance, pagparams)
.await
}

/// Fetch a network interface attached to the given instance.
pub async fn network_interface_fetch(
&self,
opctx: &OpContext,
organization_name: &Name,
project_name: &Name,
instance_name: &Name,
interface_name: &Name,
) -> LookupResult<db::model::NetworkInterface> {
let (.., db_interface) = LookupPath::new(opctx, &self.db_datastore)
.organization_name(organization_name)
.project_name(project_name)
.instance_name(instance_name)
.network_interface_name(interface_name)
.fetch()
.await?;
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,
opctx: &OpContext,
organization_name: &Name,
project_name: &Name,
instance_name: &Name,
interface_name: &Name,
updates: params::NetworkInterfaceUpdate,
) -> UpdateResult<db::model::NetworkInterface> {
let (.., authz_instance) = LookupPath::new(opctx, &self.db_datastore)
.organization_name(organization_name)
.project_name(project_name)
.instance_name(instance_name)
.lookup_for(authz::Action::Modify)
.await?;
let (.., authz_interface) = LookupPath::new(opctx, &self.db_datastore)
.instance_id(authz_instance.id())
.network_interface_name(interface_name)
.lookup_for(authz::Action::Modify)
.await?;
self.db_datastore
.instance_update_network_interface(
opctx,
&authz_instance,
&authz_interface,
db::model::NetworkInterfaceUpdate::from(updates),
)
.await
}

/// Delete a network interface from the provided instance.
///
/// Note that the primary interface for an instance cannot be deleted if
/// there are any secondary interfaces.
pub async fn instance_delete_network_interface(
&self,
opctx: &OpContext,
organization_name: &Name,
project_name: &Name,
instance_name: &Name,
interface_name: &Name,
) -> DeleteResult {
let (.., authz_instance) = LookupPath::new(opctx, &self.db_datastore)
.organization_name(organization_name)
.project_name(project_name)
.instance_name(instance_name)
.lookup_for(authz::Action::Modify)
.await?;
let (.., authz_interface) = LookupPath::new(opctx, &self.db_datastore)
.instance_id(authz_instance.id())
.network_interface_name(interface_name)
.lookup_for(authz::Action::Delete)
.await?;
self.db_datastore
.instance_delete_network_interface(
opctx,
&authz_instance,
&authz_interface,
)
.await
.map_err(|e| {
debug!(
self.log,
"failed to delete network interface";
"instance_id" => ?authz_instance.id(),
"interface_id" => ?authz_interface.id(),
"error" => ?e,
);
if matches!(
e,
network_interface::DeleteError::InstanceNotFound(_)
) {
// Return the not-found message of the authz interface
// object, so that the message reflects how the caller
// originally looked it up
authz_instance.not_found()
} else {
// Convert other errors into an appropriate client error
network_interface::DeleteError::into_external(e)
}
})
}

/// Invoked by a sled agent to publish an updated runtime state for an
/// Instance.
pub async fn notify_instance_updated(
Expand Down
1 change: 1 addition & 0 deletions nexus/src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ mod image;
mod instance;
mod ip_pool;
mod metrics;
mod network_interface;
mod organization;
mod oximeter;
mod project;
Expand Down
Loading