mirror of
https://github.com/fosrl/pangolin.git
synced 2026-08-19 02:32:56 +02:00
Compare commits
1 Commits
1.18.0
..
8ed9adbfae
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ed9adbfae |
+1
-1
@@ -1432,7 +1432,7 @@
|
||||
"alertingTriggerHcToggle": "Gesundheits-Check-Status ändern",
|
||||
"alertingTriggerResourceHealthy": "Ressource gesund",
|
||||
"alertingTriggerResourceUnhealthy": "Ressource ungesund",
|
||||
"alertingTriggerResourceDegraded": "Resource degraded",
|
||||
"alertingTriggerResourceDegraded": "Ressource verschlechtert",
|
||||
"alertingSearchHealthChecks": "Gesundheits-Checks suchen…",
|
||||
"alertingHealthChecksEmpty": "Keine Gesundheits-Checks verfügbar.",
|
||||
"alertingTriggerResourceToggle": "Ressourcenstatus ändern",
|
||||
|
||||
+15
-21
@@ -1,5 +1,5 @@
|
||||
import { z } from "zod";
|
||||
import { db, logsDb, statusHistory } from "@server/db";
|
||||
import { db, statusHistory } from "@server/db";
|
||||
import { and, eq, gte, asc } from "drizzle-orm";
|
||||
import cache from "@server/lib/cache";
|
||||
|
||||
@@ -27,7 +27,7 @@ export async function getCachedStatusHistory(
|
||||
const nowSec = Math.floor(Date.now() / 1000);
|
||||
const startSec = nowSec - days * 86400;
|
||||
|
||||
const events = await logsDb
|
||||
const events = await db
|
||||
.select()
|
||||
.from(statusHistory)
|
||||
.where(
|
||||
@@ -74,11 +74,11 @@ export const statusHistoryQuerySchema = z
|
||||
days: z
|
||||
.string()
|
||||
.optional()
|
||||
.transform((v) => (v ? parseInt(v, 10) : 90))
|
||||
.transform((v) => (v ? parseInt(v, 10) : 90)),
|
||||
})
|
||||
.pipe(
|
||||
z.object({
|
||||
days: z.number().int().min(1).max(365)
|
||||
days: z.number().int().min(1).max(365),
|
||||
})
|
||||
);
|
||||
|
||||
@@ -99,14 +99,7 @@ export interface StatusHistoryResponse {
|
||||
}
|
||||
|
||||
export function computeBuckets(
|
||||
events: {
|
||||
entityType: string;
|
||||
entityId: number;
|
||||
orgId: string;
|
||||
status: string;
|
||||
timestamp: number;
|
||||
id: number;
|
||||
}[],
|
||||
events: { entityType: string; entityId: number; orgId: string; status: string; timestamp: number; id: number }[],
|
||||
days: number
|
||||
): { buckets: StatusHistoryDayBucket[]; totalDowntime: number } {
|
||||
const nowSec = Math.floor(Date.now() / 1000);
|
||||
@@ -128,8 +121,7 @@ export function computeBuckets(
|
||||
|
||||
const currentStatus = lastBeforeDay?.status ?? null;
|
||||
|
||||
const windows: { start: number; end: number | null; status: string }[] =
|
||||
[];
|
||||
const windows: { start: number; end: number | null; status: string }[] = [];
|
||||
let dayDowntime = 0;
|
||||
let dayDegradedTime = 0;
|
||||
|
||||
@@ -140,21 +132,22 @@ export function computeBuckets(
|
||||
if (windowStatus !== null && windowStatus !== evt.status) {
|
||||
const windowEnd = evt.timestamp;
|
||||
const isDown =
|
||||
windowStatus === "offline" || windowStatus === "unhealthy";
|
||||
windowStatus === "offline" ||
|
||||
windowStatus === "unhealthy";
|
||||
const isDegraded = windowStatus === "degraded";
|
||||
if (isDown) {
|
||||
dayDowntime += windowEnd - windowStart;
|
||||
windows.push({
|
||||
start: windowStart,
|
||||
end: windowEnd,
|
||||
status: windowStatus
|
||||
status: windowStatus,
|
||||
});
|
||||
} else if (isDegraded) {
|
||||
dayDegradedTime += windowEnd - windowStart;
|
||||
windows.push({
|
||||
start: windowStart,
|
||||
end: windowEnd,
|
||||
status: windowStatus
|
||||
status: windowStatus,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -166,21 +159,22 @@ export function computeBuckets(
|
||||
if (windowStatus !== null) {
|
||||
const finalEnd = Math.min(dayEndSec, nowSec);
|
||||
const isDown =
|
||||
windowStatus === "offline" || windowStatus === "unhealthy";
|
||||
windowStatus === "offline" ||
|
||||
windowStatus === "unhealthy";
|
||||
const isDegraded = windowStatus === "degraded";
|
||||
if (isDown && finalEnd > windowStart) {
|
||||
dayDowntime += finalEnd - windowStart;
|
||||
windows.push({
|
||||
start: windowStart,
|
||||
end: finalEnd,
|
||||
status: windowStatus
|
||||
status: windowStatus,
|
||||
});
|
||||
} else if (isDegraded && finalEnd > windowStart) {
|
||||
dayDegradedTime += finalEnd - windowStart;
|
||||
windows.push({
|
||||
start: windowStart,
|
||||
end: finalEnd,
|
||||
status: windowStatus
|
||||
status: windowStatus,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -231,7 +225,7 @@ export function computeBuckets(
|
||||
uptimePercent: Math.round(uptimePct * 100) / 100,
|
||||
totalDowntimeSeconds: dayDowntime,
|
||||
downtimeWindows: windows,
|
||||
status
|
||||
status,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,7 @@ import {
|
||||
targetHealthCheck,
|
||||
targets,
|
||||
resources,
|
||||
Transaction,
|
||||
logsDb
|
||||
Transaction
|
||||
} from "@server/db";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { invalidateStatusHistoryCache } from "@server/lib/statusHistory";
|
||||
@@ -53,10 +52,10 @@ export async function fireHealthCheckHealthyAlert(
|
||||
healthCheckTargetId?: number | null,
|
||||
extra?: Record<string, unknown>,
|
||||
send: boolean = true,
|
||||
trx: Transaction | typeof db = db
|
||||
trx: Transaction | typeof db = db,
|
||||
): Promise<void> {
|
||||
try {
|
||||
await logsDb.insert(statusHistory).values({
|
||||
await trx.insert(statusHistory).values({
|
||||
entityType: "health_check",
|
||||
entityId: healthCheckId,
|
||||
orgId: orgId,
|
||||
@@ -120,7 +119,7 @@ export async function fireHealthCheckUnhealthyAlert(
|
||||
trx: Transaction | typeof db = db
|
||||
): Promise<void> {
|
||||
try {
|
||||
await logsDb.insert(statusHistory).values({
|
||||
await trx.insert(statusHistory).values({
|
||||
entityType: "health_check",
|
||||
entityId: healthCheckId,
|
||||
orgId: orgId,
|
||||
@@ -173,7 +172,7 @@ export async function fireHealthCheckUnknownAlert(
|
||||
trx: Transaction | typeof db = db
|
||||
): Promise<void> {
|
||||
try {
|
||||
await logsDb.insert(statusHistory).values({
|
||||
await trx.insert(statusHistory).values({
|
||||
entityType: "health_check",
|
||||
entityId: healthCheckId,
|
||||
orgId: orgId,
|
||||
@@ -195,12 +194,7 @@ export async function fireHealthCheckUnknownAlert(
|
||||
}
|
||||
}
|
||||
|
||||
async function handleResource(
|
||||
orgId: string,
|
||||
healthCheckTargetId?: number | null,
|
||||
send: boolean = true,
|
||||
trx: Transaction | typeof db = db
|
||||
) {
|
||||
async function handleResource(orgId: string, healthCheckTargetId?: number | null, send: boolean = true, trx: Transaction | typeof db = db) {
|
||||
if (!healthCheckTargetId) {
|
||||
return;
|
||||
}
|
||||
@@ -228,10 +222,7 @@ async function handleResource(
|
||||
const otherTargets = await trx
|
||||
.select({ hcHealth: targetHealthCheck.hcHealth })
|
||||
.from(targets)
|
||||
.innerJoin(
|
||||
targetHealthCheck,
|
||||
eq(targetHealthCheck.targetId, targets.targetId)
|
||||
)
|
||||
.innerJoin(targetHealthCheck, eq(targetHealthCheck.targetId, targets.targetId))
|
||||
.where(eq(targets.resourceId, resource.resourceId));
|
||||
|
||||
let health = "healthy";
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
import logger from "@server/logger";
|
||||
import { processAlerts } from "../processAlerts";
|
||||
import { db, logsDb, statusHistory, Transaction } from "@server/db";
|
||||
import { db, statusHistory, Transaction } from "@server/db";
|
||||
import { invalidateStatusHistoryCache } from "@server/lib/statusHistory";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -40,7 +40,7 @@ export async function fireResourceHealthyAlert(
|
||||
trx: Transaction | typeof db = db
|
||||
): Promise<void> {
|
||||
try {
|
||||
await logsDb.insert(statusHistory).values({
|
||||
await trx.insert(statusHistory).values({
|
||||
entityType: "resource",
|
||||
entityId: resourceId,
|
||||
orgId: orgId,
|
||||
@@ -101,7 +101,7 @@ export async function fireResourceUnhealthyAlert(
|
||||
trx: Transaction | typeof db = db
|
||||
): Promise<void> {
|
||||
try {
|
||||
await logsDb.insert(statusHistory).values({
|
||||
await trx.insert(statusHistory).values({
|
||||
entityType: "resource",
|
||||
entityId: resourceId,
|
||||
orgId: orgId,
|
||||
@@ -162,7 +162,7 @@ export async function fireResourceDegradedAlert(
|
||||
trx: Transaction | typeof db = db
|
||||
): Promise<void> {
|
||||
try {
|
||||
await logsDb.insert(statusHistory).values({
|
||||
await trx.insert(statusHistory).values({
|
||||
entityType: "resource",
|
||||
entityId: resourceId,
|
||||
orgId: orgId,
|
||||
@@ -223,7 +223,7 @@ export async function fireResourceUnknownAlert(
|
||||
trx: Transaction | typeof db = db
|
||||
): Promise<void> {
|
||||
try {
|
||||
await logsDb.insert(statusHistory).values({
|
||||
await trx.insert(statusHistory).values({
|
||||
entityType: "resource",
|
||||
entityId: resourceId,
|
||||
orgId: orgId,
|
||||
|
||||
@@ -13,13 +13,7 @@
|
||||
|
||||
import logger from "@server/logger";
|
||||
import { processAlerts } from "../processAlerts";
|
||||
import {
|
||||
db,
|
||||
logsDb,
|
||||
statusHistory,
|
||||
targetHealthCheck,
|
||||
Transaction
|
||||
} from "@server/db";
|
||||
import { db, sites, statusHistory, targetHealthCheck, Transaction } from "@server/db";
|
||||
import { invalidateStatusHistoryCache } from "@server/lib/statusHistory";
|
||||
import { and, eq, inArray } from "drizzle-orm";
|
||||
import { fireHealthCheckUnhealthyAlert } from "./healthCheckEvents";
|
||||
@@ -47,7 +41,7 @@ export async function fireSiteOnlineAlert(
|
||||
trx: Transaction | typeof db = db
|
||||
): Promise<void> {
|
||||
try {
|
||||
await logsDb.insert(statusHistory).values({
|
||||
await trx.insert(statusHistory).values({
|
||||
entityType: "site",
|
||||
entityId: siteId,
|
||||
orgId: orgId,
|
||||
@@ -103,7 +97,7 @@ export async function fireSiteOfflineAlert(
|
||||
trx: Transaction | typeof db = db
|
||||
): Promise<void> {
|
||||
try {
|
||||
await logsDb.insert(statusHistory).values({
|
||||
await trx.insert(statusHistory).values({
|
||||
entityType: "site",
|
||||
entityId: siteId,
|
||||
orgId: orgId,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Request, Response, NextFunction } from "express";
|
||||
import { z } from "zod";
|
||||
import { db, logsDb, statusHistory } from "@server/db";
|
||||
import { db, statusHistory } from "@server/db";
|
||||
import {
|
||||
siteProvisioningKeys,
|
||||
siteProvisioningKeyOrg,
|
||||
@@ -84,7 +84,7 @@ export async function registerNewt(
|
||||
maxBatchSize: siteProvisioningKeys.maxBatchSize,
|
||||
numUsed: siteProvisioningKeys.numUsed,
|
||||
validUntil: siteProvisioningKeys.validUntil,
|
||||
approveNewSites: siteProvisioningKeys.approveNewSites
|
||||
approveNewSites: siteProvisioningKeys.approveNewSites,
|
||||
})
|
||||
.from(siteProvisioningKeys)
|
||||
.innerJoin(
|
||||
@@ -125,10 +125,7 @@ export async function registerNewt(
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
keyRecord.maxBatchSize &&
|
||||
keyRecord.numUsed >= keyRecord.maxBatchSize
|
||||
) {
|
||||
if (keyRecord.maxBatchSize && keyRecord.numUsed >= keyRecord.maxBatchSize) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.UNAUTHORIZED,
|
||||
@@ -137,10 +134,7 @@ export async function registerNewt(
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
keyRecord.validUntil &&
|
||||
new Date(keyRecord.validUntil) < new Date()
|
||||
) {
|
||||
if (keyRecord.validUntil && new Date(keyRecord.validUntil) < new Date()) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.UNAUTHORIZED,
|
||||
@@ -160,10 +154,7 @@ export async function registerNewt(
|
||||
}
|
||||
if (!org.subnet) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.INTERNAL_SERVER_ERROR,
|
||||
"Organization subnet not found"
|
||||
)
|
||||
createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "Organization subnet not found")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -204,6 +195,7 @@ export async function registerNewt(
|
||||
let newSiteId: number | undefined;
|
||||
|
||||
await db.transaction(async (trx) => {
|
||||
|
||||
const newClientAddress = await getNextAvailableClientSubnet(orgId);
|
||||
if (!newClientAddress) {
|
||||
return next(
|
||||
@@ -227,11 +219,11 @@ export async function registerNewt(
|
||||
address: clientAddress,
|
||||
type: "newt",
|
||||
dockerSocketEnabled: true,
|
||||
status: keyRecord.approveNewSites ? "approved" : "pending"
|
||||
status: keyRecord.approveNewSites ? "approved" : "pending",
|
||||
})
|
||||
.returning();
|
||||
|
||||
await logsDb.insert(statusHistory).values({
|
||||
await trx.insert(statusHistory).values({
|
||||
entityType: "site",
|
||||
entityId: newSite.siteId,
|
||||
orgId: orgId,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Request, Response, NextFunction } from "express";
|
||||
import { z } from "zod";
|
||||
import { clients, db, exitNodes, logsDb, statusHistory } from "@server/db";
|
||||
import { clients, db, exitNodes, statusHistory } from "@server/db";
|
||||
import { roles, userSites, sites, roleSites, Site, orgs } from "@server/db";
|
||||
import response from "@server/lib/response";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
@@ -351,7 +351,7 @@ export async function createSite(
|
||||
})
|
||||
.returning();
|
||||
|
||||
await logsDb.insert(statusHistory).values({
|
||||
await trx.insert(statusHistory).values({
|
||||
entityType: "site",
|
||||
entityId: newSite.siteId,
|
||||
orgId: orgId,
|
||||
|
||||
Reference in New Issue
Block a user