From e48c58c8834d11fbefe5f190e32b3588e830eaf0 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sat, 22 Jun 2024 16:22:30 -0600 Subject: [PATCH] feat: add deploy command --- src/commands/app/deploy.ts | 89 ++++++++++++++++++++++++ src/commands/app/stop.ts | 89 ++++++++++++++++++++++++ src/commands/database/mariadb/create.ts | 4 +- src/commands/database/mariadb/deploy.ts | 89 ++++++++++++++++++++++++ src/commands/database/mongo/deploy.ts | 89 ++++++++++++++++++++++++ src/commands/database/mysql/deploy.ts | 89 ++++++++++++++++++++++++ src/commands/database/postgres/deploy.ts | 89 ++++++++++++++++++++++++ src/commands/database/redis/deploy.ts | 89 ++++++++++++++++++++++++ 8 files changed, 625 insertions(+), 2 deletions(-) create mode 100644 src/commands/app/deploy.ts create mode 100644 src/commands/app/stop.ts create mode 100644 src/commands/database/mariadb/deploy.ts create mode 100644 src/commands/database/mongo/deploy.ts create mode 100644 src/commands/database/mysql/deploy.ts create mode 100644 src/commands/database/postgres/deploy.ts create mode 100644 src/commands/database/redis/deploy.ts diff --git a/src/commands/app/deploy.ts b/src/commands/app/deploy.ts new file mode 100644 index 0000000..4ecf97a --- /dev/null +++ b/src/commands/app/deploy.ts @@ -0,0 +1,89 @@ +import { Command } from "@oclif/core"; +import { readAuthConfig } from "../../utils/utils.js"; +import chalk from "chalk"; +import { getProject, getProjects } from "../../utils/shared.js"; +import inquirer from "inquirer"; +import type { Answers } from "./create.js"; +import axios from "axios"; + +export default class AppDeploy extends Command { + static description = "Deploy an application to a project."; + + static examples = ["$ <%= config.bin %> app deploy"]; + + public async run(): Promise { + const auth = await readAuthConfig(this); + + console.log(chalk.blue.bold("\n Listing all Projects \n")); + + const projects = await getProjects(auth, this); + + const { project } = await inquirer.prompt([ + { + choices: projects.map((project) => ({ + name: project.name, + value: project, + })), + message: "Select a project to deploy the application in:", + name: "project", + type: "list", + }, + ]); + + const projectId = project.projectId; + + const projectSelected = await getProject(projectId, auth, this); + + if (projectSelected.applications.length === 0) { + this.error(chalk.yellow("No applications found in this project.")); + } + + const appAnswers = await inquirer.prompt([ + { + // @ts-ignore + choices: projectSelected.applications.map((app) => ({ + name: app.name, + value: app.applicationId, + })), + message: "Select the application to deploy:", + name: "selectedApp", + type: "list", + }, + ]); + + const applicationId = appAnswers.selectedApp; + + const confirmAnswers = await inquirer.prompt([ + { + default: false, + message: "Are you sure you want to deploy this application?", + name: "confirmDelete", + type: "confirm", + }, + ]); + + if (!confirmAnswers.confirmDelete) { + this.error(chalk.yellow("Application deployment cancelled.")); + } + + const response = await axios.post( + `${auth.url}/api/trpc/application.deploy`, + { + json: { + applicationId, + }, + }, + { + headers: { + Authorization: `Bearer ${auth.token}`, + "Content-Type": "application/json", + }, + }, + ); + + if (response.status !== 200) { + this.error(chalk.red("Error deploying application")); + } + this.log(chalk.green("Application deploy successful.")); + } +} diff --git a/src/commands/app/stop.ts b/src/commands/app/stop.ts new file mode 100644 index 0000000..b04f690 --- /dev/null +++ b/src/commands/app/stop.ts @@ -0,0 +1,89 @@ +import { Command } from "@oclif/core"; +import { readAuthConfig } from "../../utils/utils.js"; +import chalk from "chalk"; +import inquirer from "inquirer"; +import { getProject, getProjects } from "../../utils/shared.js"; +import type { Answers } from "./create.js"; +import axios from "axios"; + +export default class AppStop extends Command { + static description = "Stop an application from a project."; + + static examples = ["$ <%= config.bin %> app stop"]; + + public async run(): Promise { + const auth = await readAuthConfig(this); + + console.log(chalk.blue.bold("\n Listing all Projects \n")); + + const projects = await getProjects(auth, this); + + const { project } = await inquirer.prompt([ + { + choices: projects.map((project) => ({ + name: project.name, + value: project, + })), + message: "Select a project to stop the application in:", + name: "project", + type: "list", + }, + ]); + + const projectId = project.projectId; + + const projectSelected = await getProject(projectId, auth, this); + + if (projectSelected.applications.length === 0) { + this.error(chalk.yellow("No applications found in this project.")); + } + + const appAnswers = await inquirer.prompt([ + { + // @ts-ignore + choices: projectSelected.applications.map((app) => ({ + name: app.name, + value: app.applicationId, + })), + message: "Select the application to stop:", + name: "selectedApp", + type: "list", + }, + ]); + + const applicationId = appAnswers.selectedApp; + + const confirmAnswers = await inquirer.prompt([ + { + default: false, + message: "Are you sure you want to stop this application?", + name: "confirmDelete", + type: "confirm", + }, + ]); + + if (!confirmAnswers.confirmDelete) { + this.error(chalk.yellow("Application stop cancelled.")); + } + + const response = await axios.post( + `${auth.url}/api/trpc/application.stop`, + { + json: { + applicationId, + }, + }, + { + headers: { + Authorization: `Bearer ${auth.token}`, + "Content-Type": "application/json", + }, + }, + ); + + if (response.status !== 200) { + this.error(chalk.red("Error stopping application")); + } + this.log(chalk.green("Application stop successful.")); + } +} diff --git a/src/commands/database/mariadb/create.ts b/src/commands/database/mariadb/create.ts index 676405c..71a32df 100644 --- a/src/commands/database/mariadb/create.ts +++ b/src/commands/database/mariadb/create.ts @@ -75,8 +75,8 @@ export default class DatabaseMariadbCreate extends Command { type: "password", }, { - default: "mariadb:4", - message: "Docker Image (default: mariadb:4):", + default: "mariadb:11", + message: "Docker Image (default: mariadb:11):", name: "dockerImage", type: "input", }, diff --git a/src/commands/database/mariadb/deploy.ts b/src/commands/database/mariadb/deploy.ts new file mode 100644 index 0000000..0874a60 --- /dev/null +++ b/src/commands/database/mariadb/deploy.ts @@ -0,0 +1,89 @@ +import { Command } from "@oclif/core"; +import { readAuthConfig } from "../../../utils/utils.js"; +import chalk from "chalk"; +import { getProject, getProjects } from "../../../utils/shared.js"; +import inquirer from "inquirer"; +import type { Answers } from "../../app/create.js"; +import axios from "axios"; + +export default class DatabaseMariadbDeploy extends Command { + static description = "Deploy an mariadb to a project."; + + static examples = ["$ <%= config.bin %> app deploy"]; + + public async run(): Promise { + const auth = await readAuthConfig(this); + + console.log(chalk.blue.bold("\n Listing all Projects \n")); + + const projects = await getProjects(auth, this); + + const { project } = await inquirer.prompt([ + { + choices: projects.map((project) => ({ + name: project.name, + value: project, + })), + message: "Select a project to deploy the mariadb in:", + name: "project", + type: "list", + }, + ]); + + const projectId = project.projectId; + + const projectSelected = await getProject(projectId, auth, this); + + if (projectSelected.mariadb.length === 0) { + this.error(chalk.yellow("No mariadb found in this project.")); + } + + const appAnswers = await inquirer.prompt([ + { + // @ts-ignore + choices: projectSelected.mariadb.map((app) => ({ + name: app.name, + value: app.mariadbId, + })), + message: "Select the mariadb to deploy:", + name: "selectedApp", + type: "list", + }, + ]); + + const mariadbId = appAnswers.selectedApp; + + const confirmAnswers = await inquirer.prompt([ + { + default: false, + message: "Are you sure you want to deploy this mariadb?", + name: "confirmDelete", + type: "confirm", + }, + ]); + + if (!confirmAnswers.confirmDelete) { + this.error(chalk.yellow("mariadb deployment cancelled.")); + } + + const response = await axios.post( + `${auth.url}/api/trpc/mariadb.deploy`, + { + json: { + mariadbId, + }, + }, + { + headers: { + Authorization: `Bearer ${auth.token}`, + "Content-Type": "application/json", + }, + }, + ); + + if (response.status !== 200) { + this.error(chalk.red("Error deploying mariadb")); + } + this.log(chalk.green("Mariadb deploy successful.")); + } +} diff --git a/src/commands/database/mongo/deploy.ts b/src/commands/database/mongo/deploy.ts new file mode 100644 index 0000000..cbee40e --- /dev/null +++ b/src/commands/database/mongo/deploy.ts @@ -0,0 +1,89 @@ +import { Command } from "@oclif/core"; +import { readAuthConfig } from "../../../utils/utils.js"; +import chalk from "chalk"; +import { getProject, getProjects } from "../../../utils/shared.js"; +import inquirer from "inquirer"; +import type { Answers } from "../../app/create.js"; +import axios from "axios"; + +export default class DatabaseMongoDeploy extends Command { + static description = "Deploy an mongo to a project."; + + static examples = ["$ <%= config.bin %> app deploy"]; + + public async run(): Promise { + const auth = await readAuthConfig(this); + + console.log(chalk.blue.bold("\n Listing all Projects \n")); + + const projects = await getProjects(auth, this); + + const { project } = await inquirer.prompt([ + { + choices: projects.map((project) => ({ + name: project.name, + value: project, + })), + message: "Select a project to deploy the mongo in:", + name: "project", + type: "list", + }, + ]); + + const projectId = project.projectId; + + const projectSelected = await getProject(projectId, auth, this); + + if (projectSelected.mongo.length === 0) { + this.error(chalk.yellow("No mongo found in this project.")); + } + + const appAnswers = await inquirer.prompt([ + { + // @ts-ignore + choices: projectSelected.mongo.map((app) => ({ + name: app.name, + value: app.mongoId, + })), + message: "Select the mongo to deploy:", + name: "selectedApp", + type: "list", + }, + ]); + + const mongoId = appAnswers.selectedApp; + + const confirmAnswers = await inquirer.prompt([ + { + default: false, + message: "Are you sure you want to deploy this mongo?", + name: "confirmDelete", + type: "confirm", + }, + ]); + + if (!confirmAnswers.confirmDelete) { + this.error(chalk.yellow("mongo deployment cancelled.")); + } + + const response = await axios.post( + `${auth.url}/api/trpc/mongo.deploy`, + { + json: { + mongoId, + }, + }, + { + headers: { + Authorization: `Bearer ${auth.token}`, + "Content-Type": "application/json", + }, + }, + ); + + if (response.status !== 200) { + this.error(chalk.red("Error deploying mongo")); + } + this.log(chalk.green("Mongo deploy successful.")); + } +} diff --git a/src/commands/database/mysql/deploy.ts b/src/commands/database/mysql/deploy.ts new file mode 100644 index 0000000..b1cb76b --- /dev/null +++ b/src/commands/database/mysql/deploy.ts @@ -0,0 +1,89 @@ +import { Command } from "@oclif/core"; +import { readAuthConfig } from "../../../utils/utils.js"; +import chalk from "chalk"; +import { getProject, getProjects } from "../../../utils/shared.js"; +import inquirer from "inquirer"; +import type { Answers } from "../../app/create.js"; +import axios from "axios"; + +export default class DatabaseMysqlDeploy extends Command { + static description = "Deploy an mysql to a project."; + + static examples = ["$ <%= config.bin %> app deploy"]; + + public async run(): Promise { + const auth = await readAuthConfig(this); + + console.log(chalk.blue.bold("\n Listing all Projects \n")); + + const projects = await getProjects(auth, this); + + const { project } = await inquirer.prompt([ + { + choices: projects.map((project) => ({ + name: project.name, + value: project, + })), + message: "Select a project to deploy the mysql in:", + name: "project", + type: "list", + }, + ]); + + const projectId = project.projectId; + + const projectSelected = await getProject(projectId, auth, this); + + if (projectSelected.mysql.length === 0) { + this.error(chalk.yellow("No mysql found in this project.")); + } + + const appAnswers = await inquirer.prompt([ + { + // @ts-ignore + choices: projectSelected.mysql.map((app) => ({ + name: app.name, + value: app.mysqlId, + })), + message: "Select the mysql to deploy:", + name: "selectedApp", + type: "list", + }, + ]); + + const mysqlId = appAnswers.selectedApp; + + const confirmAnswers = await inquirer.prompt([ + { + default: false, + message: "Are you sure you want to deploy this mysql?", + name: "confirmDelete", + type: "confirm", + }, + ]); + + if (!confirmAnswers.confirmDelete) { + this.error(chalk.yellow("mysql deployment cancelled.")); + } + + const response = await axios.post( + `${auth.url}/api/trpc/mysql.deploy`, + { + json: { + mysqlId, + }, + }, + { + headers: { + Authorization: `Bearer ${auth.token}`, + "Content-Type": "application/json", + }, + }, + ); + + if (response.status !== 200) { + this.error(chalk.red("Error deploying mysql")); + } + this.log(chalk.green("Mysql deployed successful.")); + } +} diff --git a/src/commands/database/postgres/deploy.ts b/src/commands/database/postgres/deploy.ts new file mode 100644 index 0000000..36675c1 --- /dev/null +++ b/src/commands/database/postgres/deploy.ts @@ -0,0 +1,89 @@ +import { Command } from "@oclif/core"; +import { readAuthConfig } from "../../../utils/utils.js"; +import chalk from "chalk"; +import { getProject, getProjects } from "../../../utils/shared.js"; +import inquirer from "inquirer"; +import type { Answers } from "../../app/create.js"; +import axios from "axios"; + +export default class DatabasePostgresDeploy extends Command { + static description = "Deploy an postgres to a project."; + + static examples = ["$ <%= config.bin %> app deploy"]; + + public async run(): Promise { + const auth = await readAuthConfig(this); + + console.log(chalk.blue.bold("\n Listing all Projects \n")); + + const projects = await getProjects(auth, this); + + const { project } = await inquirer.prompt([ + { + choices: projects.map((project) => ({ + name: project.name, + value: project, + })), + message: "Select a project to deploy the postgres in:", + name: "project", + type: "list", + }, + ]); + + const projectId = project.projectId; + + const projectSelected = await getProject(projectId, auth, this); + + if (projectSelected.postgres.length === 0) { + this.error(chalk.yellow("No postgres found in this project.")); + } + + const appAnswers = await inquirer.prompt([ + { + // @ts-ignore + choices: projectSelected.postgres.map((app) => ({ + name: app.name, + value: app.postgresId, + })), + message: "Select the postgres to deploy:", + name: "selectedApp", + type: "list", + }, + ]); + + const postgresId = appAnswers.selectedApp; + + const confirmAnswers = await inquirer.prompt([ + { + default: false, + message: "Are you sure you want to deploy this postgres?", + name: "confirmDelete", + type: "confirm", + }, + ]); + + if (!confirmAnswers.confirmDelete) { + this.error(chalk.yellow("postgres deployment cancelled.")); + } + + const response = await axios.post( + `${auth.url}/api/trpc/postgres.deploy`, + { + json: { + postgresId, + }, + }, + { + headers: { + Authorization: `Bearer ${auth.token}`, + "Content-Type": "application/json", + }, + }, + ); + + if (response.status !== 200) { + this.error(chalk.red("Error deploying postgres")); + } + this.log(chalk.green("Postgres deployed successful.")); + } +} diff --git a/src/commands/database/redis/deploy.ts b/src/commands/database/redis/deploy.ts new file mode 100644 index 0000000..fdda563 --- /dev/null +++ b/src/commands/database/redis/deploy.ts @@ -0,0 +1,89 @@ +import { Command } from "@oclif/core"; +import { readAuthConfig } from "../../../utils/utils.js"; +import chalk from "chalk"; +import { getProject, getProjects } from "../../../utils/shared.js"; +import inquirer from "inquirer"; +import type { Answers } from "../../app/create.js"; +import axios from "axios"; + +export default class DatabaseRedisDeploy extends Command { + static description = "Deploy an redis to a project."; + + static examples = ["$ <%= config.bin %> app deploy"]; + + public async run(): Promise { + const auth = await readAuthConfig(this); + + console.log(chalk.blue.bold("\n Listing all Projects \n")); + + const projects = await getProjects(auth, this); + + const { project } = await inquirer.prompt([ + { + choices: projects.map((project) => ({ + name: project.name, + value: project, + })), + message: "Select a project to deploy the redis in:", + name: "project", + type: "list", + }, + ]); + + const projectId = project.projectId; + + const projectSelected = await getProject(projectId, auth, this); + + if (projectSelected.redis.length === 0) { + this.error(chalk.yellow("No redis found in this project.")); + } + + const appAnswers = await inquirer.prompt([ + { + // @ts-ignore + choices: projectSelected.redis.map((app) => ({ + name: app.name, + value: app.redisId, + })), + message: "Select the redis to deploy:", + name: "selectedApp", + type: "list", + }, + ]); + + const redisId = appAnswers.selectedApp; + + const confirmAnswers = await inquirer.prompt([ + { + default: false, + message: "Are you sure you want to deploy this redis?", + name: "confirmDelete", + type: "confirm", + }, + ]); + + if (!confirmAnswers.confirmDelete) { + this.error(chalk.yellow("redis deployment cancelled.")); + } + + const response = await axios.post( + `${auth.url}/api/trpc/redis.deploy`, + { + json: { + redisId, + }, + }, + { + headers: { + Authorization: `Bearer ${auth.token}`, + "Content-Type": "application/json", + }, + }, + ); + + if (response.status !== 200) { + this.error(chalk.red("Error deploying redis")); + } + this.log(chalk.green("Redis deployed successful.")); + } +}