diff --git a/app-set-prod.yaml b/app-set-prod.yaml index eb0f37f2..37aefff4 100644 --- a/app-set-prod.yaml +++ b/app-set-prod.yaml @@ -12,6 +12,7 @@ spec: revision: HEAD directories: - path: 'apps/*' + - path: 'infra/*' - path: 'ops/*' template: metadata: diff --git a/app-set-test.yaml b/app-set-test.yaml index fb4e3b9d..e01109fa 100644 --- a/app-set-test.yaml +++ b/app-set-test.yaml @@ -12,6 +12,7 @@ spec: revision: develop directories: - path: 'apps/*' + - path: 'infra/*' - path: 'ops/*' template: metadata: diff --git a/apps/faf-postgres/Chart.yaml b/apps/faf-postgres/Chart.yaml new file mode 100644 index 00000000..08246e3c --- /dev/null +++ b/apps/faf-postgres/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: faf-postgres +version: 1.0.0 diff --git a/apps/faf-postgres/templates/service.yaml b/apps/faf-postgres/templates/service.yaml new file mode 100644 index 00000000..f6f8427c --- /dev/null +++ b/apps/faf-postgres/templates/service.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Service +metadata: + name: postgres +spec: + type: ExternalName + # Define mariadb.hostName in config, if you use an external database + externalName: {{ default "postgres.postgres.svc.cluster.local" .Values.postgres.hostName }} diff --git a/apps/faf-postgres/values.yaml b/apps/faf-postgres/values.yaml new file mode 100644 index 00000000..6faac3d8 --- /dev/null +++ b/apps/faf-postgres/values.yaml @@ -0,0 +1,2 @@ +# placeholder for .Values.postgres.hostName +postgres: {} \ No newline at end of file diff --git a/cluster/storage/values.yaml b/cluster/storage/values.yaml index f21e8074..acedba51 100644 --- a/cluster/storage/values.yaml +++ b/cluster/storage/values.yaml @@ -8,6 +8,11 @@ managedStorages: # pvc: # name: optional string, default is -pvc # namespace: faf-apps + - pv: + name: postgres + size: 50Gi + pvc: + namespace: infra - pv: name: faf-replays folderName: replays diff --git a/infra/postgres/Chart.yaml b/infra/postgres/Chart.yaml new file mode 100644 index 00000000..3a947cd5 --- /dev/null +++ b/infra/postgres/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: postgres +version: 1.0.0 diff --git a/infra/postgres/templates/config.yaml b/infra/postgres/templates/config.yaml new file mode 100644 index 00000000..4e4668a4 --- /dev/null +++ b/infra/postgres/templates/config.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: postgres + labels: + app: postgres +data: + POSTGRES_USER: "postgres" \ No newline at end of file diff --git a/infra/postgres/templates/secret.yaml b/infra/postgres/templates/secret.yaml new file mode 100644 index 00000000..a038521e --- /dev/null +++ b/infra/postgres/templates/secret.yaml @@ -0,0 +1,19 @@ +apiVersion: secrets.infisical.com/v1alpha1 +kind: InfisicalSecret +metadata: + name: postgres + namespace: faf-infra +spec: + authentication: + universalAuth: + credentialsRef: + secretName: infisical-machine-identity + secretNamespace: faf-ops + secretsScope: + projectSlug: {{.Values.infisical.projectSlug}} + envSlug: {{.Values.infisical.envSlug}} + secretsPath: "/postgres" + managedSecretReference: + secretName: postgres + secretNamespace: faf-infra + creationPolicy: "Owner" diff --git a/infra/postgres/templates/service.yaml b/infra/postgres/templates/service.yaml new file mode 100644 index 00000000..0ea2442a --- /dev/null +++ b/infra/postgres/templates/service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: postgres + labels: + app: postgres +spec: + selector: + app: postgres + ports: + - port: 5432 + targetPort: 5432 diff --git a/infra/postgres/templates/statefulset.yaml b/infra/postgres/templates/statefulset.yaml new file mode 100644 index 00000000..f586cc0f --- /dev/null +++ b/infra/postgres/templates/statefulset.yaml @@ -0,0 +1,41 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: postgres + labels: + app: postgres +spec: + serviceName: postgres + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: postgres + template: + metadata: + labels: + app: postgres + spec: + containers: + - image: postgres:16.4-alpine3.20 + imagePullPolicy: Always + name: postgres + ports: + - containerPort: 5432 + protocol: TCP + envFrom: + - configMapRef: + name: postgres + - secretRef: + name: postgres + volumeMounts: + - name: postgres-pvc + mountPath: /var/lib/postgresql/data + restartPolicy: Always + volumes: + - name: config + configMap: + name: postgres + - name: postgres-pvc + persistentVolumeClaim: + claimName: postgres-pvc diff --git a/scripts/init-postgres.sh b/scripts/init-postgres.sh new file mode 100755 index 00000000..ef2783f2 --- /dev/null +++ b/scripts/init-postgres.sh @@ -0,0 +1,54 @@ +#!/bin/sh +# Setup rabbitmq vhost and users +export NAMESPACE="faf-infra" + +# fail on errors +set -e + +. ./k8s-helpers.sh + +check_resource_exists_or_fail secret postgres +check_resource_exists_or_fail statefulset postgres +check_resource_exists_or_fail pod postgres-0 + +# Function to check if a user exists +user_exists() { + kubectl -n $NAMESPACE exec -i postgres-0 -- psql --username=postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='$1'" | grep -q 1 +} + +# Function to check if a database exists +database_exists() { + kubectl -n $NAMESPACE exec -i postgres-0 -- psql --username=postgres -tAc "SELECT 1 FROM pg_database WHERE datname='$1'" | grep -q 1 +} + +create_user_and_db() { + SERVICE_NAMESPACE=$1 + SERVICE_NAME=$2 + DB_USER=$(NAMESPACE=$SERVICE_NAMESPACE get_config_value "$SERVICE_NAME" "$3") + DB_PASSWORD=$(NAMESPACE=$SERVICE_NAMESPACE get_secret_value "$SERVICE_NAME" "$4") + DB_NAME=$(NAMESPACE=$SERVICE_NAMESPACE get_config_value "$SERVICE_NAME" "$5") + + # Create user if it does not exist + if user_exists "$DB_USER"; then + echo "User $DB_USER already exists. Skipping user creation." + else + kubectl -n $NAMESPACE exec -i postgres-0 -- psql --username=postgres -c "CREATE USER \"$DB_USER\" WITH PASSWORD '$DB_PASSWORD';" + echo "User $DB_USER created." + fi + + # Create database if it does not exist + if database_exists "$DB_NAME"; then + echo "Database $DB_NAME already exists. Skipping database creation." + else + kubectl -n $NAMESPACE exec -i postgres-0 -- psql --username=postgres -c "CREATE DATABASE \"$DB_NAME\" OWNER \"$DB_USER\";" + echo "Database $DB_NAME created." + fi + + # Grant all privileges on the database to the user + kubectl -n $NAMESPACE exec -i postgres-0 -- psql --username=postgres -c "GRANT ALL PRIVILEGES ON DATABASE \"$DB_NAME\" TO \"$DB_USER\";" + echo "Granted all privileges on database $DB_NAME to user $DB_USER." +} + +create_user_and_db faf-apps faf-api DATABASE_USERNAME DATABASE_PASSWORD DATABASE_NAME + +echo "All users and databases have been processed."