Skip to content

Commit 7273924

Browse files
connect to postgres via SSL (#993)
* connect to postgres via SSL * Update app-server/src/db/mod.rs Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> * fix build (don't require env vars to be set) * fix regex * replace .expect with anyhow error * fix regex --------- Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
1 parent 5434641 commit 7273924

File tree

5 files changed

+208
-55
lines changed

5 files changed

+208
-55
lines changed

app-server/Cargo.lock

Lines changed: 38 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app-server/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ serde = "1.0"
4545
serde_json = {version = "1.0.140", features = ["preserve_order"]}
4646
sha3 = "0.10.8"
4747
sodiumoxide = "0.2.7"
48-
sqlx = {version = "0.8", features = ["runtime-tokio", "postgres", "uuid", "json", "chrono", "bigdecimal"]}
48+
sqlx = {version = "0.8", features = ["runtime-tokio", "postgres", "uuid", "json", "chrono", "bigdecimal", "tls-rustls"]}
4949
thiserror = "2"
5050
tikv-jemallocator = "0.6"
5151
tokio = {version = "1.46", features = ["macros", "rt-multi-thread"]}

app-server/src/db/mod.rs

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use std::env;
2+
3+
use regex::Regex;
14
use sqlx::PgPool;
25

36
pub mod datasets;
@@ -24,7 +27,80 @@ pub struct DB {
2427
}
2528

2629
impl DB {
27-
pub fn new(pool: PgPool) -> Self {
28-
Self { pool }
30+
pub async fn connect_from_env() -> anyhow::Result<Self> {
31+
let options = get_pg_connect_options()?;
32+
let pool = sqlx::postgres::PgPoolOptions::new()
33+
.max_connections(
34+
env::var("DATABASE_MAX_CONNECTIONS")
35+
.unwrap_or(String::from("10"))
36+
.parse::<u32>()
37+
.unwrap_or(10),
38+
)
39+
.connect_with(options)
40+
.await?;
41+
Ok(Self { pool })
42+
}
43+
}
44+
45+
fn get_pg_connect_options() -> anyhow::Result<sqlx::postgres::PgConnectOptions> {
46+
let options = if let Ok(database_url) = env::var("DATABASE_URL") {
47+
options_from_database_url(&database_url)?
48+
} else {
49+
options_from_database_env_vars()?
50+
};
51+
52+
if let Ok(ssl_root_cert) = env::var("DATABASE_SSL_ROOT_CERT") {
53+
Ok(options
54+
.ssl_mode(sqlx::postgres::PgSslMode::VerifyFull)
55+
.ssl_root_cert_from_pem(ssl_root_cert.into_bytes()))
56+
} else {
57+
Ok(options)
2958
}
3059
}
60+
61+
fn options_from_database_url(
62+
database_url: &str,
63+
) -> anyhow::Result<sqlx::postgres::PgConnectOptions> {
64+
let re = Regex::new(r"^postgres(?:ql)?://([^:]+):([^@]+)@([^:]+):(\d*)/(.+)$").unwrap();
65+
let caps = re
66+
.captures(database_url)
67+
.ok_or(anyhow::anyhow!("Invalid database URL"))?;
68+
let username = caps.get(1).map(|m| m.as_str()).unwrap_or("postgres");
69+
let password = caps
70+
.get(2)
71+
.ok_or(anyhow::anyhow!("Invalid database URL. Can't find password"))?
72+
.as_str();
73+
let host = caps
74+
.get(3)
75+
.ok_or(anyhow::anyhow!("Invalid database URL. Can't find host"))?
76+
.as_str();
77+
let port = caps
78+
.get(4)
79+
.and_then(|m| m.as_str().parse::<u16>().ok())
80+
.unwrap_or(5432);
81+
let database = caps.get(5).map(|m| m.as_str()).unwrap_or(username);
82+
Ok(sqlx::postgres::PgConnectOptions::new()
83+
.username(username)
84+
.password(password)
85+
.host(host)
86+
.port(port)
87+
.database(database))
88+
}
89+
90+
fn options_from_database_env_vars() -> anyhow::Result<sqlx::postgres::PgConnectOptions> {
91+
let username = env::var("DATABASE_USERNAME").unwrap_or(String::from("postgres"));
92+
let password = env::var("DATABASE_PASSWORD")?;
93+
let host = env::var("DATABASE_HOST")?;
94+
let port = env::var("DATABASE_PORT")
95+
.unwrap_or(String::from("5432"))
96+
.parse::<u16>()
97+
.unwrap_or(5432);
98+
let database = env::var("DATABASE_DATABASE").unwrap_or(username.clone());
99+
100+
Ok(sqlx::postgres::PgConnectOptions::new()
101+
.username(&username)
102+
.password(&password)
103+
.host(&host)
104+
.port(port)
105+
.database(&database))
106+
}

app-server/src/main.rs

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -177,24 +177,8 @@ fn main() -> anyhow::Result<()> {
177177
let cache = Arc::new(cache);
178178

179179
// === 2. Database ===
180-
let db_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
181-
182-
let max_connections = env::var("DATABASE_MAX_CONNECTIONS")
183-
.unwrap_or(String::from("10"))
184-
.parse()
185-
.unwrap_or(10);
186-
187-
log::info!("Database max connections: {}", max_connections);
188-
189-
let pool = runtime_handle.block_on(async {
190-
sqlx::postgres::PgPoolOptions::new()
191-
.max_connections(max_connections)
192-
.connect(&db_url)
193-
.await
194-
.unwrap()
195-
});
196-
197-
let db = Arc::new(db::DB::new(pool));
180+
let inner_db = runtime_handle.block_on(db::DB::connect_from_env())?;
181+
let db = Arc::new(inner_db);
198182

199183
// === 3. Message queues ===
200184
// Only enable RabbitMQ if it is a full build and RabbitMQ Feature (URL) is set
@@ -440,7 +424,7 @@ fn main() -> anyhow::Result<()> {
440424
let mq_for_http = queue.clone();
441425
let worker_tracker_for_http = worker_tracker.clone();
442426

443-
// == AWS config for S3 and Bedrock ==
427+
// == AWS config for S3 ==
444428
let aws_sdk_config = runtime_handle.block_on(async {
445429
aws_config::defaults(BehaviorVersion::latest())
446430
.region(aws_config::Region::new(

0 commit comments

Comments
 (0)