config: simplify runtime environment model
This commit is contained in:
@@ -23,6 +23,7 @@ serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
serde_yaml.workspace = true
|
||||
sha2.workspace = true
|
||||
sqlx.workspace = true
|
||||
thiserror.workspace = true
|
||||
time.workspace = true
|
||||
tokio = { workspace = true, features = ["fs"] }
|
||||
@@ -33,4 +34,3 @@ uuid.workspace = true
|
||||
[dev-dependencies]
|
||||
reqwest.workspace = true
|
||||
serial_test = "3"
|
||||
sqlx.workspace = true
|
||||
|
||||
@@ -9,6 +9,7 @@ mod storage;
|
||||
use std::{env, net::SocketAddr, path::PathBuf};
|
||||
|
||||
use crank_registry::PostgresRegistry;
|
||||
use sqlx::postgres::PgConnectOptions;
|
||||
use tokio::net::TcpListener;
|
||||
use tracing::info;
|
||||
|
||||
@@ -28,15 +29,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
)
|
||||
.init();
|
||||
|
||||
let database_url = env::var("CRANK_DATABASE_URL")?;
|
||||
let storage_root = PathBuf::from(
|
||||
env::var("CRANK_STORAGE_ROOT").unwrap_or_else(|_| "/var/lib/crank/storage".into()),
|
||||
);
|
||||
let bind_addr = env::var("CRANK_ADMIN_BIND").unwrap_or_else(|_| "0.0.0.0:3001".into());
|
||||
let public_base_url =
|
||||
env::var("CRANK_PUBLIC_BASE_URL").unwrap_or_else(|_| "http://localhost:3000".into());
|
||||
let base_url = env::var("CRANK_BASE_URL").unwrap_or_else(|_| "http://localhost:3000".into());
|
||||
let socket_addr: SocketAddr = bind_addr.parse()?;
|
||||
let registry = PostgresRegistry::connect(&database_url).await?;
|
||||
let registry = PostgresRegistry::connect_with_options(database_options_from_env()?).await?;
|
||||
let auth_settings = AuthSettings {
|
||||
session_secret: env::var("CRANK_SESSION_SECRET")?,
|
||||
password_pepper: env::var("CRANK_PASSWORD_PEPPER")?,
|
||||
@@ -44,7 +43,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.ok()
|
||||
.and_then(|value| value.parse::<i64>().ok())
|
||||
.unwrap_or(24),
|
||||
cookie_secure: public_base_url.starts_with("https://"),
|
||||
cookie_secure: base_url.starts_with("https://"),
|
||||
bootstrap_admin: BootstrapAdminConfig {
|
||||
email: env::var("CRANK_BOOTSTRAP_ADMIN_EMAIL")?,
|
||||
password: env::var("CRANK_BOOTSTRAP_ADMIN_PASSWORD")?,
|
||||
@@ -79,3 +78,25 @@ fn env_flag(name: &str) -> bool {
|
||||
Some("1" | "true" | "yes" | "on")
|
||||
)
|
||||
}
|
||||
|
||||
fn database_options_from_env() -> Result<PgConnectOptions, Box<dyn std::error::Error>> {
|
||||
if let Ok(database_url) = env::var("CRANK_DATABASE_URL") {
|
||||
return Ok(database_url.parse::<PgConnectOptions>()?);
|
||||
}
|
||||
|
||||
let host = env::var("POSTGRES_HOST").unwrap_or_else(|_| "postgres".into());
|
||||
let port = env::var("POSTGRES_PORT")
|
||||
.ok()
|
||||
.and_then(|value| value.parse::<u16>().ok())
|
||||
.unwrap_or(5432);
|
||||
let database = env::var("POSTGRES_DB").unwrap_or_else(|_| "crank".into());
|
||||
let username = env::var("POSTGRES_USER").unwrap_or_else(|_| "crank".into());
|
||||
let password = env::var("POSTGRES_PASSWORD").unwrap_or_else(|_| "crank".into());
|
||||
|
||||
Ok(PgConnectOptions::new()
|
||||
.host(&host)
|
||||
.port(port)
|
||||
.database(&database)
|
||||
.username(&username)
|
||||
.password(&password))
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ futures-util = "0.3"
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
sha2.workspace = true
|
||||
sqlx.workspace = true
|
||||
time.workspace = true
|
||||
tokio = { workspace = true, features = ["sync"] }
|
||||
tracing.workspace = true
|
||||
@@ -27,4 +28,3 @@ crank-adapter-grpc = { path = "../../crates/crank-adapter-grpc", features = ["te
|
||||
crank-mapping = { path = "../../crates/crank-mapping" }
|
||||
crank-schema = { path = "../../crates/crank-schema" }
|
||||
reqwest.workspace = true
|
||||
sqlx.workspace = true
|
||||
|
||||
@@ -7,6 +7,7 @@ use std::{env, net::SocketAddr, time::Duration};
|
||||
|
||||
use crank_registry::PostgresRegistry;
|
||||
use crank_runtime::SecretCrypto;
|
||||
use sqlx::postgres::PgConnectOptions;
|
||||
use tokio::net::TcpListener;
|
||||
use tracing::info;
|
||||
|
||||
@@ -21,18 +22,17 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
)
|
||||
.init();
|
||||
|
||||
let database_url = env::var("CRANK_DATABASE_URL")?;
|
||||
let bind_addr = env::var("CRANK_MCP_BIND").unwrap_or_else(|_| "0.0.0.0:3002".into());
|
||||
let public_base_url = env::var("CRANK_PUBLIC_BASE_URL").ok();
|
||||
let base_url = env::var("CRANK_BASE_URL").ok();
|
||||
let refresh_interval = env::var("CRANK_MCP_REFRESH_MS")
|
||||
.ok()
|
||||
.and_then(|value| value.parse::<u64>().ok())
|
||||
.map(Duration::from_millis)
|
||||
.unwrap_or_else(|| Duration::from_secs(5));
|
||||
let socket_addr: SocketAddr = bind_addr.parse()?;
|
||||
let registry = PostgresRegistry::connect(&database_url).await?;
|
||||
let registry = PostgresRegistry::connect_with_options(database_options_from_env()?).await?;
|
||||
let secret_crypto = SecretCrypto::new(&env::var("CRANK_MASTER_KEY")?)?;
|
||||
let app = build_app(registry, refresh_interval, public_base_url, secret_crypto);
|
||||
let app = build_app(registry, refresh_interval, base_url, secret_crypto);
|
||||
let listener = TcpListener::bind(socket_addr).await?;
|
||||
|
||||
info!("mcp-server listening on {}", socket_addr);
|
||||
@@ -42,6 +42,28 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn database_options_from_env() -> Result<PgConnectOptions, Box<dyn std::error::Error>> {
|
||||
if let Ok(database_url) = env::var("CRANK_DATABASE_URL") {
|
||||
return Ok(database_url.parse::<PgConnectOptions>()?);
|
||||
}
|
||||
|
||||
let host = env::var("POSTGRES_HOST").unwrap_or_else(|_| "postgres".into());
|
||||
let port = env::var("POSTGRES_PORT")
|
||||
.ok()
|
||||
.and_then(|value| value.parse::<u16>().ok())
|
||||
.unwrap_or(5432);
|
||||
let database = env::var("POSTGRES_DB").unwrap_or_else(|_| "crank".into());
|
||||
let username = env::var("POSTGRES_USER").unwrap_or_else(|_| "crank".into());
|
||||
let password = env::var("POSTGRES_PASSWORD").unwrap_or_else(|_| "crank".into());
|
||||
|
||||
Ok(PgConnectOptions::new()
|
||||
.host(&host)
|
||||
.port(port)
|
||||
.database(&database)
|
||||
.username(&username)
|
||||
.password(&password))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::{
|
||||
|
||||
@@ -91,13 +91,16 @@ until docker exec "$POSTGRES_CONTAINER" pg_isready -U "$POSTGRES_USER" -d "$POST
|
||||
sleep 1
|
||||
done
|
||||
|
||||
export CRANK_DATABASE_URL="postgres://$POSTGRES_USER:$POSTGRES_PASSWORD@127.0.0.1:$POSTGRES_PORT/$POSTGRES_DB"
|
||||
export POSTGRES_HOST="127.0.0.1"
|
||||
export POSTGRES_PORT="$POSTGRES_PORT"
|
||||
export POSTGRES_DB="$POSTGRES_DB"
|
||||
export POSTGRES_USER="$POSTGRES_USER"
|
||||
export POSTGRES_PASSWORD="$POSTGRES_PASSWORD"
|
||||
export CRANK_STORAGE_ROOT="$TMP_DIR/storage"
|
||||
export CRANK_ADMIN_BIND="0.0.0.0:$ADMIN_PORT"
|
||||
export CRANK_MCP_BIND="0.0.0.0:$MCP_PORT"
|
||||
export CRANK_MCP_REFRESH_MS="1000"
|
||||
export CRANK_LOG_LEVEL="info"
|
||||
export CRANK_SECRET_PROVIDER="env"
|
||||
export CRANK_SESSION_SECRET="e2e-session-secret"
|
||||
export CRANK_PASSWORD_PEPPER="e2e-password-pepper"
|
||||
export CRANK_MASTER_KEY="0000000000000000000000000000000000000000000000000000000000000000"
|
||||
@@ -106,8 +109,7 @@ export CRANK_BOOTSTRAP_ADMIN_EMAIL="$ADMIN_EMAIL"
|
||||
export CRANK_BOOTSTRAP_ADMIN_PASSWORD="$ADMIN_PASSWORD"
|
||||
export CRANK_BOOTSTRAP_ADMIN_DISPLAY_NAME="Crank E2E"
|
||||
export CRANK_DEMO_SEED="true"
|
||||
export CRANK_PUBLIC_BASE_URL="http://127.0.0.1:$UI_PORT"
|
||||
export CRANK_MCP_PUBLIC_URL="http://127.0.0.1:$MCP_PORT"
|
||||
export CRANK_BASE_URL="http://127.0.0.1:$UI_PORT"
|
||||
export CRANK_E2E_STREAM_FIXTURE_PORT="$STREAM_FIXTURE_PORT"
|
||||
export CRANK_E2E_GRPC_FIXTURE_BIND="$GRPC_FIXTURE_BIND"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user