feat: add RabbitMQ message broker node type with security policy enfo…#49
Open
NureniJamiu wants to merge 350 commits into
Open
feat: add RabbitMQ message broker node type with security policy enfo…#49NureniJamiu wants to merge 350 commits into
NureniJamiu wants to merge 350 commits into
Conversation
…lly during applyPlan execution
…te-then-insert pattern to prevent Docker bridge override
…ovider to prevent invalid iptables rules
… hosts formatting
…vate subnet routing
…dles and shield button
…GW is disabled in the VPC
…s and display subnet details in node options
…-validation Feature/cidr persistence and validation
* feat(backend): add roadmap format JSON Schema (schemaVersion 1) and TS types * feat(roadmaps): add reference example roadmap * feat(backend): add roadmap schema validation function, tests and CLI * feat(frontend): add roadmap types (documented copy of backend source of truth) * docs: add roadmap format reference (fields, validators, i18n, versioning policy)
* refactor(frontend): unify network topology types in shared/types/network.ts * refactor(frontend): extract canvas grid and hit-test geometry into pure canvasGeometry module * refactor(frontend): extract security-rule and firewall-edge logic into pure securityRules module * refactor(frontend): extract network config transforms into pure networkConfigOps module * refactor(frontend): move network config state, save path and audit into useNetworkConfig hook * refactor(frontend): move drag/drop/delete canvas handlers into useCanvasDragDrop hook * refactor(frontend): consolidate the six inspector modal states into one InspectorState union * refactor(frontend): relocate the canvas modal blocks into CanvasModals and CreateNodeModal
…dals (Derssa#56) * feat(frontend): add shared DB inspector building blocks (modal shell, tabs, explorer hook) * refactor(frontend): rebuild the Postgres/NoSql/Redis inspector modals on the shared components Deduplicates the three near-identical modals (~3700 lines down to ~800 plus shared components): identical shell/tabs/styles/fetch-retry/cheat-sheet/query console now live in features/nodes/components. The genuinely per-DB parts (simulation topologies, query handlers, explorer shapes) stay per node. Behavior changes (approved): the NoSql explorer gains the Retry button the other two already had, and the Postgres/NoSql startup auto-retry timers no longer leak or stack (they adopt the Redis retryTimerRef pattern via useExplorerData).
* feat(learning): add the validator execution engine
Runs the declarative validators of a roadmap step against the real state
of the project's containers. Dispatch by type through a single registry,
per-validator error isolation (an unknown type, invalid params or an
unreachable Docker daemon produce an 'error' result for that validator
and the others still run), infrastructure errors classified through the
existing dockerErrors taxonomy, and a lazy memoized container list (one
Docker call per step run). Ships the first validator, container_running.
* feat(learning): expose roadmap loading and step validation over REST
- GET /api/learning/roadmaps — catalogue of the valid roadmap files
found in roadmaps/ (invalid files are logged and never served)
- GET /api/learning/roadmaps/:id — full roadmap for the player
- POST /api/learning/validate — runs every validator of a step for a
project and returns one structured result per validator
({status, message, errorCode?, expected?, observed?} + stepPassed)
Roadmap files are re-read on each request (hot reload for authors) and
resolved from __dirname, never process.cwd(): the CLI spawns the server
without a cwd. Infrastructure failures answer 200 with per-validator
'error' results — 4xx/5xx are reserved for request problems.
* chore: ship the roadmaps directory in the published npm package
The learning engine loads roadmap files from roadmaps/ at the repo
root; without this entry the published CLI would start with an empty
catalogue.
* docs: document the learning validation API
Contract of the three /api/learning endpoints for the player (P-1/P-2):
pass/fail/error semantics and their intended UI mapping, errorCode
table, the 'Docker down answers 200 with error results' policy, a curl
walkthrough (pass and fail) against the example roadmap, and the recipe
for adding a validator type.
Implements the 7 remaining validator types (table_exists, redis_key_exists, mongo_collection_exists, edge_exists, lb_upstreams, port_denied, asg_replicas) alongside the existing container_running, so roadmap steps can check real Postgres/Redis/Mongo state, network connectivity and ASG replica counts, not just container liveness. Reuses existing infrastructure rather than duplicating it: DB validators go through containerProvider's exec* commands (same idiom as the explorers), edge_exists/port_denied reuse NetworkService's security-group rule expansion (now exposed publicly) instead of re-deriving connectivity, and asg_replicas/lb_upstreams read directly off ContainerInfo's asgId/isAsgInstance fields. A shared resolveRunningContainer/resolveSourceAndTarget helper keeps node targeting and pedagogical fail messages consistent across validators. Each validator ships with pass/fail/degraded-case unit tests, and the existing example roadmap already exercises 4 of them end to end.
…eal containers (Derssa#60) * test(learning): integration suite for the 8 validators against real containers Unit tests mock every Docker/DB call, so they prove validator logic but never contact with reality (container timing, DB readiness, real ASG label resolution). Adds engine.itest.ts: one disposable project with real containers, run through runStepValidators' default (real) dependencies for all 8 validators, pass and fail, from a single static fixture so nothing is mutated between assertions. * fix(learning): create the shared Docker network if missing in integration tests CI failed with "network akal-lab-network not found": createContainer attaches every container to that network, but it's normally created once at server startup (DockerInitializer.ensureSharedNetwork) and this suite never boots the server, so a fresh Docker daemon doesn't have it yet.
* fix(learning): 400 on missing JSON body and deterministic (id, language) roadmap selection Two API fixes ahead of the roadmap player (its first real consumer): - POST /api/learning/validate without a JSON Content-Type left req.body undefined, so the destructuring threw and the endpoint answered 500; it now falls through the existing per-field checks and returns 400. - Translations share a roadmap id and differ by language, so getRoadmap(id) returned whichever file readdir listed first and the selection was nondeterministic. The key is now (id, language): GET /roadmaps/:id accepts ?language= (exact match or 404), the language-less form picks deterministically (sorted), and /validate stays language-neutral since steps and validators are shared across translations. Contract documented in docs/learning-api.md. Also fixes the example roadmap's first hint: the node library sits on the right side of the canvas, not the left. * feat(learning): roadmap player side panel (P-1) New frontend/src/features/learning: a sidebar that turns the empty canvas into a guided session. It lists the roadmap catalogue (GET /api/learning/roadmaps), opens a roadmap by (id, language), shows every step with the current one highlighted, and a Validate button that runs POST /api/learning/validate against the real containers and renders the per-validator report (raw rendering for now — P-2 owns the rich pass/fail/error presentation). - useLearningPlayer holds the play-through state: clamped navigation, per-step results kept in memory when navigating (persistence is P-4), a ref-based guard so double-clicking Validate sends one request. - Network failures render inline with a retry action; per the learning API contract, non-2xx is a request/server problem and is never shown as a learner failure. - Minimal CanvasPage surface: one showLearning state, one topbar button, one conditional sibling in the body row. Closed panel means nothing is mounted and no learning endpoint is touched (tested). - Labels in en/fr via i18next; styling on the shared CSS variables. * refactor(learning): apply self-review findings on the player - Render RoadmapCatalog at a single JSX position so a failed roadmap load no longer remounts it (which re-fired its catalogue fetch). - Lift readErrorMessage to shared/utils and reuse it from useContainers and useLearningPlayer instead of duplicating it. - Guard openRoadmap against out-of-order resolutions (latest request wins) and against a malformed 200 body (steps must be a non-empty array) so a bad payload surfaces as a load error, not a render crash. - estimatedMinutes uses a null check: a value of 0 rendered a stray "0" text node in the catalogue card. - Pluralize the step-count label (steps_one/steps_other) so a single-step roadmap doesn't read "1 steps". - Name the requested language in the 404 when a roadmap id exists but the translation doesn't, instead of claiming the id is unknown. - Derive Previous/Next bounds once (atFirstStep/atLastStep).
* fix(learning): restrict edgeExists and portDenied validators to inbound rules * docs(learning): align roadmap instructions with UI node labels * feat(learning): add http_get_contains validator, copy block actions, and step 5 instructions * fix(learning): resolve TypeScript compilation errors in frontend and backend tests * test(learning): fix integration tests security group configuration to use inbound target rules
…states (Derssa#64) * feat(learning): pedagogical validation feedback with pass/fail/error states * refactor(learning): centralize status presets and apply review findings
…rules port mapping
…m image builder in integration tests
…ng built-in web storage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR implements and integrates the RabbitMQ message broker node type into the system architecture canvas.
closes #45
Why is this needed?
Previously, users were unable to practice designing systems with asynchronous queues, publish-subscribe topologies, or message routing keys on the canvas. Adding a dedicated RabbitMQ broker node enables these learning flows with an integrated management dashboard and interactive cheat sheets.
Key Features
rabbitmq:3-managementcontainers, enabling the AMQP protocol on port5672and the HTTP management web interface on port15672.dockerNetworkProvider.tspolicy mapping so RabbitMQ containers retain their connection to the defaultakal-lab-networkbridge. This prevents port forwarding/mapped host links (http://localhost:<mapped_port>) from being disconnected by subnet isolation policies.RabbitMqModal.tsx):guest/guest), and a launch button.amqplib) and Python (pika).15672for host console access, and port5672for client applications in other subnets).rabbitmqas a sensitive infrastructure type in thearchitectureValidator.tsengine, flagging warnings if placed in a public subnet or directly exposed to0.0.0.0/0.Changed Files
Backend
backend/src/infrastructure/docker/ContainerManager.ts(RabbitMQ image constants, pull helper, and container options configuration)backend/src/modules/network/providers/dockerNetworkProvider.ts(Bridged network policy retention and reconnect exemptions)Frontend
frontend/src/features/nodes/RabbitMqNode/RabbitMqNode.tsx[NEW] (RabbitMQ card component composingBaseNodelayout)frontend/src/features/nodes/RabbitMqNode/RabbitMqModal.tsx[NEW] (Inspector overlay with details, warnings, and code cheat sheets)frontend/src/features/nodes/RabbitMqNode/data/rabbitmqCheatSheet.json[NEW] (Concepts definitions and client developer snippets)frontend/src/pages/CanvasPage/components/NodeLibrary.tsx(Added a new "Message Brokers" category for palette placement)frontend/src/pages/CanvasPage/CanvasPage.tsx(Wired node type hooks, inspected modals hooks, drop defaults)frontend/src/shared/types/index.ts(ExtendedContainerDatatype union to include'rabbitmq')frontend/src/shared/utils/architectureValidator.ts(Addedrabbitmqtype tosensitiveTypesarray)Localization / Resources
frontend/src/locales/en.json(English translation keys for tabs, labels, and tooltips)frontend/src/locales/fr.json(French translation keys matching English specifications)Pull Request Checklist
typestring is lowercase and identical across palette,nodeTypes, API, labels, and unions.ensure<X>Image(), image selection branch, port mapping,ContainerInfounion.<X>Node.tsx(viaBaseNode),nodeTypes,NodeLibrary,ContainerDataunion, drop placeholder.npm run linton frontend & backend and verified that there are no lint warnings