diff --git a/nexus/src/external_api/http_entrypoints.rs b/nexus/src/external_api/http_entrypoints.rs index a841e3246fe..186c4bef75d 100644 --- a/nexus/src/external_api/http_entrypoints.rs +++ b/nexus/src/external_api/http_entrypoints.rs @@ -1074,6 +1074,46 @@ async fn ip_pool_list( apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await } +/// List all IP Pools that can be used by a given project. +#[endpoint { + method = GET, + path = "/v1/projects/{project}/ip-pools", + tags = ["projects"], +}] +async fn project_ip_pool_list( + rqctx: RequestContext>, + _path_params: Path, + query_params: Query, +) -> Result>, HttpError> { + // Per https://github.com/oxidecomputer/omicron/issues/2148 + // This is currently the same list as /v1/system/ip-pools, that is to say, + // IP pools that are *available to* a given project, those being ones that + // are not the internal pools for Oxide service usage. This may change + // in the future as the scoping of pools is further developed, but for now, + // this is literally a duplicate of `ip_pool_list`: + let apictx = rqctx.context(); + let handler = async { + let nexus = &apictx.nexus; + let query = query_params.into_inner(); + let pag_params = data_page_params_for(&rqctx, &query)?; + let scan_params = ScanByNameOrId::from_query(&query)?; + let paginated_by = name_or_id_pagination(&pag_params, scan_params)?; + let opctx = crate::context::op_context_for_external_api(&rqctx).await?; + let pools = nexus + .ip_pools_list(&opctx, &paginated_by) + .await? + .into_iter() + .map(IpPool::from) + .collect(); + Ok(HttpResponseOk(ScanByNameOrId::results_page( + &query, + pools, + &marker_for_name_or_id, + )?)) + }; + apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await +} + #[derive(Deserialize, JsonSchema)] pub struct IpPoolPathParam { pub pool_name: Name,