From 571b9786345adba361e2cfd552f34f1dfce1a2f9 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Sat, 13 Dec 2025 17:01:02 +0000 Subject: [PATCH 1/2] add to main --- db/atlas/migrations/0001_init.sql | 5 - db/atlas/migrations/0002_auth.sql | 6 - db/atlas/migrations/0003_stripe_xero.sql | 13 -- db/k8s/secrets/postgres-secret.yaml | 5 + github_runner/install/install_arc.sh | 224 +++++++---------------- 5 files changed, 68 insertions(+), 185 deletions(-) delete mode 100644 db/atlas/migrations/0001_init.sql delete mode 100644 db/atlas/migrations/0002_auth.sql delete mode 100644 db/atlas/migrations/0003_stripe_xero.sql diff --git a/db/atlas/migrations/0001_init.sql b/db/atlas/migrations/0001_init.sql deleted file mode 100644 index 22d8741..0000000 --- a/db/atlas/migrations/0001_init.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE TABLE users ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - email TEXT NOT NULL UNIQUE, - created_at TIMESTAMPTZ NOT NULL DEFAULT now() -); diff --git a/db/atlas/migrations/0002_auth.sql b/db/atlas/migrations/0002_auth.sql deleted file mode 100644 index 41fa9fb..0000000 --- a/db/atlas/migrations/0002_auth.sql +++ /dev/null @@ -1,6 +0,0 @@ -CREATE TABLE sessions ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, - expires_at TIMESTAMPTZ NOT NULL, - created_at TIMESTAMPTZ NOT NULL DEFAULT now() -); diff --git a/db/atlas/migrations/0003_stripe_xero.sql b/db/atlas/migrations/0003_stripe_xero.sql deleted file mode 100644 index b4ad422..0000000 --- a/db/atlas/migrations/0003_stripe_xero.sql +++ /dev/null @@ -1,13 +0,0 @@ -CREATE TABLE stripe_accounts ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - user_id UUID NOT NULL REFERENCES users(id), - stripe_account_id TEXT NOT NULL, - created_at TIMESTAMPTZ NOT NULL DEFAULT now() -); - -CREATE TABLE xero_connections ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - user_id UUID NOT NULL REFERENCES users(id), - tenant_id TEXT NOT NULL, - created_at TIMESTAMPTZ NOT NULL DEFAULT now() -); diff --git a/db/k8s/secrets/postgres-secret.yaml b/db/k8s/secrets/postgres-secret.yaml index ab14b37..755f315 100644 --- a/db/k8s/secrets/postgres-secret.yaml +++ b/db/k8s/secrets/postgres-secret.yaml @@ -7,3 +7,8 @@ stringData: POSTGRES_USER: postgres POSTGRES_PASSWORD: averysecretpasswordPersonAppleWinter938 POSTGRES_DB: stripe_invoice + DB_USER: postgres + DB_PASSWORD: averysecretpasswordPersonAppleWinter938 + DB_NAME: stripe_invoice + DB_HOST: postgres + DB_PORT: "5432" diff --git a/github_runner/install/install_arc.sh b/github_runner/install/install_arc.sh index 0ec4373..c2f4fde 100644 --- a/github_runner/install/install_arc.sh +++ b/github_runner/install/install_arc.sh @@ -1,179 +1,81 @@ #!/bin/bash -set -ex +set -euo pipefail -# ===================================================================== -# OPTIONAL — MicroK8s setup/reset steps (only use when doing a hard reset) -# ===================================================================== -# sudo microk8s reset --destroy-storage -# sudo snap remove microk8s -# sudo snap install microk8s --classic -# sudo microk8s enable dns rbac hostpath-storage host-access metrics-server ingress -# sudo microk8s enable metallb:192.168.0.200-192.168.0.220 +# ========================================================== +# FIRST SETUP SCRIPT — mist / microk8s # -# # Rebuild kubeconfig for your local user (optional) -# microk8s kubectl config view --raw > ~/.kube/config -# chmod 600 ~/.kube/config -# sudo usermod -aG microk8s $USER -# sudo chown -f -R $USER ~/.kube +# PURPOSE: +# - Bootstrap a fresh machine +# - Install & configure microk8s +# - Enable required core addons +# - Apply cluster-wide RBAC from YAML +# +# RUN: +# - Once on a fresh host +# - Or again after a full microk8s reset +# +# DOES NOT: +# - Deploy apps +# - Deploy databases +# - Contain RBAC logic inline +# +# All ongoing infra changes should be done via: +# - YAML (db/k8s/**) +# - GitHub Actions +# ========================================================== -NAMESPACE="arc-systems" -RUNNER_NAME="mealcraft-runners" +echo "=== [1/6] Installing microk8s (if needed) ===" -# # ===================================================================== -# # Remove previous ARC installation (safe even if missing) -# # ===================================================================== -# helm uninstall arc -n "${NAMESPACE}" || true -# helm uninstall "${RUNNER_NAME}" -n "${NAMESPACE}" || true +if ! command -v microk8s >/dev/null 2>&1; then + sudo snap install microk8s --classic +else + echo "microk8s already installed" +fi -# echo "=== Installing ARC Scale Set Controller ===" +echo "=== [2/6] Adding current user to microk8s group ===" -# helm install arc \ -# --namespace "${NAMESPACE}" \ -# --create-namespace \ -# oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller +sudo usermod -aG microk8s "$USER" -# echo "=== Installing MealCraft Runner Scale Set (NO Docker-in-Docker) ===" +# Required so kubectl works without sudo +sudo chown -f -R "$USER" ~/.kube || true -# helm install "${RUNNER_NAME}" \ -# --namespace "${NAMESPACE}" \ -# --create-namespace \ -# --set runnerScaleSetName="${RUNNER_NAME}" \ -# --set githubConfigUrl="https://github.com/MealCraft" \ -# --set githubConfigSecret.name="github-secret" \ -# --set githubConfigSecret.github_token="$GITHUB_PAT" \ -# --set dockerInDockerEnabled=false \ -# --set containerMode.type="runner" \ -# --set runnerLabels[0]="mealcraft" \ -# oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set +echo "=== [3/6] Enabling core microk8s addons ===" -# # ===================================================================== -# # RBAC — IMPORTANT -# # Grants permissions to the exact ARC runner SA detected earlier. -# # ===================================================================== +# These are the foundations everything else depends on +sudo microk8s enable \ + dns \ + rbac \ + hostpath-storage \ + host-access \ + metrics-server \ + ingress -echo "=== Applying RBAC for all ARC runners + Traefik ===" +# Optional: MetalLB (only if you need L2 IPs) +# sudo microk8s enable metallb:192.168.0.200-192.168.0.220 -microk8s kubectl apply -f - < ~/.kube/config +chmod 600 ~/.kube/config - # ---------------------------------------------------- - # Traefik v1 CRDs (old MicroK8s installs) - # ---------------------------------------------------- - - apiGroups: ["traefik.containo.us"] - resources: ["*"] - verbs: ["*"] +echo "=== [6/6] Applying cluster RBAC (infra deployer role) ===" - # ---------------------------------------------------- - # Traefik v2 CRDs (modern) - # ---------------------------------------------------- - - apiGroups: ["traefik.io"] - resources: - - ingressroutes - - ingressroutetcps - - ingressrouteudps - - middlewares - - middlewaretcps - - traefikservices - - tlsoptions - - tlsstores - - serverstransports - verbs: ["*"] +# IMPORTANT: +# RBAC is fully declarative and lives in YAML. +# Extend permissions by editing the YAML — NOT this script. +microk8s kubectl apply -f db/k8s/rbac/infra-deployer-rbac.yaml - # ---------------------------------------------------- - # CRDs - # ---------------------------------------------------- - - apiGroups: ["apiextensions.k8s.io"] - resources: ["customresourcedefinitions"] - verbs: ["*"] - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: mealcraft-bootstrap-binding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: mealcraft-bootstrap-role -subjects: - - kind: ServiceAccount - name: mealcraft-runners-gha-rs-no-permission - namespace: arc-systems -EOF - -microk8s kubectl apply -f - < Date: Sat, 13 Dec 2025 17:01:33 +0000 Subject: [PATCH 2/2] init scripts --- .../stripe_invoice/migrations/0001_init.sql | 5 + .../stripe_invoice/migrations/0002_auth.sql | 6 + .../migrations/0003_stripe_xero.sql | 13 ++ db/k8s/pgadmin/deployment.yaml | 87 ++++++++++++ github_runner/install/rbac.yaml | 132 ++++++++++++++++++ 5 files changed, 243 insertions(+) create mode 100644 db/atlas/stripe_invoice/migrations/0001_init.sql create mode 100644 db/atlas/stripe_invoice/migrations/0002_auth.sql create mode 100644 db/atlas/stripe_invoice/migrations/0003_stripe_xero.sql create mode 100644 db/k8s/pgadmin/deployment.yaml create mode 100644 github_runner/install/rbac.yaml diff --git a/db/atlas/stripe_invoice/migrations/0001_init.sql b/db/atlas/stripe_invoice/migrations/0001_init.sql new file mode 100644 index 0000000..22d8741 --- /dev/null +++ b/db/atlas/stripe_invoice/migrations/0001_init.sql @@ -0,0 +1,5 @@ +CREATE TABLE users ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + email TEXT NOT NULL UNIQUE, + created_at TIMESTAMPTZ NOT NULL DEFAULT now() +); diff --git a/db/atlas/stripe_invoice/migrations/0002_auth.sql b/db/atlas/stripe_invoice/migrations/0002_auth.sql new file mode 100644 index 0000000..41fa9fb --- /dev/null +++ b/db/atlas/stripe_invoice/migrations/0002_auth.sql @@ -0,0 +1,6 @@ +CREATE TABLE sessions ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + expires_at TIMESTAMPTZ NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT now() +); diff --git a/db/atlas/stripe_invoice/migrations/0003_stripe_xero.sql b/db/atlas/stripe_invoice/migrations/0003_stripe_xero.sql new file mode 100644 index 0000000..b4ad422 --- /dev/null +++ b/db/atlas/stripe_invoice/migrations/0003_stripe_xero.sql @@ -0,0 +1,13 @@ +CREATE TABLE stripe_accounts ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_id UUID NOT NULL REFERENCES users(id), + stripe_account_id TEXT NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +CREATE TABLE xero_connections ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_id UUID NOT NULL REFERENCES users(id), + tenant_id TEXT NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT now() +); diff --git a/db/k8s/pgadmin/deployment.yaml b/db/k8s/pgadmin/deployment.yaml new file mode 100644 index 0000000..6618da2 --- /dev/null +++ b/db/k8s/pgadmin/deployment.yaml @@ -0,0 +1,87 @@ +# ================================================== +# pgAdmin Secret +# ================================================== +apiVersion: v1 +kind: Secret +metadata: + name: pgadmin-secret +type: Opaque +stringData: + PGADMIN_DEFAULT_EMAIL: admin@juntekim.com + PGADMIN_DEFAULT_PASSWORD: PersonAppleWinter938 + +--- +# ================================================== +# pgAdmin Deployment (STATELESS) +# ================================================== +apiVersion: apps/v1 +kind: Deployment +metadata: + name: pgadmin +spec: + replicas: 1 + selector: + matchLabels: + app: pgadmin + template: + metadata: + labels: + app: pgadmin + spec: + containers: + - name: pgadmin + image: dpage/pgadmin4:latest + ports: + - containerPort: 80 + envFrom: + - secretRef: + name: pgadmin-secret + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 10 + periodSeconds: 10 + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 30 + periodSeconds: 20 + +--- +# ================================================== +# pgAdmin Service +# ================================================== +apiVersion: v1 +kind: Service +metadata: + name: pgadmin +spec: + type: ClusterIP + selector: + app: pgadmin + ports: + - port: 80 + targetPort: 80 + +--- +# ================================================== +# Traefik IngressRoute +# ================================================== +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: pgadmin +spec: + entryPoints: + - websecure + routes: + - match: Host(`pgadmin.juntekim.com`) + kind: Rule + services: + - name: pgadmin + port: 80 + tls: + certResolver: myresolver + diff --git a/github_runner/install/rbac.yaml b/github_runner/install/rbac.yaml new file mode 100644 index 0000000..9107fcf --- /dev/null +++ b/github_runner/install/rbac.yaml @@ -0,0 +1,132 @@ +# ========================================================= +# ClusterRole: Infra Deployer +# +# Used by: +# - GitHub ARC runners +# - Infrastructure deployment workflows +# +# Allows managing: +# - Postgres +# - Jobs / CronJobs (migrations, backups) +# - Traefik resources +# - Storage primitives +# +# Extend this file when infra needs grow. +# ========================================================= +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: infra-deployer-role +rules: + + # ----------------------------------------------------- + # Core Kubernetes resources + # ----------------------------------------------------- + - apiGroups: [""] + resources: + - pods + - services + - endpoints + - configmaps + - secrets + - namespaces + - serviceaccounts + - persistentvolumes + - persistentvolumeclaims + - nodes + verbs: ["*"] + + # ----------------------------------------------------- + # Apps (Deployments, StatefulSets, etc.) + # ----------------------------------------------------- + - apiGroups: ["apps"] + resources: + - deployments + - statefulsets + - daemonsets + - replicasets + verbs: ["*"] + + # ----------------------------------------------------- + # Batch workloads (THIS FIXES YOUR ISSUE) + # Jobs + CronJobs for: + # - DB backups + # - Atlas migrations + # ----------------------------------------------------- + - apiGroups: ["batch"] + resources: + - jobs + - cronjobs + verbs: ["*"] + + # ----------------------------------------------------- + # Networking & Ingress + # ----------------------------------------------------- + - apiGroups: ["networking.k8s.io", "extensions"] + resources: + - ingresses + - ingressclasses + verbs: ["*"] + + # ----------------------------------------------------- + # Traefik CRDs (v1 + v2) + # ----------------------------------------------------- + - apiGroups: ["traefik.containo.us"] + resources: ["*"] + verbs: ["*"] + + - apiGroups: ["traefik.io"] + resources: + - ingressroutes + - ingressroutetcps + - ingressrouteudps + - middlewares + - middlewaretcps + - traefikservices + - tlsoptions + - tlsstores + - serverstransports + verbs: ["*"] + + # ----------------------------------------------------- + # CRD management (required for Traefik & others) + # ----------------------------------------------------- + - apiGroups: ["apiextensions.k8s.io"] + resources: + - customresourcedefinitions + verbs: ["*"] + +--- +# ========================================================= +# ClusterRoleBinding: Bind Infra Deployer to ARC runners +# ========================================================= +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: infra-deployer-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: infra-deployer-role +subjects: + - kind: ServiceAccount + name: mealcraft-runners-gha-rs-no-permission + namespace: arc-systems + +--- +# ========================================================= +# ClusterRoleBinding: Bind same role to Traefik +# (Traefik needs wide read/watch permissions) +# ========================================================= +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: infra-deployer-traefik-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: infra-deployer-role +subjects: + - kind: ServiceAccount + name: traefik-ingress-controller + namespace: default