Skip to content

Commit

Permalink
feat(database-config): Allow ssl and refactor configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
Yag000 committed Sep 1, 2023
1 parent fbcd171 commit 22fac1e
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 33 deletions.
2 changes: 2 additions & 0 deletions configuration/local.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
application:
host: 127.0.0.1
database:
require_ssl: false
2 changes: 2 additions & 0 deletions configuration/production.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
application:
host: 0.0.0.0
database:
require_ssl: true
19 changes: 19 additions & 0 deletions spec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,25 @@ services:
# All incoming requests should be routed to our app
routes:
- path: /
envs:
- key: APP_APPLICATION__BASE_URL
scope: RUN_TIME
value: ${APP_URL}
- key: APP_DATABASE__USERNAME
scope: RUN_TIME
value: ${newsletter.USERNAME}
- key: APP_DATABASE__PASSWORD
scope: RUN_TIME
value: ${newsletter.PASSWORD}
- key: APP_DATABASE__HOST
scope: RUN_TIME
value: ${newsletter.HOSTNAME}
- key: APP_DATABASE__PORT
scope: RUN_TIME
value: ${newsletter.PORT}
- key: APP_DATABASE__DATABASE_NAME
scope: RUN_TIME
value: ${newsletter.DATABASE}

databases:
# PG = Postgres
Expand Down
43 changes: 24 additions & 19 deletions src/configurations.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use config::Config;
use secrecy::{ExposeSecret, Secret};
use serde_aux::field_attributes::deserialize_number_from_string;
use sqlx::{
postgres::{PgConnectOptions, PgSslMode},
ConnectOptions,
};
#[derive(serde::Deserialize)]
pub struct Settings {
pub database: DatabaseSettings,
Expand All @@ -15,6 +19,7 @@ pub struct DatabaseSettings {
pub password: Secret<String>,
pub host: String,
pub database_name: String,
pub require_ssl: bool,
}

#[derive(serde::Deserialize)]
Expand All @@ -25,25 +30,25 @@ pub struct ApplicationSettings {
}

impl DatabaseSettings {
pub fn get_connnection_string(&self) -> Secret<String> {
Secret::new(format!(
"postgres://{}:{}@{}:{}/{}",
self.username,
self.password.expose_secret(),
self.host,
self.port,
self.database_name
))
pub fn without_db(&self) -> PgConnectOptions {
let ssl_mode = if self.require_ssl {
PgSslMode::Require
} else {
PgSslMode::Prefer
};

PgConnectOptions::new()
.host(&self.host)
.username(&self.username)
.password(self.password.expose_secret())
.port(self.port)
.ssl_mode(ssl_mode)
}

pub fn get_connnection_string_without_db(&self) -> Secret<String> {
Secret::new(format!(
"postgres://{}:{}@{}:{}",
self.username,
self.password.expose_secret(),
self.host,
self.port
))
pub fn with_db(&self) -> PgConnectOptions {
let mut options = self.without_db().database(&self.database_name);
options.log_statements(tracing_log::log::LevelFilter::Trace);
options
}
}

Expand All @@ -55,10 +60,10 @@ pub fn get_configuration() -> Result<Settings, config::ConfigError> {
.unwrap_or_else(|_| "local".into())
.try_into()
.expect("Failed to parse APP_ENVIRONMENT.");
let environment_filename = format!("{}.yaml", environment.as_str());
let environment_filename = format!("{}.yml", environment.as_str());

let settings = Config::builder()
.add_source(config::File::from(configuration_directory.join("base")).required(true))
.add_source(config::File::from(configuration_directory.join("base.yml")).required(true))
.add_source(
config::File::from(configuration_directory.join(environment_filename)).required(true),
)
Expand Down
9 changes: 1 addition & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use secrecy::ExposeSecret;
use sqlx::postgres::PgPoolOptions;
use std::net::TcpListener;
use tracing::subscriber::set_global_default;
Expand All @@ -18,13 +17,7 @@ async fn main() -> Result<(), std::io::Error> {
let configuration = get_configuration().expect("Failed to read configurations");
let connection = PgPoolOptions::new()
.acquire_timeout(std::time::Duration::from_secs(2))
.connect_lazy(
configuration
.database
.get_connnection_string()
.expose_secret(),
)
.expect("Failed to connect to Postgres");
.connect_lazy_with(configuration.database.with_db());

// Bind the TCP listener socket address with the configuration port
let address = format!(
Expand Down
10 changes: 4 additions & 6 deletions tests/health_check.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use once_cell::sync::Lazy;
use secrecy::ExposeSecret;
use sqlx::{Connection, Executor, PgConnection, PgPool};
use std::net::TcpListener;
use uuid::Uuid;
Expand Down Expand Up @@ -54,17 +53,16 @@ async fn spawn_app() -> TestApp {
/// This is important in order to avoid polluting an existing database with test data.
pub async fn configure_database(config: &zero2prod::configurations::DatabaseSettings) -> PgPool {
// Create database
let mut connection =
PgConnection::connect(&config.get_connnection_string_without_db().expose_secret())
.await
.expect("Failed to connect to Postgres");
let mut connection = PgConnection::connect_with(&config.without_db())
.await
.expect("Failed to connect to Postgres");
connection
.execute(format!(r#"CREATE DATABASE "{}";"#, config.database_name).as_str())
.await
.expect("Failed to create database");

// Migrate database
let connection_pool = PgPool::connect(&config.get_connnection_string().expose_secret())
let connection_pool = PgPool::connect_with(config.with_db())
.await
.expect("Failed to connect to Postgres");
sqlx::migrate!("./migrations")
Expand Down

0 comments on commit 22fac1e

Please sign in to comment.