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::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 : /// Project ID. This is used for cache invalidation.
56 : pub(crate) project_id: Option<ProjectIdInt>,
57 : }
58 :
59 : /// Info for establishing a connection to a compute node.
60 : /// This is what we get after auth succeeded, but not before!
61 : #[derive(Clone)]
62 : pub(crate) struct NodeInfo {
63 : /// Compute node connection params.
64 : /// It's sad that we have to clone this, but this will improve
65 : /// once we migrate to a bespoke connection logic.
66 : pub(crate) config: compute::ConnCfg,
67 :
68 : /// Labels for proxy's metrics.
69 : pub(crate) aux: MetricsAuxInfo,
70 : }
71 :
72 : impl NodeInfo {
73 0 : pub(crate) async fn connect(
74 0 : &self,
75 0 : ctx: &RequestContext,
76 0 : config: &ComputeConfig,
77 0 : user_info: ComputeUserInfo,
78 0 : ) -> Result<compute::PostgresConnection, compute::ConnectionError> {
79 0 : self.config
80 0 : .connect(ctx, self.aux.clone(), config, user_info)
81 0 : .await
82 0 : }
83 :
84 4 : pub(crate) fn reuse_settings(&mut self, other: Self) {
85 4 : self.config.reuse_password(other.config);
86 4 : }
87 :
88 6 : pub(crate) fn set_keys(&mut self, keys: &ComputeCredentialKeys) {
89 6 : match keys {
90 : #[cfg(any(test, feature = "testing"))]
91 6 : ComputeCredentialKeys::Password(password) => self.config.password(password),
92 0 : ComputeCredentialKeys::AuthKeys(auth_keys) => self.config.auth_keys(*auth_keys),
93 0 : ComputeCredentialKeys::JwtPayload(_) | ComputeCredentialKeys::None => &mut self.config,
94 : };
95 6 : }
96 : }
97 :
98 : pub(crate) type NodeInfoCache =
99 : TimedLru<EndpointCacheKey, Result<NodeInfo, Box<ControlPlaneErrorMessage>>>;
100 : pub(crate) type CachedNodeInfo = Cached<&'static NodeInfoCache, NodeInfo>;
101 : pub(crate) type CachedRoleSecret = Cached<&'static ProjectInfoCacheImpl, Option<AuthSecret>>;
102 : pub(crate) type CachedAllowedIps = Cached<&'static ProjectInfoCacheImpl, Arc<Vec<IpPattern>>>;
103 :
104 : /// This will allocate per each call, but the http requests alone
105 : /// already require a few allocations, so it should be fine.
106 : pub(crate) trait ControlPlaneApi {
107 : /// Get the client's auth secret for authentication.
108 : /// Returns option because user not found situation is special.
109 : /// We still have to mock the scram to avoid leaking information that user doesn't exist.
110 : async fn get_role_secret(
111 : &self,
112 : ctx: &RequestContext,
113 : user_info: &ComputeUserInfo,
114 : ) -> Result<CachedRoleSecret, errors::GetAuthInfoError>;
115 :
116 : async fn get_allowed_ips_and_secret(
117 : &self,
118 : ctx: &RequestContext,
119 : user_info: &ComputeUserInfo,
120 : ) -> Result<(CachedAllowedIps, Option<CachedRoleSecret>), errors::GetAuthInfoError>;
121 :
122 : async fn get_endpoint_jwks(
123 : &self,
124 : ctx: &RequestContext,
125 : endpoint: EndpointId,
126 : ) -> Result<Vec<AuthRule>, errors::GetEndpointJwksError>;
127 :
128 : /// Wake up the compute node and return the corresponding connection info.
129 : async fn wake_compute(
130 : &self,
131 : ctx: &RequestContext,
132 : user_info: &ComputeUserInfo,
133 : ) -> Result<CachedNodeInfo, errors::WakeComputeError>;
134 : }
|