v0.5.178: graceful shutdown, CSRF_SECRET fail-fast, /ready probe
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ipwhitelist",
|
"name": "ipwhitelist",
|
||||||
"version": "0.5.177",
|
"version": "0.5.178",
|
||||||
"description": "IP WhiteList microservice for cloud provider",
|
"description": "IP WhiteList microservice for cloud provider",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -74,10 +74,22 @@ async function start() {
|
|||||||
console.error('FATAL: DB_PASS не задан в production!');
|
console.error('FATAL: DB_PASS не задан в production!');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
if (!process.env.CSRF_SECRET || process.env.CSRF_SECRET === 'dev-csrf-secret-change-in-prod') {
|
||||||
|
console.error('FATAL: CSRF_SECRET не задан или равен дефолту в production!');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// k8s liveness probe — простая проверка что сервер жив
|
// k8s liveness + readiness probes
|
||||||
app.get('/healthz', (req, res) => res.send('OK'));
|
app.get('/healthz', (req, res) => res.send('OK'));
|
||||||
|
app.get('/ready', async (req, res) => {
|
||||||
|
try {
|
||||||
|
await pool.query('SELECT 1');
|
||||||
|
res.send('OK');
|
||||||
|
} catch (e) {
|
||||||
|
res.status(503).send('DB not ready');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// JWKS endpoint для валидации токенов внешними сервисами (только в mock-режиме)
|
// JWKS endpoint для валидации токенов внешними сервисами (только в mock-режиме)
|
||||||
if (auth.jwksHandler) app.get('/.well-known/jwks.json', auth.jwksHandler);
|
if (auth.jwksHandler) app.get('/.well-known/jwks.json', auth.jwksHandler);
|
||||||
@@ -123,7 +135,20 @@ async function start() {
|
|||||||
// Запускаем сервер только если файл запущен напрямую (не через require)
|
// Запускаем сервер только если файл запущен напрямую (не через require)
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
start()
|
start()
|
||||||
.then(a => a.listen(PORT, () => console.log('Server on port ' + PORT)))
|
.then(a => {
|
||||||
|
const server = a.listen(PORT, () => console.log('Server on port ' + PORT));
|
||||||
|
// Graceful shutdown по SIGTERM (k8s)
|
||||||
|
process.on('SIGTERM', () => {
|
||||||
|
console.log('SIGTERM — shutting down...');
|
||||||
|
server.close(() => {
|
||||||
|
console.log('HTTP closed');
|
||||||
|
const { pool } = require('./src/db');
|
||||||
|
pool.end().then(() => { console.log('DB pool closed'); process.exit(0); });
|
||||||
|
});
|
||||||
|
setTimeout(() => { console.log('Forced exit'); process.exit(0); }, 10000);
|
||||||
|
});
|
||||||
|
return server;
|
||||||
|
})
|
||||||
.catch(e => { console.error('Startup error:', e); process.exit(1); });
|
.catch(e => { console.error('Startup error:', e); process.exit(1); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
// ═══════════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
version: '0.5.177',
|
version: '0.5.178',
|
||||||
|
|
||||||
// ── IAM ──────────────────────────────────────────────────────────────────
|
// ── IAM ──────────────────────────────────────────────────────────────────
|
||||||
iamUrl: process.env.V2_IAM_URL || 'https://auth-api.ngcloud.ru/api/v1/auth/user',
|
iamUrl: process.env.V2_IAM_URL || 'https://auth-api.ngcloud.ru/api/v1/auth/user',
|
||||||
|
|||||||
Reference in New Issue
Block a user