From b432677daf95bc1412fe870c8e2ac80c4b3e1881 Mon Sep 17 00:00:00 2001 From: David Crespo Date: Thu, 18 Jan 2024 15:45:23 -0600 Subject: [PATCH] /v1/ip-pools/{pool} responds with SiloIpPool too --- nexus/src/app/ip_pool.rs | 9 ++++----- nexus/src/external_api/http_entrypoints.rs | 10 +++++++--- nexus/tests/integration_tests/endpoints.rs | 10 ++++++++++ nexus/tests/integration_tests/ip_pools.rs | 3 ++- nexus/types/src/external_api/views.rs | 3 +-- openapi/nexus.json | 4 ++-- 6 files changed, 26 insertions(+), 13 deletions(-) diff --git a/nexus/src/app/ip_pool.rs b/nexus/src/app/ip_pool.rs index d1a9ecfbd28..1aceb3c4a3d 100644 --- a/nexus/src/app/ip_pool.rs +++ b/nexus/src/app/ip_pool.rs @@ -88,17 +88,16 @@ impl super::Nexus { &'a self, opctx: &'a OpContext, pool: &'a NameOrId, - ) -> LookupResult { + ) -> LookupResult<(db::model::IpPool, db::model::IpPoolResource)> { let (authz_pool, pool) = self.ip_pool_lookup(opctx, pool)?.fetch().await?; // 404 if no link is found in the current silo let link = self.db_datastore.ip_pool_fetch_link(opctx, pool.id()).await; - if link.is_err() { - return Err(authz_pool.not_found()); + match link { + Ok(link) => Ok((pool, link)), + Err(_) => Err(authz_pool.not_found()), } - - Ok(pool) } /// List silos for a given pool diff --git a/nexus/src/external_api/http_entrypoints.rs b/nexus/src/external_api/http_entrypoints.rs index 992c93c4a1b..d1fb5759d56 100644 --- a/nexus/src/external_api/http_entrypoints.rs +++ b/nexus/src/external_api/http_entrypoints.rs @@ -1379,14 +1379,18 @@ async fn project_ip_pool_list( async fn project_ip_pool_view( rqctx: RequestContext>, path_params: Path, -) -> Result, HttpError> { +) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { let opctx = crate::context::op_context_for_external_api(&rqctx).await?; let nexus = &apictx.nexus; let pool_selector = path_params.into_inner().pool; - let pool = nexus.silo_ip_pool_fetch(&opctx, &pool_selector).await?; - Ok(HttpResponseOk(IpPool::from(pool))) + let (pool, silo_link) = + nexus.silo_ip_pool_fetch(&opctx, &pool_selector).await?; + Ok(HttpResponseOk(views::SiloIpPool { + identity: pool.identity(), + is_default: silo_link.is_default, + })) }; apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await } diff --git a/nexus/tests/integration_tests/endpoints.rs b/nexus/tests/integration_tests/endpoints.rs index 11bfa34c5f2..e8d54b876e8 100644 --- a/nexus/tests/integration_tests/endpoints.rs +++ b/nexus/tests/integration_tests/endpoints.rs @@ -80,6 +80,8 @@ pub static DEMO_SILO_NAME: Lazy = Lazy::new(|| "demo-silo".parse().unwrap()); pub static DEMO_SILO_URL: Lazy = Lazy::new(|| format!("/v1/system/silos/{}", *DEMO_SILO_NAME)); +pub static DEMO_SILO_IP_POOLS_URL: Lazy = + Lazy::new(|| format!("{}/ip-pools", *DEMO_SILO_URL)); pub static DEMO_SILO_POLICY_URL: Lazy = Lazy::new(|| format!("/v1/system/silos/{}/policy", *DEMO_SILO_NAME)); pub static DEMO_SILO_QUOTAS_URL: Lazy = @@ -1110,6 +1112,14 @@ pub static VERIFY_ENDPOINTS: Lazy> = Lazy::new(|| { AllowedMethod::Delete, ], }, + VerifyEndpoint { + url: &DEMO_SILO_IP_POOLS_URL, + visibility: Visibility::Protected, + unprivileged_access: UnprivilegedAccess::None, + allowed_methods: vec![ + AllowedMethod::Get, + ], + }, VerifyEndpoint { url: &DEMO_SILO_POLICY_URL, visibility: Visibility::Protected, diff --git a/nexus/tests/integration_tests/ip_pools.rs b/nexus/tests/integration_tests/ip_pools.rs index 440376361f2..43499eb5a9b 100644 --- a/nexus/tests/integration_tests/ip_pools.rs +++ b/nexus/tests/integration_tests/ip_pools.rs @@ -945,8 +945,9 @@ async fn test_ip_pool_list_in_silo(cptestctx: &ControlPlaneTestContext) { // fetch the pool directly too let url = format!("/v1/ip-pools/{}", mypool_name); - let pool: IpPool = object_get(client, &url).await; + let pool = object_get::(client, &url).await; assert_eq!(pool.identity.name.as_str(), mypool_name); + assert!(pool.is_default); // fetching the other pool directly 404s let url = format!("/v1/ip-pools/{}", otherpool_name); diff --git a/nexus/types/src/external_api/views.rs b/nexus/types/src/external_api/views.rs index cc0e8c62c19..1030e441f75 100644 --- a/nexus/types/src/external_api/views.rs +++ b/nexus/types/src/external_api/views.rs @@ -303,8 +303,7 @@ pub struct IpPool { pub identity: IdentityMetadata, } -/// A collection of IP ranges. If a pool is linked to a silo, IP addresses from -/// the pool can be allocated within that silo +/// An IP pool in the context of a silo, which means we can include is_default #[derive(ObjectIdentity, Clone, Debug, Deserialize, Serialize, JsonSchema)] pub struct SiloIpPool { #[serde(flatten)] diff --git a/openapi/nexus.json b/openapi/nexus.json index 21d9a98f51c..bdbe738a871 100644 --- a/openapi/nexus.json +++ b/openapi/nexus.json @@ -2191,7 +2191,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/IpPoolResultsPage" + "$ref": "#/components/schemas/SiloIpPoolResultsPage" } } } @@ -2232,7 +2232,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/IpPool" + "$ref": "#/components/schemas/SiloIpPool" } } }