mirror of
https://github.com/neondatabase/neon.git
synced 2026-05-20 22:50:38 +00:00
https://github.com/neondatabase/cloud/issues/23008 For TLS between proxy and compute, we are using an internally provisioned CA to sign the compute certificates. This change ensures that proxy will load them from a supplied env var pointing to the correct file - this file and env var will be configured later, using a kubernetes secret. Control plane responds with a `server_name` field if and only if the compute uses TLS. This server name is the name we use to validate the certificate. Control plane still sends us the IP to connect to as well (to support overlay IP). To support this change, I'd had to split `host` and `host_addr` into separate fields. Using `host_addr` and bypassing `lookup_addr` if possible (which is what happens in production). `host` then is only used for the TLS connection. There's no blocker to merging this. The code paths will not be triggered until the new control plane is deployed and the `enableTLS` compute flag is enabled on a project.
74 lines
2.5 KiB
Rust
74 lines
2.5 KiB
Rust
use std::net::SocketAddr;
|
|
|
|
use arc_swap::ArcSwapOption;
|
|
use tokio::sync::Semaphore;
|
|
|
|
use super::jwt::{AuthRule, FetchAuthRules};
|
|
use crate::auth::backend::jwt::FetchAuthRulesError;
|
|
use crate::compute::ConnCfg;
|
|
use crate::compute_ctl::ComputeCtlApi;
|
|
use crate::context::RequestContext;
|
|
use crate::control_plane::NodeInfo;
|
|
use crate::control_plane::messages::{ColdStartInfo, EndpointJwksResponse, MetricsAuxInfo};
|
|
use crate::http;
|
|
use crate::intern::{BranchIdTag, EndpointIdTag, InternId, ProjectIdTag};
|
|
use crate::types::EndpointId;
|
|
use crate::url::ApiUrl;
|
|
|
|
pub struct LocalBackend {
|
|
pub(crate) initialize: Semaphore,
|
|
pub(crate) compute_ctl: ComputeCtlApi,
|
|
pub(crate) node_info: NodeInfo,
|
|
}
|
|
|
|
impl LocalBackend {
|
|
pub fn new(postgres_addr: SocketAddr, compute_ctl: ApiUrl) -> Self {
|
|
LocalBackend {
|
|
initialize: Semaphore::new(1),
|
|
compute_ctl: ComputeCtlApi {
|
|
api: http::Endpoint::new(compute_ctl, http::new_client()),
|
|
},
|
|
node_info: NodeInfo {
|
|
config: ConnCfg::new(postgres_addr.ip().to_string(), postgres_addr.port()),
|
|
// TODO(conrad): make this better reflect compute info rather than endpoint info.
|
|
aux: MetricsAuxInfo {
|
|
endpoint_id: EndpointIdTag::get_interner().get_or_intern("local"),
|
|
project_id: ProjectIdTag::get_interner().get_or_intern("local"),
|
|
branch_id: BranchIdTag::get_interner().get_or_intern("local"),
|
|
compute_id: "local".into(),
|
|
cold_start_info: ColdStartInfo::WarmCached,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Copy)]
|
|
pub(crate) struct StaticAuthRules;
|
|
|
|
pub static JWKS_ROLE_MAP: ArcSwapOption<EndpointJwksResponse> = ArcSwapOption::const_empty();
|
|
|
|
impl FetchAuthRules for StaticAuthRules {
|
|
async fn fetch_auth_rules(
|
|
&self,
|
|
_ctx: &RequestContext,
|
|
_endpoint: EndpointId,
|
|
) -> Result<Vec<AuthRule>, FetchAuthRulesError> {
|
|
let mappings = JWKS_ROLE_MAP.load();
|
|
let role_mappings = mappings
|
|
.as_deref()
|
|
.ok_or(FetchAuthRulesError::RoleJwksNotConfigured)?;
|
|
let mut rules = vec![];
|
|
for setting in &role_mappings.jwks {
|
|
rules.push(AuthRule {
|
|
id: setting.id.clone(),
|
|
jwks_url: setting.jwks_url.clone(),
|
|
audience: setting.jwt_audience.clone(),
|
|
role_names: setting.role_names.clone(),
|
|
});
|
|
}
|
|
|
|
Ok(rules)
|
|
}
|
|
}
|