Revert "format"

This reverts commit d32d48a188c0cbb0af7cf8c706dc64e8dea2acc2.
This commit is contained in:
Ishaan Dey 2024-05-13 20:38:01 -07:00
parent d32d48a188
commit 2f46cfd5d3
3 changed files with 135 additions and 981 deletions

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,6 @@
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@google-cloud/container": "^5.12.0",
"@kubernetes/client-node": "^0.21.0", "@kubernetes/client-node": "^0.21.0",
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
@ -20,11 +19,11 @@
"zod": "^3.23.6" "zod": "^3.23.6"
}, },
"devDependencies": { "devDependencies": {
"typescript": "^5.4.5",
"@types/cors": "^2.8.17", "@types/cors": "^2.8.17",
"@types/express": "^4.17.21", "@types/express": "^4.17.21",
"@types/node": "^20.12.8", "@types/node": "^20.12.8",
"nodemon": "^3.1.0", "nodemon": "^3.1.0",
"ts-node": "^10.9.2", "ts-node": "^10.9.2"
"typescript": "^5.4.5"
} }
} }

View File

@ -1,152 +1,159 @@
import express, { Express, Request, Response } from "express"; import express, { Express, Request, Response } from "express"
import dotenv from "dotenv"; import dotenv from "dotenv"
import fs from "fs"; import fs from "fs"
import yaml from "yaml"; import yaml from "yaml"
import path from "path"; import path from "path"
import cors from "cors"; import cors from "cors"
import { import {
KubeConfig, KubeConfig,
AppsV1Api, AppsV1Api,
CoreV1Api, CoreV1Api,
NetworkingV1Api, NetworkingV1Api,
} from "@kubernetes/client-node"; } from "@kubernetes/client-node"
import { z } from "zod"; import { z } from "zod"
const app = express()
const port = process.env.PORT || 8080
app.use(express.json())
dotenv.config()
const app = express();
const port = process.env.PORT || 8080;
app.use(express.json());
dotenv.config();
// const corsOptions = { // const corsOptions = {
// origin: ['http://localhost:3000', 'https://s.ishaand.com', 'http://localhost:4000', /\.ws\.ishaand\.com$/], // origin: ['http://localhost:3000', 'https://s.ishaand.com', 'http://localhost:4000', /\.ws\.ishaand\.com$/],
// } // }
// app.use(cors(corsOptions)) // app.use(cors(corsOptions))
app.use(cors()); app.use(cors())
const kubeconfig = new KubeConfig(); const kubeconfig = new KubeConfig()
// if (process.env.NODE_ENV !== "deployment") {
console.log("GKE_CLUSTER_SERVER", process.env.GKE_CLUSTER_SERVER); kubeconfig.loadFromOptions({
console.log(
"GKE_CLUSTER_CA_DATA",
process.env.GKE_CLUSTER_CA_DATA?.slice(0, 36)
);
kubeconfig.loadFromOptions({
clusters: [ clusters: [
{ {
name: "gke_sylvan-epoch-422219-f9_us-central1_sandbox-cluster", name: 'gke_sylvan-epoch-422219-f9_us-central1_sandbox-cluster',
server: process.env.GKE_CLUSTER_SERVER!, server: process.env.GKE_CLUSTER_SERVER!,
caData: process.env.GKE_CLUSTER_CA_DATA, caData: process.env.GKE_CLUSTER_CA_DATA,
}, }
], ],
users: [ users: [
{ {
name: "gke_sylvan-epoch-422219-f9_us-central1_sandbox-cluster", name: 'gke_sylvan-epoch-422219-f9_us-central1_sandbox-cluster',
exec: { exec: {
apiVersion: "client.authentication.k8s.io/v1beta1", apiVersion: 'client.authentication.k8s.io/v1beta1',
command: "gke-gcloud-auth-plugin", command: 'gke-gcloud-auth-plugin',
installHint: installHint: 'Install gke-gcloud-auth-plugin for use with kubectl by following https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl#install_plugin',
"Install gke-gcloud-auth-plugin for use with kubectl by following https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl#install_plugin", interactiveMode: 'IfAvailable',
interactiveMode: "IfAvailable", provideClusterInfo: true
provideClusterInfo: true, }
}, }
},
], ],
contexts: [ contexts: [
{ {
name: "gke_sylvan-epoch-422219-f9_us-central1_sandbox-cluster", name: 'gke_sylvan-epoch-422219-f9_us-central1_sandbox-cluster',
cluster: "gke_sylvan-epoch-422219-f9_us-central1_sandbox-cluster", cluster: 'gke_sylvan-epoch-422219-f9_us-central1_sandbox-cluster',
user: "gke_sylvan-epoch-422219-f9_us-central1_sandbox-cluster", user: 'gke_sylvan-epoch-422219-f9_us-central1_sandbox-cluster'
}, }
], ],
currentContext: "gke_sylvan-epoch-422219-f9_us-central1_sandbox-cluster", currentContext: "gke_sylvan-epoch-422219-f9_us-central1_sandbox-cluster"
}); });
// }
// kubeconfig.loadFromDefault()
const appsV1Api = kubeconfig.makeApiClient(AppsV1Api); const appsV1Api = kubeconfig.makeApiClient(AppsV1Api)
const coreV1Api = kubeconfig.makeApiClient(CoreV1Api); const coreV1Api = kubeconfig.makeApiClient(CoreV1Api)
const networkingV1Api = kubeconfig.makeApiClient(NetworkingV1Api); const networkingV1Api = kubeconfig.makeApiClient(NetworkingV1Api)
const readAndParseKubeYaml = ( const readAndParseKubeYaml = (
filePath: string, filePath: string,
sandboxId: string sandboxId: string
): Array<any> => { ): Array<any> => {
const fileContent = fs.readFileSync(filePath, "utf8"); const fileContent = fs.readFileSync(filePath, "utf8")
const docs = yaml.parseAllDocuments(fileContent).map((doc) => { const docs = yaml.parseAllDocuments(fileContent).map((doc) => {
let docString = doc.toString(); let docString = doc.toString()
const regex = new RegExp(`<SANDBOX>`, "g"); const regex = new RegExp(`<SANDBOX>`, "g")
docString = docString.replace(regex, sandboxId); docString = docString.replace(regex, sandboxId)
if (!process.env.CF_API_TOKEN) { if (!process.env.CF_API_TOKEN) {
throw new Error("CF_API_TOKEN is not defined"); throw new Error("CF_API_TOKEN is not defined")
} }
const regexEnv1 = new RegExp(`<CF_API_TOKEN>`, "g"); const regexEnv1 = new RegExp(`<CF_API_TOKEN>`, "g")
docString = docString.replace(regexEnv1, process.env.CF_API_TOKEN); docString = docString.replace(regexEnv1, process.env.CF_API_TOKEN)
if (!process.env.CF_USER_ID) { if (!process.env.CF_USER_ID) {
throw new Error("CF_USER_ID is not defined"); throw new Error("CF_USER_ID is not defined")
} }
const regexEnv2 = new RegExp(`<CF_USER_ID>`, "g"); const regexEnv2 = new RegExp(`<CF_USER_ID>`, "g")
docString = docString.replace(regexEnv2, process.env.CF_USER_ID); docString = docString.replace(regexEnv2, process.env.CF_USER_ID)
return yaml.parse(docString); return yaml.parse(docString)
}); })
return docs; return docs
}; }
const dataSchema = z.object({ const dataSchema = z.object({
userId: z.string(), userId: z.string(),
sandboxId: z.string(), sandboxId: z.string(),
}); })
const namespace = "ingress-nginx"; const namespace = "ingress-nginx"
app.post("/test", async (req, res) => { app.post("/test", async (req, res) => {
const pods = await coreV1Api.listNamespacedPod(namespace); const pods = await coreV1Api.listNamespacedPod(namespace)
res.status(200).send({ res.status(200).send({ pods: pods.body.items.map(item => item?.metadata?.generateName), message: "Orchestrator is up and running." })
pods: pods.body.items.map((item) => item?.metadata?.generateName),
message: "Orchestrator is up and running.",
});
// res.status(200).send({ message: "Orchestrator is up and running." }) // res.status(200).send({ message: "Orchestrator is up and running." })
}); })
app.post("/start", async (req, res) => { app.post("/start", async (req, res) => {
const { sandboxId } = dataSchema.parse(req.body); const { sandboxId } = dataSchema.parse(req.body)
// async function main() {
// const client = new container.v1.ClusterManagerClient();
// async function quickstart() {
// const zone = 'us-central1-a';
// const projectId = await client.getProjectId();
// const request = {
// projectId: projectId,
// zone: zone,
// };
// const [response] = await client.listClusters(request);
// console.log('Clusters: ', response);
// }
// quickstart();
// }
// main().catch(console.error);
try { try {
console.log("Creating resources for sandbox", sandboxId);
console.log("Creating resources for sandbox", sandboxId)
const kubeManifests = readAndParseKubeYaml( const kubeManifests = readAndParseKubeYaml(
path.join(__dirname, "../service.yaml"), path.join(__dirname, "../service.yaml"),
sandboxId sandboxId
); )
async function resourceExists(api: any, getMethod: string, name: string) { async function resourceExists(api: any, getMethod: string, name: string) {
try { try {
await api[getMethod](name, namespace); await api[getMethod](name, namespace)
return true; return true
} catch (e: any) { } catch (e: any) {
if (e.response && e.response.statusCode === 404) { if (e.response && e.response.statusCode === 404) {
console.log( console.log("Resource does not exist.", e.response.body.message, e.response.body.details)
"Resource does not exist.", return false
e.response.body.message,
e.response.body.details
);
return false;
} }
throw e; throw e
} }
} }
const createResource = async (api: any, method: string, manifest: any) => { const createResource = async (api: any, method: string, manifest: any) => {
const { const { kind, metadata: { name } } = manifest;
kind, if (!(await resourceExists(api, 'readNamespaced' + kind, name))) {
metadata: { name }, await api['createNamespaced' + kind](namespace, manifest);
} = manifest;
if (!(await resourceExists(api, "readNamespaced" + kind, name))) {
await api["createNamespaced" + kind](namespace, manifest);
console.log(`Created ${kind.toLowerCase()}`, name); console.log(`Created ${kind.toLowerCase()}`, name);
} else { } else {
console.log(`${kind} ${name} already exists.`); console.log(`${kind} ${name} already exists.`);
@ -154,77 +161,74 @@ app.post("/start", async (req, res) => {
}; };
const promises = kubeManifests.map(async (manifest) => { const promises = kubeManifests.map(async (manifest) => {
const { const { kind, metadata: { name } } = manifest
kind,
metadata: { name },
} = manifest;
console.log("Kind:", kind); console.log("Kind:", kind)
switch (manifest.kind) { switch (manifest.kind) {
case "Deployment": case 'Deployment':
return createResource(appsV1Api, "Deployment", manifest); return createResource(appsV1Api, 'Deployment', manifest);
case "Service": case 'Service':
return createResource(coreV1Api, "Service", manifest); return createResource(coreV1Api, 'Service', manifest);
case "Ingress": case 'Ingress':
return createResource(networkingV1Api, "Ingress", manifest); return createResource(networkingV1Api, 'Ingress', manifest);
default: default:
console.error("Unsupported kind:", manifest.kind); console.error("Unsupported kind:", manifest.kind);
return Promise.reject("Unsupported kind: " + manifest.kind); return Promise.reject("Unsupported kind: " + manifest.kind);
} }
}); })
await Promise.all(promises); await Promise.all(promises)
console.log("All done!"); console.log("All done!")
res.status(200).send({ message: "Resources created." }); res.status(200).send({ message: "Resources created." })
} catch (error: any) { } catch (error: any) {
const body = error.response.body; const body = error.response.body
console.log("Failed to create resources", error); console.log("Failed to create resources", error)
if (body.code === 409) { if (body.code === 409) {
return res.status(200).send({ message: "Resource already exists." }); return res.status(200).send({ message: "Resource already exists." })
} }
res.status(500).send({ message: "Failed to create resources." }); res.status(500).send({ message: "Failed to create resources." })
} }
}); })
app.post("/stop", async (req, res) => { app.post("/stop", async (req, res) => {
const { sandboxId } = dataSchema.parse(req.body); const { sandboxId } = dataSchema.parse(req.body)
console.log("Deleting resources for sandbox", sandboxId); console.log("Deleting resources for sandbox", sandboxId)
try { try {
const kubeManifests = readAndParseKubeYaml( const kubeManifests = readAndParseKubeYaml(
path.join(__dirname, "../service.yaml"), path.join(__dirname, "../service.yaml"),
sandboxId sandboxId
); )
const promises = kubeManifests.map(async (manifest) => { const promises = kubeManifests.map(async (manifest) => {
if (manifest.kind === "Deployment") if (manifest.kind === "Deployment")
await appsV1Api.deleteNamespacedDeployment( await appsV1Api.deleteNamespacedDeployment(
manifest.metadata?.name || "", manifest.metadata?.name || "",
namespace namespace
); )
else if (manifest.kind === "Service") else if (manifest.kind === "Service")
await coreV1Api.deleteNamespacedService( await coreV1Api.deleteNamespacedService(
manifest.metadata?.name || "", manifest.metadata?.name || "",
namespace namespace
); )
else if (manifest.kind === "Ingress") else if (manifest.kind === "Ingress")
await networkingV1Api.deleteNamespacedIngress( await networkingV1Api.deleteNamespacedIngress(
manifest.metadata?.name || "", manifest.metadata?.name || "",
namespace namespace
); )
}); })
await Promise.all(promises); await Promise.all(promises)
res.status(200).send({ message: "Resources deleted." }); res.status(200).send({ message: "Resources deleted." })
} catch (error) { } catch (error) {
console.log("Failed to delete resources", error); console.log("Failed to delete resources", error)
res.status(500).send({ message: "Failed to delete resources." }); res.status(500).send({ message: "Failed to delete resources." })
} }
}); })
app.listen(port, () => { app.listen(port, () => {
console.log(`Listening on port: ${port}`); console.log(`Listening on port: ${port}`)
}); })