diff --git a/CLAUDE.md b/CLAUDE.md index 5c4e53a9..7c6692cc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,7 +13,7 @@ When a change is requested, the default assumption is: update the design doc *an - `docs/` — Design documentation: `docs/requirements/` (high-level + per-component specs), `docs/test_infra/` (test infrastructure), `docs/plans/` (design-decision and implementation-plan docs). The spec the code implements. - `docker/` — 8-node cluster topology (2 central + 3 sites), `deploy.sh`, per-node `appsettings.*.json`. See [`docker/README.md`](docker/README.md) for setup, ports, and management commands. Rebuild + redeploy with `bash docker/deploy.sh`. - `docker-env2/` — Minimal second cluster topology (2 central + 1 site × 2 nodes), runs concurrently with `docker/` on host ports 91XX. Built specifically for testing the Transport (#24) feature with two real environments. See [`docker-env2/README.md`](docker-env2/README.md). Rebuild + redeploy with `bash docker-env2/deploy.sh`. -- `infra/` — Docker Compose for local test services (LDAP, MS SQL, OPC UA, SMTP, REST API, Traefik). +- `infra/` — Docker Compose for local test services (MS SQL, OPC UA, SMTP, REST API, Traefik). **LDAP is no longer started here** — dev/test LDAP is the shared GLAuth on `10.100.0.35:3893` (source of truth: `scadaproj/infra/glauth/`). - `deploy/` — Production/on-host deployment artifacts (e.g. `deploy/wonder-app-vd03/`: `appsettings.Central.json`, `appsettings.Site.json`, `install.ps1`/`uninstall.ps1`, `RUNBOOK.md`). - `deployments/` — Deployment topology notes (`docker-cluster.md`, `docker-cluster-env2.md`, `README.md`). - `code-reviews/` — Per-component code-review notes (one folder per component, plus `_template`). @@ -29,7 +29,7 @@ When a change is requested, the default assumption is: update the design doc *an - `README.md` — Master index with component table and architecture diagrams. - `docs/requirements/HighLevelReqs.md` — Complete high-level requirements covering all functional areas. - `docs/requirements/Component-*.md` — Individual component design documents (one per component) — the spec the code implements. -- `docs/test_infra/test_infra.md` — Master test infrastructure doc (OPC UA, LDAP, MS SQL, SMTP, REST API, Traefik). +- `docs/test_infra/test_infra.md` — Master test infrastructure doc (OPC UA, MS SQL, SMTP, REST API, Traefik). LDAP is the shared GLAuth on `10.100.0.35:3893` (not a local infra container; see `scadaproj/infra/glauth/`). - `docs/plans/` — Design decision and implementation-plan documents from refinement sessions. ## Sister Projects @@ -225,5 +225,5 @@ Related repos cloned as sibling directories under `~/Desktop/` — referenced fo - **Test user**: `--username multi-role --password password` — has Admin, Design, and Deployment roles. The `admin` user only has the Admin role and cannot create templates, data connections, or deploy. - **Config file**: `~/.scadabridge/config.json` — stores `managementUrl` and default format. See `docker/README.md` for a ready-to-use test config. - **Rebuild cluster**: `bash docker/deploy.sh` — builds the `scadabridge:latest` image and recreates all containers. Run this after code changes to ManagementActor, Host, or any server-side component. -- **Infrastructure services**: `cd infra && docker compose up -d` — starts LDAP, MS SQL, OPC UA, SMTP, and REST API. These are separate from the cluster containers in `docker/`. -- **All test LDAP passwords**: `password` (see `infra/glauth/config.toml` for users and groups). +- **Infrastructure services**: `cd infra && docker compose up -d` — starts MS SQL, OPC UA, SMTP, and REST API. These are separate from the cluster containers in `docker/`. **LDAP is NOT started here** — it is the shared GLAuth on `10.100.0.35:3893` (dc=zb,dc=local); source of truth and config: `scadaproj/infra/glauth/`. +- **All test LDAP passwords**: `password` (see `scadaproj/infra/glauth/config.toml` for users and groups; canonical cross-app login: `multi-role`). diff --git a/docs/test_infra/test_infra.md b/docs/test_infra/test_infra.md index 21990f1e..f78828d4 100644 --- a/docs/test_infra/test_infra.md +++ b/docs/test_infra/test_infra.md @@ -8,7 +8,7 @@ This document describes the local Docker-based test infrastructure for ScadaBrid |---------|-------|---------|--------|-------------| | OPC UA Server | `mcr.microsoft.com/iotedge/opc-plc:latest` | 50000 (OPC UA), 8080 (web) | `infra/opcua/nodes.json` | `infra/` | | OPC UA Server 2 | `mcr.microsoft.com/iotedge/opc-plc:latest` | 50010 (OPC UA), 8081 (web) | `infra/opcua/nodes.json` | `infra/` | -| LDAP Server | `glauth/glauth:latest` | 3893 | `infra/glauth/config.toml` | `infra/` | +| LDAP Server | `glauth/glauth:latest` | 3893 | `scadaproj/infra/glauth/config.toml` | **Shared** — `zb-shared-glauth` on `10.100.0.35`; NOT started by `infra/` stack (retired 2026-06-04). See `scadaproj/infra/glauth/`. | | MS SQL 2022 | `mcr.microsoft.com/mssql/server:2022-latest` | 1433 | `infra/mssql/setup.sql` | `infra/` | | SMTP (Mailpit) | `axllent/mailpit:latest` | 1025 (SMTP), 8025 (web) | Environment vars | `infra/` | | REST API (Flask) | Custom build (`infra/restapi/Dockerfile`) | 5200 | `infra/restapi/app.py` | `infra/` | @@ -65,7 +65,7 @@ For use in `appsettings.Development.json`: "ScadaBridgeMachineData": "Server=localhost,1433;Database=ScadaBridgeMachineData;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true" }, "Ldap": { - "Server": "localhost", + "Server": "10.100.0.35", "Port": 3893, "BaseDN": "dc=zb,dc=local", "UseSsl": false @@ -98,7 +98,7 @@ For use in `appsettings.Development.json`: ```bash cd infra docker compose down # stop containers, preserve SQL data volume -docker compose stop opcua # stop a single service (also: opcua2, ldap, mssql, smtp, restapi) +docker compose stop opcua # stop a single service (also: opcua2, mssql, smtp, restapi) # note: ldap is no longer a local service ``` **Full teardown** (removes volumes, optionally images and venv): @@ -117,7 +117,7 @@ After a full teardown, the next `docker compose up -d` starts fresh — re-run t infra/ docker-compose.yml # All seven services teardown.sh # Teardown script (volumes, images, venv) - glauth/config.toml # LDAP users and groups + glauth/config.toml # LDAP users and groups — HISTORICAL (retired 2026-06-04); live config is scadaproj/infra/glauth/config.toml mssql/setup.sql # Database and user creation mssql/machinedata_seed.sql # Machine Data tables, stored procedures, sample data opcua/nodes.json # Custom OPC UA tag definitions diff --git a/docs/test_infra/test_infra_ldap.md b/docs/test_infra/test_infra_ldap.md index 0e1f8bdf..3c303075 100644 --- a/docs/test_infra/test_infra_ldap.md +++ b/docs/test_infra/test_infra_ldap.md @@ -1,5 +1,11 @@ # Test Infrastructure: LDAP Server +> **SUPERSEDED 2026-06-04** — ScadaBridge no longer runs its own glauth. Dev/test LDAP is now the +> shared GLAuth on **10.100.0.35:3893** (dc=zb,dc=local); source of truth and runbook: +> **`scadaproj/infra/glauth/`** (`~/Desktop/scadaproj/infra/glauth/config.toml`). The +> `scadabridge-ldap` container has been retired (commented out in `infra/docker-compose.yml`). +> The content below describes the retired local setup, kept for reference/rollback. + ## Overview The test LDAP server uses [GLAuth](https://glauth.github.io/), a lightweight LDAP server backed by a TOML config file. It provides test users and groups that map to ScadaBridge's role-based authorization model. @@ -8,6 +14,7 @@ The test LDAP server uses [GLAuth](https://glauth.github.io/), a lightweight LDA - **Image**: `glauth/glauth:latest` - **LDAP port**: 3893 (plain LDAP, no TLS — dev only) +- **Host (shared)**: `10.100.0.35` — the shared `zb-shared-glauth` container on the Linux docker host (replaces `localhost` below) ## Base DN @@ -58,16 +65,19 @@ The full DNs for all test users: ## Verification -1. Check the container is running: +1. Check the shared container is running (on the docker host): ```bash -docker ps --filter name=scadabridge-ldap +# The container now runs on 10.100.0.35 as zb-shared-glauth, not locally. +# To verify from the docker host: +# docker ps --filter name=zb-shared-glauth +# Formerly: docker ps --filter name=scadabridge-ldap (retired) ``` -2. Test a user bind with `ldapsearch`: +2. Test a user bind with `ldapsearch` against the shared host: ```bash -ldapsearch -H ldap://localhost:3893 \ +ldapsearch -H ldap://10.100.0.35:3893 \ -D "cn=admin,ou=SCADA-Admins,ou=users,dc=zb,dc=local" \ -w password \ -b "dc=zb,dc=local" \ @@ -77,7 +87,7 @@ ldapsearch -H ldap://localhost:3893 \ 3. Search for group membership: ```bash -ldapsearch -H ldap://localhost:3893 \ +ldapsearch -H ldap://10.100.0.35:3893 \ -D "cn=admin,ou=SCADA-Admins,ou=users,dc=zb,dc=local" \ -w password \ -b "dc=zb,dc=local" \ @@ -112,7 +122,7 @@ python infra/tools/ldap_tool.py groups python infra/tools/ldap_tool.py search --filter "(cn=multi-role)" ``` -Use `--host` and `--port` to override defaults (localhost:3893). Run with `--help` for full usage. +Use `--host 10.100.0.35 --port 3893` to point at the shared server. Run with `--help` for full usage. ## Relevance to ScadaBridge Components @@ -122,6 +132,6 @@ Use `--host` and `--port` to override defaults (localhost:3893). Run with `--hel ## Notes - GLAuth uses plain LDAP on port 3893. ScadaBridge's Security & Auth component requires LDAPS/StartTLS in production. For dev testing, configure the LDAP client to allow plaintext connections. -- To add users or groups, edit `infra/glauth/config.toml` locally and restart the container: `docker compose restart ldap`. Note that the file is named `config.toml` on the host but is mounted into the container as `/app/config/config.cfg` (the path GLAuth expects). +- To add users or groups, edit **`scadaproj/infra/glauth/config.toml`** (the shared source of truth at `~/Desktop/scadaproj/infra/glauth/config.toml`) and restart the `zb-shared-glauth` container on the docker host. **Do not edit the retired `ScadaBridge/infra/glauth/config.toml`** — that file is historical only. The config is mounted into the container as `/app/config/config.cfg` (the path GLAuth expects). - The `admin` user is configured with `[[users.capabilities]]` (`action = "search"`, `object = "*"`) in the GLAuth config. This grants the admin account permission to perform LDAP search operations, which is required for user/group lookups. - Anonymous bind is not allowed. All LDAP operations (including searches) require an authenticated bind. Use the `admin` account for search operations. diff --git a/infra/README.md b/infra/README.md index 0a5b9e5c..ad937f22 100644 --- a/infra/README.md +++ b/infra/README.md @@ -14,7 +14,7 @@ This starts the following services: |---------|------|---------| | OPC UA (Azure IoT OPC PLC) | 50000 (OPC UA), 8080 (web) | Simulated OPC UA server with ScadaBridge-style tags | | OPC UA 2 (Azure IoT OPC PLC) | 50010 (OPC UA), 8081 (web) | Second OPC UA server instance (same tags, independent state) | -| LDAP (GLAuth) | 3893 | Lightweight LDAP with test users/groups matching ScadaBridge roles | +| ~~LDAP (GLAuth)~~ | ~~3893~~ | **RETIRED (2026-06-04)** — no longer started by this stack. Dev/test LDAP is the shared GLAuth on `10.100.0.35:3893` (dc=zb,dc=local). Central nodes bind `Ldap:Server=10.100.0.35`. Source of truth + config: `scadaproj/infra/glauth/`. | | MS SQL 2022 | 1433 | Configuration and machine data databases | | SMTP (Mailpit) | 1025 (SMTP), 8025 (web) | Email capture for notification testing | | REST API (Flask) | 5200 | External REST API for Gateway and Inbound API testing | @@ -56,7 +56,7 @@ docker compose down **Stop a single service** (leave the others running): ```bash -docker compose stop opcua # or: opcua2, ldap, mssql, smtp, restapi +docker compose stop opcua # or: opcua2, mssql, smtp, restapi (ldap is no longer a local service) docker compose start opcua # bring it back without recreating ```