make ip check in health checks more reliable
This commit is contained in:
parent
f2258cf27e
commit
0292f57f3e
|
@ -0,0 +1,23 @@
|
||||||
|
name: Test - packages/health-check
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- packages/health-check/**
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: packages/health-check
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: 16.x
|
||||||
|
|
||||||
|
- run: yarn
|
||||||
|
- run: yarn jest
|
|
@ -7,10 +7,10 @@ WORKDIR /usr/app
|
||||||
ENV PATH="/usr/app/bin:${PATH}"
|
ENV PATH="/usr/app/bin:${PATH}"
|
||||||
|
|
||||||
# schedule critical checks to run every 5 minutes (any failures will disable server)
|
# schedule critical checks to run every 5 minutes (any failures will disable server)
|
||||||
RUN echo '*/5 * * * * /usr/app/bin/cli run critical > /dev/stdout' >> /etc/crontabs/root
|
RUN echo '*/5 * * * * source /etc/environment ; /usr/app/bin/cli run critical >> /proc/1/fd/1' >> /etc/crontabs/root
|
||||||
|
|
||||||
# schedule extended checks to run on every hour (optional checks, report only)
|
# schedule extended checks to run on every hour (optional checks, report only)
|
||||||
RUN echo '0 * * * * /usr/app/bin/cli run extended > /dev/stdout' >> /etc/crontabs/root
|
RUN echo '0 * * * * source /etc/environment ; /usr/app/bin/cli run extended >> /proc/1/fd/1' >> /etc/crontabs/root
|
||||||
|
|
||||||
COPY package.json yarn.lock ./
|
COPY package.json yarn.lock ./
|
||||||
|
|
||||||
|
@ -30,9 +30,10 @@ ENV NODE_ENV production
|
||||||
# 3. start crond in the background to schedule periodic health checks
|
# 3. start crond in the background to schedule periodic health checks
|
||||||
# 4. start the health-check api service
|
# 4. start the health-check api service
|
||||||
CMD [ "sh", "-c", \
|
CMD [ "sh", "-c", \
|
||||||
"serverip=$(node src/whatismyip.js) ; \
|
"serverip=$(node src/whatismyip.js) && \
|
||||||
dnsmasq --no-resolv --log-facility=/var/log/dnsmasq.log --address=/$PORTAL_DOMAIN/$serverip --server=127.0.0.11 ; \
|
echo export serverip=${serverip} >> /etc/environment && \
|
||||||
echo \"$(sed 's/127.0.0.11/127.0.0.1/' /etc/resolv.conf)\" > /etc/resolv.conf ; \
|
dnsmasq --no-resolv --log-facility=/var/log/dnsmasq.log --address=/$PORTAL_DOMAIN/$serverip --server=127.0.0.11 && \
|
||||||
crond ; \
|
echo \"$(sed 's/127.0.0.11/127.0.0.1/' /etc/resolv.conf)\" > /etc/resolv.conf && \
|
||||||
|
crond && \
|
||||||
node src/index.js" \
|
node src/index.js" \
|
||||||
]
|
]
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
"yargs": "^17.3.1"
|
"yargs": "^17.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"jest": "^27.5.0",
|
||||||
"prettier": "^2.5.1"
|
"prettier": "^2.5.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
const got = require("got");
|
const got = require("got");
|
||||||
|
const { ipCheckService, ipRegex } = require("../utils");
|
||||||
|
|
||||||
const getCurrentAddress = async () => {
|
const getCurrentAddress = async () => {
|
||||||
|
// use serverip env variable when available (set via Dockerfile)
|
||||||
|
if (process.env.serverip) return process.env.serverip;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { body } = await got("http://whatismyip.akamai.com");
|
const { body } = await got(`http://${ipCheckService}`);
|
||||||
if (body) return body;
|
if (ipRegex.test(body)) return body;
|
||||||
throw new Error("whatismyip.akamai.com responded with empty body");
|
|
||||||
|
throw new Error(`${ipCheckService} responded with invalid ip: "${body}"`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error.message);
|
console.log(error.message); // log error to console for future reference
|
||||||
return "-- error fetching ip address from whatismyip.akamai.com --";
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,7 +21,8 @@ module.exports = async function middleware() {
|
||||||
const ip = await getCurrentAddress();
|
const ip = await getCurrentAddress();
|
||||||
|
|
||||||
return (check) => {
|
return (check) => {
|
||||||
if (check.ip && check.ip !== ip) {
|
// check only if current ip and check ip are provided
|
||||||
|
if (ip && check.ip && check.ip !== ip) {
|
||||||
check.up = false;
|
check.up = false;
|
||||||
check.errors = check.errors ?? [];
|
check.errors = check.errors ?? [];
|
||||||
check.errors.push({
|
check.errors.push({
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
const got = require("got");
|
const ipCheckService = "whatismyip.akamai.com";
|
||||||
|
const ipRegex = new RegExp(
|
||||||
|
`^(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}$`
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the time between start and now in milliseconds
|
* Get the time between start and now in milliseconds
|
||||||
|
@ -60,6 +63,8 @@ function getAuthCookie() {
|
||||||
if (!password) throw new Error("ACCOUNTS_TEST_USER_PASSWORD cannot be empty");
|
if (!password) throw new Error("ACCOUNTS_TEST_USER_PASSWORD cannot be empty");
|
||||||
|
|
||||||
async function authenticate() {
|
async function authenticate() {
|
||||||
|
const got = require("got");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// authenticate with given test user credentials
|
// authenticate with given test user credentials
|
||||||
const response = await got.post(`${process.env.SKYNET_DASHBOARD_URL}/api/login`, {
|
const response = await got.post(`${process.env.SKYNET_DASHBOARD_URL}/api/login`, {
|
||||||
|
@ -114,4 +119,6 @@ module.exports = {
|
||||||
ensureValidJSON,
|
ensureValidJSON,
|
||||||
getAuthCookie,
|
getAuthCookie,
|
||||||
isPortalModuleEnabled,
|
isPortalModuleEnabled,
|
||||||
|
ipCheckService,
|
||||||
|
ipRegex,
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
describe("ipRegex", () => {
|
||||||
|
const { ipRegex } = require("./utils");
|
||||||
|
|
||||||
|
test("should test true for valid ip", () => {
|
||||||
|
expect(ipRegex.test("8.8.8.8")).toEqual(true);
|
||||||
|
expect(ipRegex.test("127.0.0.1")).toEqual(true);
|
||||||
|
expect(ipRegex.test("192.168.0.1")).toEqual(true);
|
||||||
|
expect(ipRegex.test("10.10.10.10")).toEqual(true);
|
||||||
|
expect(ipRegex.test("135.124.12.47")).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should test false for invalid ip", () => {
|
||||||
|
expect(ipRegex.test("888.8.8.8")).toEqual(false);
|
||||||
|
expect(ipRegex.test("....")).toEqual(false);
|
||||||
|
expect(ipRegex.test(null)).toEqual(false);
|
||||||
|
expect(ipRegex.test("foo")).toEqual(false);
|
||||||
|
expect(ipRegex.test("")).toEqual(false);
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,13 +1,18 @@
|
||||||
const http = require("http");
|
const http = require("http");
|
||||||
|
const { ipCheckService, ipRegex } = require("./utils");
|
||||||
|
|
||||||
const request = http.request({ host: "whatismyip.akamai.com" }, (response) => {
|
const request = http.request({ host: ipCheckService }, (response) => {
|
||||||
response.on("data", (data) => {
|
response.on("data", (data) => {
|
||||||
process.stdout.write(data);
|
if (ipRegex.test(data)) {
|
||||||
|
process.stdout.write(data);
|
||||||
|
} else {
|
||||||
|
throw new Error(`${ipCheckService} responded with invalid ip: "${data}"`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
request.on("error", (error) => {
|
request.on("error", (error) => {
|
||||||
console.error(error);
|
throw error; // throw error to exit with code 1
|
||||||
});
|
});
|
||||||
|
|
||||||
request.end();
|
request.end();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue