Working db setup with admin-cli

This commit is contained in:
2024-11-24 15:38:25 -08:00
parent 7230c2d015
commit df978d7250
5 changed files with 111 additions and 64 deletions

View File

@@ -6,3 +6,6 @@ edition = "2021"
[dependencies]
clap = { version = "4.5.20", features = ["derive"] }
postgres = "0.19.9"
base64 = "0.22.1"
serde = "1.0.215"
serde_json = "1.0.133"

View File

@@ -1,7 +1,10 @@
use std::env;
use std::fs;
use std::io::Read;
use clap::Parser;
use postgres::{Client, NoTls};
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _};
use serde::Serialize;
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
@@ -9,31 +12,58 @@ struct Args {
/// Setup everything from scratch
#[arg(short, long)]
setup: bool,
/// Setup just the Database
#[arg(short, long)]
db: bool
}
fn execute_sql(connection_string: &str, filename: &'static str) -> Result<(), postgres::Error> {
let content = fs::read_to_string(filename)
.expect(&format!("Failed to load file: {}", filename));
let mut client = Client::connect(connection_string, NoTls)?;
client.batch_execute(&content)
#[derive(Serialize)]
struct Config {
postgres_user: String,
postgres_pass: String,
}
fn setup_database() -> Result<(), postgres::Error> {
fn random_string(size: usize) -> String {
// Next we'll generate a bunch of random numbers
let mut buffer = vec![0; size];
let mut f = std::fs::File::open("/dev/urandom").unwrap();
f.read_exact(&mut buffer).unwrap();
URL_SAFE_NO_PAD.encode(buffer)
}
fn full_setup() -> Result<Config, postgres::Error> {
// Check to make sure we have the DB url set to connect
const KEY: &'static str = "DB_CONNECTION_STRING" ;
let connection_string = env::var(KEY).expect(
&format!("The env var {} is not set!", KEY)
);
execute_sql(&connection_string, "../db/tables.sql")
let setup_tables_script = fs::read_to_string("db/setup-tables.sql")
.expect("Failed to load file: db/setup-tables.sql");
let bubble_admin_password = random_string(32);
let mut client = Client::connect(&connection_string, NoTls)?;
// Preliminary bs
client.execute("DROP DATABASE IF EXISTS bubble;", &[])?;
client.execute("CREATE DATABASE bubble;", &[])?;
client.execute("DROP USER IF EXISTS bubble_admin;", &[])?;
client.execute(
&format!("CREATE USER bubble_admin WITH ENCRYPTED PASSWORD '{}';", bubble_admin_password),
&[]
)?;
// Ensure the admin has ownership of the db we created
client.execute("ALTER DATABASE bubble OWNER TO bubble_admin", &[])?;
// Service table creation
client.batch_execute(&setup_tables_script)?;
Ok(Config {
postgres_user: "bubble_admin".into(),
postgres_pass: bubble_admin_password
})
}
fn main() {
let args = Args::parse();
if args.db { let _ = setup_database(); }
println!("Setup is {}", args.setup);
println!("Setup is {}", args.db);
if args.setup {
match full_setup() {
Ok(config) => println!("{}", serde_json::to_string(&config).unwrap()),
Err(e) => eprintln!("{:#?}", e)
}
}
}