LCOV - code coverage report
Current view: top level - proxy/src/control_plane - mod.rs (source / functions) Coverage Total Hit
Test: 07bee600374ccd486c69370d0972d9035964fe68.info Lines: 36.8 % 19 7
Test Date: 2025-02-20 13:11:02 Functions: 50.0 % 4 2

            Line data    Source code
       1              : //! Various stuff for dealing with the Neon Console.
       2              : //! Later we might move some API wrappers here.
       3              : 
       4              : /// Payloads used in the console's APIs.
       5              : pub mod messages;
       6              : 
       7              : /// Wrappers for console APIs and their mocks.
       8              : pub mod client;
       9              : 
      10              : pub(crate) mod errors;
      11              : 
      12              : use std::sync::Arc;
      13              : 
      14              : use crate::auth::backend::jwt::AuthRule;
      15              : use crate::auth::backend::{ComputeCredentialKeys, ComputeUserInfo};
      16              : use crate::auth::IpPattern;
      17              : use crate::cache::project_info::ProjectInfoCacheImpl;
      18              : use crate::cache::{Cached, TimedLru};
      19              : use crate::config::ComputeConfig;
      20              : use crate::context::RequestContext;
      21              : use crate::control_plane::messages::{ControlPlaneErrorMessage, MetricsAuxInfo};
      22              : use crate::intern::{AccountIdInt, ProjectIdInt};
      23              : use crate::types::{EndpointCacheKey, EndpointId};
      24              : use crate::{compute, scram};
      25              : 
      26              : /// Various cache-related types.
      27              : pub mod caches {
      28              :     pub use super::client::ApiCaches;
      29              : }
      30              : 
      31              : /// Various cache-related types.
      32              : pub mod locks {
      33              :     pub use super::client::ApiLocks;
      34              : }
      35              : 
      36              : /// Console's management API.
      37              : pub mod mgmt;
      38              : 
      39              : /// Auth secret which is managed by the cloud.
      40              : #[derive(Clone, Eq, PartialEq, Debug)]
      41              : pub(crate) enum AuthSecret {
      42              :     #[cfg(any(test, feature = "testing"))]
      43              :     /// Md5 hash of user's password.
      44              :     Md5([u8; 16]),
      45              : 
      46              :     /// [SCRAM](crate::scram) authentication info.
      47              :     Scram(scram::ServerSecret),
      48              : }
      49              : 
      50              : #[derive(Default)]
      51              : pub(crate) struct AuthInfo {
      52              :     pub(crate) secret: Option<AuthSecret>,
      53              :     /// List of IP addresses allowed for the autorization.
      54              :     pub(crate) allowed_ips: Vec<IpPattern>,
      55              :     /// List of VPC endpoints allowed for the autorization.
      56              :     pub(crate) allowed_vpc_endpoint_ids: Vec<String>,
      57              :     /// Project ID. This is used for cache invalidation.
      58              :     pub(crate) project_id: Option<ProjectIdInt>,
      59              :     /// Account ID. This is used for cache invalidation.
      60              :     pub(crate) account_id: Option<AccountIdInt>,
      61              :     /// Are public connections or VPC connections blocked?
      62              :     pub(crate) access_blocker_flags: AccessBlockerFlags,
      63              : }
      64              : 
      65              : /// Info for establishing a connection to a compute node.
      66              : /// This is what we get after auth succeeded, but not before!
      67              : #[derive(Clone)]
      68              : pub(crate) struct NodeInfo {
      69              :     /// Compute node connection params.
      70              :     /// It's sad that we have to clone this, but this will improve
      71              :     /// once we migrate to a bespoke connection logic.
      72              :     pub(crate) config: compute::ConnCfg,
      73              : 
      74              :     /// Labels for proxy's metrics.
      75              :     pub(crate) aux: MetricsAuxInfo,
      76              : }
      77              : 
      78              : impl NodeInfo {
      79            0 :     pub(crate) async fn connect(
      80            0 :         &self,
      81            0 :         ctx: &RequestContext,
      82            0 :         config: &ComputeConfig,
      83            0 :         user_info: ComputeUserInfo,
      84            0 :     ) -> Result<compute::PostgresConnection, compute::ConnectionError> {
      85            0 :         self.config
      86            0 :             .connect(ctx, self.aux.clone(), config, user_info)
      87            0 :             .await
      88            0 :     }
      89              : 
      90            4 :     pub(crate) fn reuse_settings(&mut self, other: Self) {
      91            4 :         self.config.reuse_password(other.config);
      92            4 :     }
      93              : 
      94            6 :     pub(crate) fn set_keys(&mut self, keys: &ComputeCredentialKeys) {
      95            6 :         match keys {
      96              :             #[cfg(any(test, feature = "testing"))]
      97            6 :             ComputeCredentialKeys::Password(password) => self.config.password(password),
      98            0 :             ComputeCredentialKeys::AuthKeys(auth_keys) => self.config.auth_keys(*auth_keys),
      99            0 :             ComputeCredentialKeys::JwtPayload(_) | ComputeCredentialKeys::None => &mut self.config,
     100              :         };
     101            6 :     }
     102              : }
     103              : 
     104              : #[derive(Clone, Default, Eq, PartialEq, Debug)]
     105              : pub(crate) struct AccessBlockerFlags {
     106              :     pub public_access_blocked: bool,
     107              :     pub vpc_access_blocked: bool,
     108              : }
     109              : 
     110              : pub(crate) type NodeInfoCache =
     111              :     TimedLru<EndpointCacheKey, Result<NodeInfo, Box<ControlPlaneErrorMessage>>>;
     112              : pub(crate) type CachedNodeInfo = Cached<&'static NodeInfoCache, NodeInfo>;
     113              : pub(crate) type CachedRoleSecret = Cached<&'static ProjectInfoCacheImpl, Option<AuthSecret>>;
     114              : pub(crate) type CachedAllowedIps = Cached<&'static ProjectInfoCacheImpl, Arc<Vec<IpPattern>>>;
     115              : pub(crate) type CachedAllowedVpcEndpointIds =
     116              :     Cached<&'static ProjectInfoCacheImpl, Arc<Vec<String>>>;
     117              : pub(crate) type CachedAccessBlockerFlags =
     118              :     Cached<&'static ProjectInfoCacheImpl, AccessBlockerFlags>;
     119              : 
     120              : /// This will allocate per each call, but the http requests alone
     121              : /// already require a few allocations, so it should be fine.
     122              : pub(crate) trait ControlPlaneApi {
     123              :     /// Get the client's auth secret for authentication.
     124              :     /// Returns option because user not found situation is special.
     125              :     /// We still have to mock the scram to avoid leaking information that user doesn't exist.
     126              :     async fn get_role_secret(
     127              :         &self,
     128              :         ctx: &RequestContext,
     129              :         user_info: &ComputeUserInfo,
     130              :     ) -> Result<CachedRoleSecret, errors::GetAuthInfoError>;
     131              : 
     132              :     async fn get_allowed_ips(
     133              :         &self,
     134              :         ctx: &RequestContext,
     135              :         user_info: &ComputeUserInfo,
     136              :     ) -> Result<CachedAllowedIps, errors::GetAuthInfoError>;
     137              : 
     138              :     async fn get_allowed_vpc_endpoint_ids(
     139              :         &self,
     140              :         ctx: &RequestContext,
     141              :         user_info: &ComputeUserInfo,
     142              :     ) -> Result<CachedAllowedVpcEndpointIds, errors::GetAuthInfoError>;
     143              : 
     144              :     async fn get_block_public_or_vpc_access(
     145              :         &self,
     146              :         ctx: &RequestContext,
     147              :         user_info: &ComputeUserInfo,
     148              :     ) -> Result<CachedAccessBlockerFlags, errors::GetAuthInfoError>;
     149              : 
     150              :     async fn get_endpoint_jwks(
     151              :         &self,
     152              :         ctx: &RequestContext,
     153              :         endpoint: EndpointId,
     154              :     ) -> Result<Vec<AuthRule>, errors::GetEndpointJwksError>;
     155              : 
     156              :     /// Wake up the compute node and return the corresponding connection info.
     157              :     async fn wake_compute(
     158              :         &self,
     159              :         ctx: &RequestContext,
     160              :         user_info: &ComputeUserInfo,
     161              :     ) -> Result<CachedNodeInfo, errors::WakeComputeError>;
     162              : }
        

Generated by: LCOV version 2.1-beta