mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-03 17:26:07 +00:00
review fixes
This commit is contained in:
@@ -31,6 +31,7 @@ export const gatewayV2DalFactory = (db: TDbClient) => {
|
|||||||
|
|
||||||
if (isHeartbeatStale) {
|
if (isHeartbeatStale) {
|
||||||
const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000);
|
const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000);
|
||||||
|
void query.whereNotNull(`${TableName.GatewayV2}.heartbeat`);
|
||||||
void query.where(`${TableName.GatewayV2}.heartbeat`, "<", oneHourAgo);
|
void query.where(`${TableName.GatewayV2}.heartbeat`, "<", oneHourAgo);
|
||||||
void query.where((v) => {
|
void query.where((v) => {
|
||||||
void v
|
void v
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { PgSqlLock } from "@app/keystore/keystore";
|
|||||||
import { crypto } from "@app/lib/crypto";
|
import { crypto } from "@app/lib/crypto";
|
||||||
import { DatabaseErrorCode } from "@app/lib/error-codes";
|
import { DatabaseErrorCode } from "@app/lib/error-codes";
|
||||||
import { BadRequestError, DatabaseError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, DatabaseError, NotFoundError } from "@app/lib/errors";
|
||||||
|
import { groupBy } from "@app/lib/fn";
|
||||||
import { GatewayProxyProtocol } from "@app/lib/gateway/types";
|
import { GatewayProxyProtocol } from "@app/lib/gateway/types";
|
||||||
import { withGatewayV2Proxy } from "@app/lib/gateway-v2/gateway-v2";
|
import { withGatewayV2Proxy } from "@app/lib/gateway-v2/gateway-v2";
|
||||||
import { logger } from "@app/lib/logger";
|
import { logger } from "@app/lib/logger";
|
||||||
@@ -902,13 +903,7 @@ export const gatewayV2ServiceFactory = ({
|
|||||||
"Found gateways with last heartbeat over an hour ago. Sending notifications."
|
"Found gateways with last heartbeat over an hour ago. Sending notifications."
|
||||||
);
|
);
|
||||||
|
|
||||||
const gatewaysByOrg = unhealthyGateways.reduce<Record<string, (typeof unhealthyGateways)[number][]>>((acc, gw) => {
|
const gatewaysByOrg = groupBy(unhealthyGateways, (gw) => gw.orgId);
|
||||||
if (!acc[gw.orgId]) {
|
|
||||||
acc[gw.orgId] = [];
|
|
||||||
}
|
|
||||||
acc[gw.orgId].push(gw);
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
for await (const [orgId, gateways] of Object.entries(gatewaysByOrg)) {
|
for await (const [orgId, gateways] of Object.entries(gatewaysByOrg)) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ export const relayDalFactory = (db: TDbClient) => {
|
|||||||
|
|
||||||
if (isHeartbeatStale) {
|
if (isHeartbeatStale) {
|
||||||
const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000);
|
const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000);
|
||||||
|
void query.whereNotNull(`${TableName.Relay}.heartbeat`);
|
||||||
void query.where(`${TableName.Relay}.heartbeat`, "<", oneHourAgo);
|
void query.where(`${TableName.Relay}.heartbeat`, "<", oneHourAgo);
|
||||||
void query.where((v) => {
|
void query.where((v) => {
|
||||||
void v
|
void v
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { OrgMembershipRole, TRelays } from "@app/db/schemas";
|
|||||||
import { PgSqlLock } from "@app/keystore/keystore";
|
import { PgSqlLock } from "@app/keystore/keystore";
|
||||||
import { crypto } from "@app/lib/crypto";
|
import { crypto } from "@app/lib/crypto";
|
||||||
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
|
import { groupBy } from "@app/lib/fn";
|
||||||
import { createRelayConnection } from "@app/lib/gateway-v2/gateway-v2";
|
import { createRelayConnection } from "@app/lib/gateway-v2/gateway-v2";
|
||||||
import { logger } from "@app/lib/logger";
|
import { logger } from "@app/lib/logger";
|
||||||
import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type";
|
import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type";
|
||||||
@@ -1220,14 +1221,7 @@ export const relayServiceFactory = ({
|
|||||||
"Found relays with last heartbeat over an hour ago. Sending notifications."
|
"Found relays with last heartbeat over an hour ago. Sending notifications."
|
||||||
);
|
);
|
||||||
|
|
||||||
const relaysByOrg = unhealthyRelays.reduce<Record<string, TRelays[]>>((acc, r) => {
|
const relaysByOrg = groupBy(unhealthyRelays, (r) => r.orgId ?? "instance");
|
||||||
const key = r.orgId ?? "instance";
|
|
||||||
if (!acc[key]) {
|
|
||||||
acc[key] = [];
|
|
||||||
}
|
|
||||||
acc[key].push(r);
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
for await (const [orgId, relays] of Object.entries(relaysByOrg)) {
|
for await (const [orgId, relays] of Object.entries(relaysByOrg)) {
|
||||||
try {
|
try {
|
||||||
@@ -1244,7 +1238,7 @@ export const relayServiceFactory = ({
|
|||||||
recipients,
|
recipients,
|
||||||
subjectLine: "Relay Health Alert",
|
subjectLine: "Relay Health Alert",
|
||||||
substitutions: {
|
substitutions: {
|
||||||
type: "relay",
|
type: "instance-relay",
|
||||||
names: relayNames
|
names: relayNames
|
||||||
},
|
},
|
||||||
template: SmtpTemplates.HealthAlert
|
template: SmtpTemplates.HealthAlert
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
|||||||
import { BaseLink } from "./BaseLink";
|
import { BaseLink } from "./BaseLink";
|
||||||
|
|
||||||
interface HealthAlertTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface HealthAlertTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
type: "gateway" | "relay";
|
type: "gateway" | "relay" | "instance-relay";
|
||||||
names: string;
|
names: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,8 +24,14 @@ export const HealthAlertTemplate = ({ siteUrl, names, type }: HealthAlertTemplat
|
|||||||
heartbeat in over an hour: <strong>{names}</strong>.
|
heartbeat in over an hour: <strong>{names}</strong>.
|
||||||
</Text>
|
</Text>
|
||||||
<Text className="text-black text-[14px] leading-[24px]">
|
<Text className="text-black text-[14px] leading-[24px]">
|
||||||
If your issue persists, you can contact the Infisical team at{" "}
|
{type === "instance-relay" && (
|
||||||
<BaseLink href="mailto:[email protected]">[email protected]</BaseLink>.
|
<>
|
||||||
|
If your issue persists, you can contact the Infisical team at{" "}
|
||||||
|
<BaseLink href="mailto:[email protected]">[email protected]</BaseLink>.
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{type === "relay" && <>Please contact your relay administrators.</>}
|
||||||
|
{type === "gateway" && <>Please contact your gateway administrators.</>}
|
||||||
</Text>
|
</Text>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ import { useDeleteGatewayV2ById } from "@app/hooks/api/gateways-v2";
|
|||||||
|
|
||||||
import { EditGatewayDetailsModal } from "./components/EditGatewayDetailsModal";
|
import { EditGatewayDetailsModal } from "./components/EditGatewayDetailsModal";
|
||||||
|
|
||||||
export const GatewayHealthStatus = ({ heartbeat }: { heartbeat?: string }) => {
|
const GatewayHealthStatus = ({ heartbeat }: { heartbeat?: string }) => {
|
||||||
const heartbeatDate = heartbeat ? new Date(heartbeat) : null;
|
const heartbeatDate = heartbeat ? new Date(heartbeat) : null;
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000);
|
const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000);
|
||||||
|
|||||||
@@ -42,7 +42,24 @@ import { withPermission } from "@app/hoc";
|
|||||||
import { usePopUp } from "@app/hooks";
|
import { usePopUp } from "@app/hooks";
|
||||||
import { useDeleteRelayById, useGetRelays } from "@app/hooks/api/relays";
|
import { useDeleteRelayById, useGetRelays } from "@app/hooks/api/relays";
|
||||||
|
|
||||||
import { GatewayHealthStatus } from "../GatewayTab/GatewayTab";
|
const RelayHealthStatus = ({ heartbeat }: { heartbeat?: string }) => {
|
||||||
|
const heartbeatDate = heartbeat ? new Date(heartbeat) : null;
|
||||||
|
const now = new Date();
|
||||||
|
const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000);
|
||||||
|
|
||||||
|
const isHealthy = heartbeatDate && heartbeatDate >= oneHourAgo;
|
||||||
|
const tooltipContent = heartbeatDate
|
||||||
|
? `Last heartbeat: ${heartbeatDate.toLocaleString()}`
|
||||||
|
: "No heartbeat data available";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip content={tooltipContent}>
|
||||||
|
<span className={`cursor-default ${isHealthy ? "text-green-400" : "text-red-400"}`}>
|
||||||
|
{isHealthy ? "Healthy" : "Unreachable"}
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const RelayTab = withPermission(
|
export const RelayTab = withPermission(
|
||||||
() => {
|
() => {
|
||||||
@@ -143,7 +160,7 @@ export const RelayTab = withPermission(
|
|||||||
<Td>{el.host}</Td>
|
<Td>{el.host}</Td>
|
||||||
<Td>{formatRelative(new Date(el.createdAt), new Date())}</Td>
|
<Td>{formatRelative(new Date(el.createdAt), new Date())}</Td>
|
||||||
<Td>
|
<Td>
|
||||||
<GatewayHealthStatus heartbeat={el.heartbeat} />
|
<RelayHealthStatus heartbeat={el.heartbeat} />
|
||||||
</Td>
|
</Td>
|
||||||
<Td className="w-5">
|
<Td className="w-5">
|
||||||
<Tooltip className="max-w-sm text-center" content="Options">
|
<Tooltip className="max-w-sm text-center" content="Options">
|
||||||
|
|||||||
Reference in New Issue
Block a user