diff --git a/.gitignore b/.gitignore index 30eaf3933d..cc57bb0a99 100644 --- a/.gitignore +++ b/.gitignore @@ -53,4 +53,6 @@ tests/coverage settings.json -GoSDK/tester/ \ No newline at end of file +GoSDK/tester/ + +.gitconfig \ No newline at end of file diff --git a/Common/Types/Exception/ExceptionCode.ts b/Common/Types/Exception/ExceptionCode.ts index dcd902aa52..3446d03c8f 100644 --- a/Common/Types/Exception/ExceptionCode.ts +++ b/Common/Types/Exception/ExceptionCode.ts @@ -1,4 +1,5 @@ enum ExceptionCode { + NotImplementedException = 0, GeneralException = 1, APIException = 2, BadDataException = 400, diff --git a/Common/Types/Exception/NotImplementedException.ts b/Common/Types/Exception/NotImplementedException.ts new file mode 100644 index 0000000000..e727b6b075 --- /dev/null +++ b/Common/Types/Exception/NotImplementedException.ts @@ -0,0 +1,11 @@ +import Exception from './Exception'; +import ExceptionCode from './ExceptionCode'; + +export default class BadDataException extends Exception { + public constructor() { + super( + ExceptionCode.NotImplementedException, + 'This code is not implemented' + ); + } +} diff --git a/Common/Types/IP/IP.ts b/Common/Types/IP/IP.ts new file mode 100644 index 0000000000..09326c5b57 --- /dev/null +++ b/Common/Types/IP/IP.ts @@ -0,0 +1,27 @@ +import NotImplementedException from '../Exception/NotImplementedException'; + +export default class IP { + private _ip: string = ''; + public get ip(): string { + return this._ip; + } + public set ip(v: string) { + this._ip = v; + } + + public constructor(ip: string) { + this.ip = ip; + } + + public toString(): string { + return this.ip; + } + + public isIPv4(): boolean { + throw new NotImplementedException(); + } + + public isIPv6(): boolean { + throw new NotImplementedException(); + } +} diff --git a/Common/Types/IP/IPv4.ts b/Common/Types/IP/IPv4.ts new file mode 100644 index 0000000000..8f4144b10b --- /dev/null +++ b/Common/Types/IP/IPv4.ts @@ -0,0 +1,16 @@ +import IP from './IP'; + +export default class IPv4 extends IP { + public constructor(ip: string) { + // TODO: Validate if this is actually ipv4 before calling super() + super(ip); + } + + public override isIPv4(): boolean { + return true; + } + + public override isIPv6(): boolean { + return false; + } +} diff --git a/Common/Types/IP/IPv6.ts b/Common/Types/IP/IPv6.ts new file mode 100644 index 0000000000..99a3ef6481 --- /dev/null +++ b/Common/Types/IP/IPv6.ts @@ -0,0 +1,16 @@ +import IP from './IP'; + +export default class IPv6 extends IP { + public constructor(ip: string) { + // TODO: Validate if this is actually ipv6 before calling super() + super(ip); + } + + public override isIPv4(): boolean { + return false; + } + + public override isIPv6(): boolean { + return true; + } +} diff --git a/Common/Types/PositiveNumber.ts b/Common/Types/PositiveNumber.ts index 5d483048ff..379043be7a 100644 --- a/Common/Types/PositiveNumber.ts +++ b/Common/Types/PositiveNumber.ts @@ -9,7 +9,15 @@ export default class PositiveNumber { this._positiveNumber = v; } - public constructor(positiveNumber: number) { + public constructor(positiveNumber: number | string) { + if (typeof positiveNumber === 'string') { + try { + positiveNumber = Number.parseInt(positiveNumber, 10); + } catch (error) { + throw new BadDataException(`Invlaid number: ${positiveNumber}`); + } + } + if (positiveNumber < 0) { throw new BadDataException('positiveNumber cannot be less than 0'); } diff --git a/CommonServer/Config.ts b/CommonServer/Config.ts index 572c815aa7..91c6ab6b61 100644 --- a/CommonServer/Config.ts +++ b/CommonServer/Config.ts @@ -22,7 +22,13 @@ export const ClusterKey: ObjectID = new ObjectID( export const RealtimeHostname: string = process.env['REALTIME_HOSTNAME'] || ''; -export const BackendHostname: string = process.env['BACKEND_HOSTNAME'] || ''; +export const DashboardApiHostname: string = + process.env['DASHBOARD_API_HOSTNAME'] || ''; + +export const ProbeApiHostname: string = process.env['PROBE_API_HOSTNAME'] || ''; + +export const DataIngestorHostname: string = + process.env['DATA_INGESTOR_HOSTNAME'] || ''; export const Version: string = process.env['npm_package_version'] || ''; diff --git a/Probe/Utils/Config.ts b/Probe/Config.ts similarity index 75% rename from Probe/Utils/Config.ts rename to Probe/Config.ts index d1d1593de0..ad00b441d1 100755 --- a/Probe/Utils/Config.ts +++ b/Probe/Config.ts @@ -1,6 +1,7 @@ -import packageJson from '../package.json'; +import ObjectID from 'Common/Types/ObjectID'; +import PositiveNumber from 'Common/Types/PositiveNumber'; -const COMMAND: $TSFixMe = { +export const COMMAND: $TSFixMe = { linux: { load: "top -b -n 2 | egrep --color 'load average|%Cpu'", cpu: "egrep --color 'processor|cores' /proc/cpuinfo", @@ -36,13 +37,10 @@ const COMMAND: $TSFixMe = { }, }; -export default { - COMMAND, - serverUrl: process.env['SERVER_URL'], - probeName: process.env['PROBE_NAME'], - probeKey: process.env['PROBE_KEY'], - clusterKey: process.env['CLUSTER_KEY'], - probeVersion: packageJson.version, - dataIngestorUrl: process.env['DATA_INGESTOR_URL'], - probeApiUrl: process.env['PROBE_API_URL'], -}; +export const ProbeName: string = process.env['PROBE_NAME'] || ''; + +export const ProbeKey: ObjectID = new ObjectID(process.env['PROBE_KEY'] || ''); + +export const ResourcesLimit: PositiveNumber = new PositiveNumber( + process.env['RESOURCES_LIMIT'] || '' +); diff --git a/Probe/Index.ts b/Probe/Index.ts index 0aaf62244c..a3e82a247d 100755 --- a/Probe/Index.ts +++ b/Probe/Index.ts @@ -3,8 +3,8 @@ import 'CommonServer/utils/process'; import asyncSleep from 'await-sleep'; -import Main from './workers/main'; -import config from './utils/config'; +import Main from './Workers/Index'; +import config from './Config'; import logger from 'CommonServer/Utils/Logger'; const cronMinuteStartTime: $TSFixMe = Math.floor(Math.random() * 50); diff --git a/Probe/Utils/Api.ts b/Probe/Utils/Api.ts old mode 100755 new mode 100644 index bcc2df18a1..e69de29bb2 --- a/Probe/Utils/Api.ts +++ b/Probe/Utils/Api.ts @@ -1,128 +0,0 @@ -import axios from 'axios'; -import config from './config'; - -const _this: $TSFixMe = { - getHeaders: () => { - return { - 'Access-Control-Allow-Origin': '*', - Accept: 'application/json', - 'Content-Type': 'application/json;charset=UTF-8', - probeName: config.probeName, - probeKey: config.probeKey, - clusterKey: config.clusterKey, - probeVersion: config.probeVersion, - }; - }, - - post: (url: URL, data: $TSFixMe) => { - const headers: $TSFixMe = this.getHeaders(); - - return new Promise((resolve: Function, reject: Function) => { - /* - * Error [ERR_FR_MAX_BODY_LENGTH_EXCEEDED]: Request body larger than maxBodyLength limit - * https://stackoverflow.com/questions/58655532/increasing-maxcontentlength-and-maxbodylength-in-axios - */ - - axios({ - method: 'POST', - url: `${config.dataIngestorUrl}/${url}`, - headers, - data, - maxContentLength: Infinity, - maxBodyLength: Infinity, - }) - .then((response: $TSFixMe) => { - resolve(response.data); - }) - .then((error: Error) => { - if (error && error.response && error.response.data) { - error = error.response.data; - } - if (error && error.data) { - error = error.data; - } - reject(error); - }); - }); - }, - - get: (url: URL, limit: number = 10) => { - const headers: $TSFixMe = this.getHeaders(); - return new Promise((resolve: Function, reject: Function) => { - axios({ - method: 'GET', - url: `${config.probeApiUrl}/${url}?limit=${limit}`, - headers, - }) - .then((response: $TSFixMe) => { - resolve(response.data); - }) - .then((error: Error) => { - if (error && error.response && error.response.data) { - error = error.response.data; - } - if (error && error.data) { - error = error.data; - } - reject(error); - }); - }); - }, - - put: (url: URL, data: $TSFixMe) => { - const headers: $TSFixMe = this.getHeaders(); - return new Promise((resolve: Function, reject: Function) => { - /* - * Error [ERR_FR_MAX_BODY_LENGTH_EXCEEDED]: Request body larger than maxBodyLength limit - * https://stackoverflow.com/questions/58655532/increasing-maxcontentlength-and-maxbodylength-in-axios - */ - - axios({ - method: 'PUT', - url: `${config.dataIngestorUrl}/${url}`, - headers, - data, - maxContentLength: Infinity, - maxBodyLength: Infinity, - }) - .then((response: $TSFixMe) => { - resolve(response.data); - }) - .then((error: Error) => { - if (error && error.response && error.response.data) { - error = error.response.data; - } - if (error && error.data) { - error = error.data; - } - reject(error); - }); - }); - }, - - delete: (url: URL, data: $TSFixMe) => { - const headers: $TSFixMe = this.getHeaders(); - return new Promise((resolve: Function, reject: Function) => { - axios({ - method: 'DELETE', - url: `${config.dataIngestorUrl}/${url}`, - headers, - data, - }) - .then((response: $TSFixMe) => { - resolve(response.data); - }) - .then((error: Error) => { - if (error && error.response && error.response.data) { - error = error.response.data; - } - if (error && error.data) { - error = error.data; - } - reject(error); - }); - }); - }, -}; - -export default _this; diff --git a/Probe/Utils/ContainerService.ts b/Probe/Utils/ContainerService.ts deleted file mode 100644 index 67874fc8c2..0000000000 --- a/Probe/Utils/ContainerService.ts +++ /dev/null @@ -1,7 +0,0 @@ -import BackendAPI from './api'; - -export default { - scan: async function (security: $TSFixMe): void { - return await BackendAPI.post(`probe/scan/docker`, { security }); - }, -}; diff --git a/Probe/Utils/FsHandlers.ts b/Probe/Utils/FsHandlers.ts deleted file mode 100644 index 2d62689339..0000000000 --- a/Probe/Utils/FsHandlers.ts +++ /dev/null @@ -1,62 +0,0 @@ -import fs from 'fs'; -import Path from 'path'; -import { promisify } from 'util'; -const readdir: $TSFixMe = promisify(fs.readdir); -const rmdir: $TSFixMe = promisify(fs.rmdir); -const unlink: $TSFixMe = promisify(fs.unlink); - -/** - * @description a promise based utility to read content of a file - * @param {string} filePath path to file - */ -function readFileContent(filePath: $TSFixMe): void { - return new Promise((resolve: Function, reject: Function) => { - if (fs.existsSync(filePath)) { - fs.readFile( - filePath, - { encoding: 'utf8' }, - (error: $TSFixMe, data: $TSFixMe): void => { - if (error) { - reject(error); - } - resolve(data); - } - ); - } - }); -} - -/** - * @description an asynchronous function to handle deleting a file - * @param {string} file path to file - */ -async function deleteFile(file: $TSFixMe): void { - if (fs.existsSync(file)) { - await unlink(file); - } -} - -/** - * @description a promise based utility to handle deleting a folder and it's content - * @param {string} dir directory with or without file - */ -async function deleteFolderRecursive(dir: $TSFixMe): void { - if (fs.existsSync(dir)) { - const entries: $TSFixMe = await readdir(dir, { withFileTypes: true }); - await Promise.all( - entries.map((entry: $TSFixMe) => { - const fullPath: $TSFixMe = Path.join(dir, entry.name); - return entry.isDirectory() - ? deleteFolderRecursive(fullPath) - : unlink(fullPath); - }) - ); - await rmdir(dir); // Finally remove now empty directory - } -} - -export default { - readFileContent, - deleteFile, - deleteFolderRecursive, -}; diff --git a/Probe/Utils/Ping.ts b/Probe/Utils/Ping.ts new file mode 100644 index 0000000000..3763616d20 --- /dev/null +++ b/Probe/Utils/Ping.ts @@ -0,0 +1,18 @@ +import Hostname from 'Common/Types/API/Hostname'; +import IPv4 from 'Common/Types/IP/IPv4'; +import IPv6 from 'Common/Types/IP/IPv6'; +import PositiveNumber from 'Common/Types/PositiveNumber'; +import NotImplementedException from 'Common/Types/Exception/NotImplementedException'; + +export interface PingResponse { + isAlive: boolean; + responseTimeInMS: PositiveNumber; +} + +export default class Ping { + public static async fetch( + _host: Hostname | IPv4 | IPv6 + ): Promise { + throw new NotImplementedException(); + } +} diff --git a/Probe/Utils/PingFetch.ts b/Probe/Utils/PingFetch.ts index 351a43b375..c02e40dc29 100644 --- a/Probe/Utils/PingFetch.ts +++ b/Probe/Utils/PingFetch.ts @@ -1,6 +1,5 @@ import logger from 'CommonServer/Utils/Logger'; import fetch from 'node-fetch-commonjs'; - import sslCert from 'get-ssl-certificate'; import https from 'https'; import http from 'http'; diff --git a/Probe/Utils/SSL.ts b/Probe/Utils/SSL.ts new file mode 100644 index 0000000000..1b133c0f07 --- /dev/null +++ b/Probe/Utils/SSL.ts @@ -0,0 +1,24 @@ +import Hostname from 'Common/Types/API/Hostname'; +import NotImplementedException from 'Common/Types/Exception/NotImplementedException'; + +export interface SslResponse { + isSelfSigned: boolean; + createdAt: Date; + expiresAt: Date; + commonName: string; + organizationalUnit: string; + organization: string; + locality: string; + state: string; + country: string; + serialNumber: string; + fingerprint: string; + fingerprint256: string; + fingerprint512: string; +} + +export default class SSL { + public static async fetch(_host: Hostname): Promise { + throw new NotImplementedException(); + } +} diff --git a/Probe/Utils/Website.ts b/Probe/Utils/Website.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Probe/Workers/Main.ts b/Probe/Workers/Index.ts similarity index 95% rename from Probe/Workers/Main.ts rename to Probe/Workers/Index.ts index 62ce845cba..a85f5eb069 100755 --- a/Probe/Workers/Main.ts +++ b/Probe/Workers/Index.ts @@ -1,20 +1,19 @@ import logger from 'CommonServer/Utils/Logger'; import ProbeAPI from '../Utils/api'; -import ApiMonitors from './apiMonitors'; -import UrlMonitors from './urlMonitors'; -import IPMonitors from './ipMonitors'; -import ServerMonitors from './serverMonitors'; - +import ApiMonitors from './ApiMonitors'; +import UrlMonitors from './UrlMonitors'; +import IPMonitors from './IpMonitors'; +import ServerMonitors from './ServerMonitors'; +import asyncSleep from 'await-sleep'; import IncomingHttpRequestMonitors from './incomingHttpRequestMonitors'; import KubernetesMonitors from './kubernetesMonitors'; + let limit: $TSFixMe = process.env['RESOURCES_LIMIT']; if (limit && typeof limit === 'string') { limit = parseInt(limit); } -import asyncSleep from 'await-sleep'; - const _this: $TSFixMe = { runJob: async function (): void { logger.info(`Getting a list of ${limit} monitors`); diff --git a/Probe/Workers/KubernetesMonitors.ts b/Probe/Workers/KubernetesMonitors.ts index bde649d25a..ab097ac1ef 100644 --- a/Probe/Workers/KubernetesMonitors.ts +++ b/Probe/Workers/KubernetesMonitors.ts @@ -2,12 +2,9 @@ import { spawn } from 'child_process'; import fs from 'fs'; import Path from 'path'; import fetch from 'node-fetch-commonjs'; - import { v4 as uuidv4 } from 'uuid'; import ApiService from '../Utils/apiService'; - import { serverUrl } from '../Config'; - import { deleteFile } from '../Utils/fsHandlers'; export default { diff --git a/Probe/tsconfig.json b/Probe/tsconfig.json index dfdad2c2a5..12fe7a7861 100644 --- a/Probe/tsconfig.json +++ b/Probe/tsconfig.json @@ -49,7 +49,7 @@ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./build/dist", /* Specify an output folder for all emitted files. */ + "outDir": "build/dist", /* Specify an output folder for all emitted files. */ // "removeComments": true, /* Disable emitting comments. */ // "noEmit": true, /* Disable emitting files from a compilation. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */