Skip to content

refactor(service-monitor): migrate module from server - #2775

Open
shikanime wants to merge 13 commits into
mainfrom
feat/service-monitor-nestjs
Open

shikanime wants to merge 13 commits into
mainfrom
feat/service-monitor-nestjs

Conversation

@shikanime

@shikanime shikanime commented Sep 24, 2026 •

Copy link
Copy Markdown
Member

Issues liées

Refs #1889


Quel est le comportement actuel ?

Les routes GET /api/v1/health-services, GET /api/v1/complete-services et GET /api/v1/refresh-services sont servies par l'ancienne application Fastify apps/server, via le registre services de @cpn-console/hooks.

Quel est le nouveau comportement ?

Migration du module service-monitor vers apps/server-nestjs :

  • ServiceMonitorController : routes GET /health-services, GET /complete-services (admin ListSystem), GET /refresh-services (admin ManageSystem).
  • ServiceMonitorService : agrège les services de santé terminus de chaque module plugin (ArgoCDHealthService, GitlabHealthService, RegistryHealthService, KeycloakHealthService, NexusHealthService, SonarqubeHealthService, VaultHealthService). Aucune dépendance aux paquets @cpn-console/*-plugin ni au registre services de @cpn-console/hooks, tous deux appelés à être supprimés.
  • Le gating reproduit PluginModule et HealthzModule : ConditionalModule.registerWhen sur les variables USE_*, Keycloak toujours actif ; les sondes sont exécutées à l'initialisation du module.
  • Réalignement sur les conventions du dépôt : réutilisation de MonitorInfos et MonitorStatus de @cpn-console/shared (plus de type local dupliqué), narrow typé sans as conformément à la politique stricte du dépôt, titres legacy des plugins (ArgoCD, Gitlab, Harbor, Keycloak, Nexus, SonarQube, Vault), et cause renseigné sur les sondes en échec comme dans la registry legacy.
  • La PR nginx associée est empilée : feat(nginx-strangler): route service-monitor to server-nestjs #2776.

Cette PR introduit-elle un breaking change ?

Non.

Autres informations

Parité avec l'ancien serveur : mêmes routes, même schéma de réponse (MonitorInfos), mêmes permissions admin. Le nom affiché est le titre du plugin (ex. ArgoCD), comme avec le registre hooks.

@shikanime
shikanime requested a review from a team as a code owner September 24, 2026 10:24
@github-actions github-actions Bot added the built label Sep 24, 2026
@shikanime
shikanime added this pull request to stack #2777 September 24, 2026 10:34
@shikanime shikanime added the preview Deploy preview app with Argo-cd label Sep 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🤖 Hey !

A preview of the application is available at : https://console-pr-2775.dso.cpin-hp.numerique-interieur.fr

Please be patient, deployment may take a few minutes.

Comment thread apps/server-nestjs/package.json
Comment thread apps/server-nestjs/src/modules/service-monitor/service-monitor.service.ts Outdated
@StephaneTrebel
StephaneTrebel self-requested a review September 24, 2026 14:03

@StephaneTrebel StephaneTrebel left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

La migration introduit quatre écarts bloquants de sécurité et de parité fonctionnelle. Ils doivent être corrigés avant la bascule Nginx de la MR empilée #2776.

Comment thread apps/server-nestjs/src/modules/service-monitor/service-monitor.service.ts Outdated
Comment thread apps/server-nestjs/src/modules/service-monitor/service-monitor.service.ts Outdated
Comment thread apps/server-nestjs/src/modules/service-monitor/service-monitor.service.ts Outdated
@iliesmrf iliesmrf added this to the 9.27.0 milestone Sep 25, 2026
@shikanime

Copy link
Copy Markdown
Member Author

L'import AuthModule de ServiceMonitorModule est rapatrié ici depuis #2776 : le module migré doit fournir les dépendances de son UserGuard.

La PR de bascule (#2776) ne porte plus que apps/nginx-strangler/conf.d/routing.conf.

@shikanime shikanime removed the preview Deploy preview app with Argo-cd label Sep 28, 2026
@shikanime shikanime self-assigned this Sep 29, 2026
@shikanime shikanime added the refactor Refactor code label Sep 29, 2026
@shikanime
shikanime requested review from a team and StephaneTrebel and removed request for StephaneTrebel September 29, 2026 13:07
Comment thread apps/server-nestjs/src/modules/registry/registry-health.service.ts Outdated
Comment thread apps/server-nestjs/src/modules/registry/registry-health.service.ts Outdated
Comment thread apps/server-nestjs/src/modules/registry/registry-health.service.ts Outdated
Comment thread apps/server-nestjs/src/modules/registry/registry-health.service.ts Outdated
Comment thread apps/server-nestjs/src/modules/service-monitor/service-monitor.service.spec.ts Outdated
Comment thread apps/server-nestjs/src/modules/service-monitor/service-monitor.service.ts Outdated
Comment thread apps/server-nestjs/src/modules/service-monitor/service-monitor.service.ts Outdated
Comment thread apps/server-nestjs/src/modules/sonarqube/sonarqube-health.service.ts Outdated
Comment thread apps/server-nestjs/src/modules/sonarqube/sonarqube-health.service.ts Outdated
Comment thread apps/server-nestjs/src/modules/service-monitor/service-monitor.service.ts Outdated

@shikanime shikanime left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict : Commentaire

Le monitor migré reproduit fidèlement la sémantique legacy (sonde périodique, dernier état servi entre passes, cause masquée sur la route publique, états SonarQube et sonde Harbor complète repris). Les points bloquants soulevés sur les commits précédents semblent traités à head ; seul un fragilité mineure subsiste dans le mapping du probe terminus.

Comment thread apps/server-nestjs/src/modules/service-monitor/service-monitor.utils.ts Outdated
Comment thread apps/server-nestjs/src/modules/service-monitor/service-monitor.service.ts Outdated
@shikanime
shikanime force-pushed the feat/service-monitor-nestjs branch 3 times, most recently from b1888a6 to 8b0c087 Compare October 1, 2026 15:15
@iliesmrf iliesmrf modified the milestones: 9.27.0, 9.28.0 Oct 2, 2026
@shikanime
shikanime force-pushed the feat/service-monitor-nestjs branch from 43fbc77 to a0fbda4 Compare October 2, 2026 11:56

@StephaneTrebel StephaneTrebel left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

La migration service-monitor remplace le registre legacy par des sondes Nest conditionnelles et conserve les trois niveaux d’accès ainsi que le format de réponse. Le ledger #1889 est global et non clos à l’échelle de cette PR ; fils résolus et CI verte sur cette tête.

@shikanime
shikanime force-pushed the feat/service-monitor-nestjs branch 4 times, most recently from 049c346 to b9f1ac5 Compare October 2, 2026 15:23
StephaneTrebel
StephaneTrebel previously approved these changes Oct 2, 2026

@StephaneTrebel StephaneTrebel left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approbation renouvelée : la résolution de health-check cible explicitement la clé de l’indicateur, ce qui évite de dépendre de l’ordre des propriétés de réponse. Aucune régression identifiée sur cette tête.

…iases

Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: If8a72fc86040c89440538abed8b4a0ce6a6a6964

Signed-off-by: Shikanime Deva <22115108+shikanime@users.noreply.github.com>
Co-authored-by: Automata <automata@shikanime.studio>

Signed-off-by: Shikanime Deva <22115108+shikanime@users.noreply.github.com>
…-promise awaits

Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: I335fba92cfd5882a8a05c51ef59d26696a6a6964

Signed-off-by: Shikanime Deva <22115108+shikanime@users.noreply.github.com>
…ealthCheck

Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: Iaecd853ed363b4bfd770aa5b447aec656a6a6964

Signed-off-by: Shikanime Deva <22115108+shikanime@users.noreply.github.com>

@shikanime shikanime left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revue du head 37a6405e — module service-monitor propre et bien cadré : le service agrège les health services terminus des modules plugins sans dépendre des paquets @cpn-console/*-plugin ni du registre hooks (les 7 dépendances plugin sont bien retirées de package.json, et plus aucun import résiduel sur le head), gating ConditionalModule.registerWhen sur USE_* avec Keycloak toujours actif, routes admin gardées (ListSystem / ManageSystem) en parité avec le legacy. fromHealthCheck(result, key) reçoit bien la clé d'indicator explicitement — pas de devinette sur la forme de unknown, narrow par type-guard, zéro cast as. 25 specs ajoutées, aucune supprimée. Les specs d'adaptation (registry-health monitor() sur /api/v2.0/health, sonarqube SONARQUBE_HEALTH_STATUS) reproduisent le comportement legacy documenté. Rien de bloquant.

Résumé des sévérités : 0 bloquant, 0 important, 2 nits.

export const SONARQUBE_PROJECT_QUALIFIER_VIEW = 'VW'

// Health monitor messages
export const REQUEST_ERROR_MESSAGE = 'Erreur lors la requête'

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit — REQUEST_ERROR_MESSAGE = 'Erreur lors la requête' est désormais défini trois fois avec la même valeur (ici, service-monitor.constants.ts:5, et l'ancien plugin). Le module service-monitor est le seul consommateur du message côté NestJS : le laisser dans service-monitor.constants.ts et l'importer ici éviterait une divergence future des libellés. À défaut, un commentaire croisé sur la constante.

import { VaultHealthService } from '../vault/vault-health.service'
import { INTERVAL_MS, PENDING_MESSAGE, REQUEST_ERROR_MESSAGE } from './service-monitor.constants'
import { fromHealthCheck, toCause } from './service-monitor.utils'
import type { ProbeOutcome } from './service-monitor.utils'

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit — L'import type { ProbeOutcome } est placé après les imports de valeurs (fromHealthCheck), ce que #2776 corrige d'ailleurs en le remontant en tête de bloc. Autant le corriger ici, dans la PR qui crée le fichier, plutôt que de porter un fix d'ordre d'import dans une PR de bascule nginx.

Deduplicate the private isRecord copies in service-monitor.utils and
sonarqube-health.service onto src/utils/record.utils, next to
hasEntries.

Co-authored-by: Automata <automata@shikanime.studio>
Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: I86a0cc083756a99f4b7f47c8c7ce8a596a6a6964

Signed-off-by: Shikanime Deva <22115108+shikanime@users.noreply.github.com>
@shikanime
shikanime force-pushed the feat/service-monitor-nestjs branch from 6d8d6f7 to aa67145 Compare October 8, 2026 12:25
@shikanime shikanime linked an issue Oct 8, 2026 that may be closed by this pull request
4 tasks
StephaneTrebel
StephaneTrebel previously approved these changes Oct 9, 2026

@StephaneTrebel StephaneTrebel left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✨ La migration reprend les trois routes, les permissions différenciées et les verdicts Harbor/SonarQube plutôt que de se limiter à un simple ping. Aucun finding relevé dans le diff ; la bascule nginx reste explicitement portée par la MR empilée #2776.

… type block

Co-authored-by: Automata <automata@shikanime.studio>
Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: I6b3e511e25e17db048f94a7cb31bdbb56a6a6964
@shikanime
shikanime force-pushed the feat/service-monitor-nestjs branch 2 times, most recently from cf237df to d124668 Compare October 12, 2026 14:20
…ession

Remove the parallel monitor() probe paths: Harbor and SonarQube expose a
single check() that probes the legacy monitor endpoint and reports the
verdict directly with indicator.up()/down(), carrying message and cause
as indicator data. fromHealthCheck lifts message and cause into the
MonitorInfos shape, so every probe aggregates through the same check()
path without MonitorStatus leaking into the health services.

Co-authored-by: Automata <automata@shikanime.studio>
Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: I746a21c6837dd2c448f192aec7d763ca6a6a6964
@shikanime
shikanime force-pushed the feat/service-monitor-nestjs branch from d124668 to 8c355a5 Compare October 12, 2026 14:35
shikanime and others added 6 commits October 12, 2026 17:08
Replace the private MonitoredService.lastStatus array and snapshot() with
the module cache (CacheModule.register + @Inject(CACHE_MANAGER)), matching
the registry and keycloak-secret-provider pattern. Reads fall back to the
pending status until the first probe pass writes a key.

Co-authored-by: Automata <automata@shikanime.studio>
Replace the hand-rolled setInterval timer (and its OnModuleDestroy
cleanup) with @Cron(CronExpression.EVERY_5_MINUTES) on runAll, matching
INTERVAL_MS; ScheduleModule.forRoot() is already global. onModuleInit
keeps the first pass.

Co-authored-by: Automata <automata@shikanime.studio>
The service now returns MonitorInfos.cause on every read; the public
GET /health-services strips it in the controller, where the admin-only
boundary lives. getCompleteServiceHealth and read(withCause) collapse
into getServiceHealth; a cached status no longer merges over the pending
fallback, so an OK entry never inherits the pending cause.

Co-authored-by: Automata <automata@shikanime.studio>
The service returns the raw cached cause; toCause stringification now
happens in toServiceHealth at the presentation layer, alongside the
public-route stripping. fromHealthCheck stays in utils (probe parsing).

Co-authored-by: Automata <automata@shikanime.studio>
toPublicServiceHealth replaces the inline destructure in health-services,
keeping the admin-only cause rationale next to its siblings.

Co-authored-by: Automata <automata@shikanime.studio>
Co-authored-by: Automata <automata@shikanime.studio>
@cloud-pi-native-sonarqube

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

built refactor Refactor code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

💡 [REQUEST] - Migrer le module service-monitor vers server-nestjs

3 participants