Feat Prometheus metrics (#1299)

* Russian translation

* Add Prometheus metrics
[Feat]: Simple Stats API #1285

* Revert "Add Prometheus metrics"

This reverts commit a998f6be8a.

* Add Prometheus metrics
[Feat]: Simple Stats API #1285

* Fix short link. Generate One Time Link (#1301)

Co-authored-by: Vadim Babadzhanyan <vadim.babadzhanyan@my.games>

* fix one time links (#1304)

Closes #1302
Co-authored-by: Bernd Storath <999999bst@gmail.com>

* fixup: issue templates due to labels reorg

Signed-off-by: Philip H <47042125+pheiduck@users.noreply.github.com>

* Separate port for prometheus metrics
Add Prometheus metrics [Feat]: Simple Stats API #1285

* Separate port for prometheus metrics
Add Prometheus metrics [Feat]: Simple Stats API #1285

* Fix port in Readme
Separate port for prometheus metrics
Add Prometheus metrics [Feat]: Simple Stats API #1285

* Add Prometheus port in Service
Separate port for prometheus metrics
Add Prometheus metrics [Feat]: Simple Stats API #1285

* Revert "Add Prometheus port in Service"

This reverts commit a7376abcf1.

* Revert "Fix port in Readme"

This reverts commit 9760bde2f2.

* Revert "Separate port for prometheus metrics"

This reverts commit 58f5b6806e.

* Revert "Separate port for prometheus metrics"

This reverts commit 6d246ea4bd.

* Add Prometheus metrics with Basic Auth
[Feat]: Simple Stats API #1285

* Disable by default
[Feat]: Simple Stats API #1285

* [Feat]: Simple Stats API #1285

* Update README.md

---------

Co-authored-by: Vadim Babadzhanyan <vadim.babadzhanyan@my.games>
Co-authored-by: Bernd Storath <bernd.storath@offizium.de>
Co-authored-by: Philip H <47042125+pheiduck@users.noreply.github.com>
This commit is contained in:
Vadim Babadzhanyan
2024-08-23 13:10:20 +03:00
committed by GitHub
parent 41be774761
commit 7be9884aec
7 changed files with 156 additions and 6 deletions

View File

@@ -2,6 +2,7 @@
const bcrypt = require('bcryptjs');
const crypto = require('node:crypto');
const basicAuth = require('basic-auth');
const { createServer } = require('node:http');
const { stat, readFile } = require('node:fs/promises');
const { resolve, sep } = require('node:path');
@@ -36,9 +37,12 @@ const {
WG_ENABLE_ONE_TIME_LINKS,
UI_ENABLE_SORT_CLIENTS,
WG_ENABLE_EXPIRES_TIME,
ENABLE_PROMETHEUS_METRICS,
PROMETHEUS_METRICS_PASSWORD,
} = require('../config');
const requiresPassword = !!PASSWORD_HASH;
const requiresPrometheusPassword = !!PROMETHEUS_METRICS_PASSWORD;
/**
* Checks if `password` matches the PASSWORD_HASH.
@@ -48,13 +52,12 @@ const requiresPassword = !!PASSWORD_HASH;
* @param {string} password String to test
* @returns {boolean} true if matching environment, otherwise false
*/
const isPasswordValid = (password) => {
const isPasswordValid = (password, hash) => {
if (typeof password !== 'string') {
return false;
}
if (PASSWORD_HASH) {
return bcrypt.compareSync(password, PASSWORD_HASH);
if (hash) {
return bcrypt.compareSync(password, hash);
}
return false;
@@ -162,7 +165,7 @@ module.exports = class Server {
});
}
if (!isPasswordValid(password)) {
if (!isPasswordValid(password, PASSWORD_HASH)) {
throw createError({
status: 401,
message: 'Incorrect Password',
@@ -192,7 +195,7 @@ module.exports = class Server {
}
if (req.url.startsWith('/api/') && req.headers['authorization']) {
if (isPasswordValid(req.headers['authorization'])) {
if (isPasswordValid(req.headers['authorization'], PASSWORD_HASH)) {
return next();
}
return res.status(401).json({
@@ -332,6 +335,51 @@ module.exports = class Server {
});
};
// Prometheus Metrics API
const routerPrometheusMetrics = createRouter();
app.use(routerPrometheusMetrics);
// Check Prometheus credentials
app.use(
fromNodeMiddleware((req, res, next) => {
if (!requiresPrometheusPassword || !req.url.startsWith('/metrics')) {
return next();
}
const user = basicAuth(req);
if (requiresPrometheusPassword && !user) {
res.statusCode = 401;
return { error: 'Not Logged In' };
}
if (user.pass) {
if (isPasswordValid(user.pass, PROMETHEUS_METRICS_PASSWORD)) {
return next();
}
res.statusCode = 401;
return { error: 'Incorrect Password' };
}
res.statusCode = 401;
return { error: 'Not Logged In' };
}),
);
// Prometheus Routes
routerPrometheusMetrics
.get('/metrics', defineEventHandler(async (event) => {
setHeader(event, 'Content-Type', 'text/plain');
if (ENABLE_PROMETHEUS_METRICS === 'true') {
return WireGuard.getMetrics();
}
return '';
}))
.get('/metrics/json', defineEventHandler(async (event) => {
setHeader(event, 'Content-Type', 'application/json');
if (ENABLE_PROMETHEUS_METRICS === 'true') {
return WireGuard.getMetricsJSON();
}
return '';
}));
// backup_restore
const router3 = createRouter();
app.use(router3);