From cb6b31c9e43643a981a0ff4e7488911adff790da Mon Sep 17 00:00:00 2001 From: pablomendezroyo Date: Tue, 4 Mar 2025 09:57:17 +0100 Subject: [PATCH 01/13] Add release file notifications to toolkit --- packages/toolkit/src/repository/repository.ts | 3 ++- packages/types/src/notifications.ts | 22 +++++++++++++++++++ packages/types/src/pkg.ts | 2 ++ packages/types/src/releaseFiles.ts | 10 ++++++++- 4 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 packages/types/src/notifications.ts diff --git a/packages/toolkit/src/repository/repository.ts b/packages/toolkit/src/repository/repository.ts index a57c3cf632..7d204faf78 100644 --- a/packages/toolkit/src/repository/repository.ts +++ b/packages/toolkit/src/repository/repository.ts @@ -205,7 +205,8 @@ export class DappnodeRepository extends ApmRepository { disclaimer: await this.getPkgAsset(releaseFilesToDownload.disclaimer, ipfsEntries), gettingStarted: await this.getPkgAsset(releaseFilesToDownload.gettingStarted, ipfsEntries), prometheusTargets: await this.getPkgAsset(releaseFilesToDownload.prometheusTargets, ipfsEntries), - grafanaDashboards: await this.getPkgAsset(releaseFilesToDownload.grafanaDashboards, ipfsEntries) + grafanaDashboards: await this.getPkgAsset(releaseFilesToDownload.grafanaDashboards, ipfsEntries), + notifications: await this.getPkgAsset(releaseFilesToDownload.notifications, ipfsEntries) }; } diff --git a/packages/types/src/notifications.ts b/packages/types/src/notifications.ts new file mode 100644 index 0000000000..fdd3a04a79 --- /dev/null +++ b/packages/types/src/notifications.ts @@ -0,0 +1,22 @@ +export interface GatusConfig { + endpoints: Endpoint[]; +} + +interface Endpoint { + name: string; + enabled: boolean; + url: string; + method: string; + conditions: string[]; + interval: string; // e.g., "1m" + group: string; + alerts: Alert[]; +} + +interface Alert { + type: string; + "failure-threshold": number; + "success-threshold": number; + "send-on-resolved": boolean; + description: string; +} diff --git a/packages/types/src/pkg.ts b/packages/types/src/pkg.ts index dd74b29166..16d9d6a973 100644 --- a/packages/types/src/pkg.ts +++ b/packages/types/src/pkg.ts @@ -1,5 +1,6 @@ import { Compose } from "./compose.js"; import { Manifest, PrometheusTarget, GrafanaDashboard } from "./manifest.js"; +import { GatusConfig } from "./notifications.js"; import { SetupWizard } from "./setupWizard.js"; /** @@ -97,6 +98,7 @@ export type DirectoryFiles = { gettingStarted?: string; prometheusTargets?: PrometheusTarget[]; grafanaDashboards?: GrafanaDashboard[]; + notifications?: GatusConfig; }; export interface FileConfig { diff --git a/packages/types/src/releaseFiles.ts b/packages/types/src/releaseFiles.ts index 2c4d6df4b5..074f9183e9 100644 --- a/packages/types/src/releaseFiles.ts +++ b/packages/types/src/releaseFiles.ts @@ -84,6 +84,13 @@ export const releaseFiles = Object.freeze({ maxSize: 10e6, // ~ 10MB required: false as const, multiple: true as const + }), + notifications: Object.freeze({ + regex: /.*notifications.yaml$/, + format: FileFormat.YAML, + maxSize: 10e3, + required: false as const, + multiple: false as const }) } as const); @@ -95,5 +102,6 @@ export const releaseFilesToDownload = { disclaimer: releaseFiles.disclaimer, gettingStarted: releaseFiles.gettingStarted, prometheusTargets: releaseFiles.prometheusTargets, - grafanaDashboards: releaseFiles.grafanaDashboards + grafanaDashboards: releaseFiles.grafanaDashboards, + notifications: releaseFiles.notifications }; From 530a4a9fd82172c6f8906216e399b620592f8a0d Mon Sep 17 00:00:00 2001 From: pablomendezroyo Date: Tue, 4 Mar 2025 10:01:10 +0100 Subject: [PATCH 02/13] join notifications in manifest --- packages/installer/src/dappnodeInstaller.ts | 9 +++++++-- packages/types/src/manifest.ts | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/installer/src/dappnodeInstaller.ts b/packages/installer/src/dappnodeInstaller.ts index 40aa987a35..d2d2ce0ce0 100644 --- a/packages/installer/src/dappnodeInstaller.ts +++ b/packages/installer/src/dappnodeInstaller.ts @@ -23,6 +23,7 @@ import { parseTimeoutSeconds } from "./utils.js"; import { getEthersProvider } from "./ethClient/index.js"; import { omit } from "lodash-es"; import { ethers } from "ethers"; +import { GatusConfig } from "../../types/dist/notifications.js"; /** * Returns the ipfsUrl to initialize the ipfs instance @@ -72,7 +73,8 @@ export class DappnodeInstaller extends DappnodeRepository { disclaimer: pkgRelease.disclaimer, gettingStarted: pkgRelease.gettingStarted, grafanaDashboards: pkgRelease.grafanaDashboards, - prometheusTargets: pkgRelease.prometheusTargets + prometheusTargets: pkgRelease.prometheusTargets, + notifications: pkgRelease.notifications }); // set compose to custom dappnode compose in release @@ -151,7 +153,8 @@ export class DappnodeInstaller extends DappnodeRepository { disclaimer, gettingStarted, prometheusTargets, - grafanaDashboards + grafanaDashboards, + notifications }: { manifest: Manifest; SetupWizard?: SetupWizard; @@ -159,12 +162,14 @@ export class DappnodeInstaller extends DappnodeRepository { gettingStarted?: string; prometheusTargets?: PrometheusTarget[]; grafanaDashboards?: GrafanaDashboard[]; + notifications?: GatusConfig; }): Manifest { if (SetupWizard) manifest.setupWizard = SetupWizard; if (disclaimer) manifest.disclaimer = { message: disclaimer }; if (gettingStarted) manifest.gettingStarted = gettingStarted; if (prometheusTargets) manifest.prometheusTargets = prometheusTargets; if (grafanaDashboards && grafanaDashboards.length > 0) manifest.grafanaDashboards = grafanaDashboards; + if (notifications) manifest.notifications = notifications; return manifest; } diff --git a/packages/types/src/manifest.ts b/packages/types/src/manifest.ts index f81ed8acdb..74e9042299 100644 --- a/packages/types/src/manifest.ts +++ b/packages/types/src/manifest.ts @@ -1,3 +1,4 @@ +import { GatusConfig } from "./notifications.js"; import { SetupSchema, SetupTarget, SetupUiJson, SetupWizard } from "./setupWizard.js"; export interface Manifest { @@ -98,6 +99,9 @@ export interface Manifest { // setupWizard for compacted manifests in core packages setupWizard?: SetupWizard; + + // notifications + notifications?: GatusConfig; } export interface UpstreamItem { From ec6dbc9be833859e3cc75818c4dfc892175fea19 Mon Sep 17 00:00:00 2001 From: Pablo Mendez Date: Tue, 4 Mar 2025 10:30:29 +0100 Subject: [PATCH 03/13] fix unit test --- packages/installer/test/unit/release/findEntries.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/installer/test/unit/release/findEntries.test.ts b/packages/installer/test/unit/release/findEntries.test.ts index c8a27f3b19..649e374acf 100644 --- a/packages/installer/test/unit/release/findEntries.test.ts +++ b/packages/installer/test/unit/release/findEntries.test.ts @@ -54,7 +54,8 @@ describe("validateTarImage", () => { "host-grafana-dashboard.json", "prometheus-targets.json", "setup-wizard.json", - "signature.json" + "signature.json", + "notifications.yaml" ].map((name) => ({ name, path: `Qm-root/${name}`, @@ -70,6 +71,7 @@ describe("validateTarImage", () => { disclaimer: "disclaimer.md", gettingStarted: "getting-started.md", prometheusTargets: "prometheus-targets.json", + notifications: "notifications.yaml", grafanaDashboards: ["docker-grafana-dashboard.json", "host-grafana-dashboard.json"] }; From c44789f0105f5ec86da216cd233c6dec129ab479 Mon Sep 17 00:00:00 2001 From: Pablo Mendez Date: Wed, 5 Mar 2025 09:13:06 +0100 Subject: [PATCH 04/13] use with instead of assert --- packages/common/src/validation/index.ts | 6 +++--- .../src/api/middlewares/ethForward/resolveDomain.ts | 4 ++-- packages/dockerCompose/src/validate.ts | 2 +- packages/schemas/src/validateManifestSchema.ts | 2 +- packages/schemas/src/validateSetupWizardSchema.ts | 2 +- packages/types/src/releaseFiles.ts | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/common/src/validation/index.ts b/packages/common/src/validation/index.ts index c1bbd27c43..fef11b3e0a 100644 --- a/packages/common/src/validation/index.ts +++ b/packages/common/src/validation/index.ts @@ -1,7 +1,7 @@ import Ajv from "ajv"; -import routesArgumentsSchema from "./schemas/RoutesArguments.schema.json" assert { type: "json" }; -import routesReturnSchema from "./schemas/RoutesReturn.schema.json" assert { type: "json" }; -import subscriptionsArgumentsSchema from "./schemas/SubscriptionsArguments.schema.json" assert { type: "json" }; +import routesArgumentsSchema from "./schemas/RoutesArguments.schema.json" with { type: "json" }; +import routesReturnSchema from "./schemas/RoutesReturn.schema.json" with { type: "json" }; +import subscriptionsArgumentsSchema from "./schemas/SubscriptionsArguments.schema.json" with { type: "json" }; import { Args } from "typescript-json-schema"; const ajv = new Ajv({ allErrors: true, strict: false }); diff --git a/packages/dappmanager/src/api/middlewares/ethForward/resolveDomain.ts b/packages/dappmanager/src/api/middlewares/ethForward/resolveDomain.ts index ecc1c62f55..ab50670574 100644 --- a/packages/dappmanager/src/api/middlewares/ethForward/resolveDomain.ts +++ b/packages/dappmanager/src/api/middlewares/ethForward/resolveDomain.ts @@ -1,7 +1,7 @@ import { ethers } from "ethers"; import { getEthersProvider, getEthUrl } from "@dappnode/installer"; -import resolverAbi from "./abi/resolverAbi.json" assert { type: "json" }; -import ensAbi from "./abi/ens.json" assert { type: "json" }; +import resolverAbi from "./abi/resolverAbi.json" with { type: "json" }; +import ensAbi from "./abi/ens.json" with { type: "json" }; import { Network, Content, NotFoundError, EnsResolverError } from "./types.js"; import { decodeContentHash, isEmpty, decodeDnsLink, decodeContent } from "./utils/index.js"; import memoize from "memoizee"; diff --git a/packages/dockerCompose/src/validate.ts b/packages/dockerCompose/src/validate.ts index 4abd66771b..640f60615b 100644 --- a/packages/dockerCompose/src/validate.ts +++ b/packages/dockerCompose/src/validate.ts @@ -1,5 +1,5 @@ import { getSchemaValidator } from "@dappnode/utils"; -import compose3xSchema from "./compose_v3x.schema.json" assert { type: "json" }; +import compose3xSchema from "./compose_v3x.schema.json" with { type: "json" }; import { Compose } from "@dappnode/types"; /** diff --git a/packages/schemas/src/validateManifestSchema.ts b/packages/schemas/src/validateManifestSchema.ts index 0e18a052b8..561044d288 100644 --- a/packages/schemas/src/validateManifestSchema.ts +++ b/packages/schemas/src/validateManifestSchema.ts @@ -1,7 +1,7 @@ import { ajv } from "./ajv.js"; import { CliError } from "./error.js"; import { processError } from "./utils.js"; -import manifestSchema from "./schemas/manifest.schema.json" assert { type: "json" }; +import manifestSchema from "./schemas/manifest.schema.json" with { type: "json" }; import { Manifest } from "@dappnode/types"; /** diff --git a/packages/schemas/src/validateSetupWizardSchema.ts b/packages/schemas/src/validateSetupWizardSchema.ts index 9e59a215e3..e1f07147c0 100644 --- a/packages/schemas/src/validateSetupWizardSchema.ts +++ b/packages/schemas/src/validateSetupWizardSchema.ts @@ -1,6 +1,6 @@ import { ajv } from "./ajv.js"; import { processError } from "./utils.js"; -import setupWizardSchema from "./schemas/setup-wizard.schema.json" assert { type: "json" }; +import setupWizardSchema from "./schemas/setup-wizard.schema.json" with { type: "json" }; import { CliError } from "./error.js"; import { SetupWizard } from "@dappnode/types"; diff --git a/packages/types/src/releaseFiles.ts b/packages/types/src/releaseFiles.ts index 074f9183e9..af7df593fd 100644 --- a/packages/types/src/releaseFiles.ts +++ b/packages/types/src/releaseFiles.ts @@ -86,7 +86,7 @@ export const releaseFiles = Object.freeze({ multiple: true as const }), notifications: Object.freeze({ - regex: /.*notifications.yaml$/, + regex: /^.*notifications\.yaml$/, format: FileFormat.YAML, maxSize: 10e3, required: false as const, From 1b3d0d867aec9860c08018c7d4d7a3014426410e Mon Sep 17 00:00:00 2001 From: Pablo Mendez Date: Wed, 5 Mar 2025 09:14:17 +0100 Subject: [PATCH 05/13] return missing notifications --- packages/installer/src/dappnodeInstaller.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/installer/src/dappnodeInstaller.ts b/packages/installer/src/dappnodeInstaller.ts index d2d2ce0ce0..fd9bd7adb2 100644 --- a/packages/installer/src/dappnodeInstaller.ts +++ b/packages/installer/src/dappnodeInstaller.ts @@ -109,7 +109,8 @@ export class DappnodeInstaller extends DappnodeRepository { disclaimer: pkgRelease.disclaimer, gettingStarted: pkgRelease.gettingStarted, grafanaDashboards: pkgRelease.grafanaDashboards, - prometheusTargets: pkgRelease.prometheusTargets + prometheusTargets: pkgRelease.prometheusTargets, + notifications: pkgRelease.notifications }); }); From 84ff200984590ba1b35c8e392b57b4530e4ab298 Mon Sep 17 00:00:00 2001 From: Pablo Mendez Date: Wed, 5 Mar 2025 09:53:38 +0100 Subject: [PATCH 06/13] move writemanifest to installer --- .../src/installer/writeAndValidateFiles.ts | 13 +++++++++++-- packages/utils/src/index.ts | 1 - packages/utils/src/writeManifest.ts | 6 ------ 3 files changed, 11 insertions(+), 9 deletions(-) delete mode 100644 packages/utils/src/writeManifest.ts diff --git a/packages/installer/src/installer/writeAndValidateFiles.ts b/packages/installer/src/installer/writeAndValidateFiles.ts index 8ad61238a9..a69c6688c0 100644 --- a/packages/installer/src/installer/writeAndValidateFiles.ts +++ b/packages/installer/src/installer/writeAndValidateFiles.ts @@ -1,10 +1,10 @@ import fs from "fs"; import { Log } from "@dappnode/logger"; import { validatePath } from "@dappnode/utils"; -import { InstallPackageData } from "@dappnode/types"; +import { InstallPackageData, Manifest } from "@dappnode/types"; import { dockerComposeConfig } from "@dappnode/dockerapi"; import { ComposeEditor } from "@dappnode/dockercompose"; -import { isNotFoundError, writeManifest } from "@dappnode/utils"; +import { isNotFoundError } from "@dappnode/utils"; /** * Write the new compose and test it with config @@ -47,3 +47,12 @@ function copyIfExists(src: string, dest: string): void { if (!isNotFoundError(e)) throw e; } } + +/** + * Util: Write manifest to file + * @param manfiestPath + * @param manifest + */ +function writeManifest(manfiestPath: string, manifest: Manifest): void { + fs.writeFileSync(manfiestPath, JSON.stringify(manifest, null, 2)); +} diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index b2625f7596..62361276b9 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -37,6 +37,5 @@ export { shouldUpdate } from "./shouldUpdate.js"; export { getPublicIpFromUrls } from "./getPublicIpFromUrls.js"; export { computeSemverUpdateType } from "./computeSemverUpdateType.js"; export * from "./coreVersionId.js"; -export { writeManifest } from "./writeManifest.js"; export { readManifestIfExists } from "./readManifestIfExists.js"; export { removeCidrSuffix } from "./removeCidrSuffix.js"; diff --git a/packages/utils/src/writeManifest.ts b/packages/utils/src/writeManifest.ts deleted file mode 100644 index 00cc398a1c..0000000000 --- a/packages/utils/src/writeManifest.ts +++ /dev/null @@ -1,6 +0,0 @@ -import fs from "fs"; -import { Manifest } from "@dappnode/types"; - -export function writeManifest(manfiestPath: string, manifest: Manifest): void { - fs.writeFileSync(manfiestPath, JSON.stringify(manifest, null, 2)); -} From 222bb346b53c4fb6876b721039c7cc4ce229eab2 Mon Sep 17 00:00:00 2001 From: Pablo Mendez Date: Wed, 5 Mar 2025 18:10:59 +0100 Subject: [PATCH 07/13] return notifications in package manifest endpoint --- packages/dappmanager/src/api/routes/packageManifest.ts | 3 ++- packages/types/src/index.ts | 1 + packages/types/src/notifications.ts | 9 ++++++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/dappmanager/src/api/routes/packageManifest.ts b/packages/dappmanager/src/api/routes/packageManifest.ts index d8b38b9d59..bbc63afb0c 100644 --- a/packages/dappmanager/src/api/routes/packageManifest.ts +++ b/packages/dappmanager/src/api/routes/packageManifest.ts @@ -54,7 +54,8 @@ export const packageManifest = wrapHandler(async (req, res) => { "links", "repository", "bugs", - "license" + "license", + "notifications" ]); res.status(200).send(filteredManifest); diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 61b5aa63dd..15c5bf572b 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -10,6 +10,7 @@ export * from "./releaseFiles.js"; export * from "./errors.js"; export * from "./routes.js"; export * from "./subscriptions.js"; +export * from "./notifications.js"; // utils export * from "./utils/index.js"; diff --git a/packages/types/src/notifications.ts b/packages/types/src/notifications.ts index fdd3a04a79..440570aaf4 100644 --- a/packages/types/src/notifications.ts +++ b/packages/types/src/notifications.ts @@ -2,7 +2,7 @@ export interface GatusConfig { endpoints: Endpoint[]; } -interface Endpoint { +export interface Endpoint { name: string; enabled: boolean; url: string; @@ -11,6 +11,13 @@ interface Endpoint { interval: string; // e.g., "1m" group: string; alerts: Alert[]; + description: string; // dappnode specific + metric?: { + // dappnode specific + min: number; + max: number; + unit: string; // e.g ÂșC + }; } interface Alert { From 16ca50425b7911e6c7120652900f5f9eb511c94a Mon Sep 17 00:00:00 2001 From: Pablo Mendez Date: Thu, 6 Mar 2025 07:08:03 +0100 Subject: [PATCH 08/13] use assert instead of with --- packages/common/src/validation/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/common/src/validation/index.ts b/packages/common/src/validation/index.ts index fef11b3e0a..c1bbd27c43 100644 --- a/packages/common/src/validation/index.ts +++ b/packages/common/src/validation/index.ts @@ -1,7 +1,7 @@ import Ajv from "ajv"; -import routesArgumentsSchema from "./schemas/RoutesArguments.schema.json" with { type: "json" }; -import routesReturnSchema from "./schemas/RoutesReturn.schema.json" with { type: "json" }; -import subscriptionsArgumentsSchema from "./schemas/SubscriptionsArguments.schema.json" with { type: "json" }; +import routesArgumentsSchema from "./schemas/RoutesArguments.schema.json" assert { type: "json" }; +import routesReturnSchema from "./schemas/RoutesReturn.schema.json" assert { type: "json" }; +import subscriptionsArgumentsSchema from "./schemas/SubscriptionsArguments.schema.json" assert { type: "json" }; import { Args } from "typescript-json-schema"; const ajv = new Ajv({ allErrors: true, strict: false }); From 7d7319ad8e1970c5b166ff38d8cf2ac8a37ebf5c Mon Sep 17 00:00:00 2001 From: Pablo Mendez Date: Thu, 6 Mar 2025 09:25:04 +0100 Subject: [PATCH 09/13] fix import --- packages/installer/src/dappnodeInstaller.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/installer/src/dappnodeInstaller.ts b/packages/installer/src/dappnodeInstaller.ts index fd9bd7adb2..42786a7a4b 100644 --- a/packages/installer/src/dappnodeInstaller.ts +++ b/packages/installer/src/dappnodeInstaller.ts @@ -11,7 +11,8 @@ import { PackageRequest, SetupWizard, GrafanaDashboard, - PrometheusTarget + PrometheusTarget, + GatusConfig } from "@dappnode/types"; import { DappGetState, DappgetOptions, dappGet } from "./dappGet/index.js"; import { validateDappnodeCompose, validateManifestSchema } from "@dappnode/schemas"; @@ -23,7 +24,6 @@ import { parseTimeoutSeconds } from "./utils.js"; import { getEthersProvider } from "./ethClient/index.js"; import { omit } from "lodash-es"; import { ethers } from "ethers"; -import { GatusConfig } from "../../types/dist/notifications.js"; /** * Returns the ipfsUrl to initialize the ipfs instance From c02c85751e63e5c49f217ee2b1a4185a17bca820 Mon Sep 17 00:00:00 2001 From: Pablo Mendez Date: Thu, 6 Mar 2025 09:47:57 +0100 Subject: [PATCH 10/13] implement first approach backend calls --- .../admin-ui/src/__mock-backend__/index.ts | 4 +- packages/dappmanager/src/calls/gatusConfig.ts | 56 +++++++++++++++++++ packages/dappmanager/src/calls/index.ts | 1 + packages/types/src/routes.ts | 13 +++++ 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 packages/dappmanager/src/calls/gatusConfig.ts diff --git a/packages/admin-ui/src/__mock-backend__/index.ts b/packages/admin-ui/src/__mock-backend__/index.ts index b547e360dc..f47b444496 100644 --- a/packages/admin-ui/src/__mock-backend__/index.ts +++ b/packages/admin-ui/src/__mock-backend__/index.ts @@ -386,7 +386,9 @@ export const otherCalls: Omit = { dockerLatestVersion: "20.10.8" }), getIsConnectedToInternet: async () => false, - getCoreVersion: async () => "0.2.92" + getCoreVersion: async () => "0.2.92", + gatusGetEndpoints: async () => new Map(), + gatusUpdateEndpoint: async () => {} }; export const calls: Routes = { diff --git a/packages/dappmanager/src/calls/gatusConfig.ts b/packages/dappmanager/src/calls/gatusConfig.ts new file mode 100644 index 0000000000..4cb22a8df4 --- /dev/null +++ b/packages/dappmanager/src/calls/gatusConfig.ts @@ -0,0 +1,56 @@ +import { listPackages } from "@dappnode/dockerapi"; +import { GatusConfig, Endpoint, Manifest } from "@dappnode/types"; +import { getManifestPath } from "@dappnode/utils"; +import fs from "fs"; + +/** + * Get gatus endpoints indexed by dnpName + */ +export async function gatusGetEndpoints(): Promise> { + const packages = await listPackages(); + + // Read all manifests files and retrieve the gatus config + const endpoints = new Map(); + for (const pkg of packages) { + const manifestPath = getManifestPath(pkg.dnpName, pkg.isCore); + const manifest: Manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8")); + if (manifest.notifications) endpoints.set(pkg.dnpName, manifest.notifications); + } + + return endpoints; +} + +/** + * Update endpoint properties + * @param dnpName + * @param updatedEndpoint + */ +export async function gatusUpdateEndpoint({ + dnpName, + updatedEndpoint +}: { + dnpName: string; + updatedEndpoint: Endpoint; +}): Promise { + // Get current endpoint status + const manifest: Manifest = JSON.parse(fs.readFileSync(getManifestPath(dnpName, false), "utf8")); + if (!manifest.notifications) throw new Error("No notifications found in manifest"); + + const endpoint = manifest.notifications.endpoints.find((e) => e.name === updatedEndpoint.name); + if (!endpoint) throw new Error(`Endpoint ${updatedEndpoint.name} not found in manifest`); + + // Update endpoint + Object.assign(endpoint, updatedEndpoint); + + // Save manifest + fs.writeFileSync(getManifestPath(dnpName, false), JSON.stringify(manifest, null, 2)); + + // Update endpoint in gatus + // await fetch(`http://notifier.notifications.dappnode:8082/gatus/endpoints`, { + // method: "POST", + // headers: { + // "Content-Type": "application/json" + // }, + // body: JSON.stringify(endpoint) + // }); +} diff --git a/packages/dappmanager/src/calls/index.ts b/packages/dappmanager/src/calls/index.ts index a61851ced7..e2b1b1f658 100644 --- a/packages/dappmanager/src/calls/index.ts +++ b/packages/dappmanager/src/calls/index.ts @@ -22,6 +22,7 @@ export { getCoreVersion } from "./getCoreVersion.js"; export { getUserActionLogs } from "./getUserActionLogs.js"; export { getHostUptime } from "./getHostUptime.js"; export { getIsConnectedToInternet } from "./getIsConnectedToInternet.js"; +export { gatusGetEndpoints, gatusUpdateEndpoint } from "./gatusConfig.js"; export * from "./httpsPortal.js"; export { ipfsTest } from "./ipfsTest.js"; export { ipfsClientTargetSet } from "./ipfsClientTargetSet.js"; diff --git a/packages/types/src/routes.ts b/packages/types/src/routes.ts index 5173890dc1..cb15f79aef 100644 --- a/packages/types/src/routes.ts +++ b/packages/types/src/routes.ts @@ -45,6 +45,7 @@ import { } from "./calls.js"; import { PackageEnvs } from "./compose.js"; import { PackageBackup } from "./manifest.js"; +import { Endpoint, GatusConfig } from "./notifications.js"; import { TrustedReleaseKey } from "./pkg.js"; import { OptimismConfigSet, OptimismConfigGet } from "./rollups.js"; import { Network, StakerConfigGet, StakerConfigSet } from "./stakers.js"; @@ -261,6 +262,16 @@ export interface Routes { */ fetchDnpRequest: (kwargs: { id: string; version?: string }) => Promise; + /** + * Gatus get endpoints + */ + gatusGetEndpoints(): Promise>; + + /** + * Gatus update endpoint + */ + gatusUpdateEndpoint: (kwargs: { dnpName: string; updatedEndpoint: Endpoint }) => Promise; + /** * Returns the user action logs. This logs are stored in a different * file and format, and are meant to ease user support @@ -690,6 +701,8 @@ export const routesData: { [P in keyof Routes]: RouteData } = { fetchDirectory: {}, fetchRegistry: {}, fetchDnpRequest: {}, + gatusGetEndpoints: { log: true }, + gatusUpdateEndpoint: { log: true }, getUserActionLogs: {}, getHostUptime: {}, httpsPortalMappingAdd: { log: true }, From b7526ee51dfcdb815c105bf833b2366f85c3e19b Mon Sep 17 00:00:00 2001 From: Pablo Mendez Date: Thu, 6 Mar 2025 11:48:06 +0100 Subject: [PATCH 11/13] use node 22 and assert instead of with --- Dockerfile | 2 +- packages/common/src/validation/index.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3c30344886..d7a3c4fa2e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Arguments -ARG BASE_IMAGE=node:20.16.0-alpine3.19 +ARG BASE_IMAGE=node:22.14.0-alpine3.21 ARG BUILDPLATFORM # Initial stage to gather git data diff --git a/packages/common/src/validation/index.ts b/packages/common/src/validation/index.ts index c1bbd27c43..fef11b3e0a 100644 --- a/packages/common/src/validation/index.ts +++ b/packages/common/src/validation/index.ts @@ -1,7 +1,7 @@ import Ajv from "ajv"; -import routesArgumentsSchema from "./schemas/RoutesArguments.schema.json" assert { type: "json" }; -import routesReturnSchema from "./schemas/RoutesReturn.schema.json" assert { type: "json" }; -import subscriptionsArgumentsSchema from "./schemas/SubscriptionsArguments.schema.json" assert { type: "json" }; +import routesArgumentsSchema from "./schemas/RoutesArguments.schema.json" with { type: "json" }; +import routesReturnSchema from "./schemas/RoutesReturn.schema.json" with { type: "json" }; +import subscriptionsArgumentsSchema from "./schemas/SubscriptionsArguments.schema.json" with { type: "json" }; import { Args } from "typescript-json-schema"; const ajv = new Ajv({ allErrors: true, strict: false }); From e1428027608899df39ca723dd4b93c3dfb076e90 Mon Sep 17 00:00:00 2001 From: Pablo Mendez Date: Thu, 6 Mar 2025 11:49:22 +0100 Subject: [PATCH 12/13] rollback docker image --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index d7a3c4fa2e..3c30344886 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Arguments -ARG BASE_IMAGE=node:22.14.0-alpine3.21 +ARG BASE_IMAGE=node:20.16.0-alpine3.19 ARG BUILDPLATFORM # Initial stage to gather git data From c09b754218e3a0adf2c5c8d6b6e9ca492eee6baa Mon Sep 17 00:00:00 2001 From: Pablo Mendez Date: Thu, 6 Mar 2025 12:02:30 +0100 Subject: [PATCH 13/13] rollback to assert --- packages/common/src/validation/index.ts | 6 +++--- .../src/api/middlewares/ethForward/resolveDomain.ts | 4 ++-- packages/dockerCompose/src/validate.ts | 2 +- packages/schemas/src/validateManifestSchema.ts | 2 +- packages/schemas/src/validateSetupWizardSchema.ts | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/common/src/validation/index.ts b/packages/common/src/validation/index.ts index fef11b3e0a..c1bbd27c43 100644 --- a/packages/common/src/validation/index.ts +++ b/packages/common/src/validation/index.ts @@ -1,7 +1,7 @@ import Ajv from "ajv"; -import routesArgumentsSchema from "./schemas/RoutesArguments.schema.json" with { type: "json" }; -import routesReturnSchema from "./schemas/RoutesReturn.schema.json" with { type: "json" }; -import subscriptionsArgumentsSchema from "./schemas/SubscriptionsArguments.schema.json" with { type: "json" }; +import routesArgumentsSchema from "./schemas/RoutesArguments.schema.json" assert { type: "json" }; +import routesReturnSchema from "./schemas/RoutesReturn.schema.json" assert { type: "json" }; +import subscriptionsArgumentsSchema from "./schemas/SubscriptionsArguments.schema.json" assert { type: "json" }; import { Args } from "typescript-json-schema"; const ajv = new Ajv({ allErrors: true, strict: false }); diff --git a/packages/dappmanager/src/api/middlewares/ethForward/resolveDomain.ts b/packages/dappmanager/src/api/middlewares/ethForward/resolveDomain.ts index ab50670574..ecc1c62f55 100644 --- a/packages/dappmanager/src/api/middlewares/ethForward/resolveDomain.ts +++ b/packages/dappmanager/src/api/middlewares/ethForward/resolveDomain.ts @@ -1,7 +1,7 @@ import { ethers } from "ethers"; import { getEthersProvider, getEthUrl } from "@dappnode/installer"; -import resolverAbi from "./abi/resolverAbi.json" with { type: "json" }; -import ensAbi from "./abi/ens.json" with { type: "json" }; +import resolverAbi from "./abi/resolverAbi.json" assert { type: "json" }; +import ensAbi from "./abi/ens.json" assert { type: "json" }; import { Network, Content, NotFoundError, EnsResolverError } from "./types.js"; import { decodeContentHash, isEmpty, decodeDnsLink, decodeContent } from "./utils/index.js"; import memoize from "memoizee"; diff --git a/packages/dockerCompose/src/validate.ts b/packages/dockerCompose/src/validate.ts index 640f60615b..4abd66771b 100644 --- a/packages/dockerCompose/src/validate.ts +++ b/packages/dockerCompose/src/validate.ts @@ -1,5 +1,5 @@ import { getSchemaValidator } from "@dappnode/utils"; -import compose3xSchema from "./compose_v3x.schema.json" with { type: "json" }; +import compose3xSchema from "./compose_v3x.schema.json" assert { type: "json" }; import { Compose } from "@dappnode/types"; /** diff --git a/packages/schemas/src/validateManifestSchema.ts b/packages/schemas/src/validateManifestSchema.ts index 561044d288..0e18a052b8 100644 --- a/packages/schemas/src/validateManifestSchema.ts +++ b/packages/schemas/src/validateManifestSchema.ts @@ -1,7 +1,7 @@ import { ajv } from "./ajv.js"; import { CliError } from "./error.js"; import { processError } from "./utils.js"; -import manifestSchema from "./schemas/manifest.schema.json" with { type: "json" }; +import manifestSchema from "./schemas/manifest.schema.json" assert { type: "json" }; import { Manifest } from "@dappnode/types"; /** diff --git a/packages/schemas/src/validateSetupWizardSchema.ts b/packages/schemas/src/validateSetupWizardSchema.ts index e1f07147c0..9e59a215e3 100644 --- a/packages/schemas/src/validateSetupWizardSchema.ts +++ b/packages/schemas/src/validateSetupWizardSchema.ts @@ -1,6 +1,6 @@ import { ajv } from "./ajv.js"; import { processError } from "./utils.js"; -import setupWizardSchema from "./schemas/setup-wizard.schema.json" with { type: "json" }; +import setupWizardSchema from "./schemas/setup-wizard.schema.json" assert { type: "json" }; import { CliError } from "./error.js"; import { SetupWizard } from "@dappnode/types";