diff --git a/.forgejo/workflows/deploy-edge-proxy.yml b/.forgejo/workflows/deploy-edge-proxy.yml deleted file mode 100644 index 87125e3..0000000 --- a/.forgejo/workflows/deploy-edge-proxy.yml +++ /dev/null @@ -1,31 +0,0 @@ -# name: Deploy Edge Proxy -# run-name: ${{ gitea.actor }} Deploy Edge Proxy -# on: -# push: -# branches: [ master ] - -# env: -# GARDEN_DEPLOY_ACTION: minecluster-proxy - -# jobs: -# deploy-edge: -# steps: -# # Setup Oasis -# - name: Oasis Setup -# uses: https://gitea.dunemask.dev/elysium/elysium-actions@oasis-setup-auto -# with: -# deploy-env: edge -# infisical-token: ${{ secrets.INFISICAL_ELYSIUM_EDGE_READ_TOKEN }} -# # Deploy to Edge Cluster -# - name: Deploy to Edge Cluster -# run: garden deploy $GARDEN_DEPLOY_ACTION --force --force-build --env usw-edge -# working-directory: ${{ env.OASIS_WORKSPACE }} -# # Alert via Discord -# - name: Discord Alert -# if: always() -# uses: https://gitea.dunemask.dev/elysium/elysium-actions@discord-status -# with: -# status: ${{ job.status }} -# channel: deployments -# header: DEPLOY EDGE -# additional-content: "Minecluster Proxy" \ No newline at end of file diff --git a/.forgejo/workflows/qa-api-tests.yml b/.forgejo/workflows/qa-api-tests.yml deleted file mode 100644 index 596e11a..0000000 --- a/.forgejo/workflows/qa-api-tests.yml +++ /dev/null @@ -1,42 +0,0 @@ -# name: QA API Tests -# run-name: ${{ gitea.actor }} QA API Test -# on: -# pull_request: -# branches: [ master ] - -# env: -# REPO_DIR: ${{ gitea.workspace }}/minecluster -# GARDEN_LINK_ACTION: build.minecluster-image - -# jobs: -# qa-api-tests: -# steps: -# # Setup Oasis -# - name: Oasis Setup -# uses: https://gitea.dunemask.dev/elysium/elysium-actions@oasis-setup-auto -# with: -# deploy-env: ci -# infisical-token: ${{ secrets.INFISICAL_ELYSIUM_CI_READ_TOKEN }} -# # Test Code -# - name: Checkout repository -# uses: actions/checkout@v3 -# with: -# path: ${{ env.REPO_DIR }} -# # Garden link -# - name: Link Repo code to Garden -# run: garden link action $GARDEN_LINK_ACTION $REPO_DIR --env usw-ci --var cubit-projects=cairo,minecluster -# working-directory: ${{ env.OASIS_WORKSPACE }} -# # Cubit CI Tests -# - name: Run Cubit tests in CI env -# run: garden workflow qa-api-tests --env usw-ci --var ci-ttl=25m -# working-directory: ${{ env.OASIS_WORKSPACE }} -# # Discord Alert -# - name: Discord Alert -# if: always() -# uses: https://gitea.dunemask.dev/elysium/elysium-actions@discord-status -# with: -# status: ${{ job.status }} -# channel: ci -# header: QA API Tests -# additional-content: "CI Namespace: `${{env.CI_NAMESPACE}}`" - \ No newline at end of file diff --git a/.forgejo/workflows/s3-repo-backup.yml b/.forgejo/workflows/s3-repo-backup.yml deleted file mode 100644 index 4e4e7fd..0000000 --- a/.forgejo/workflows/s3-repo-backup.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: S3 Repo Backup -run-name: ${{ forgejo.actor }} S3 Repo Backup -on: - push: - branches: [ master ] - -jobs: - s3-repo-backup: - steps: - - name: S3 Backup - uses: https://forgejo.dunemask.dev/elysium/elysium-actions@s3-backup - with: - infisical-token: ${{ secrets.INFISICAL_ELYSIUM_EDGE_READ_TOKEN }} - infisical-project: ${{ vars.INFISICAL_DEPLOYMENTS_PROJECT_ID }} - - name: Status Alert - if: always() - run: echo "The Job ended with status ${{ job.status }}." diff --git a/.gitea/workflows/deploy-edge-proxy.yml b/.gitea/workflows/deploy-edge-proxy.yml new file mode 100644 index 0000000..c961b21 --- /dev/null +++ b/.gitea/workflows/deploy-edge-proxy.yml @@ -0,0 +1,31 @@ +name: Deploy Edge Proxy +run-name: ${{ gitea.actor }} Deploy Edge Proxy +on: + push: + branches: [ master ] + +env: + GARDEN_DEPLOY_ACTION: minecluster-proxy + +jobs: + deploy-edge: + steps: + # Setup Oasis + - name: Oasis Setup + uses: https://gitea.dunemask.dev/elysium/elysium-actions@oasis-setup-auto + with: + deploy-env: edge + infisical-token: ${{ secrets.INFISICAL_ELYSIUM_EDGE_READ_TOKEN }} + # Deploy to Edge Cluster + - name: Deploy to Edge Cluster + run: garden deploy $GARDEN_DEPLOY_ACTION --force --force-build --env usw-edge + working-directory: ${{ env.OASIS_WORKSPACE }} + # Alert via Discord + - name: Discord Alert + if: always() + uses: https://gitea.dunemask.dev/elysium/elysium-actions@discord-status + with: + status: ${{ job.status }} + channel: deployments + header: DEPLOY EDGE + additional-content: "Minecluster Proxy" \ No newline at end of file diff --git a/.forgejo/workflows/deploy-edge.yml b/.gitea/workflows/deploy-edge.yml similarity index 52% rename from .forgejo/workflows/deploy-edge.yml rename to .gitea/workflows/deploy-edge.yml index afb0c78..04be45d 100644 --- a/.forgejo/workflows/deploy-edge.yml +++ b/.gitea/workflows/deploy-edge.yml @@ -1,8 +1,8 @@ name: Deploy USW-MC -run-name: ${{ forgejo.actor }} Deploy USW-MC +run-name: ${{ gitea.actor }} Deploy USW-MC on: - push: - branches: [master] + push: + branches: [ master ] env: GARDEN_DEPLOY_ACTION: minecluster @@ -10,35 +10,34 @@ env: jobs: deploy-edge: steps: - # Configure proper kubeconfig (Used when cluster does not match the edge environment) + # Configure proper kubeconfig - name: Get usw-mc deployment kubeconfig - uses: https://forgejo.dunemask.dev/elysium/elysium-actions@infisical-env + uses: https://gitea.dunemask.dev/elysium/elysium-actions@infisical-env with: infisical-token: ${{ secrets.INFISICAL_ELYSIUM_EDGE_READ_TOKEN }} - project-id: ${{ vars.INFISICAL_DEPLOYMENTS_PROJECT_ID }} secret-envs: edge - secret-paths: /kubernetes/usw-mc + secret-paths: /kubernetes # Setup Oasis - name: Oasis Setup - uses: https://forgejo.dunemask.dev/elysium/elysium-actions@oasis-setup-auto + uses: https://gitea.dunemask.dev/elysium/elysium-actions@oasis-setup-auto with: deploy-env: edge infisical-token: ${{ secrets.INFISICAL_ELYSIUM_EDGE_READ_TOKEN }} - infisical-project: ${{ vars.INFISICAL_DEPLOYMENTS_PROJECT_ID }} - extra-secret-paths: /dashboard + extra-secret-paths: /alexandria extra-secret-envs: edge + kubeconfig: ${{ env.KUBERNETES_CONFIG_USW_MC }} # Deploy to Edge - name: Deploy to Edge env - run: garden deploy $GARDEN_DEPLOY_ACTION --force --force-build --env usw-edge + run: garden deploy $GARDEN_DEPLOY_ACTION --force --force-build --env usw-mc working-directory: ${{ env.OASIS_WORKSPACE }} - env: # (Used when cluster does not match the edge environment) - MCL_KUBECONFIG: ${{ env.KUBERNETES_CONFIG_USW_MC }} + env: + MCL_KUBECONFIG: ${{ secrets.KUBECONFIG_USW_MC }} # Alert via Discord - name: Discord Alert if: always() - uses: https://forgejo.dunemask.dev/elysium/elysium-actions@discord-status + uses: https://gitea.dunemask.dev/elysium/elysium-actions@discord-status with: status: ${{ job.status }} channel: deployments header: DEPLOY MC - additional-content: "Minecluster Server Manager Deployment" + additional-content: "Minecluster Server Manager Deployment" \ No newline at end of file diff --git a/.gitea/workflows/qa-api-tests.yml b/.gitea/workflows/qa-api-tests.yml new file mode 100644 index 0000000..8222cdf --- /dev/null +++ b/.gitea/workflows/qa-api-tests.yml @@ -0,0 +1,42 @@ +name: QA API Tests +run-name: ${{ gitea.actor }} QA API Test +on: + pull_request: + branches: [ master ] + +env: + REPO_DIR: ${{ gitea.workspace }}/minecluster + GARDEN_LINK_ACTION: build.minecluster-image + +jobs: + qa-api-tests: + steps: + # Setup Oasis + - name: Oasis Setup + uses: https://gitea.dunemask.dev/elysium/elysium-actions@oasis-setup-auto + with: + deploy-env: ci + infisical-token: ${{ secrets.INFISICAL_ELYSIUM_CI_READ_TOKEN }} + # Test Code + - name: Checkout repository + uses: actions/checkout@v3 + with: + path: ${{ env.REPO_DIR }} + # Garden link + - name: Link Repo code to Garden + run: garden link action $GARDEN_LINK_ACTION $REPO_DIR --env usw-ci --var cubit-projects=cairo,minecluster + working-directory: ${{ env.OASIS_WORKSPACE }} + # Cubit CI Tests + - name: Run Cubit tests in CI env + run: garden workflow qa-api-tests --env usw-ci --var ci-ttl=25m + working-directory: ${{ env.OASIS_WORKSPACE }} + # Discord Alert + - name: Discord Alert + if: always() + uses: https://gitea.dunemask.dev/elysium/elysium-actions@discord-status + with: + status: ${{ job.status }} + channel: ci + header: QA API Tests + additional-content: "CI Namespace: `${{env.CI_NAMESPACE}}`" + \ No newline at end of file diff --git a/.gitea/workflows/s3-repo-backup.yml b/.gitea/workflows/s3-repo-backup.yml new file mode 100644 index 0000000..77b0702 --- /dev/null +++ b/.gitea/workflows/s3-repo-backup.yml @@ -0,0 +1,31 @@ +name: S3 Repo Backup +run-name: ${{ gitea.actor }} S3 Repo Backup +on: + push: + branches: [ master ] + +env: + S3_BACKUP_ENDPOINT: https://s3.dunemask.dev + S3_BACKUP_KEY_ID: gitea-repo-backup + S3_BACKUP_KEY: ${{ secrets.S3_REPO_BACKUP_KEY }} + REPO_DIR: ${{ gitea.workspace }}/${{ gitea.respository }} +jobs: + s3-repo-backup: + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + path: ${{ env.REPO_DIR }} + - name: S3 Backup + uses: peter-evans/s3-backup@v1 + env: + ACCESS_KEY_ID: ${{ env.S3_BACKUP_KEY_ID }} + SECRET_ACCESS_KEY: ${{ env.S3_BACKUP_KEY }} + MIRROR_SOURCE: ${{ env.REPO_DIR }} + MIRROR_TARGET: backups/gitea-repositories/${{ gitea.repository }} + STORAGE_SERVICE_URL: ${{env.S3_BACKUP_ENDPOINT}} + with: + args: --overwrite --remove + - name: Status Alert + if: always() + run: echo "The Job ended with status ${{ job.status }}." diff --git a/.gitignore b/.gitignore index 5c86a6a..d570088 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ node_modules/ -.env diff --git a/lib/database/migrations/1_create_servers_table.sql b/lib/database/migrations/1_create_servers_table.sql index 6386fc5..fe3f357 100644 --- a/lib/database/migrations/1_create_servers_table.sql +++ b/lib/database/migrations/1_create_servers_table.sql @@ -1,7 +1,7 @@ CREATE SEQUENCE servers_id_seq; CREATE TABLE servers ( id bigint NOT NULL DEFAULT nextval('servers_id_seq') PRIMARY KEY, - owner_cairo_id varchar(63), + owner_cairo_id bigint, host varchar(255) DEFAULT NULL, name varchar(255) DEFAULT NULL, version varchar(63) DEFAULT 'latest', diff --git a/lib/database/queries/server-queries.js b/lib/database/queries/server-queries.js index 59dea89..feafec2 100644 --- a/lib/database/queries/server-queries.js +++ b/lib/database/queries/server-queries.js @@ -16,10 +16,6 @@ const getMclName = (host, id) => `${host.toLowerCase().replaceAll(".", "-")}-${id}`; export async function checkAuthorization(serverId, cairoId) { - console.log( - `Checking Authorization for user ${cairoId} for serverId ${serverId}`, - ); - if (!cairoId) return false; const q = selectWhereAllQuery(table, { id: serverId, owner_cairo_id: cairoId, diff --git a/lib/k8s/configs/containers/ftp-server.yml b/lib/k8s/configs/containers/ftp-server.yml index 3544592..aade99b 100644 --- a/lib/k8s/configs/containers/ftp-server.yml +++ b/lib/k8s/configs/containers/ftp-server.yml @@ -6,7 +6,7 @@ env: image: garethflowers/ftp-server imagePullPolicy: IfNotPresent livenessProbe: - exec: { command: ["/bin/sh", "-c", "netstat -a | grep -q ftp"] } + exec: { command: ["echo"] } failureThreshold: 20 initialDelaySeconds: 0 periodSeconds: 5 @@ -15,7 +15,7 @@ livenessProbe: name: changeme-name-ftp ports: [] # Programatically add all the ports for easier readability, Ports include: 20,21,40000-400009 readinessProbe: - exec: { command: ["/bin/sh", "-c", "netstat -a | grep -q ftp"] } + exec: { command: ["echo"] } failureThreshold: 20 initialDelaySeconds: 0 periodSeconds: 5 diff --git a/lib/k8s/k8s-config.js b/lib/k8s/k8s-config.js index cbe55b6..4167552 100644 --- a/lib/k8s/k8s-config.js +++ b/lib/k8s/k8s-config.js @@ -9,6 +9,4 @@ try { } catch (e) { kc.loadFromDefault(); } -if(kc.contexts.length === 1) kc.setCurrentContext(kc.contexts[0].name); -if(!kc.currentContext) throw new Error("Could not infer current context! Please set it manually in the Kubeconfig!"); export default kc; diff --git a/lib/routes/auth-route.js b/lib/routes/auth-route.js index 638e163..8409975 100644 --- a/lib/routes/auth-route.js +++ b/lib/routes/auth-route.js @@ -2,14 +2,11 @@ import { Router } from "express"; import cairoAuthMiddleware from "./middlewares/auth-middleware.js"; const router = Router(); -const cairoProjectId = process.env.MCL_CAIRO_PROJECT; -if(!cairoProjectId) throw Error("Cairo Project Required!"); - const ok = (_r, res) => res.sendStatus(200); function cairoRedirect(req, res) { res.redirect( - `${process.env.MCL_CAIRO_URL}/cairo/authenticate?redirectUri=${req.query.redirectUri}&projectId=${cairoProjectId}`, + `${process.env.MCL_CAIRO_URL}/cairo/auth?redirectUri=${req.query.redirectUri}`, ); } diff --git a/lib/routes/middlewares/auth-middleware.js b/lib/routes/middlewares/auth-middleware.js index 5758cb4..8f4318f 100644 --- a/lib/routes/middlewares/auth-middleware.js +++ b/lib/routes/middlewares/auth-middleware.js @@ -4,36 +4,21 @@ import bearerTokenMiddleware from "express-bearer-token"; import { ERR, VERB } from "../../util/logging.js"; // Constants -const { MCL_CAIRO_URL, MCL_CAIRO_PROJECT } = process.env; +const { MCL_CAIRO_URL } = process.env; const cairoAuthMiddleware = Router(); const cairoAuthenticate = async (token) => { const config = { headers: { Authorization: `Bearer ${token}` } }; - return fetch(`${MCL_CAIRO_URL}/api/${MCL_CAIRO_PROJECT}/auth/credentials`, config).then(async (res) => { - if (res.status >= 300) { - const errorMessage = await res - .json() - .then((data) => JSON.stringify(data)) - .catch(() => res.statusText); - throw Error( - `Could not authenticate with user, receieved message: ${errorMessage}`, - ); - } - - return res.json(); - }); + return fetch(`${MCL_CAIRO_URL}/api/user/info`, config).then((res) => + res.json(), + ); }; // Middleware const cairoAuthHandler = (req, res, next) => { if (!req.token) return res.status(401).send("Cairo auth required!"); cairoAuthenticate(req.token) - .then((authData) => { - console.log(authData); - if (!authData?.user?.id) - throw Error(`Cairo didn't return the expected data! ${authData?.user?.id}`); - req.cairoId = authData?.user?.id; - }) + .then((authData) => (req.cairoId = authData.id)) .then(() => next()) .catch((err) => { ERR("AUTH", err.response ? err.response.data : err.message); diff --git a/src/util/auth.js b/src/util/auth.js index 69b9d8c..f25a6bb 100644 --- a/src/util/auth.js +++ b/src/util/auth.js @@ -1,8 +1,8 @@ import { useState, useEffect } from "react"; import { useSearchParams } from "react-router-dom"; -const tokenStorageName = "cairoUserToken"; -const tokenQuery = "cairoUserToken"; +const tokenStorageName = "cairoAuthToken"; +const tokenQuery = "cairoAuthToken"; const verifyAuth = (authToken) => fetch("/api/auth/verify", {