mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
New infrastructure components: - rds_probe: Rust database inspection tool with IAM auth - credential_server.py: REST credential provider server - credential_provider.py: credential resolution chain - ene_rds_fractal_fold.py / ene_rds_wiki_layer.py: RDS-backed ENE layers - import_dumps_to_rds.py / export_linear_from_rds.py: ingestion pipeline - recover_credential_server.sh: deployment script (sanitized) Sanitize hardcoded secrets across codebase: - Strip API keys from recover_credential_server.sh → env var lookups - Replace hardcoded Wolfram appid (HYJE3R3R63) → env var in 5 scripts - Strip fallback key values from config/index.js - Add .claude/ and optimized_basis_v3.bin to .gitignore Ingested 2,685 records into RDS: 2,421 Linear issues + 264 wiki pages
102 lines
2.8 KiB
Rust
102 lines
2.8 KiB
Rust
use sqlx::{postgres::PgPoolOptions, PgPool};
|
|
use std::env;
|
|
use std::process::Command;
|
|
|
|
pub struct DbConfig {
|
|
pub host: String,
|
|
pub port: u16,
|
|
pub user: String,
|
|
pub password: String,
|
|
pub dbname: String,
|
|
}
|
|
|
|
fn get_iam_token(host: &str, user: &str, region: &str) -> Option<String> {
|
|
let output = Command::new("aws")
|
|
.args(&[
|
|
"rds", "generate-db-auth-token",
|
|
"--hostname", host,
|
|
"--port", "5432",
|
|
"--username", user,
|
|
"--region", region,
|
|
])
|
|
.output()
|
|
.ok()?;
|
|
|
|
if output.status.success() {
|
|
let token = String::from_utf8_lossy(&output.stdout).trim().to_string();
|
|
if !token.is_empty() {
|
|
return Some(token);
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
impl DbConfig {
|
|
pub fn from_env() -> Self {
|
|
let host = env::var("RDS_HOST")
|
|
.unwrap_or("database-1-instance-1.cghu8yqogqwo.us-east-1.rds.amazonaws.com".to_string());
|
|
let user = env::var("RDS_USER").unwrap_or("postgres".to_string());
|
|
let region = env::var("AWS_DEFAULT_REGION").unwrap_or("us-east-1".to_string());
|
|
|
|
let password = if let Ok(pwd) = env::var("RDS_PASSWORD") {
|
|
if !pwd.is_empty() {
|
|
pwd
|
|
} else {
|
|
get_iam_token(&host, &user, ®ion).unwrap_or_default()
|
|
}
|
|
} else {
|
|
get_iam_token(&host, &user, ®ion).unwrap_or_default()
|
|
};
|
|
|
|
Self {
|
|
host,
|
|
port: env::var("RDS_PORT")
|
|
.unwrap_or("5432".to_string())
|
|
.parse()
|
|
.unwrap_or(5432),
|
|
user,
|
|
password,
|
|
dbname: env::var("RDS_DB").unwrap_or("postgres".to_string()),
|
|
}
|
|
}
|
|
|
|
pub fn dsn(&self) -> String {
|
|
format!(
|
|
"postgres://{}:{}@{}:{}/{}?sslmode=require",
|
|
self.user,
|
|
urlencoding(&self.password),
|
|
self.host,
|
|
self.port,
|
|
self.dbname
|
|
)
|
|
}
|
|
}
|
|
|
|
fn urlencoding(s: &str) -> String {
|
|
let mut encoded = String::new();
|
|
for c in s.chars() {
|
|
match c {
|
|
'a'..='z' | 'A'..='Z' | '0'..='9' | '-' | '_' | '.' | '~' => {
|
|
encoded.push(c);
|
|
}
|
|
_ => {
|
|
encoded.push('%');
|
|
encoded.push_str(&format!("{:02X}", c as u8));
|
|
}
|
|
}
|
|
}
|
|
encoded
|
|
}
|
|
|
|
pub async fn create_pool(config: &DbConfig) -> Result<PgPool, sqlx::Error> {
|
|
PgPoolOptions::new()
|
|
.max_connections(1)
|
|
.acquire_timeout(std::time::Duration::from_secs(30))
|
|
.connect(&config.dsn()).await
|
|
}
|
|
|
|
pub async fn get_pool() -> Result<PgPool, Box<dyn std::error::Error>> {
|
|
let config = DbConfig::from_env();
|
|
let pool = create_pool(&config).await?;
|
|
Ok(pool)
|
|
}
|