From 2b792b0985d4836741d04e95228c35232a189f30 Mon Sep 17 00:00:00 2001 From: maslow Date: Thu, 9 Mar 2023 15:45:56 +0800 Subject: [PATCH] fix(server): some resources missing when deleting app (#875) --- server/package-lock.json | 277 ++++++------------ server/package.json | 4 +- server/prisma/schema.prisma | 8 +- .../application/application-task.service.ts | 115 ++++++-- server/src/application/application.module.ts | 6 + server/src/application/application.service.ts | 18 +- .../src/application/configuration.service.ts | 25 ++ .../application/dto/update-application.dto.ts | 4 +- server/src/constants.ts | 8 +- server/src/database/policy/policy.service.ts | 16 + server/src/function/function.service.ts | 7 + server/src/gateway/bucket-domain.service.ts | 23 ++ server/src/region/bundle.service.ts | 18 +- server/src/storage/storage.service.ts | 2 +- server/src/trigger/trigger.service.ts | 10 + server/src/website/website.service.ts | 23 ++ 16 files changed, 328 insertions(+), 236 deletions(-) create mode 100644 server/src/application/configuration.service.ts diff --git a/server/package-lock.json b/server/package-lock.json index d7bfee9e9a..4faacefc53 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -11,7 +11,6 @@ "dependencies": { "@aws-sdk/client-s3": "^3.245.0", "@aws-sdk/client-sts": "^3.226.0", - "@hokify/agenda": "^6.3.0", "@kubernetes/client-node": "^0.17.1", "@nestjs/axios": "^1.0.0", "@nestjs/common": "^9.0.0", @@ -32,7 +31,7 @@ "dotenv": "^16.0.3", "fast-json-patch": "^3.1.1", "lodash": "^4.17.21", - "mongodb": "^4.12.1", + "mongodb": "^5.1.0", "mongodb-uri": "^0.9.7", "nanoid": "^3.3.4", "npm-package-arg": "^10.1.0", @@ -52,7 +51,6 @@ "@types/express": "^4.17.13", "@types/jest": "28.1.8", "@types/lodash": "^4.14.191", - "@types/mongodb": "^4.0.7", "@types/mongodb-uri": "^0.9.1", "@types/node": "^16.0.0", "@types/npm-package-arg": "^6.1.1", @@ -5729,30 +5727,6 @@ "integrity": "sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA==", "dev": true }, - "node_modules/@hokify/agenda": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@hokify/agenda/-/agenda-6.3.0.tgz", - "integrity": "sha512-fWrKMDe/8QHJXLOdEsMogb6cb213Z82iNsnU7nFrSIMFifEXSkXNTyCZ99FV3KLf+Du1gS/M9/8uTC6FHyWRZQ==", - "dependencies": { - "cron-parser": "^4", - "date.js": "~0.3.3", - "debug": "~4", - "human-interval": "~2", - "luxon": "^3", - "mongodb": "^4" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@hokify/agenda/node_modules/luxon": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.2.1.tgz", - "integrity": "sha512-QrwPArQCNLAKGO/C+ZIilgIuDnEnKx5QYODdDtbFaxzsbZcc/a7WFq7MhsVYgRlwawLtvOUESTlfJ+hc/USqPg==", - "engines": { - "node": ">=12" - } - }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.7", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", @@ -7192,16 +7166,6 @@ "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", "dev": true }, - "node_modules/@types/mongodb": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-4.0.7.tgz", - "integrity": "sha512-lPUYPpzA43baXqnd36cZ9xxorprybxXDzteVKCPAdp14ppHtFJHnXYvNpmBvtMUTb5fKXVv6sVbzo1LHkWhJlw==", - "deprecated": "mongodb provides its own types. @types/mongodb is no longer needed.", - "dev": true, - "dependencies": { - "mongodb": "*" - } - }, "node_modules/@types/mongodb-uri": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/@types/mongodb-uri/-/mongodb-uri-0.9.1.tgz", @@ -9179,25 +9143,6 @@ "luxon": "^1.23.x" } }, - "node_modules/cron-parser": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.7.0.tgz", - "integrity": "sha512-BdAELR+MCT2ZWsIBhZKDuUqIUCBjHHulPJnm53OfdRLA4EWBjva3R+KM5NeidJuGsNXdEcZkjC7SCnkW5rAFSA==", - "dependencies": { - "luxon": "^3.1.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/cron-parser/node_modules/luxon": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.2.1.tgz", - "integrity": "sha512-QrwPArQCNLAKGO/C+ZIilgIuDnEnKx5QYODdDtbFaxzsbZcc/a7WFq7MhsVYgRlwawLtvOUESTlfJ+hc/USqPg==", - "engines": { - "node": ">=12" - } - }, "node_modules/cron-validate": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/cron-validate/-/cron-validate-1.4.5.tgz", @@ -9300,6 +9245,23 @@ "validator": "^13.7.0" } }, + "node_modules/database-proxy/node_modules/mongodb": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.14.0.tgz", + "integrity": "sha512-coGKkWXIBczZPr284tYKFLg+KbGPPLlSbdgfKAb6QqCFt5bo5VFZ50O3FFzsw4rnkqjwT6D8Qcoo9nshYKM7Mg==", + "dependencies": { + "bson": "^4.7.0", + "mongodb-connection-string-url": "^2.5.4", + "socks": "^2.7.1" + }, + "engines": { + "node": ">=12.9.0" + }, + "optionalDependencies": { + "@aws-sdk/credential-providers": "^3.186.0", + "saslprep": "^1.0.3" + } + }, "node_modules/database-ql": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/database-ql/-/database-ql-1.0.0-beta.2.tgz", @@ -9311,31 +9273,11 @@ "lodash.unset": "4.5.2" } }, - "node_modules/date.js": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/date.js/-/date.js-0.3.3.tgz", - "integrity": "sha512-HgigOS3h3k6HnW011nAb43c5xx5rBXk8P2v/WIT9Zv4koIaVXiH2BURguI78VVp+5Qc076T7OR378JViCnZtBw==", - "dependencies": { - "debug": "~3.1.0" - } - }, - "node_modules/date.js/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/date.js/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -9351,7 +9293,8 @@ "node_modules/debug/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/decache": { "version": "4.6.1", @@ -11235,14 +11178,6 @@ "npm": ">=1.3.7" } }, - "node_modules/human-interval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/human-interval/-/human-interval-2.0.1.tgz", - "integrity": "sha512-r4Aotzf+OtKIGQCB3odUowy4GfUDTy3aTWTfLd7ZF2gBCy3XW3v/dJLRefZnOFFnjqs5B1TypvS8WarpBkYUNQ==", - "dependencies": { - "numbered": "^1.1.0" - } - }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -13181,26 +13116,41 @@ } }, "node_modules/mongodb": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.12.1.tgz", - "integrity": "sha512-koT87tecZmxPKtxRQD8hCKfn+ockEL2xBiUvx3isQGI6mFmagWt4f4AyCE9J4sKepnLhMacoCTQQA6SLAI2L6w==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.1.0.tgz", + "integrity": "sha512-qgKb7y+EI90y4weY3z5+lIgm8wmexbonz0GalHkSElQXVKtRuwqXuhXKccyvIjXCJVy9qPV82zsinY0W1FBnJw==", "dependencies": { - "bson": "^4.7.0", - "mongodb-connection-string-url": "^2.5.4", + "bson": "^5.0.1", + "mongodb-connection-string-url": "^2.6.0", "socks": "^2.7.1" }, "engines": { - "node": ">=12.9.0" + "node": ">=14.20.1" }, "optionalDependencies": { - "@aws-sdk/credential-providers": "^3.186.0", "saslprep": "^1.0.3" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.201.0", + "mongodb-client-encryption": "^2.3.0", + "snappy": "^7.2.2" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + } } }, "node_modules/mongodb-connection-string-url": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.4.tgz", - "integrity": "sha512-SeAxuWs0ez3iI3vvmLk/j2y+zHwigTDKQhtdxTgt5ZCOQQS5+HW4g45/Xw5vzzbn7oQXCNQ24Z40AkJsizEy7w==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", "dependencies": { "@types/whatwg-url": "^8.2.1", "whatwg-url": "^11.0.0" @@ -13245,6 +13195,14 @@ "node": ">= 0.6.0" } }, + "node_modules/mongodb/node_modules/bson": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.0.1.tgz", + "integrity": "sha512-y09gBGusgHtinMon/GVbv1J6FrXhnr/+6hqLlSmEFzkz6PodqF6TxjyvfvY3AfO+oG1mgUtbC86xSbOlwvM62Q==", + "engines": { + "node": ">=14.20.1" + } + }, "node_modules/morgan": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", @@ -13510,11 +13468,6 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/numbered": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/numbered/-/numbered-1.1.0.tgz", - "integrity": "sha512-pv/ue2Odr7IfYOO0byC1KgBI10wo5YDauLhxY6/saNzAdAs0r1SotGCPzzCLNPL0xtrAwWRialLu23AAu9xO1g==" - }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -21343,26 +21296,6 @@ "integrity": "sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA==", "dev": true }, - "@hokify/agenda": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@hokify/agenda/-/agenda-6.3.0.tgz", - "integrity": "sha512-fWrKMDe/8QHJXLOdEsMogb6cb213Z82iNsnU7nFrSIMFifEXSkXNTyCZ99FV3KLf+Du1gS/M9/8uTC6FHyWRZQ==", - "requires": { - "cron-parser": "^4", - "date.js": "~0.3.3", - "debug": "~4", - "human-interval": "~2", - "luxon": "^3", - "mongodb": "^4" - }, - "dependencies": { - "luxon": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.2.1.tgz", - "integrity": "sha512-QrwPArQCNLAKGO/C+ZIilgIuDnEnKx5QYODdDtbFaxzsbZcc/a7WFq7MhsVYgRlwawLtvOUESTlfJ+hc/USqPg==" - } - } - }, "@humanwhocodes/config-array": { "version": "0.11.7", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", @@ -22472,15 +22405,6 @@ "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", "dev": true }, - "@types/mongodb": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-4.0.7.tgz", - "integrity": "sha512-lPUYPpzA43baXqnd36cZ9xxorprybxXDzteVKCPAdp14ppHtFJHnXYvNpmBvtMUTb5fKXVv6sVbzo1LHkWhJlw==", - "dev": true, - "requires": { - "mongodb": "*" - } - }, "@types/mongodb-uri": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/@types/mongodb-uri/-/mongodb-uri-0.9.1.tgz", @@ -24028,21 +23952,6 @@ "luxon": "^1.23.x" } }, - "cron-parser": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.7.0.tgz", - "integrity": "sha512-BdAELR+MCT2ZWsIBhZKDuUqIUCBjHHulPJnm53OfdRLA4EWBjva3R+KM5NeidJuGsNXdEcZkjC7SCnkW5rAFSA==", - "requires": { - "luxon": "^3.1.0" - }, - "dependencies": { - "luxon": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.2.1.tgz", - "integrity": "sha512-QrwPArQCNLAKGO/C+ZIilgIuDnEnKx5QYODdDtbFaxzsbZcc/a7WFq7MhsVYgRlwawLtvOUESTlfJ+hc/USqPg==" - } - } - }, "cron-validate": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/cron-validate/-/cron-validate-1.4.5.tgz", @@ -24125,6 +24034,20 @@ "mongodb": "^4.1.1", "mysql2": "^2.2.5", "validator": "^13.7.0" + }, + "dependencies": { + "mongodb": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.14.0.tgz", + "integrity": "sha512-coGKkWXIBczZPr284tYKFLg+KbGPPLlSbdgfKAb6QqCFt5bo5VFZ50O3FFzsw4rnkqjwT6D8Qcoo9nshYKM7Mg==", + "requires": { + "@aws-sdk/credential-providers": "^3.186.0", + "bson": "^4.7.0", + "mongodb-connection-string-url": "^2.5.4", + "saslprep": "^1.0.3", + "socks": "^2.7.1" + } + } } }, "database-ql": { @@ -24138,33 +24061,11 @@ "lodash.unset": "4.5.2" } }, - "date.js": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/date.js/-/date.js-0.3.3.tgz", - "integrity": "sha512-HgigOS3h3k6HnW011nAb43c5xx5rBXk8P2v/WIT9Zv4koIaVXiH2BURguI78VVp+5Qc076T7OR378JViCnZtBw==", - "requires": { - "debug": "~3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "requires": { "ms": "2.1.2" }, @@ -24172,7 +24073,8 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -25607,14 +25509,6 @@ "sshpk": "^1.7.0" } }, - "human-interval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/human-interval/-/human-interval-2.0.1.tgz", - "integrity": "sha512-r4Aotzf+OtKIGQCB3odUowy4GfUDTy3aTWTfLd7ZF2gBCy3XW3v/dJLRefZnOFFnjqs5B1TypvS8WarpBkYUNQ==", - "requires": { - "numbered": "^1.1.0" - } - }, "human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -27066,21 +26960,27 @@ } }, "mongodb": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.12.1.tgz", - "integrity": "sha512-koT87tecZmxPKtxRQD8hCKfn+ockEL2xBiUvx3isQGI6mFmagWt4f4AyCE9J4sKepnLhMacoCTQQA6SLAI2L6w==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.1.0.tgz", + "integrity": "sha512-qgKb7y+EI90y4weY3z5+lIgm8wmexbonz0GalHkSElQXVKtRuwqXuhXKccyvIjXCJVy9qPV82zsinY0W1FBnJw==", "requires": { - "@aws-sdk/credential-providers": "^3.186.0", - "bson": "^4.7.0", - "mongodb-connection-string-url": "^2.5.4", + "bson": "^5.0.1", + "mongodb-connection-string-url": "^2.6.0", "saslprep": "^1.0.3", "socks": "^2.7.1" + }, + "dependencies": { + "bson": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.0.1.tgz", + "integrity": "sha512-y09gBGusgHtinMon/GVbv1J6FrXhnr/+6hqLlSmEFzkz6PodqF6TxjyvfvY3AfO+oG1mgUtbC86xSbOlwvM62Q==" + } } }, "mongodb-connection-string-url": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.4.tgz", - "integrity": "sha512-SeAxuWs0ez3iI3vvmLk/j2y+zHwigTDKQhtdxTgt5ZCOQQS5+HW4g45/Xw5vzzbn7oQXCNQ24Z40AkJsizEy7w==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", "requires": { "@types/whatwg-url": "^8.2.1", "whatwg-url": "^11.0.0" @@ -27336,11 +27236,6 @@ "boolbase": "^1.0.0" } }, - "numbered": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/numbered/-/numbered-1.1.0.tgz", - "integrity": "sha512-pv/ue2Odr7IfYOO0byC1KgBI10wo5YDauLhxY6/saNzAdAs0r1SotGCPzzCLNPL0xtrAwWRialLu23AAu9xO1g==" - }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", diff --git a/server/package.json b/server/package.json index 891d7d569a..8bf65c3aa1 100644 --- a/server/package.json +++ b/server/package.json @@ -26,7 +26,6 @@ "dependencies": { "@aws-sdk/client-s3": "^3.245.0", "@aws-sdk/client-sts": "^3.226.0", - "@hokify/agenda": "^6.3.0", "@kubernetes/client-node": "^0.17.1", "@nestjs/axios": "^1.0.0", "@nestjs/common": "^9.0.0", @@ -47,7 +46,7 @@ "dotenv": "^16.0.3", "fast-json-patch": "^3.1.1", "lodash": "^4.17.21", - "mongodb": "^4.12.1", + "mongodb": "^5.1.0", "mongodb-uri": "^0.9.7", "nanoid": "^3.3.4", "npm-package-arg": "^10.1.0", @@ -67,7 +66,6 @@ "@types/express": "^4.17.13", "@types/jest": "28.1.8", "@types/lodash": "^4.14.191", - "@types/mongodb": "^4.0.7", "@types/mongodb-uri": "^0.9.1", "@types/node": "^16.0.0", "@types/npm-package-arg": "^6.1.1", diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma index 7e961c6673..c1b988a60a 100644 --- a/server/prisma/schema.prisma +++ b/server/prisma/schema.prisma @@ -136,9 +136,9 @@ model Bundle { } model ApplicationBundle { - id String @id @default(auto()) @map("_id") @db.ObjectId - appid String @unique - bundleId String @db.ObjectId + id String @id @default(auto()) @map("_id") @db.ObjectId + appid String @unique + bundleId String @db.ObjectId name String displayName String resource BundleResource @@ -333,7 +333,7 @@ model DatabasePolicyRule { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - policy DatabasePolicy @relation(fields: [appid, policyName], references: [appid, name]) + policy DatabasePolicy @relation(fields: [appid, policyName], references: [appid, name], onDelete: Cascade) @@unique([appid, policyName, collectionName]) } diff --git a/server/src/application/application-task.service.ts b/server/src/application/application-task.service.ts index d88f485cc5..c353ceccac 100644 --- a/server/src/application/application-task.service.ts +++ b/server/src/application/application-task.service.ts @@ -16,6 +16,13 @@ import { RegionService } from 'src/region/region.service' import { RuntimeDomainService } from 'src/gateway/runtime-domain.service' import { ServerConfig, TASK_LOCK_INIT_TIME } from 'src/constants' import { SystemDatabase } from 'src/database/system-database' +import { TriggerService } from 'src/trigger/trigger.service' +import { FunctionService } from 'src/function/function.service' +import { ApplicationConfigurationService } from './configuration.service' +import { BundleService } from 'src/region/bundle.service' +import { WebsiteService } from 'src/website/website.service' +import { PolicyService } from 'src/database/policy/policy.service' +import { BucketDomainService } from 'src/gateway/bucket-domain.service' @Injectable() export class ApplicationTaskService { @@ -27,7 +34,14 @@ export class ApplicationTaskService { private readonly clusterService: ClusterService, private readonly storageService: StorageService, private readonly databaseService: DatabaseService, - private readonly gatewayService: RuntimeDomainService, + private readonly runtimeDomainService: RuntimeDomainService, + private readonly bucketDomainService: BucketDomainService, + private readonly triggerService: TriggerService, + private readonly functionService: FunctionService, + private readonly configurationService: ApplicationConfigurationService, + private readonly bundleService: BundleService, + private readonly websiteService: WebsiteService, + private readonly policyService: PolicyService, ) {} @Cron(CronExpression.EVERY_SECOND) @@ -52,7 +66,7 @@ export class ApplicationTaskService { * Phase `Creating`: * - create namespace * - create storage user - * - create gateway domain + * - create runtime domain * - create database & user * - move phase `Creating` to `Created` */ @@ -110,15 +124,15 @@ export class ApplicationTaskService { database = await this.databaseService.create(app.appid) } - // reconcile gateway - let gateway = await this.gatewayService.findOne(appid) - if (!gateway) { + // reconcile runtime domain + let runtimeDomain = await this.runtimeDomainService.findOne(appid) + if (!runtimeDomain) { this.logger.log(`Creating gateway for application ${appid}`) - gateway = await this.gatewayService.create(appid) + runtimeDomain = await this.runtimeDomainService.create(appid) } // waiting resources' phase to be `Created` - if (gateway?.phase !== DomainPhase.Created) { + if (runtimeDomain?.phase !== DomainPhase.Created) { return await this.unlock(appid) } @@ -149,7 +163,17 @@ export class ApplicationTaskService { /** * Phase `Deleting`: - * - delete namespace, storage, database, gateway + * - delete triggers (k8s cronjob) + * - delete cloud functions + * - delete policies + * - delete application configuration + * - delete application bundle + * - delete website + * - delete runtime domain (apisix route) + * - delete bucket domain (apisix route) + * - delete database (mongo db) + * - delete storage (minio buckets & user) + * - delete namespace * - move phase `Deleting` to `Deleted` */ async handleDeletingPhase() { @@ -178,35 +202,82 @@ export class ApplicationTaskService { const region = await this.regionService.findByAppId(appid) assert(region, `Region ${region.name} not found`) - // delete namespace (include the instance) - const namespace = await this.clusterService.getAppNamespace(region, appid) - if (namespace) { - await this.clusterService.removeAppNamespace(region, appid) + // delete triggers + const hadTriggers = await this.triggerService.count(appid) + if (hadTriggers > 0) { + await this.triggerService.removeAll(appid) return await this.unlock(appid) } - // delete storage - const storage = await this.storageService.findOne(appid) - if (storage) { - await this.storageService.delete(appid) + // delete cloud functions + const hadFunctions = await this.functionService.count(appid) + if (hadFunctions > 0) { + await this.functionService.removeAll(appid) + return await this.unlock(appid) + } + + // delete database proxy policies + const hadPolicies = await this.policyService.count(appid) + if (hadPolicies > 0) { + await this.policyService.removeAll(appid) + return await this.unlock(appid) + } + + // delete application configuration + const hadConfigurations = await this.configurationService.count(appid) + if (hadConfigurations > 0) { + await this.configurationService.remove(appid) + return await this.unlock(appid) + } + + // delete application bundle + const bundle = await this.bundleService.findApplicationBundle(appid) + if (bundle) { + await this.bundleService.deleteApplicationBundle(appid) + return await this.unlock(appid) + } + + // delete website + const hadWebsites = await this.websiteService.count(appid) + if (hadWebsites > 0) { + await this.websiteService.removeAll(appid) + return await this.unlock(appid) + } + + // delete runtime domain + const runtimeDomain = await this.runtimeDomainService.findOne(appid) + if (runtimeDomain) { + await this.runtimeDomainService.delete(appid) + return await this.unlock(appid) + } + + // delete bucket domains + const hadBucketDomains = await this.bucketDomainService.count(appid) + if (hadBucketDomains > 0) { + await this.bucketDomainService.deleteAll(appid) return await this.unlock(appid) } - // delete database + // delete application database const database = await this.databaseService.findOne(appid) if (database) { await this.databaseService.delete(database) return await this.unlock(appid) } - // delete gateway - const gateway = await this.gatewayService.findOne(appid) - if (gateway) { - await this.gatewayService.delete(appid) + // delete application storage + const storage = await this.storageService.findOne(appid) + if (storage) { + await this.storageService.deleteUsersAndBuckets(appid) return await this.unlock(appid) } - // TODO: delete app configuration & bundle + // delete application namespace (include the instance) + const namespace = await this.clusterService.getAppNamespace(region, appid) + if (namespace) { + await this.clusterService.removeAppNamespace(region, appid) + return await this.unlock(appid) + } // update phase to `Deleted` const updated = await db.collection('Application').updateOne( diff --git a/server/src/application/application.module.ts b/server/src/application/application.module.ts index 2ac0c34763..292227ce85 100644 --- a/server/src/application/application.module.ts +++ b/server/src/application/application.module.ts @@ -10,6 +10,9 @@ import { EnvironmentVariableController } from './environment.controller' import { StorageModule } from '../storage/storage.module' import { DatabaseModule } from 'src/database/database.module' import { GatewayModule } from 'src/gateway/gateway.module' +import { ApplicationConfigurationService } from './configuration.service' +import { TriggerService } from 'src/trigger/trigger.service' +import { WebsiteService } from 'src/website/website.service' @Module({ imports: [StorageModule, DatabaseModule, GatewayModule], @@ -21,6 +24,9 @@ import { GatewayModule } from 'src/gateway/gateway.module' JwtService, FunctionService, EnvironmentVariableService, + ApplicationConfigurationService, + TriggerService, + WebsiteService, ], exports: [ApplicationService], }) diff --git a/server/src/application/application.service.ts b/server/src/application/application.service.ts index 28b2814229..42e4a44f6b 100644 --- a/server/src/application/application.service.ts +++ b/server/src/application/application.service.ts @@ -121,8 +121,13 @@ export class ApplicationService { data.state = dto.state } - const application = await this.prisma.application.update({ - where: { appid }, + const application = await this.prisma.application.updateMany({ + where: { + appid, + phase: { + notIn: [ApplicationPhase.Deleting, ApplicationPhase.Deleted], + }, + }, data, }) @@ -135,8 +140,13 @@ export class ApplicationService { async remove(appid: string) { try { - const res = await this.prisma.application.update({ - where: { appid }, + const res = await this.prisma.application.updateMany({ + where: { + appid, + phase: { + in: [ApplicationPhase.Started, ApplicationPhase.Stopped], + }, + }, data: { state: ApplicationState.Deleted, }, diff --git a/server/src/application/configuration.service.ts b/server/src/application/configuration.service.ts new file mode 100644 index 0000000000..b96789b93f --- /dev/null +++ b/server/src/application/configuration.service.ts @@ -0,0 +1,25 @@ +import { Injectable, Logger } from '@nestjs/common' +import { PrismaService } from 'src/prisma/prisma.service' + +@Injectable() +export class ApplicationConfigurationService { + private readonly logger = new Logger(ApplicationConfigurationService.name) + + constructor(private readonly prisma: PrismaService) {} + + async count(appid: string) { + return this.prisma.applicationConfiguration.count({ + where: { + appid, + }, + }) + } + + async remove(appid: string) { + return this.prisma.applicationConfiguration.delete({ + where: { + appid, + }, + }) + } +} diff --git a/server/src/application/dto/update-application.dto.ts b/server/src/application/dto/update-application.dto.ts index 1224c4ebb5..8fd34c1821 100644 --- a/server/src/application/dto/update-application.dto.ts +++ b/server/src/application/dto/update-application.dto.ts @@ -1,6 +1,6 @@ import { ApiPropertyOptional } from '@nestjs/swagger' import { ApplicationState } from '@prisma/client' -import { IsIn } from 'class-validator' +import { IsIn, IsString, Length } from 'class-validator' const STATES = [ ApplicationState.Running, @@ -12,6 +12,8 @@ export class UpdateApplicationDto { * Application name */ @ApiPropertyOptional() + @IsString() + @Length(1, 64) name?: string @ApiPropertyOptional({ diff --git a/server/src/constants.ts b/server/src/constants.ts index 9831214fd3..52df22a90f 100644 --- a/server/src/constants.ts +++ b/server/src/constants.ts @@ -56,19 +56,19 @@ export class ServerConfig { /* switcher of task controllers */ static get DISABLED_INSTANCE_TASK() { - return process.env.DISABLED_INSTANCE_TASK || false + return process.env.DISABLED_INSTANCE_TASK === 'true' } static get DISABLED_APPLICATION_TASK() { - return process.env.DISABLED_APPLICATION_TASK || false + return process.env.DISABLED_APPLICATION_TASK === 'true' } static get DISABLED_GATEWAY_TASK() { - return process.env.DISABLED_GATEWAY_TASK || false + return process.env.DISABLED_GATEWAY_TASK === 'true' } static get DISABLED_STORAGE_TASK() { - return process.env.DISABLED_STORAGE_TASK || false + return process.env.DISABLED_STORAGE_TASK === 'true' } static get APPID_LENGTH(): number { diff --git a/server/src/database/policy/policy.service.ts b/server/src/database/policy/policy.service.ts index 69f0bd9bad..b35ee25f78 100644 --- a/server/src/database/policy/policy.service.ts +++ b/server/src/database/policy/policy.service.ts @@ -100,6 +100,22 @@ export class PolicyService { return res } + async removeAll(appid: string) { + // delete rules first + await this.prisma.databasePolicyRule.deleteMany({ + where: { + appid, + }, + }) + + const res = await this.prisma.databasePolicy.deleteMany({ + where: { + appid, + }, + }) + return res + } + async publish(policy: DatabasePolicy & { rules: DatabasePolicyRule[] }) { const { db, client } = await this.databaseService.findAndConnect( policy.appid, diff --git a/server/src/function/function.service.ts b/server/src/function/function.service.ts index 0b45a4d80e..71bbaca21f 100644 --- a/server/src/function/function.service.ts +++ b/server/src/function/function.service.ts @@ -91,6 +91,13 @@ export class FunctionService { return res } + async removeAll(appid: string) { + const res = await this.prisma.cloudFunction.deleteMany({ + where: { appid }, + }) + return res + } + async publish(func: CloudFunction) { const { db, client } = await this.databaseService.findAndConnect(func.appid) const session = client.startSession() diff --git a/server/src/gateway/bucket-domain.service.ts b/server/src/gateway/bucket-domain.service.ts index 40329c1d5a..45e274ec9a 100644 --- a/server/src/gateway/bucket-domain.service.ts +++ b/server/src/gateway/bucket-domain.service.ts @@ -56,6 +56,16 @@ export class BucketDomainService { return doc } + async count(appid: string) { + const count = await this.prisma.bucketDomain.count({ + where: { + appid, + }, + }) + + return count + } + /** * Delete app domain in database: * - turn to `Deleted` state @@ -73,4 +83,17 @@ export class BucketDomainService { return doc } + + async deleteAll(appid: string) { + const docs = await this.prisma.bucketDomain.updateMany({ + where: { + appid, + }, + data: { + state: DomainState.Deleted, + }, + }) + + return docs + } } diff --git a/server/src/region/bundle.service.ts b/server/src/region/bundle.service.ts index e2ab1f8423..c2f1b5ab1f 100644 --- a/server/src/region/bundle.service.ts +++ b/server/src/region/bundle.service.ts @@ -13,12 +13,6 @@ export class BundleService { }) } - async findApplicationBundle(appid: string) { - return this.prisma.applicationBundle.findUnique({ - where: { appid }, - }) - } - async findOneByName(name: string, regionName: string) { return this.prisma.bundle.findFirst({ where: { @@ -29,4 +23,16 @@ export class BundleService { }, }) } + + async findApplicationBundle(appid: string) { + return this.prisma.applicationBundle.findUnique({ + where: { appid }, + }) + } + + async deleteApplicationBundle(appid: string) { + return this.prisma.applicationBundle.delete({ + where: { appid }, + }) + } } diff --git a/server/src/storage/storage.service.ts b/server/src/storage/storage.service.ts index b38447b272..058302ca91 100644 --- a/server/src/storage/storage.service.ts +++ b/server/src/storage/storage.service.ts @@ -72,7 +72,7 @@ export class StorageService { return user } - async delete(appid: string) { + async deleteUsersAndBuckets(appid: string) { // delete user in minio const region = await this.regionService.findByAppId(appid) diff --git a/server/src/trigger/trigger.service.ts b/server/src/trigger/trigger.service.ts index 06a55c1cc5..8299ac136b 100644 --- a/server/src/trigger/trigger.service.ts +++ b/server/src/trigger/trigger.service.ts @@ -60,6 +60,16 @@ export class TriggerService { return res } + async removeAll(appid: string) { + const res = await this.prisma.cronTrigger.updateMany({ + where: { appid }, + data: { + state: TriggerState.Deleted, + }, + }) + return res + } + isValidCronExpression(cron: string) { const ret = CronValidate(cron) if (ret.isValid()) { diff --git a/server/src/website/website.service.ts b/server/src/website/website.service.ts index a70d6dcb05..b876bbbda0 100644 --- a/server/src/website/website.service.ts +++ b/server/src/website/website.service.ts @@ -42,6 +42,16 @@ export class WebsiteService { return website } + async count(appid: string) { + const count = await this.prisma.websiteHosting.count({ + where: { + appid: appid, + }, + }) + + return count + } + async findAll(appid: string) { const websites = await this.prisma.websiteHosting.findMany({ where: { @@ -125,4 +135,17 @@ export class WebsiteService { return website } + + async removeAll(appid: string) { + const websites = await this.prisma.websiteHosting.updateMany({ + where: { + appid, + }, + data: { + state: DomainState.Deleted, + }, + }) + + return websites + } }