mirror of
https://github.com/Significant-Gravitas/AutoGPT-Code-Ability.git
synced 2026-11-11 08:31:26 -10:00
172 lines
5.2 KiB
Python
172 lines
5.2 KiB
Python
import logging
|
|
import os
|
|
|
|
import psycopg2
|
|
from dotenv import load_dotenv
|
|
from google.auth import default
|
|
from googleapiclient.discovery import build
|
|
from psycopg2 import sql
|
|
|
|
import codex.common.utils
|
|
|
|
load_dotenv()
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def create_postgres_database(db_name):
|
|
logger.info(f"Attempting to create database {db_name}")
|
|
|
|
USER_DB_ADMIN: str | None = os.getenv("USER_DB_ADMIN")
|
|
if not USER_DB_ADMIN:
|
|
raise EnvironmentError("USER_DB_ADMIN not found in environment variables.")
|
|
|
|
USER_DB_PASS = os.getenv("USER_DB_PASS")
|
|
if not USER_DB_PASS:
|
|
raise EnvironmentError("USER_DB_PASS not found in environment variables.")
|
|
|
|
USER_CONN_NAME = os.getenv("USER_CONN_NAME")
|
|
if not USER_CONN_NAME:
|
|
raise EnvironmentError("USER_CONN_NAME not found in environment variables.")
|
|
|
|
conn = psycopg2.connect(
|
|
dbname="postgres",
|
|
user=USER_DB_ADMIN,
|
|
password=USER_DB_PASS,
|
|
host=USER_CONN_NAME,
|
|
)
|
|
conn.autocommit = True # Necessary to execute a create database command
|
|
cur = conn.cursor()
|
|
|
|
# Create database
|
|
cur.execute(sql.SQL("CREATE DATABASE {}").format(sql.Identifier(db_name)))
|
|
|
|
cur.close()
|
|
conn.close()
|
|
logger.info(f"Database {db_name} created successfully.")
|
|
|
|
|
|
def setup_cloudsql_db(db_username, db_password):
|
|
logger.info(f"Attempting to create user {db_username}")
|
|
PROJECT_ID = os.getenv("GCP_PROJECT_ID", default="codex-user-deployments-dev")
|
|
if not PROJECT_ID:
|
|
raise EnvironmentError("GCP project ID not found in environment variables.")
|
|
INSTANCE_ID = os.getenv("CLOUD_SQL_INSTANCE_ID", default="codex-user-db-dev")
|
|
if not INSTANCE_ID:
|
|
raise EnvironmentError(
|
|
"Cloud SQL instance ID not found in environment variables."
|
|
)
|
|
|
|
credentials, _ = default()
|
|
|
|
service = build("sqladmin", "v1beta4", credentials=credentials)
|
|
user_body = {"name": db_username, "password": db_password}
|
|
|
|
response = (
|
|
service.users()
|
|
.insert(project=PROJECT_ID, instance=INSTANCE_ID, body=user_body)
|
|
.execute()
|
|
)
|
|
|
|
logger.info(f"User creation response: {response}")
|
|
|
|
|
|
def grant_permissions_postgres(db_name, new_user):
|
|
logger.info(f"Attempting to grant user {new_user} permissions on {db_name}")
|
|
|
|
DB_USER: str | None = os.getenv("USER_DB_ADMIN", default="postgres")
|
|
if not DB_USER:
|
|
raise EnvironmentError("USER_DB_ADMIN not found in environment variables.")
|
|
|
|
DB_PASS = os.getenv("USER_DB_PASS")
|
|
if not DB_PASS:
|
|
raise EnvironmentError("USER_DB_PASS not found in environment variables.")
|
|
|
|
DB_CONN = os.getenv("USER_CONN_NAME")
|
|
if not DB_CONN:
|
|
raise EnvironmentError("USER_CONN_NAME not found in environment variables.")
|
|
|
|
conn = psycopg2.connect(
|
|
dbname="postgres",
|
|
user=DB_USER,
|
|
password=DB_PASS,
|
|
host=DB_CONN,
|
|
)
|
|
|
|
conn.autocommit = (
|
|
True # Ensure commands are committed without a separate commit statement
|
|
)
|
|
cur = conn.cursor()
|
|
|
|
# Grant permissions
|
|
cur.execute(
|
|
sql.SQL(
|
|
"""
|
|
GRANT CONNECT ON DATABASE {db} TO {user};
|
|
GRANT USAGE, CREATE ON SCHEMA public TO {user};
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO {user};
|
|
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO {user};
|
|
"""
|
|
).format(db=sql.Identifier(db_name), user=sql.Identifier(new_user))
|
|
)
|
|
logger.info(f"Permissions successfully granted to {new_user} on {db_name}.")
|
|
|
|
cur.close()
|
|
conn.close()
|
|
|
|
|
|
def add_secret_to_repo(repo_name: str, secret_name: str, secret_value: str):
|
|
from github import Github # noqa
|
|
|
|
"""Add a secret to the GitHub repository."""
|
|
|
|
logger.info(f"Attempting to add secret {secret_name} on {repo_name}")
|
|
GIT_TOKEN: str | None = os.environ.get("GIT_TOKEN")
|
|
if not GIT_TOKEN:
|
|
raise EnvironmentError("GitHub token not found in environment variables.")
|
|
|
|
g = Github(GIT_TOKEN)
|
|
repo = g.get_repo(repo_name)
|
|
repo.create_secret(secret_name, secret_value, secret_type="actions")
|
|
|
|
logger.info(
|
|
f"Secret {secret_name} of value {secret_value} successfully added to {repo_name}"
|
|
)
|
|
|
|
|
|
async def create_cloud_db(repo_url: str) -> tuple[str, str]:
|
|
"""
|
|
Creates CloudSQL DB for users
|
|
Args:
|
|
repo_url (str): The repository URL
|
|
|
|
Returns:
|
|
str, str: Database username and name
|
|
"""
|
|
logger.info("Starting DB processes.")
|
|
|
|
try:
|
|
# create database
|
|
repo_name = repo_url.split("/")[-1]
|
|
db_name = repo_name + "_db"
|
|
create_postgres_database(db_name)
|
|
|
|
# create db credentials
|
|
user, password = codex.common.utils.generate_db_credentials()
|
|
|
|
# create user in cloudsql
|
|
setup_cloudsql_db(user, password)
|
|
|
|
# grant user permissions to db
|
|
grant_permissions_postgres(db_name, user)
|
|
|
|
# update secrets
|
|
org_repo_name = "agpt-coder/" + repo_name
|
|
add_secret_to_repo(org_repo_name, "DB_USER", user)
|
|
add_secret_to_repo(org_repo_name, "DB_PASS", password)
|
|
add_secret_to_repo(org_repo_name, "DB_NAME", db_name)
|
|
|
|
return db_name, user
|
|
except Exception as e:
|
|
logger.exception(e)
|
|
raise e
|