feat: add unified decommission and database provisioning modules

This commit is contained in:
Fredrick Amnehagen 2026-02-05 19:48:16 +01:00
parent 171b2a63dd
commit b0f97f80df
4 changed files with 114 additions and 2 deletions

42
infra_cli/database.py Normal file
View file

@ -0,0 +1,42 @@
from .ssh import SSHClient
class DatabaseManager:
def __init__(self, config):
# Database server details
self.host = config.get('database.host', '10.32.70.54')
self.user = config.get('database.user', 'root')
self.ssh_key = config.get('proxmox.ssh_key_path')
self.client = SSHClient(self.host, self.user, self.ssh_key)
def exec_sql(self, sql):
# Runs SQL as postgres user via SSH
res = self.client.run(f"su - postgres -c \"psql -c \\"{sql}\"\"")
if res.returncode != 0:
raise RuntimeError(f"PostgreSQL command failed: {res.stderr}")
return res.stdout
def create_database(self, db_name, owner=None):
sql = f"CREATE DATABASE {db_name}"
if owner:
sql += f" OWNER {owner}"
return self.exec_sql(sql)
def create_user(self, username, password):
sql = f"CREATE USER {username} WITH PASSWORD '{password}'"
return self.exec_sql(sql)
def grant_privileges(self, db_name, username):
sql = f"GRANT ALL PRIVILEGES ON DATABASE {db_name} TO {username}"
return self.exec_sql(sql)
def list_databases(self):
return self.exec_sql("\l")
def list_users(self):
return self.exec_sql("\du")
def drop_database(self, db_name):
return self.exec_sql(f"DROP DATABASE IF EXISTS {db_name}")
def drop_user(self, username):
return self.exec_sql(f"DROP USER IF EXISTS {username}")

View file

@ -6,6 +6,7 @@ from .router import RouterManager
from .proxmox import ProxmoxManager
from .samba import SambaManager
from .cloudflare import CloudflareManager
from .database import DatabaseManager
import sys
@click.group()
@ -19,6 +20,47 @@ def cli(ctx, config):
click.echo(f"Error: {e}", err=True)
sys.exit(1)
@cli.group()
def db():
"""Manage PostgreSQL Databases and Users"""
pass
@db.command(name='list-dbs')
@click.pass_obj
def db_list_dbs(config):
mgr = DatabaseManager(config)
click.echo(mgr.list_databases())
@db.command(name='list-users')
@click.pass_obj
def db_list_users(config):
mgr = DatabaseManager(config)
click.echo(mgr.list_users())
@db.command(name='provision')
@click.argument('project_name')
@click.option('--password', help='Database user password')
@click.pass_obj
def db_provision(config, project_name, password):
"""Create a database and user for a project"""
import secrets
import string
db_name = project_name.lower().replace("-", "_")
username = f"{db_name}_user"
pwd = password or ''.join(secrets.choice(string.ascii_letters + string.digits) for i in range(16))
mgr = DatabaseManager(config)
click.echo(f"Creating user {username}...")
mgr.create_user(username, pwd)
click.echo(f"Creating database {db_name} owned by {username}...")
mgr.create_database(db_name, owner=username)
click.echo("\nProvisioning Complete:")
click.echo(f" DB Name: {db_name}")
click.echo(f" Username: {username}")
click.echo(f" Password: {pwd}")
@cli.group()
def cloudflare():
"""Manage Cloudflare DNS and DDNS"""