From 02e0e45bc461d2b8880d0fcf666b4328fa5915c1 Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Mon, 24 May 2021 16:27:30 +0200 Subject: [PATCH 1/6] add new critical checks --- packages/health-check/src/checks/critical.js | 71 +++++++++++++------- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/packages/health-check/src/checks/critical.js b/packages/health-check/src/checks/critical.js index 4fe48f39..a39ad8a2 100644 --- a/packages/health-check/src/checks/critical.js +++ b/packages/health-check/src/checks/critical.js @@ -1,7 +1,10 @@ const got = require("got"); const FormData = require("form-data"); -const { StatusCodes } = require("http-status-codes"); const { calculateElapsedTime, getResponseContent } = require("../utils"); +const { SkynetClient } = require("skynet-js"); + +const skynetClient = new SkynetClient(process.env.SKYNET_PORTAL_API); +const exampleSkylink = "AACogzrAimYPG42tDOKhS3lXZD8YvlF8Q8R17afe95iV2Q"; // uploadCheck returns the result of uploading a sample file async function uploadCheck(done) { @@ -25,37 +28,33 @@ async function uploadCheck(done) { data.ip = error?.response?.ip ?? null; } - done({ - name: "upload_file", - time: calculateElapsedTime(time), - ...data, - }); + done({ name: "upload_file", time: calculateElapsedTime(time), ...data }); +} + +// websiteCheck checks whether the main website is working +async function websiteCheck(done) { + return genericAccessCheck("website", process.env.SKYNET_PORTAL_API, done); } // downloadCheck returns the result of downloading the hard coded link async function downloadCheck(done) { - const time = process.hrtime(); - const skylink = "AACogzrAimYPG42tDOKhS3lXZD8YvlF8Q8R17afe95iV2Q"; - const data = { up: false }; + const url = await skynetClient.getSkylinkUrl(exampleSkylink); - try { - const response = await got(`${process.env.SKYNET_PORTAL_API}/${skylink}?nocache=true`); + return genericAccessCheck("skylink", url, done); +} - data.statusCode = response.statusCode; - data.up = true; - data.ip = response.ip; - } catch (error) { - data.statusCode = error?.response?.statusCode || error.statusCode || error.status; - data.errorMessage = error.message; - data.errorResponseContent = getResponseContent(error.response); - data.ip = error?.response?.ip ?? null; - } +// skylinkSubdomainCheck returns the result of downloading the hard coded link via subdomain +async function skylinkSubdomainCheck(done) { + const url = await skynetClient.getSkylinkUrl(exampleSkylink, { subdomain: true }); - done({ - name: "download_file", - time: calculateElapsedTime(time), - ...data, - }); + return genericAccessCheck("skylink_via_subdomain", done); +} + +// skylinkSubdomainCheck returns the result of downloading the hard coded link via subdomain +async function handshakeSubdomainCheck(done) { + const url = await skynetClient.getHnsUrl("note-to-self", { subdomain: true }); + + return genericAccessCheck("hns_via_subdomain", url, done); } async function accountHealthCheck(done) { @@ -83,7 +82,27 @@ async function accountHealthCheck(done) { }); } -const checks = [uploadCheck, downloadCheck]; +async function genericAccessCheck(name, url, done) { + const time = process.hrtime(); + const data = { up: false, url }; + + try { + const response = await got(url, { headers: { cookie: "nocache=true" } }); + + data.statusCode = response.statusCode; + data.up = true; + data.ip = response.ip; + } catch (error) { + data.statusCode = error?.response?.statusCode || error.statusCode || error.status; + data.errorMessage = error.message; + data.errorResponseContent = getResponseContent(error.response); + data.ip = error?.response?.ip ?? null; + } + + done({ name, time: calculateElapsedTime(time), ...data }); +} + +const checks = [uploadCheck, websiteCheck, downloadCheck, skylinkSubdomainCheck, handshakeSubdomainCheck]; if (process.env.ACCOUNTS_ENABLED) { checks.push(accountHealthCheck); From a2f7b7581a800be0c5bea601817f285c25cb7d9a Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Mon, 24 May 2021 16:47:39 +0200 Subject: [PATCH 2/6] fix argument list --- packages/health-check/src/checks/critical.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/health-check/src/checks/critical.js b/packages/health-check/src/checks/critical.js index a39ad8a2..838cb6c0 100644 --- a/packages/health-check/src/checks/critical.js +++ b/packages/health-check/src/checks/critical.js @@ -47,7 +47,7 @@ async function downloadCheck(done) { async function skylinkSubdomainCheck(done) { const url = await skynetClient.getSkylinkUrl(exampleSkylink, { subdomain: true }); - return genericAccessCheck("skylink_via_subdomain", done); + return genericAccessCheck("skylink_via_subdomain", url, done); } // skylinkSubdomainCheck returns the result of downloading the hard coded link via subdomain From 175ee075c792f6d4b448d8485b7b021b38178bdb Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Mon, 24 May 2021 17:07:37 +0200 Subject: [PATCH 3/6] fix comments and add new account test --- packages/health-check/src/checks/critical.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/health-check/src/checks/critical.js b/packages/health-check/src/checks/critical.js index 838cb6c0..1c51cfdb 100644 --- a/packages/health-check/src/checks/critical.js +++ b/packages/health-check/src/checks/critical.js @@ -50,13 +50,19 @@ async function skylinkSubdomainCheck(done) { return genericAccessCheck("skylink_via_subdomain", url, done); } -// skylinkSubdomainCheck returns the result of downloading the hard coded link via subdomain +// handshakeSubdomainCheck returns the result of downloading the skylink via handshake domain async function handshakeSubdomainCheck(done) { const url = await skynetClient.getHnsUrl("note-to-self", { subdomain: true }); return genericAccessCheck("hns_via_subdomain", url, done); } +// handshakeSubdomainCheck returns the result of accessing account dashboard website +async function accountWebsiteCheck(done) { + return genericAccessCheck("account_website", process.env.SKYNET_DASHBOARD_URL, done); +} + +// accountHealthCheck returns the result of accounts service health checks async function accountHealthCheck(done) { const time = process.hrtime(); const data = { up: false }; @@ -75,11 +81,7 @@ async function accountHealthCheck(done) { data.ip = error?.response?.ip ?? null; } - done({ - name: "account_health", - time: calculateElapsedTime(time), - ...data, - }); + done({ name: "accounts", time: calculateElapsedTime(time), ...data }); } async function genericAccessCheck(name, url, done) { @@ -105,7 +107,7 @@ async function genericAccessCheck(name, url, done) { const checks = [uploadCheck, websiteCheck, downloadCheck, skylinkSubdomainCheck, handshakeSubdomainCheck]; if (process.env.ACCOUNTS_ENABLED) { - checks.push(accountHealthCheck); + checks.push(accountHealthCheck, accountWebsiteCheck); } module.exports = checks; From 838d82c3b50567a7ce693d81ecda9402e7cbee8c Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Mon, 24 May 2021 17:12:16 +0200 Subject: [PATCH 4/6] redirect to /login --- packages/health-check/src/checks/critical.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/health-check/src/checks/critical.js b/packages/health-check/src/checks/critical.js index 1c51cfdb..6a13a20b 100644 --- a/packages/health-check/src/checks/critical.js +++ b/packages/health-check/src/checks/critical.js @@ -59,7 +59,9 @@ async function handshakeSubdomainCheck(done) { // handshakeSubdomainCheck returns the result of accessing account dashboard website async function accountWebsiteCheck(done) { - return genericAccessCheck("account_website", process.env.SKYNET_DASHBOARD_URL, done); + const url = `${process.env.SKYNET_DASHBOARD_URL}/auth/login`; + + return genericAccessCheck("account_website", url, done); } // accountHealthCheck returns the result of accounts service health checks From 6649726598e51eb740ac9d65af4c8a0ab357d892 Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Mon, 24 May 2021 17:13:29 +0200 Subject: [PATCH 5/6] move crontab fill on top --- packages/health-check/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/health-check/Dockerfile b/packages/health-check/Dockerfile index dcae0b1b..214200e3 100644 --- a/packages/health-check/Dockerfile +++ b/packages/health-check/Dockerfile @@ -2,14 +2,14 @@ FROM node:16.1.0-alpine WORKDIR /usr/app +RUN echo '*/5 * * * * /usr/app/cli/run critical > /dev/stdout' >> /etc/crontabs/root +RUN echo '0 * * * * /usr/app/cli/run extended > /dev/stdout' >> /etc/crontabs/root + COPY package.json . RUN yarn --no-lockfile COPY src src COPY cli cli -RUN echo '*/5 * * * * /usr/app/cli/run critical > /dev/stdout' >> /etc/crontabs/root -RUN echo '0 * * * * /usr/app/cli/run extended > /dev/stdout' >> /etc/crontabs/root - EXPOSE 3100 ENV NODE_ENV production CMD [ "sh", "-c", "crond ; echo $(node src/whatismyip.js) siasky.net account.siasky.net >> /etc/hosts ; node --max-http-header-size=64000 src/index.js" ] From 0a5b6bbe70132dd2963567f32fb7f0a5155ce5da Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Mon, 24 May 2021 17:30:29 +0200 Subject: [PATCH 6/6] add more comments --- packages/health-check/Dockerfile | 9 +++++++++ packages/health-check/src/checks/critical.js | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/health-check/Dockerfile b/packages/health-check/Dockerfile index 214200e3..d4cbe9df 100644 --- a/packages/health-check/Dockerfile +++ b/packages/health-check/Dockerfile @@ -2,7 +2,10 @@ FROM node:16.1.0-alpine WORKDIR /usr/app +# schedule critical checks to run every 5 minutes (any failures will disable server) RUN echo '*/5 * * * * /usr/app/cli/run critical > /dev/stdout' >> /etc/crontabs/root + +# schedule extended checks to run on every hour (optional checks, report only) RUN echo '0 * * * * /usr/app/cli/run extended > /dev/stdout' >> /etc/crontabs/root COPY package.json . @@ -12,4 +15,10 @@ COPY cli cli EXPOSE 3100 ENV NODE_ENV production + +# command consists of 3 parts: +# 1. starting crond +# 2. aliasing siasky.net and account.siasky.net with current server ip so health checks +# test portal end-to-end on prod domain (important for testing ssl certificates) +# 3. running api service CMD [ "sh", "-c", "crond ; echo $(node src/whatismyip.js) siasky.net account.siasky.net >> /etc/hosts ; node --max-http-header-size=64000 src/index.js" ] diff --git a/packages/health-check/src/checks/critical.js b/packages/health-check/src/checks/critical.js index 6a13a20b..9b71ab03 100644 --- a/packages/health-check/src/checks/critical.js +++ b/packages/health-check/src/checks/critical.js @@ -57,7 +57,7 @@ async function handshakeSubdomainCheck(done) { return genericAccessCheck("hns_via_subdomain", url, done); } -// handshakeSubdomainCheck returns the result of accessing account dashboard website +// accountWebsiteCheck returns the result of accessing account dashboard website async function accountWebsiteCheck(done) { const url = `${process.env.SKYNET_DASHBOARD_URL}/auth/login`;