Skip to main content

docbox_management/
server.rs

1use crate::{
2    config::{AdminDatabaseSetupUserConfig, ServerConfigData, ServerConfigDataSecretError},
3    database::ServerDatabaseProvider,
4};
5use aws_config::SdkConfig;
6use docbox_core::{
7    aws::SqsClient,
8    database::{DatabasePoolCache, DatabasePoolCacheConfig},
9    events::{EventPublisherFactory, sqs::SqsEventPublisherFactory},
10    search::{SearchIndexFactory, SearchIndexFactoryError},
11    secrets::{SecretManager, SecretManagerError},
12    storage::StorageLayerFactory,
13};
14use std::sync::Arc;
15use thiserror::Error;
16
17#[derive(Debug, Error)]
18pub enum LoadManagedServerError {
19    #[error("failed to load server config secret: {0}")]
20    SecretManager(#[from] SecretManagerError),
21
22    #[error("failed to load server config secret: {0}")]
23    LoadSecret(#[from] ServerConfigDataSecretError),
24
25    #[error("server config database setup user secret not found")]
26    MissingDatabaseSecret,
27
28    #[error("must provided either setup_user or setup_user_secret_name in database config")]
29    MissingSetupUser,
30
31    #[error("failed to create search index factory: {0}")]
32    CreateSearchFactory(#[from] SearchIndexFactoryError),
33}
34
35/// Loaded server with all dependencies required to perform
36/// management actions on the server
37pub struct ManagedServer {
38    // Database provider for management database access
39    pub db_provider: ServerDatabaseProvider,
40    // Database access
41    pub db_cache: Arc<DatabasePoolCache>,
42    /// Secrets manager access
43    pub secrets: SecretManager,
44    /// Search access
45    pub search: SearchIndexFactory,
46    /// Storage access
47    pub storage: StorageLayerFactory,
48    /// Events access
49    pub events: EventPublisherFactory,
50}
51
52/// Load a managed server to perform db actions
53pub async fn load_managed_server(
54    aws_config: &SdkConfig,
55    config: &ServerConfigData,
56) -> Result<ManagedServer, LoadManagedServerError> {
57    // Setup server secret manager
58    let secrets = SecretManager::from_config(aws_config, config.secrets.clone());
59
60    // Setup database cache / connector
61    let db_cache = Arc::new(DatabasePoolCache::from_config(
62        aws_config.clone(),
63        DatabasePoolCacheConfig {
64            host: config.database.host.clone(),
65            port: config.database.port,
66            root_secret_name: config.database.root_secret_name.clone(),
67            root_iam: config.database.root_iam,
68            ..Default::default()
69        },
70        secrets.clone(),
71    ));
72
73    // Setup search factory
74    let search = SearchIndexFactory::from_config(
75        aws_config,
76        secrets.clone(),
77        db_cache.clone(),
78        config.search.clone(),
79    )?;
80
81    // Setup storage factory
82    let storage = StorageLayerFactory::from_config(aws_config, config.storage.clone());
83
84    let db_provider = match (
85        config.database.setup_user.as_ref(),
86        config.database.setup_user_secret_name.as_deref(),
87    ) {
88        (Some(setup_user), _) => ServerDatabaseProvider {
89            config: config.database.clone(),
90            username: setup_user.username.clone(),
91            password: setup_user.password.clone(),
92        },
93        (_, Some(setup_user_secret_name)) => {
94            let secret: AdminDatabaseSetupUserConfig = secrets
95                .parsed_secret(setup_user_secret_name)
96                .await?
97                .ok_or(LoadManagedServerError::MissingDatabaseSecret)?;
98
99            tracing::debug!("loaded database secrets from secret manager");
100
101            ServerDatabaseProvider {
102                config: config.database.clone(),
103                username: secret.username.clone(),
104                password: secret.password.clone(),
105            }
106        }
107        (None, None) => {
108            return Err(LoadManagedServerError::MissingSetupUser);
109        }
110    };
111
112    // Create the SQS client
113    // Warning: Will panic if the configuration provided is invalid
114    let sqs_client = SqsClient::new(aws_config);
115
116    // Setup event publisher factories
117    let sqs_publisher_factory = SqsEventPublisherFactory::new(sqs_client.clone());
118    let events = EventPublisherFactory::new(sqs_publisher_factory);
119
120    Ok(ManagedServer {
121        db_provider,
122        db_cache,
123        secrets,
124        search,
125        storage,
126        events,
127    })
128}