mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-01-19 16:19:45 -06:00
Merge pull request #1150 from bluewave-labs/feat/be/docker-monitors
feat/be/docker monitors, references #1139
This commit is contained in:
@@ -28,7 +28,7 @@ const MonitorSchema = mongoose.Schema(
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
enum: ["http", "ping", "pagespeed", "hardware"],
|
||||
enum: ["http", "ping", "pagespeed", "hardware", "docker"],
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
|
||||
@@ -28,6 +28,7 @@ import NetworkService from "./service/networkService.js";
|
||||
import axios from "axios";
|
||||
import ping from "ping";
|
||||
import http from "http";
|
||||
import Docker from "dockerode";
|
||||
|
||||
// Email service and dependencies
|
||||
import EmailService from "./service/emailService.js";
|
||||
@@ -45,7 +46,7 @@ import NotificationService from "./service/notificationService.js";
|
||||
|
||||
import db from "./db/mongo/MongoDB.js";
|
||||
const SERVICE_NAME = "Server";
|
||||
const SHUTDOWN_TIMEOUT = 0;
|
||||
const SHUTDOWN_TIMEOUT = 1000;
|
||||
|
||||
let isShuttingDown = false;
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
@@ -130,7 +131,7 @@ const startApp = async () => {
|
||||
nodemailer,
|
||||
logger
|
||||
);
|
||||
const networkService = new NetworkService(axios, ping, logger, http);
|
||||
const networkService = new NetworkService(axios, ping, logger, http, Docker);
|
||||
const statusService = new StatusService(db, logger);
|
||||
const notificationService = new NotificationService(emailService, db, logger);
|
||||
const jobQueue = await JobQueue.createJobQueue(
|
||||
|
||||
276
Server/package-lock.json
generated
276
Server/package-lock.json
generated
@@ -14,6 +14,7 @@
|
||||
"bcrypt": "^5.1.1",
|
||||
"bullmq": "5.25.6",
|
||||
"cors": "^2.8.5",
|
||||
"dockerode": "4.0.2",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^4.19.2",
|
||||
"handlebars": "^4.7.8",
|
||||
@@ -89,6 +90,12 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@balena/dockerignore": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz",
|
||||
"integrity": "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@bcoe/v8-coverage": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
|
||||
@@ -996,6 +1003,15 @@
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
|
||||
},
|
||||
"node_modules/asn1": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
|
||||
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safer-buffer": "~2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/assertion-error": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
|
||||
@@ -1032,6 +1048,26 @@
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/bcrypt": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz",
|
||||
@@ -1045,6 +1081,15 @@
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
|
||||
"integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
},
|
||||
"node_modules/binary-extensions": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
||||
@@ -1056,6 +1101,17 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/bl": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer": "^5.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "^3.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "1.20.3",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
|
||||
@@ -1152,6 +1208,30 @@
|
||||
"node": ">=16.20.1"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-equal-constant-time": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||
@@ -1163,6 +1243,15 @@
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/buildcheck": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.6.tgz",
|
||||
"integrity": "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bullmq": {
|
||||
"version": "5.25.6",
|
||||
"resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.25.6.tgz",
|
||||
@@ -1708,6 +1797,20 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/cpu-features": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz",
|
||||
"integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==",
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"buildcheck": "~0.0.6",
|
||||
"nan": "^2.19.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cron-parser": {
|
||||
"version": "4.9.0",
|
||||
"resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz",
|
||||
@@ -2014,6 +2117,58 @@
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/docker-modem": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-5.0.3.tgz",
|
||||
"integrity": "sha512-89zhop5YVhcPEt5FpUFGr3cDyceGhq/F9J+ZndQ4KfqNvfbJpPMfgeixFgUj5OjCYAboElqODxY5Z1EBsSa6sg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"debug": "^4.1.1",
|
||||
"readable-stream": "^3.5.0",
|
||||
"split-ca": "^1.0.1",
|
||||
"ssh2": "^1.15.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/docker-modem/node_modules/debug": {
|
||||
"version": "4.3.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/docker-modem/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dockerode": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/dockerode/-/dockerode-4.0.2.tgz",
|
||||
"integrity": "sha512-9wM1BVpVMFr2Pw3eJNXrYYt6DT9k0xMcsSCjtPvyQ+xa1iPg/Mo3T/gUcwI0B2cczqCeCYRPF8yFYDwtFXT0+w==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@balena/dockerignore": "^1.0.2",
|
||||
"docker-modem": "^5.0.3",
|
||||
"tar-fs": "~2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-serializer": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
|
||||
@@ -2145,6 +2300,15 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/end-of-stream": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
@@ -2439,6 +2603,12 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-constants": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
||||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fs-minipass": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
||||
@@ -2822,6 +2992,26 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/ignore-by-default": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
|
||||
@@ -4129,6 +4319,12 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/mkdirp-classic": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mocha": {
|
||||
"version": "10.8.2",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz",
|
||||
@@ -4503,6 +4699,13 @@
|
||||
"mkdirp": "bin/cmd.js"
|
||||
}
|
||||
},
|
||||
"node_modules/nan": {
|
||||
"version": "2.22.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz",
|
||||
"integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==",
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.7",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
|
||||
@@ -5553,6 +5756,16 @@
|
||||
"integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/pump": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
|
||||
"integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
@@ -6046,6 +6259,29 @@
|
||||
"memory-pager": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/split-ca": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz",
|
||||
"integrity": "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/ssh2": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.16.0.tgz",
|
||||
"integrity": "sha512-r1X4KsBGedJqo7h8F5c4Ybpcr5RjyP+aWIG007uBPRjmdQWfEiVLzSK71Zji1B9sKxwaCvD8y8cwSkYrlLiRRg==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"asn1": "^0.2.6",
|
||||
"bcrypt-pbkdf": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.16.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"cpu-features": "~0.0.10",
|
||||
"nan": "^2.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ssl-checker": {
|
||||
"version": "2.0.10",
|
||||
"resolved": "https://registry.npmjs.org/ssl-checker/-/ssl-checker-2.0.10.tgz",
|
||||
@@ -6248,6 +6484,40 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/tar-fs": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz",
|
||||
"integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chownr": "^1.1.1",
|
||||
"mkdirp-classic": "^0.5.2",
|
||||
"pump": "^3.0.0",
|
||||
"tar-stream": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tar-fs/node_modules/chownr": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
|
||||
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/tar-stream": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
|
||||
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bl": "^4.0.3",
|
||||
"end-of-stream": "^1.4.1",
|
||||
"fs-constants": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^3.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/text-hex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
||||
@@ -6311,6 +6581,12 @@
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
|
||||
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
|
||||
},
|
||||
"node_modules/tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
|
||||
"license": "Unlicense"
|
||||
},
|
||||
"node_modules/type-detect": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"bcrypt": "^5.1.1",
|
||||
"bullmq": "5.25.6",
|
||||
"cors": "^2.8.5",
|
||||
"dockerode": "4.0.2",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^4.19.2",
|
||||
"handlebars": "^4.7.8",
|
||||
|
||||
@@ -180,8 +180,8 @@ class JobQueue {
|
||||
} catch (error) {
|
||||
this.logger.error({
|
||||
message: error.message,
|
||||
service: SERVICE_NAME,
|
||||
method: "createWorker",
|
||||
service: error.service ?? SERVICE_NAME,
|
||||
method: error.method ?? "createJobHandler",
|
||||
details: `Error processing job ${job.id}: ${error.message}`,
|
||||
stack: error.stack,
|
||||
});
|
||||
|
||||
@@ -8,11 +8,12 @@ import { errorMessages, successMessages } from "../utils/messages.js";
|
||||
* @param {Object} http - The HTTP utility for network operations.
|
||||
*/
|
||||
class NetworkService {
|
||||
constructor(axios, ping, logger, http) {
|
||||
constructor(axios, ping, logger, http, Docker) {
|
||||
this.TYPE_PING = "ping";
|
||||
this.TYPE_HTTP = "http";
|
||||
this.TYPE_PAGESPEED = "pagespeed";
|
||||
this.TYPE_HARDWARE = "hardware";
|
||||
this.TYPE_DOCKER = "docker";
|
||||
this.SERVICE_NAME = "NetworkService";
|
||||
this.NETWORK_ERROR = 5000;
|
||||
this.PING_ERROR = 5001;
|
||||
@@ -20,6 +21,7 @@ class NetworkService {
|
||||
this.ping = ping;
|
||||
this.logger = logger;
|
||||
this.http = http;
|
||||
this.Docker = Docker;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,28 +64,34 @@ class NetworkService {
|
||||
* @property {string} message - The message indicating the result of the ping request.
|
||||
*/
|
||||
async requestPing(job) {
|
||||
const url = job.data.url;
|
||||
const { response, responseTime, error } = await this.timeRequest(() =>
|
||||
this.ping.promise.probe(url)
|
||||
);
|
||||
try {
|
||||
const url = job.data.url;
|
||||
const { response, responseTime, error } = await this.timeRequest(() =>
|
||||
this.ping.promise.probe(url)
|
||||
);
|
||||
|
||||
const pingResponse = {
|
||||
monitorId: job.data._id,
|
||||
type: "ping",
|
||||
responseTime,
|
||||
payload: response,
|
||||
};
|
||||
if (error) {
|
||||
pingResponse.status = false;
|
||||
pingResponse.code = this.PING_ERROR;
|
||||
pingResponse.message = errorMessages.PING_CANNOT_RESOLVE;
|
||||
const pingResponse = {
|
||||
monitorId: job.data._id,
|
||||
type: "ping",
|
||||
responseTime,
|
||||
payload: response,
|
||||
};
|
||||
if (error) {
|
||||
pingResponse.status = false;
|
||||
pingResponse.code = this.PING_ERROR;
|
||||
pingResponse.message = errorMessages.PING_CANNOT_RESOLVE;
|
||||
return pingResponse;
|
||||
}
|
||||
|
||||
pingResponse.code = 200;
|
||||
pingResponse.status = response.alive;
|
||||
pingResponse.message = successMessages.PING_SUCCESS;
|
||||
return pingResponse;
|
||||
} catch (error) {
|
||||
error.service = this.SERVICE_NAME;
|
||||
error.method = "requestPing";
|
||||
throw error;
|
||||
}
|
||||
|
||||
pingResponse.code = 200;
|
||||
pingResponse.status = response.alive;
|
||||
pingResponse.message = successMessages.PING_SUCCESS;
|
||||
return pingResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,34 +112,40 @@ class NetworkService {
|
||||
* @property {string} message - The message indicating the result of the HTTP request.
|
||||
*/
|
||||
async requestHttp(job) {
|
||||
const url = job.data.url;
|
||||
const config = {};
|
||||
try {
|
||||
const url = job.data.url;
|
||||
const config = {};
|
||||
|
||||
job.data.secret !== undefined &&
|
||||
(config.headers = { Authorization: `Bearer ${job.data.secret}` });
|
||||
job.data.secret !== undefined &&
|
||||
(config.headers = { Authorization: `Bearer ${job.data.secret}` });
|
||||
|
||||
const { response, responseTime, error } = await this.timeRequest(() =>
|
||||
this.axios.get(url, config)
|
||||
);
|
||||
const { response, responseTime, error } = await this.timeRequest(() =>
|
||||
this.axios.get(url, config)
|
||||
);
|
||||
|
||||
const httpResponse = {
|
||||
monitorId: job.data._id,
|
||||
type: job.data.type,
|
||||
responseTime,
|
||||
payload: response?.data,
|
||||
};
|
||||
const httpResponse = {
|
||||
monitorId: job.data._id,
|
||||
type: job.data.type,
|
||||
responseTime,
|
||||
payload: response?.data,
|
||||
};
|
||||
|
||||
if (error) {
|
||||
const code = error.response?.status || this.NETWORK_ERROR;
|
||||
httpResponse.code = code;
|
||||
httpResponse.status = false;
|
||||
httpResponse.message = this.http.STATUS_CODES[code] || "Network Error";
|
||||
if (error) {
|
||||
const code = error.response?.status || this.NETWORK_ERROR;
|
||||
httpResponse.code = code;
|
||||
httpResponse.status = false;
|
||||
httpResponse.message = this.http.STATUS_CODES[code] || "Network Error";
|
||||
return httpResponse;
|
||||
}
|
||||
httpResponse.status = true;
|
||||
httpResponse.code = response.status;
|
||||
httpResponse.message = this.http.STATUS_CODES[response.status];
|
||||
return httpResponse;
|
||||
} catch (error) {
|
||||
error.service = this.SERVICE_NAME;
|
||||
error.method = "requestHttp";
|
||||
throw error;
|
||||
}
|
||||
httpResponse.status = true;
|
||||
httpResponse.code = response.status;
|
||||
httpResponse.message = this.http.STATUS_CODES[response.status];
|
||||
return httpResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,15 +165,114 @@ class NetworkService {
|
||||
* @property {string} message - The message indicating the result of the PageSpeed request.
|
||||
*/
|
||||
async requestPagespeed(job) {
|
||||
const url = job.data.url;
|
||||
const updatedJob = { ...job };
|
||||
const pagespeedUrl = `https://pagespeedonline.googleapis.com/pagespeedonline/v5/runPagespeed?url=${url}&category=seo&category=accessibility&category=best-practices&category=performance`;
|
||||
updatedJob.data.url = pagespeedUrl;
|
||||
return this.requestHttp(updatedJob);
|
||||
try {
|
||||
const url = job.data.url;
|
||||
const updatedJob = { ...job };
|
||||
const pagespeedUrl = `https://pagespeedonline.googleapis.com/pagespeedonline/v5/runPagespeed?url=${url}&category=seo&category=accessibility&category=best-practices&category=performance`;
|
||||
updatedJob.data.url = pagespeedUrl;
|
||||
return await this.requestHttp(updatedJob);
|
||||
} catch (error) {
|
||||
error.service = this.SERVICE_NAME;
|
||||
error.method = "requestPagespeed";
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an HTTP request to check hardware status and returns the response.
|
||||
*
|
||||
* @param {Object} job - The job object containing the data for the hardware request.
|
||||
* @param {Object} job.data - The data object within the job.
|
||||
* @param {string} job.data.url - The URL to send the hardware status request to.
|
||||
* @param {string} job.data._id - The monitor ID for the hardware request.
|
||||
* @param {string} job.data.type - The type of request, which is "hardware".
|
||||
* @returns {Promise<Object>} An object containing the hardware status response details.
|
||||
* @property {string} monitorId - The monitor ID for the hardware request.
|
||||
* @property {string} type - The type of request ("hardware").
|
||||
* @property {number} responseTime - The time taken for the request to complete, in milliseconds.
|
||||
* @property {Object} payload - The response payload from the hardware status request.
|
||||
* @property {boolean} status - The status of the request (true if successful, false otherwise).
|
||||
* @property {number} code - The response code (200 if successful, error code otherwise).
|
||||
* @property {string} message - The message indicating the result of the hardware status request.
|
||||
*/
|
||||
async requestHardware(job) {
|
||||
return this.requestHttp(job);
|
||||
try {
|
||||
return await this.requestHttp(job);
|
||||
} catch (error) {
|
||||
error.service = this.SERVICE_NAME;
|
||||
error.method = "requestHardware";
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a request to inspect a Docker container and returns its status.
|
||||
*
|
||||
* @param {Object} job - The job object containing the data for the Docker request.
|
||||
* @param {Object} job.data - The data object within the job.
|
||||
* @param {string} job.data.url - The container ID or name to inspect.
|
||||
* @param {string} job.data._id - The monitor ID for the Docker request.
|
||||
* @param {string} job.data.type - The type of request, which is "docker".
|
||||
* @returns {Promise<Object>} An object containing the Docker container status details.
|
||||
* @property {string} monitorId - The monitor ID for the Docker request.
|
||||
* @property {string} type - The type of request ("docker").
|
||||
* @property {number} responseTime - The time taken for the Docker inspection to complete, in milliseconds.
|
||||
* @property {boolean} status - The status of the container (true if running, false otherwise).
|
||||
* @property {number} code - The response code (200 if successful, error code otherwise).
|
||||
* @property {string} message - The message indicating the result of the Docker inspection.
|
||||
*/
|
||||
async requestDocker(job) {
|
||||
try {
|
||||
const docker = new this.Docker({
|
||||
socketPath: "/var/run/docker.sock",
|
||||
handleError: true, // Enable error handling
|
||||
});
|
||||
|
||||
const containers = await docker.listContainers({ all: true });
|
||||
const containerExists = containers.some((c) => c.Id === job.data.url);
|
||||
if (!containerExists) {
|
||||
throw new Error(errorMessages.DOCKER_NOT_FOUND);
|
||||
}
|
||||
const container = docker.getContainer(job.data.url);
|
||||
|
||||
const { response, responseTime, error } = await this.timeRequest(() =>
|
||||
container.inspect()
|
||||
);
|
||||
|
||||
const dockerResponse = {
|
||||
monitorId: job.data._id,
|
||||
type: job.data.type,
|
||||
responseTime,
|
||||
};
|
||||
|
||||
if (error) {
|
||||
dockerResponse.status = false;
|
||||
dockerResponse.code = error.statusCode || this.NETWORK_ERROR;
|
||||
dockerResponse.message = error.reason || errorMessages.DOCKER_FAIL;
|
||||
return dockerResponse;
|
||||
}
|
||||
dockerResponse.status = response?.State?.Status === "running" ? true : false;
|
||||
dockerResponse.code = 200;
|
||||
dockerResponse.message = successMessages.DOCKER_SUCCESS;
|
||||
return dockerResponse;
|
||||
} catch (error) {
|
||||
error.service = this.SERVICE_NAME;
|
||||
error.method = "requestDocker";
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unsupported job types by throwing an error with details.
|
||||
*
|
||||
* @param {string} type - The unsupported job type that was provided
|
||||
* @throws {Error} An error with service name, method name and unsupported type message
|
||||
*/
|
||||
handleUnsupportedType(type) {
|
||||
const err = new Error(`Unsupported type: ${type}`);
|
||||
err.service = this.SERVICE_NAME;
|
||||
err.method = "getStatus";
|
||||
throw err;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,7 +285,8 @@ class NetworkService {
|
||||
* @throws {Error} Throws an error if the job type is unsupported.
|
||||
*/
|
||||
async getStatus(job) {
|
||||
switch (job.data.type) {
|
||||
const type = job?.data?.type ?? "unknown";
|
||||
switch (type) {
|
||||
case this.TYPE_PING:
|
||||
return await this.requestPing(job);
|
||||
case this.TYPE_HTTP:
|
||||
@@ -181,13 +295,10 @@ class NetworkService {
|
||||
return await this.requestPagespeed(job);
|
||||
case this.TYPE_HARDWARE:
|
||||
return await this.requestHardware(job);
|
||||
case this.TYPE_DOCKER:
|
||||
return await this.requestDocker(job);
|
||||
default:
|
||||
this.logger.error({
|
||||
message: `Unsupported type: ${job.data.type}`,
|
||||
service: this.SERVICE_NAME,
|
||||
method: "getStatus",
|
||||
});
|
||||
return {};
|
||||
return this.handleUnsupportedType(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +133,7 @@ class StatusService {
|
||||
ping: this.db.createCheck,
|
||||
pagespeed: this.db.createPageSpeedCheck,
|
||||
hardware: this.db.createHardwareCheck,
|
||||
docker: this.db.createCheck,
|
||||
};
|
||||
const operation = operationMap[networkResponse.type];
|
||||
|
||||
|
||||
@@ -2,8 +2,9 @@ import sinon from "sinon";
|
||||
import NetworkService from "../../service/networkService.js";
|
||||
import { expect } from "chai";
|
||||
import http from "http";
|
||||
import { errorMessages } from "../../utils/messages.js";
|
||||
describe("Network Service", () => {
|
||||
let axios, ping, logger, networkService;
|
||||
let axios, ping, Docker, logger, networkService;
|
||||
|
||||
beforeEach(() => {
|
||||
axios = {
|
||||
@@ -12,6 +13,17 @@ describe("Network Service", () => {
|
||||
status: 200,
|
||||
}),
|
||||
};
|
||||
Docker = class {
|
||||
listContainers = sinon.stub().resolves([
|
||||
{
|
||||
Names: ["http://test.com"],
|
||||
Id: "http://test.com",
|
||||
},
|
||||
]);
|
||||
getContainer = sinon.stub().returns({
|
||||
inspect: sinon.stub().resolves({ State: { Status: "running" } }),
|
||||
});
|
||||
};
|
||||
ping = {
|
||||
promise: {
|
||||
probe: sinon
|
||||
@@ -20,7 +32,7 @@ describe("Network Service", () => {
|
||||
},
|
||||
};
|
||||
logger = { error: sinon.stub() };
|
||||
networkService = new NetworkService(axios, ping, logger, http);
|
||||
networkService = new NetworkService(axios, ping, logger, http, Docker);
|
||||
});
|
||||
describe("constructor", () => {
|
||||
it("should create a new NetworkService instance", () => {
|
||||
@@ -70,6 +82,18 @@ describe("Network Service", () => {
|
||||
expect(pingResult.status).to.be.false;
|
||||
expect(pingResult.code).to.equal(networkService.PING_ERROR);
|
||||
});
|
||||
it("should throw an error if ping cannot resolve", async () => {
|
||||
const error = new Error("test error");
|
||||
networkService.timeRequest = sinon.stub().throws(error);
|
||||
try {
|
||||
await networkService.requestPing({
|
||||
data: { url: "http://test.com", _id: "123" },
|
||||
});
|
||||
} catch (error) {
|
||||
expect(error).to.exist;
|
||||
expect(error.method).to.equal("requestPing");
|
||||
}
|
||||
});
|
||||
});
|
||||
describe("requestHttp", () => {
|
||||
it("should return a response object if http successful", async () => {
|
||||
@@ -108,6 +132,18 @@ describe("Network Service", () => {
|
||||
expect(httpResult.status).to.be.false;
|
||||
expect(httpResult.code).to.equal(networkService.NETWORK_ERROR);
|
||||
});
|
||||
it("should throw an error if an error occurs", async () => {
|
||||
const error = new Error("test error");
|
||||
networkService.timeRequest = sinon.stub().throws(error);
|
||||
try {
|
||||
await networkService.requestHttp({
|
||||
data: { url: "http://test.com", _id: "123" },
|
||||
});
|
||||
} catch (error) {
|
||||
expect(error).to.exist;
|
||||
expect(error.method).to.equal("requestHttp");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("requestPagespeed", () => {
|
||||
@@ -147,6 +183,18 @@ describe("Network Service", () => {
|
||||
expect(pagespeedResult.status).to.be.false;
|
||||
expect(pagespeedResult.code).to.equal(networkService.NETWORK_ERROR);
|
||||
});
|
||||
it("should throw an error if pagespeed cannot resolve", async () => {
|
||||
const error = new Error("test error");
|
||||
networkService.timeRequest = sinon.stub().throws(error);
|
||||
try {
|
||||
await networkService.requestPagespeed({
|
||||
data: { url: "http://test.com", _id: "123" },
|
||||
});
|
||||
} catch (error) {
|
||||
expect(error).to.exist;
|
||||
expect(error.method).to.equal("requestPagespeed");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("requestHardware", () => {
|
||||
@@ -201,6 +249,99 @@ describe("Network Service", () => {
|
||||
expect(httpResult.status).to.be.false;
|
||||
expect(httpResult.code).to.equal(networkService.NETWORK_ERROR);
|
||||
});
|
||||
it("should throw an error if hardware cannot resolve", async () => {
|
||||
const error = new Error("test error");
|
||||
networkService.timeRequest = sinon.stub().throws(error);
|
||||
try {
|
||||
await networkService.requestHardware({
|
||||
data: { url: "http://test.com", _id: "123" },
|
||||
});
|
||||
} catch (error) {
|
||||
expect(error).to.exist;
|
||||
expect(error.method).to.equal("requestHardware");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("requestDocker", () => {
|
||||
it("should return a response object if docker successful", async () => {
|
||||
const job = { data: { url: "http://test.com", _id: "123", type: "docker" } };
|
||||
const dockerResult = await networkService.requestDocker(job);
|
||||
expect(dockerResult.monitorId).to.equal("123");
|
||||
expect(dockerResult.type).to.equal("docker");
|
||||
expect(dockerResult.responseTime).to.be.a("number");
|
||||
expect(dockerResult.status).to.be.true;
|
||||
});
|
||||
|
||||
it("should return a response object with status false if container not running", async () => {
|
||||
Docker = class {
|
||||
listContainers = sinon.stub().resolves([
|
||||
{
|
||||
Names: ["/my_container"],
|
||||
Id: "abc123",
|
||||
},
|
||||
]);
|
||||
getContainer = sinon.stub().returns({
|
||||
inspect: sinon.stub().resolves({ State: { Status: "stopped" } }),
|
||||
});
|
||||
};
|
||||
networkService = new NetworkService(axios, ping, logger, http, Docker);
|
||||
const job = { data: { url: "abc123", _id: "123", type: "docker" } };
|
||||
const dockerResult = await networkService.requestDocker(job);
|
||||
expect(dockerResult.status).to.be.false;
|
||||
expect(dockerResult.code).to.equal(200);
|
||||
});
|
||||
|
||||
it("should handle an error when fetching the container", async () => {
|
||||
Docker = class {
|
||||
listContainers = sinon.stub().resolves([
|
||||
{
|
||||
Names: ["/my_container"],
|
||||
Id: "abc123",
|
||||
},
|
||||
]);
|
||||
getContainer = sinon.stub().returns({
|
||||
inspect: sinon.stub().throws(new Error("test error")),
|
||||
});
|
||||
};
|
||||
networkService = new NetworkService(axios, ping, logger, http, Docker);
|
||||
const job = { data: { url: "abc123", _id: "123", type: "docker" } };
|
||||
const dockerResult = await networkService.requestDocker(job);
|
||||
expect(dockerResult.status).to.be.false;
|
||||
expect(dockerResult.code).to.equal(networkService.NETWORK_ERROR);
|
||||
});
|
||||
|
||||
it("should throw an error if operations fail", async () => {
|
||||
Docker = class {
|
||||
listContainers = sinon.stub().resolves([
|
||||
{
|
||||
Names: ["/my_container"],
|
||||
Id: "abc123",
|
||||
},
|
||||
]);
|
||||
getContainer = sinon.stub().throws(new Error("test error"));
|
||||
};
|
||||
networkService = new NetworkService(axios, ping, logger, http, Docker);
|
||||
const job = { data: { url: "abc123", _id: "123", type: "docker" } };
|
||||
try {
|
||||
await networkService.requestDocker(job);
|
||||
} catch (error) {
|
||||
expect(error.message).to.equal("test error");
|
||||
}
|
||||
});
|
||||
it("should throw an error if no matching images found", async () => {
|
||||
Docker = class {
|
||||
listContainers = sinon.stub().resolves([]);
|
||||
getContainer = sinon.stub().throws(new Error("test error"));
|
||||
};
|
||||
networkService = new NetworkService(axios, ping, logger, http, Docker);
|
||||
const job = { data: { url: "abc123", _id: "123", type: "docker" } };
|
||||
try {
|
||||
await networkService.requestDocker(job);
|
||||
} catch (error) {
|
||||
expect(error.message).to.equal(errorMessages.DOCKER_NOT_FOUND);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("getStatus", () => {
|
||||
@@ -209,39 +350,81 @@ describe("Network Service", () => {
|
||||
networkService.requestHttp = sinon.stub();
|
||||
networkService.requestPagespeed = sinon.stub();
|
||||
networkService.requestHardware = sinon.stub();
|
||||
networkService.requestDocker = sinon.stub();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
});
|
||||
it("should call requestPing if type is ping", () => {
|
||||
networkService.getStatus({ data: { type: "ping" } });
|
||||
it("should call requestPing if type is ping", async () => {
|
||||
await networkService.getStatus({ data: { type: "ping" } });
|
||||
expect(networkService.requestPing.calledOnce).to.be.true;
|
||||
expect(networkService.requestDocker.notCalled).to.be.true;
|
||||
expect(networkService.requestHttp.notCalled).to.be.true;
|
||||
expect(networkService.requestPagespeed.notCalled).to.be.true;
|
||||
});
|
||||
it("should call requestHttp if type is http", () => {
|
||||
networkService.getStatus({ data: { type: "http" } });
|
||||
it("should call requestHttp if type is http", async () => {
|
||||
await networkService.getStatus({ data: { type: "http" } });
|
||||
expect(networkService.requestPing.notCalled).to.be.true;
|
||||
expect(networkService.requestDocker.notCalled).to.be.true;
|
||||
expect(networkService.requestHttp.calledOnce).to.be.true;
|
||||
expect(networkService.requestPagespeed.notCalled).to.be.true;
|
||||
});
|
||||
it("should call requestPagespeed if type is pagespeed", () => {
|
||||
networkService.getStatus({ data: { type: "pagespeed" } });
|
||||
it("should call requestPagespeed if type is pagespeed", async () => {
|
||||
await networkService.getStatus({ data: { type: "pagespeed" } });
|
||||
expect(networkService.requestPing.notCalled).to.be.true;
|
||||
expect(networkService.requestDocker.notCalled).to.be.true;
|
||||
expect(networkService.requestHttp.notCalled).to.be.true;
|
||||
expect(networkService.requestPagespeed.calledOnce).to.be.true;
|
||||
});
|
||||
it("should call requestHardware if type is hardware", () => {
|
||||
networkService.getStatus({ data: { type: "hardware" } });
|
||||
it("should call requestHardware if type is hardware", async () => {
|
||||
await networkService.getStatus({ data: { type: "hardware" } });
|
||||
expect(networkService.requestHardware.calledOnce).to.be.true;
|
||||
expect(networkService.requestDocker.notCalled).to.be.true;
|
||||
expect(networkService.requestPing.notCalled).to.be.true;
|
||||
expect(networkService.requestPagespeed.notCalled).to.be.true;
|
||||
});
|
||||
it("should log an error if an unknown type is provided", () => {
|
||||
networkService.getStatus({ data: { type: "unknown" } });
|
||||
expect(logger.error.calledOnce).to.be.true;
|
||||
expect(logger.error.args[0][0].message).to.equal("Unsupported type: unknown");
|
||||
it("should call requestDocker if type is Docker", async () => {
|
||||
await networkService.getStatus({ data: { type: "docker" } });
|
||||
expect(networkService.requestDocker.calledOnce).to.be.true;
|
||||
expect(networkService.requestHardware.notCalled).to.be.true;
|
||||
expect(networkService.requestPing.notCalled).to.be.true;
|
||||
expect(networkService.requestPagespeed.notCalled).to.be.true;
|
||||
});
|
||||
it("should throw an error if an unknown type is provided", async () => {
|
||||
try {
|
||||
await networkService.getStatus({ data: { type: "unknown" } });
|
||||
} catch (error) {
|
||||
expect(error.service).to.equal("NetworkService");
|
||||
expect(error.method).to.equal("getStatus");
|
||||
expect(error.message).to.equal("Unsupported type: unknown");
|
||||
}
|
||||
});
|
||||
it("should throw an error if job type is undefined", async () => {
|
||||
try {
|
||||
await networkService.getStatus({ data: { type: undefined } });
|
||||
} catch (error) {
|
||||
expect(error.service).to.equal("NetworkService");
|
||||
expect(error.method).to.equal("getStatus");
|
||||
expect(error.message).to.equal("Unsupported type: unknown");
|
||||
}
|
||||
});
|
||||
it("should throw an error if job is empty", async () => {
|
||||
try {
|
||||
await networkService.getStatus({});
|
||||
} catch (error) {
|
||||
expect(error.method).to.equal("getStatus");
|
||||
expect(error.message).to.equal("Unsupported type: unknown");
|
||||
}
|
||||
});
|
||||
it("should throw an error if job is null", async () => {
|
||||
try {
|
||||
await networkService.getStatus(null);
|
||||
} catch (error) {
|
||||
expect(error.service).to.equal("NetworkService");
|
||||
expect(error.method).to.equal("getStatus");
|
||||
expect(error.message).to.equal("Unsupported type: unknown");
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -55,6 +55,10 @@ const errorMessages = {
|
||||
// Status Page Errors
|
||||
STATUS_PAGE_NOT_FOUND: "Status page not found",
|
||||
STATUS_PAGE_URL_NOT_UNIQUE: "Status page url must be unique",
|
||||
|
||||
// Docker
|
||||
DOCKER_FAIL: "Failed to fetch Docker container information",
|
||||
DOCKER_NOT_FOUND: "Docker container not found",
|
||||
};
|
||||
|
||||
const successMessages = {
|
||||
@@ -123,6 +127,9 @@ const successMessages = {
|
||||
// Status Page
|
||||
STATUS_PAGE_BY_URL: "Got status page by url successfully",
|
||||
STATUS_PAGE_CREATE: "Status page created successfully",
|
||||
|
||||
// Docker
|
||||
DOCKER_SUCCESS: "Docker container status fetched successfully",
|
||||
};
|
||||
|
||||
export { errorMessages, successMessages };
|
||||
|
||||
Reference in New Issue
Block a user