From 92a77d0876dd2451bb1bcb6c8e774e7beef4d79f Mon Sep 17 00:00:00 2001 From: CJ_Clippy Date: Wed, 19 Jun 2024 17:43:25 -0800 Subject: [PATCH] separate staging from prod --- Makefile | 11 ++- apps/base/fp/release.yaml | 3 - apps/base/windmill/.gitkeep | 0 apps/production/fp-values.yaml | 17 ++++ apps/production/kustomization.yaml | 6 +- apps/production/podinfo-values.yaml | 21 ----- apps/staging/chisel/chisel.yaml | 25 ------ apps/staging/chisel/kustomization.yaml | 5 -- apps/staging/fp-values.yaml | 17 ++++ apps/staging/kustomization.yaml | 7 ++ apps/staging/podinfo-values.yaml | 2 +- clusters/staging/apps.yaml | 2 +- clusters/staging/infrastructure.yaml | 1 + infrastructure/configs/cluster-issuers.yaml | 2 +- infrastructure/controllers/cert-manager.yaml | 2 + packages/infra/package.json | 12 +++ packages/infra/pnpm-lock.yaml | 23 +++++ .../infra/vultr-delete-orphaned-resources.js | 84 +++++++++++++++++++ ...ux-bootstrap.sh => flux-bootstrap-prod.sh} | 0 scripts/flux-bootstrap-staging.sh | 17 ++++ scripts/postgres-restore.sh | 5 +- 21 files changed, 197 insertions(+), 65 deletions(-) delete mode 100644 apps/base/windmill/.gitkeep create mode 100644 apps/production/fp-values.yaml delete mode 100644 apps/production/podinfo-values.yaml delete mode 100644 apps/staging/chisel/chisel.yaml delete mode 100644 apps/staging/chisel/kustomization.yaml create mode 100644 apps/staging/fp-values.yaml create mode 100644 packages/infra/package.json create mode 100644 packages/infra/pnpm-lock.yaml create mode 100644 packages/infra/vultr-delete-orphaned-resources.js rename scripts/{flux-bootstrap.sh => flux-bootstrap-prod.sh} (100%) mode change 100755 => 100644 create mode 100755 scripts/flux-bootstrap-staging.sh mode change 100644 => 100755 scripts/postgres-restore.sh diff --git a/Makefile b/Makefile index 739488a..ea46b11 100644 --- a/Makefile +++ b/Makefile @@ -7,12 +7,17 @@ namespaces: secrets: ./scripts/k8s-secrets.sh -flux: - ./scripts/flux-bootstrap.sh +flux-prod: + ./scripts/flux-bootstrap-prod.sh + +flux-staging: + ./scripts/flux-bootstrap-staging.sh dev: kind namespaces secrets chisel velero -prod: namespaces secrets velero flux +prod: namespaces secrets velero flux-prod + +staging: namespaces secrets velero flux-staging velero: ./scripts/velero-create.sh diff --git a/apps/base/fp/release.yaml b/apps/base/fp/release.yaml index d0e9164..dfadb03 100644 --- a/apps/base/fp/release.yaml +++ b/apps/base/fp/release.yaml @@ -42,9 +42,6 @@ spec: url: https://strapi.piko.sbtp.xyz certIssuer: letsencrypt-staging hostname: strapi.futureporn.svc.cluster.local - ingressClassName: ngrok - ngrok: - hostname: grateful-engaging-cicada.ngrok-free.app realtime: imageName: gitea.futureporn.net/futureporn/realtime:latest adminEmail: cj@futureporn.net diff --git a/apps/base/windmill/.gitkeep b/apps/base/windmill/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/apps/production/fp-values.yaml b/apps/production/fp-values.yaml new file mode 100644 index 0000000..c5efa7e --- /dev/null +++ b/apps/production/fp-values.yaml @@ -0,0 +1,17 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: fp + namespace: futureporn +spec: + values: + next: + certIssuer: letsencrypt-prod + hostname: next.futureporn.net + scout: + certIssuer: letsencrypt-prod + cdnBucketUrl: https://futureporn-b2.b-cdn.net + s3BucketName: futureporn-b2 + strapi: + url: https://portal.futureporn.net + hostname: portal.futureporn.net \ No newline at end of file diff --git a/apps/production/kustomization.yaml b/apps/production/kustomization.yaml index 2a8a3de..b1e2a63 100644 --- a/apps/production/kustomization.yaml +++ b/apps/production/kustomization.yaml @@ -1,11 +1,11 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization +namespace: futureporn resources: - - ../base/podinfo - ../base/temporal - ../base/fp patches: - - path: podinfo-values.yaml + - path: fp-values.yaml target: kind: HelmRelease - name: podinfo + name: fp diff --git a/apps/production/podinfo-values.yaml b/apps/production/podinfo-values.yaml deleted file mode 100644 index ec7fe71..0000000 --- a/apps/production/podinfo-values.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: podinfo - namespace: futureporn -spec: - chart: - spec: - version: ">=1.0.0" - values: - ingress: - hosts: - - host: podinfo.sbtp.xyz - paths: - - path: / - pathType: Prefix - backend: - service: - name: podinfo - port: - number: 9898 \ No newline at end of file diff --git a/apps/staging/chisel/chisel.yaml b/apps/staging/chisel/chisel.yaml deleted file mode 100644 index c63a8a8..0000000 --- a/apps/staging/chisel/chisel.yaml +++ /dev/null @@ -1,25 +0,0 @@ - -apiVersion: source.toolkit.fluxcd.io/v1beta2 -kind: GitRepository -metadata: - name: chisel-operator - namespace: futureporn -spec: - interval: 5m - url: https://github.com/FyraLabs/chisel-operator - ref: - branch: master ---- -apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 -kind: Kustomization -metadata: - name: chisel-operator - namespace: futureporn -spec: - interval: 10m - targetNamespace: futureporn - sourceRef: - kind: GitRepository - name: chisel-operator - path: "./kustomize" - prune: true \ No newline at end of file diff --git a/apps/staging/chisel/kustomization.yaml b/apps/staging/chisel/kustomization.yaml deleted file mode 100644 index 624a6a1..0000000 --- a/apps/staging/chisel/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -namespace: futureporn -resources: - - chisel.yaml diff --git a/apps/staging/fp-values.yaml b/apps/staging/fp-values.yaml new file mode 100644 index 0000000..5c71159 --- /dev/null +++ b/apps/staging/fp-values.yaml @@ -0,0 +1,17 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: fp + namespace: futureporn +spec: + values: + next: + certIssuer: letsencrypt-staging + hostname: next.sbtp.xyz + scout: + certIssuer: letsencrypt-staging + cdnBucketUrl: https://fp-dev.b-cdn.net + s3BucketName: fp-dev + strapi: + url: https://strapi.sbtp.xyz + hostname: strapi.sbtp.xyz \ No newline at end of file diff --git a/apps/staging/kustomization.yaml b/apps/staging/kustomization.yaml index fd28a65..7678aff 100644 --- a/apps/staging/kustomization.yaml +++ b/apps/staging/kustomization.yaml @@ -3,7 +3,14 @@ kind: Kustomization namespace: futureporn resources: - ../base/podinfo + - ../base/temporal + - ../base/fp patches: - path: podinfo-values.yaml target: kind: HelmRelease + name: podinfo + - path: fp-values.yaml + target: + kind: HelmRelease + name: fp diff --git a/apps/staging/podinfo-values.yaml b/apps/staging/podinfo-values.yaml index a1f71e6..6e7eaa0 100644 --- a/apps/staging/podinfo-values.yaml +++ b/apps/staging/podinfo-values.yaml @@ -12,7 +12,7 @@ spec: values: ingress: hosts: - - host: podinfo.staging + - host: podinfo.sbtp.xyz paths: - path: / pathType: ImplementationSpecific diff --git a/clusters/staging/apps.yaml b/clusters/staging/apps.yaml index 71e5f2f..ff4fd05 100644 --- a/clusters/staging/apps.yaml +++ b/clusters/staging/apps.yaml @@ -4,7 +4,7 @@ metadata: name: apps namespace: flux-system spec: - interval: 10m0s + interval: 1m0s dependsOn: - name: infra-configs sourceRef: diff --git a/clusters/staging/infrastructure.yaml b/clusters/staging/infrastructure.yaml index ce67ceb..e2e688b 100644 --- a/clusters/staging/infrastructure.yaml +++ b/clusters/staging/infrastructure.yaml @@ -14,6 +14,7 @@ spec: path: ./infrastructure/controllers prune: true wait: true + --- apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization diff --git a/infrastructure/configs/cluster-issuers.yaml b/infrastructure/configs/cluster-issuers.yaml index c450efd..233df56 100644 --- a/infrastructure/configs/cluster-issuers.yaml +++ b/infrastructure/configs/cluster-issuers.yaml @@ -6,7 +6,7 @@ metadata: spec: acme: # Replace the email address with your own contact email - email: fluxcdbot@users.noreply.github.com + email: cj@futureporn.net # The server is replaced in /clusters/production/infrastructure.yaml server: https://acme-staging-v02.api.letsencrypt.org/directory privateKeySecretRef: diff --git a/infrastructure/controllers/cert-manager.yaml b/infrastructure/controllers/cert-manager.yaml index 2ac4bef..85d17e2 100644 --- a/infrastructure/controllers/cert-manager.yaml +++ b/infrastructure/controllers/cert-manager.yaml @@ -3,6 +3,7 @@ apiVersion: v1 kind: Namespace metadata: name: cert-manager + --- apiVersion: source.toolkit.fluxcd.io/v1 kind: HelmRepository @@ -12,6 +13,7 @@ metadata: spec: interval: 24h url: https://charts.jetstack.io + --- apiVersion: helm.toolkit.fluxcd.io/v2 kind: HelmRelease diff --git a/packages/infra/package.json b/packages/infra/package.json new file mode 100644 index 0000000..8a5abbd --- /dev/null +++ b/packages/infra/package.json @@ -0,0 +1,12 @@ +{ + "name": "scripts", + "type": "module", + "version": "1.0.0", + "description": "", + "keywords": [], + "author": "", + "license": "Unlicense", + "dependencies": { + "dotenv": "^16.4.5" + } +} diff --git a/packages/infra/pnpm-lock.yaml b/packages/infra/pnpm-lock.yaml new file mode 100644 index 0000000..28a12ba --- /dev/null +++ b/packages/infra/pnpm-lock.yaml @@ -0,0 +1,23 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + dotenv: + specifier: ^16.4.5 + version: 16.4.5 + +packages: + + dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} + +snapshots: + + dotenv@16.4.5: {} diff --git a/packages/infra/vultr-delete-orphaned-resources.js b/packages/infra/vultr-delete-orphaned-resources.js new file mode 100644 index 0000000..7820e82 --- /dev/null +++ b/packages/infra/vultr-delete-orphaned-resources.js @@ -0,0 +1,84 @@ +#!/usr/bin/env node + + +import dotenv from 'dotenv' +dotenv.config({ path: '../../.env' }) + +const apiV2Base = 'https://api.vultr.com/v2' + + +if (!process.env.VULTR_API_KEY) throw new Error('VULTR_API_KEY is missing in env'); + + + +async function deleteOrphanedLoadBalancers() { + console.log('getting load balancers') + const loadBalancersRes = await fetch(`${apiV2Base}/load-balancers`, { + method: 'GET', + headers: { + 'authorization': `Bearer ${process.env.VULTR_API_KEY}` + } + }) + const loadBalancerJson = await loadBalancersRes.json() + const orphanedLoadBalancers = loadBalancerJson.load_balancers.filter((lb) => (lb.instances.length === 0)) + console.log(`found ${orphanedLoadBalancers.length} orphaned load balancers.`) + console.log('waiting 1 second') + await new Promise((resolve) => { setTimeout(resolve, 1000) }) + + for (const lb of orphanedLoadBalancers) { + console.log(`deleting load balancer ${lb.id}`) + + const deleteLoadBalancerRes = await fetch(`https://api.vultr.com/v2/load-balancers/${lb.id}`, { + method: 'DELETE', + headers: { + 'Authorization': `Bearer ${process.env.VULTR_API_KEY}` + } + }) + + console.log('waiting 1 second') + await new Promise((resolve) => { setTimeout(resolve, 1000) }) + } +} + + +async function deleteOrphanedBlockStorage() { + console.log('getting block storage') + + const blocksRes = await fetch(`${apiV2Base}/blocks`, { + method: 'GET', + headers: { + 'authorization': `Bearer ${process.env.VULTR_API_KEY}` + } + }) + const blocksJson = await blocksRes.json() + + const orphanedBlocks = blocksJson.blocks.filter((b) => b.attached_to_instance === '') + console.log(`found ${orphanedBlocks.length} orphaned block storages`) + + console.log('waiting 1 second') + await new Promise((resolve) => { setTimeout(resolve, 1000) }) + for (const block of orphanedBlocks) { + console.log(`deleting block ${block.id}`) + + const deleteBlocksRes = await fetch(`${apiV2Base}/blocks/${block.id}`, { + method: 'DELETE', + headers: { + 'Authorization': `Bearer ${process.env.VULTR_API_KEY}` + } + }) + + console.log('waiting 1 second') + await new Promise((resolve) => { setTimeout(resolve, 1000) }) + + } + + +} + + +async function main() { + await deleteOrphanedLoadBalancers() + await deleteOrphanedBlockStorage() +} + +main() diff --git a/scripts/flux-bootstrap.sh b/scripts/flux-bootstrap-prod.sh old mode 100755 new mode 100644 similarity index 100% rename from scripts/flux-bootstrap.sh rename to scripts/flux-bootstrap-prod.sh diff --git a/scripts/flux-bootstrap-staging.sh b/scripts/flux-bootstrap-staging.sh new file mode 100755 index 0000000..afcb3ea --- /dev/null +++ b/scripts/flux-bootstrap-staging.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +## this way is annoying because deployment asks for git password +# flux bootstrap git \ +# --kubeconfig /home/cj/.kube/vke.yaml \ +# --url=https://gitea.futureporn.net/futureporn/fp.git \ +# --branch=main \ +# --username=cj_clippy \ +# --token-auth=true \ +# --path=clusters/staging + +## this way is more automatic although it does ask for yes/no confirmation that the ssh key has repo access +flux bootstrap git \ + --url="ssh://git@gitea.futureporn.net:2222/futureporn/fp" \ + --branch=main \ + --path="clusters/staging" \ + --private-key-file=/home/cj/.ssh/fp-flux \ No newline at end of file diff --git a/scripts/postgres-restore.sh b/scripts/postgres-restore.sh old mode 100644 new mode 100755 index 1491393..c44906a --- a/scripts/postgres-restore.sh +++ b/scripts/postgres-restore.sh @@ -1,5 +1,6 @@ #!/bin/bash +dbname=2024-06-19_22-24-03-futureporn-db.psql ## drop futureporn_db kubectl -n futureporn exec postgres -- psql -U postgres --command "DROP DATABASE futureporn_db;" @@ -26,6 +27,6 @@ kubectl -n futureporn exec postgres -- psql -U postgres --command "\ # kubectl exec -i POD_NAME -- pg_restore -U USERNAME -C -d DATABASE < dump.sql -kubectl -n futureporn cp /home/cj/Documents/futureporn-meta/backups/2024-06-18_20-35-38-futureporn-db.psql postgres:/tmp/db.psql +kubectl -n futureporn cp /home/cj/Documents/futureporn-meta/backups/$dbname postgres:/tmp/db.psql kubectl -n futureporn exec -i postgres -- pg_restore -U postgres -d futureporn_db /tmp/db.psql -# kubectl -n futureporn exec -ti db-postgresql-0 -- rm /tmp/db.psql \ No newline at end of file +# kubectl -n futureporn exec -ti db-postgresql-0 -- rm /tmp/db.psql