diff --git a/code-reviews/CLI/findings.md b/code-reviews/CLI/findings.md index e6e1bcad..e79da3cc 100644 --- a/code-reviews/CLI/findings.md +++ b/code-reviews/CLI/findings.md @@ -22,7 +22,7 @@ The dominant theme is **graceful-degradation gaps**: several user-supplied input URLs, malformed `--bindings`/`--overrides` JSON, non-JSON success bodies) are deserialized or constructed without `try/catch`, so a normal user mistake surfaces as an unhandled exception with a stack trace instead of a clean error message and exit code 1. A second -theme is **dead configuration**: the `SCADALINK_FORMAT` environment variable and the +theme is **dead configuration**: the `SCADABRIDGE_FORMAT` environment variable and the `defaultFormat` config-file field are loaded by `CliConfig` but never consulted by any command, so the documented format-precedence chain does not work. The third theme is **substantial design-document drift**: `Component-CLI.md` describes a name-keyed, @@ -126,7 +126,7 @@ _Re-review (2026-05-28, `1eb6e97`):_ ## Findings -### CLI-001 — `SCADALINK_FORMAT` env var and config-file format are dead; format precedence broken +### CLI-001 — `SCADABRIDGE_FORMAT` env var and config-file format are dead; format precedence broken | | | |--|--| @@ -137,7 +137,7 @@ _Re-review (2026-05-28, `1eb6e97`):_ **Description** -`CliConfig.Load()` reads `SCADALINK_FORMAT` and the `defaultFormat` config-file field into +`CliConfig.Load()` reads `SCADABRIDGE_FORMAT` and the `defaultFormat` config-file field into `CliConfig.DefaultFormat`, and `Component-CLI.md` documents a format-precedence chain (command-line option → env var → config file). However, every command resolves the format with `var format = result.GetValue(formatOption) ?? "json";` and `formatOption` is created @@ -145,7 +145,7 @@ in `Program.cs:11` with `DefaultValueFactory = _ => "json"`. `GetValue` therefor returns a non-null value ("json" when the flag is absent), so the `?? "json"` fallback never fires and `config.DefaultFormat` is never consulted. The env var and config-file format settings are dead code: `scadabridge site list` always outputs JSON regardless of -`SCADALINK_FORMAT=table` or a `defaultFormat` entry in `~/.scadabridge/config.json`. The +`SCADABRIDGE_FORMAT=table` or a `defaultFormat` entry in `~/.scadabridge/config.json`. The documented behaviour silently does not work. **Recommendation** @@ -312,14 +312,14 @@ wrong element types, and JSON null). Credentials are supplied only via `--username` / `--password`. A password on the command line is visible to any local user via the process list (`ps`, `/proc//cmdline`) and is typically persisted into shell history. Unlike the management URL — which can also come -from `SCADALINK_MANAGEMENT_URL` or the config file — there is no environment-variable +from `SCADABRIDGE_MANAGEMENT_URL` or the config file — there is no environment-variable fallback, no `--password-stdin`, and no interactive prompt for the password. For a tool explicitly intended for CI/CD automation this materially increases the chance of credential leakage. **Recommendation** -Add a `SCADALINK_PASSWORD` environment variable fallback and/or a `--password-stdin` +Add a `SCADABRIDGE_PASSWORD` environment variable fallback and/or a `--password-stdin` option (read the password from stdin), and document that `--password` on the command line is discouraged. Optionally prompt interactively when stdin is a TTY and no password was supplied. @@ -327,7 +327,7 @@ supplied. **Resolution** Resolved 2026-05-16 (commit pending). Root cause confirmed — credentials had no -non-command-line source. Added `SCADALINK_USERNAME` / `SCADALINK_PASSWORD` environment +non-command-line source. Added `SCADABRIDGE_USERNAME` / `SCADABRIDGE_PASSWORD` environment fallbacks: `CliConfig.Load` now reads them into new `CliConfig.Username` / `Password` properties (credentials are sourced from environment variables only, never the config file, so they are not persisted). `CommandHelpers.ResolveCredential` resolves precedence @@ -387,7 +387,7 @@ bind-connections`/`assign-area`, `data-connection assign/unassign`, `security ap enable/disable`) are removed; previously-omitted commands (`instance alarm-override set/delete/list`, `external-system method` subgroup, `site deploy-artifacts`) are added. A note now points to `src/ZB.MOM.WW.ScadaBridge.CLI/README.md` as the authoritative reference. The -Configuration section also documents the new `SCADALINK_USERNAME`/`SCADALINK_PASSWORD` +Configuration section also documents the new `SCADABRIDGE_USERNAME`/`SCADABRIDGE_PASSWORD` env vars (see CLI-006). ### CLI-008 — `--format` value is not validated @@ -817,7 +817,7 @@ and a caller-supplied success handler. In duplicating it, two contracts that `2` = authorization failure," so this is a contract regression. 2. **Error-message phrasing drift.** The two duplicated error paths (`bundle:258-260`, `:264-266`) emit shorter messages that omit the - `SCADALINK_MANAGEMENT_URL` / `SCADALINK_USERNAME` env-var hints the canonical paths + `SCADABRIDGE_MANAGEMENT_URL` / `SCADABRIDGE_USERNAME` env-var hints the canonical paths give — confusing if the user is trying to debug what's missing. **Recommendation** diff --git a/code-reviews/ConfigurationDatabase/findings.md b/code-reviews/ConfigurationDatabase/findings.md index e3f509ce..0e6a1c6c 100644 --- a/code-reviews/ConfigurationDatabase/findings.md +++ b/code-reviews/ConfigurationDatabase/findings.md @@ -230,7 +230,7 @@ Resolved 2026-05-16 (commit pending). Root cause confirmed against source: the f fell back to a literal `User Id=sa;Password=YourPassword;...` connection string when no configured value was found. Removed the hardcoded fallback entirely. The factory now resolves the connection string from the Host's appsettings files or, when those are not -present, from the `SCADALINK_DESIGNTIME_CONNECTIONSTRING` environment variable, and +present, from the `SCADABRIDGE_DESIGNTIME_CONNECTIONSTRING` environment variable, and throws a clear `InvalidOperationException` (naming both the config key and the env var) when neither yields a value. Also hardened `SetBasePath` to be applied only when the `ZB.MOM.WW.ScadaBridge.Host` directory exists, so the factory degrades cleanly instead of throwing diff --git a/docker-env2/docker-compose.yml b/docker-env2/docker-compose.yml index 1e05da9e..0a248233 100644 --- a/docker-env2/docker-compose.yml +++ b/docker-env2/docker-compose.yml @@ -3,7 +3,7 @@ services: image: scadabridge:latest container_name: scadabridge-env2-central-a environment: - SCADALINK_CONFIG: Central + SCADABRIDGE_CONFIG: Central ASPNETCORE_ENVIRONMENT: Development ASPNETCORE_URLS: "http://+:5000" ports: @@ -20,7 +20,7 @@ services: image: scadabridge:latest container_name: scadabridge-env2-central-b environment: - SCADALINK_CONFIG: Central + SCADABRIDGE_CONFIG: Central ASPNETCORE_ENVIRONMENT: Development ASPNETCORE_URLS: "http://+:5000" ports: @@ -37,7 +37,7 @@ services: image: scadabridge:latest container_name: scadabridge-env2-site-x-a environment: - SCADALINK_CONFIG: Site + SCADABRIDGE_CONFIG: Site ports: - "9121:8082" # Akka remoting - "9123:8083" # gRPC streaming @@ -53,7 +53,7 @@ services: image: scadabridge:latest container_name: scadabridge-env2-site-x-b environment: - SCADALINK_CONFIG: Site + SCADABRIDGE_CONFIG: Site ports: - "9122:8082" # Akka remoting - "9124:8083" # gRPC streaming diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index b52669ed..eed0fce9 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -3,7 +3,7 @@ services: image: scadabridge:latest container_name: scadabridge-central-a environment: - SCADALINK_CONFIG: Central + SCADABRIDGE_CONFIG: Central ASPNETCORE_ENVIRONMENT: Development ASPNETCORE_URLS: "http://+:5000" ports: @@ -20,7 +20,7 @@ services: image: scadabridge:latest container_name: scadabridge-central-b environment: - SCADALINK_CONFIG: Central + SCADABRIDGE_CONFIG: Central ASPNETCORE_ENVIRONMENT: Development ASPNETCORE_URLS: "http://+:5000" ports: @@ -37,7 +37,7 @@ services: image: scadabridge:latest container_name: scadabridge-site-a-a environment: - SCADALINK_CONFIG: Site + SCADABRIDGE_CONFIG: Site ports: - "9021:8082" # Akka remoting (host access for debugging) - "9023:8083" # gRPC streaming @@ -53,7 +53,7 @@ services: image: scadabridge:latest container_name: scadabridge-site-a-b environment: - SCADALINK_CONFIG: Site + SCADABRIDGE_CONFIG: Site ports: - "9022:8082" # Akka remoting - "9024:8083" # gRPC streaming @@ -69,7 +69,7 @@ services: image: scadabridge:latest container_name: scadabridge-site-b-a environment: - SCADALINK_CONFIG: Site + SCADABRIDGE_CONFIG: Site ports: - "9031:8082" # Akka remoting - "9033:8083" # gRPC streaming @@ -85,7 +85,7 @@ services: image: scadabridge:latest container_name: scadabridge-site-b-b environment: - SCADALINK_CONFIG: Site + SCADABRIDGE_CONFIG: Site ports: - "9032:8082" # Akka remoting - "9034:8083" # gRPC streaming @@ -101,7 +101,7 @@ services: image: scadabridge:latest container_name: scadabridge-site-c-a environment: - SCADALINK_CONFIG: Site + SCADABRIDGE_CONFIG: Site ports: - "9041:8082" # Akka remoting - "9043:8083" # gRPC streaming @@ -117,7 +117,7 @@ services: image: scadabridge:latest container_name: scadabridge-site-c-b environment: - SCADALINK_CONFIG: Site + SCADABRIDGE_CONFIG: Site ports: - "9042:8082" # Akka remoting - "9044:8083" # gRPC streaming diff --git a/docs/plans/2026-05-20-auditlog-m1-foundation.md b/docs/plans/2026-05-20-auditlog-m1-foundation.md index eb773ae0..5d4b29fa 100644 --- a/docs/plans/2026-05-20-auditlog-m1-foundation.md +++ b/docs/plans/2026-05-20-auditlog-m1-foundation.md @@ -165,7 +165,7 @@ Five indexes with explicit names: - `scadabridge_audit_writer`: GRANT INSERT ON AuditLog; GRANT SELECT ON AuditLog. (No UPDATE, no DELETE.) - `scadabridge_audit_purger`: GRANT ALTER ON SCHEMA::dbo; GRANT SELECT ON AuditLog. (Enables ALTER PARTITION FUNCTION SWITCH and SWITCH PARTITION.) - `Down()` drops indexes, table, scheme, function, then both roles. -- Create: `tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/Migrations/AddAuditLogTableMigrationTests.cs` — uses a fixture connecting to the running `infra/mssql` container via the connection string in `infra/mssql/.env` (or skips with `Skip.If` when the env var `SCADALINK_MSSQL_TEST_CONN` is unset, so CI without the container still passes). +- Create: `tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/Migrations/AddAuditLogTableMigrationTests.cs` — uses a fixture connecting to the running `infra/mssql` container via the connection string in `infra/mssql/.env` (or skips with `Skip.If` when the env var `SCADABRIDGE_MSSQL_TEST_CONN` is unset, so CI without the container still passes). Integration test assertions: - `sys.partition_functions` contains `pf_AuditLog_Month`. @@ -191,10 +191,10 @@ Integration test assertions: **Notes for the implementer:** - Use `Microsoft.Data.SqlClient` directly in the test fixture (not EF) to issue raw SQL for grant assertions. -- `Skip.If(string.IsNullOrEmpty(Environment.GetEnvironmentVariable("SCADALINK_MSSQL_TEST_CONN")), "MSSQL not available")` — keeps tests CI-safe. +- `Skip.If(string.IsNullOrEmpty(Environment.GetEnvironmentVariable("SCADABRIDGE_MSSQL_TEST_CONN")), "MSSQL not available")` — keeps tests CI-safe. - Test database name: `ScadaBridgeAuditMigrationTest_` (created per fixture, dropped on dispose). -**Bundle C acceptance:** Migration applied to a fresh test DB on the `infra/mssql` container creates the partition function/scheme/table/indexes/roles. Smoke test confirms UPDATE is denied for the writer role. All migration tests pass when `SCADALINK_MSSQL_TEST_CONN` is set; skip cleanly when unset. +**Bundle C acceptance:** Migration applied to a fresh test DB on the `infra/mssql` container creates the partition function/scheme/table/indexes/roles. Smoke test confirms UPDATE is denied for the writer role. All migration tests pass when `SCADABRIDGE_MSSQL_TEST_CONN` is set; skip cleanly when unset. --- diff --git a/docs/plans/2026-05-24-second-environment.md b/docs/plans/2026-05-24-second-environment.md index c097f901..c06ccdeb 100644 --- a/docs/plans/2026-05-24-second-environment.md +++ b/docs/plans/2026-05-24-second-environment.md @@ -414,7 +414,7 @@ services: image: scadabridge:latest container_name: scadabridge-env2-central-a environment: - SCADALINK_CONFIG: Central + SCADABRIDGE_CONFIG: Central ASPNETCORE_ENVIRONMENT: Development ASPNETCORE_URLS: "http://+:5000" ports: @@ -431,7 +431,7 @@ services: image: scadabridge:latest container_name: scadabridge-env2-central-b environment: - SCADALINK_CONFIG: Central + SCADABRIDGE_CONFIG: Central ASPNETCORE_ENVIRONMENT: Development ASPNETCORE_URLS: "http://+:5000" ports: @@ -448,7 +448,7 @@ services: image: scadabridge:latest container_name: scadabridge-env2-site-x-a environment: - SCADALINK_CONFIG: Site + SCADABRIDGE_CONFIG: Site ports: - "9121:8082" # Akka remoting - "9123:8083" # gRPC streaming @@ -464,7 +464,7 @@ services: image: scadabridge:latest container_name: scadabridge-env2-site-x-b environment: - SCADALINK_CONFIG: Site + SCADABRIDGE_CONFIG: Site ports: - "9122:8082" # Akka remoting - "9124:8083" # gRPC streaming diff --git a/docs/plans/2026-05-24-transport-design.md b/docs/plans/2026-05-24-transport-design.md index 4ea1b575..2788b991 100644 --- a/docs/plans/2026-05-24-transport-design.md +++ b/docs/plans/2026-05-24-transport-design.md @@ -81,7 +81,7 @@ Exactly one of `content.json` or `content.enc` is present. "createdAtUtc": "2026-05-24T12:34:56Z", "sourceEnvironment": "dev-cluster-a", "exportedBy": "alice@corp.example", - "scadaLinkVersion": "1.4.2", + "scadaBridgeVersion": "1.4.2", "contentHash": "sha256:...", "encryption": { "algorithm": "AES-256-GCM", diff --git a/docs/plans/2026-05-24-transport.md b/docs/plans/2026-05-24-transport.md index 1a81cbe4..8e2a63de 100644 --- a/docs/plans/2026-05-24-transport.md +++ b/docs/plans/2026-05-24-transport.md @@ -734,7 +734,7 @@ Tests: **Step 2-5:** Run-fail → implement → run-pass → commit. -`ManifestBuilder` accepts: `sourceEnvironment, exportedBy, scadaLinkVersion, encryption?, contents[], contentBytes` and returns a `BundleManifest` with `ContentHash = SHA-256(contentBytes)`. +`ManifestBuilder` accepts: `sourceEnvironment, exportedBy, scadaBridgeVersion, encryption?, contents[], contentBytes` and returns a `BundleManifest` with `ContentHash = SHA-256(contentBytes)`. `ManifestValidator.Validate(BundleManifest manifest, byte[] contentBytes)` returns a `ValidationResult` enum (`Ok | UnsupportedFormatVersion | ContentHashMismatch | MalformedManifest`). diff --git a/docs/plans/2026-05-31-folder-repo-rename-scadabridge-design.md b/docs/plans/2026-05-31-folder-repo-rename-scadabridge-design.md index b4a711d7..4bffa1cf 100644 --- a/docs/plans/2026-05-31-folder-repo-rename-scadabridge-design.md +++ b/docs/plans/2026-05-31-folder-repo-rename-scadabridge-design.md @@ -59,20 +59,24 @@ They are read by code (`Environment.GetEnvironmentVariable(...)` in Host/CLI/tes Scrubbing these would destroy their before→after meaning: - `tools/rename-to-scadabridge.sh` — prior rename tooling. +- `tools/scrub-scadalink-refs.sh` — this scrub script (its substitution rules are the mapping). - `docker/rename-databases.sh` — DB rename helper (`ALTER DATABASE ScadaLinkConfig MODIFY NAME = ScadaBridgeConfig`, `ALTER LOGIN [scadalink_app] ...`). - `docs/plans/2026-05-28-scadabridge-rename-design.md` — prior rename design. - `docs/plans/2026-05-31-folder-repo-rename-scadabridge-design.md` — **this document** (also a before→after record). +- `docs/plans/2026-05-31-folder-repo-rename-scadabridge-plan.md` — the implementation plan (its substitution table and embedded script are the mapping). ### Completeness gate -Must return only the four carve-outs: +Must return only the six carve-outs: ```bash git grep -niE "scadalink" -- . \ ':!tools/rename-to-scadabridge.sh' \ + ':!tools/scrub-scadalink-refs.sh' \ ':!docker/rename-databases.sh' \ ':!docs/plans/2026-05-28-scadabridge-rename-design.md' \ - ':!docs/plans/2026-05-31-folder-repo-rename-scadabridge-design.md' + ':!docs/plans/2026-05-31-folder-repo-rename-scadabridge-design.md' \ + ':!docs/plans/2026-05-31-folder-repo-rename-scadabridge-plan.md' ``` ## Section 3 — Collision folder diff --git a/docs/requirements/Component-CLI.md b/docs/requirements/Component-CLI.md index acd994b6..ebad0ef7 100644 --- a/docs/requirements/Component-CLI.md +++ b/docs/requirements/Component-CLI.md @@ -310,9 +310,9 @@ Configuration is resolved in the following priority order (highest wins): 1. **Command-line options**: `--url`, `--username`, `--password`, `--format`. 2. **Environment variables**: - - `SCADALINK_MANAGEMENT_URL` — Management API URL (e.g., `http://central-host:5000`). - - `SCADALINK_FORMAT` — Default output format (`json` or `table`). - - `SCADALINK_USERNAME` / `SCADALINK_PASSWORD` — LDAP credentials. Preferred over + - `SCADABRIDGE_MANAGEMENT_URL` — Management API URL (e.g., `http://central-host:5000`). + - `SCADABRIDGE_FORMAT` — Default output format (`json` or `table`). + - `SCADABRIDGE_USERNAME` / `SCADABRIDGE_PASSWORD` — LDAP credentials. Preferred over `--password` on the command line, which is visible in process listings and shell history. Credentials are never read from the config file. 3. **Configuration file**: `~/.scadabridge/config.json` — Persistent defaults for management URL and output format only (never credentials). diff --git a/docs/requirements/Component-Transport.md b/docs/requirements/Component-Transport.md index 6b504d16..bf48c791 100644 --- a/docs/requirements/Component-Transport.md +++ b/docs/requirements/Component-Transport.md @@ -53,7 +53,7 @@ Exactly one of `content.json` or `content.enc` is present. "createdAtUtc": "2026-05-24T12:34:56Z", "sourceEnvironment": "dev-cluster-a", "exportedBy": "alice@corp.example", - "scadaLinkVersion": "1.4.2", + "scadaBridgeVersion": "1.4.2", "contentHash": "sha256:...", "encryption": { "algorithm": "AES-256-GCM", @@ -325,7 +325,7 @@ The `manifest.json` file is always present in the ZIP root and is never encrypte "createdAtUtc": "2026-05-24T12:34:56Z", "sourceEnvironment": "dev-cluster-a", "exportedBy": "alice@corp.example", - "scadaLinkVersion": "1.4.2", + "scadaBridgeVersion": "1.4.2", "contentHash": "sha256:abc123...", "encryption": { "algorithm": "AES-256-GCM", @@ -371,7 +371,7 @@ The `manifest.json` file is always present in the ZIP root and is never encrypte | `createdAtUtc` | ISO-8601 UTC timestamp of when the export was created. | | `sourceEnvironment` | The `SourceEnvironment` name of the exporting cluster (from `TransportOptions`). Displayed in the import wizard and required to be retyped at the confirm step. | | `exportedBy` | Authenticated username of the person who performed the export. | -| `scadaLinkVersion` | Application version of the exporting node. Used for diagnostic display only. | +| `scadaBridgeVersion` | Application version of the exporting node. Used for diagnostic display only. | | `contentHash` | `sha256:` — SHA-256 of the raw `content.json` or `content.enc` bytes (pre-encryption). Verified on upload before any decryption. | | `encryption` | Present only when a passphrase was supplied. Contains the KDF parameters and the per-bundle random salt and IV needed to re-derive the key and decrypt. Omitted for plaintext bundles. | | `encryption.algorithm` | Always `"AES-256-GCM"` in v1. | diff --git a/docs/requirements/HighLevelReqs.md b/docs/requirements/HighLevelReqs.md index 1afb2f90..acfe27b7 100644 --- a/docs/requirements/HighLevelReqs.md +++ b/docs/requirements/HighLevelReqs.md @@ -531,7 +531,7 @@ Sites log operational events locally, including: - The CLI sends user credentials via HTTP Basic Auth. The server authenticates against **LDAP/AD** and resolves roles before dispatching commands to the ManagementActor. - CLI commands mirror all Management Service operations: templates, instances, sites, data connections, deployments, external systems, notifications, security (API keys and role mappings), audit log queries, and health status. - Output is **JSON by default** (machine-readable, suitable for scripting) with an optional `--format table` flag for human-readable tabular output. -- Configuration is resolved from command-line options, **environment variables** (`SCADALINK_MANAGEMENT_URL`, `SCADALINK_FORMAT`), or a **configuration file** (`~/.scadabridge/config.json`). +- Configuration is resolved from command-line options, **environment variables** (`SCADABRIDGE_MANAGEMENT_URL`, `SCADABRIDGE_FORMAT`), or a **configuration file** (`~/.scadabridge/config.json`). - The CLI is a separate executable from the Host binary — it is deployed on any machine with HTTP access to a central node. ## 14. General Conventions diff --git a/src/ZB.MOM.WW.ScadaBridge.CLI/CliConfig.cs b/src/ZB.MOM.WW.ScadaBridge.CLI/CliConfig.cs index a7e33ecf..8f319041 100644 --- a/src/ZB.MOM.WW.ScadaBridge.CLI/CliConfig.cs +++ b/src/ZB.MOM.WW.ScadaBridge.CLI/CliConfig.cs @@ -13,14 +13,14 @@ public class CliConfig public string DefaultFormat { get; set; } = "json"; /// - /// LDAP username from the SCADALINK_USERNAME environment variable, if set. + /// LDAP username from the SCADABRIDGE_USERNAME environment variable, if set. /// Credentials are intentionally only sourced from environment variables (or the /// command line) — never from the config file — so they are not persisted to disk. /// public string? Username { get; set; } /// - /// LDAP password from the SCADALINK_PASSWORD environment variable, if set. + /// LDAP password from the SCADABRIDGE_PASSWORD environment variable, if set. /// Provides a safer alternative to --password, which leaks into process /// listings and shell history. /// @@ -69,20 +69,20 @@ public class CliConfig } // Override from environment variables - var envUrl = Environment.GetEnvironmentVariable("SCADALINK_MANAGEMENT_URL"); + var envUrl = Environment.GetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL"); if (!string.IsNullOrEmpty(envUrl)) config.ManagementUrl = envUrl; - var envFormat = Environment.GetEnvironmentVariable("SCADALINK_FORMAT"); + var envFormat = Environment.GetEnvironmentVariable("SCADABRIDGE_FORMAT"); if (!string.IsNullOrEmpty(envFormat)) config.DefaultFormat = envFormat; // Credentials from environment variables only (never the config file). - var envUsername = Environment.GetEnvironmentVariable("SCADALINK_USERNAME"); + var envUsername = Environment.GetEnvironmentVariable("SCADABRIDGE_USERNAME"); if (!string.IsNullOrEmpty(envUsername)) config.Username = envUsername; - var envPassword = Environment.GetEnvironmentVariable("SCADALINK_PASSWORD"); + var envPassword = Environment.GetEnvironmentVariable("SCADABRIDGE_PASSWORD"); if (!string.IsNullOrEmpty(envPassword)) config.Password = envPassword; diff --git a/src/ZB.MOM.WW.ScadaBridge.CLI/Commands/AuditCommandHelpers.cs b/src/ZB.MOM.WW.ScadaBridge.CLI/Commands/AuditCommandHelpers.cs index 3a3d685f..9ec5c1c5 100644 --- a/src/ZB.MOM.WW.ScadaBridge.CLI/Commands/AuditCommandHelpers.cs +++ b/src/ZB.MOM.WW.ScadaBridge.CLI/Commands/AuditCommandHelpers.cs @@ -76,7 +76,7 @@ public static class AuditCommandHelpers if (string.IsNullOrWhiteSpace(url)) { return AuditConnection.Fail( - "No management URL specified. Use --url, set SCADALINK_MANAGEMENT_URL, or add 'managementUrl' to ~/.scadabridge/config.json.", + "No management URL specified. Use --url, set SCADABRIDGE_MANAGEMENT_URL, or add 'managementUrl' to ~/.scadabridge/config.json.", "NO_URL"); } @@ -93,7 +93,7 @@ public static class AuditCommandHelpers if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password)) { return AuditConnection.Fail( - "Credentials required. Use --username/--password or set SCADALINK_USERNAME/SCADALINK_PASSWORD.", + "Credentials required. Use --username/--password or set SCADABRIDGE_USERNAME/SCADABRIDGE_PASSWORD.", "NO_CREDENTIALS"); } diff --git a/src/ZB.MOM.WW.ScadaBridge.CLI/Commands/CommandHelpers.cs b/src/ZB.MOM.WW.ScadaBridge.CLI/Commands/CommandHelpers.cs index 3fa049db..52fd949d 100644 --- a/src/ZB.MOM.WW.ScadaBridge.CLI/Commands/CommandHelpers.cs +++ b/src/ZB.MOM.WW.ScadaBridge.CLI/Commands/CommandHelpers.cs @@ -51,7 +51,7 @@ internal static class CommandHelpers if (string.IsNullOrWhiteSpace(url)) { OutputFormatter.WriteError( - "No management URL specified. Use --url, set SCADALINK_MANAGEMENT_URL, or add 'managementUrl' to ~/.scadabridge/config.json.", + "No management URL specified. Use --url, set SCADABRIDGE_MANAGEMENT_URL, or add 'managementUrl' to ~/.scadabridge/config.json.", "NO_URL"); return 1; } @@ -65,14 +65,14 @@ internal static class CommandHelpers } // Resolve credentials: command-line options take precedence, then the - // SCADALINK_USERNAME / SCADALINK_PASSWORD environment variables. + // SCADABRIDGE_USERNAME / SCADABRIDGE_PASSWORD environment variables. var username = ResolveCredential(result.GetValue(usernameOption), config.Username); var password = ResolveCredential(result.GetValue(passwordOption), config.Password); if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password)) { OutputFormatter.WriteError( - "Credentials required. Use --username/--password or set SCADALINK_USERNAME/SCADALINK_PASSWORD.", + "Credentials required. Use --username/--password or set SCADABRIDGE_USERNAME/SCADABRIDGE_PASSWORD.", "NO_CREDENTIALS"); return 1; } diff --git a/src/ZB.MOM.WW.ScadaBridge.CLI/Commands/DebugCommands.cs b/src/ZB.MOM.WW.ScadaBridge.CLI/Commands/DebugCommands.cs index efef69b4..06e7ceed 100644 --- a/src/ZB.MOM.WW.ScadaBridge.CLI/Commands/DebugCommands.cs +++ b/src/ZB.MOM.WW.ScadaBridge.CLI/Commands/DebugCommands.cs @@ -57,7 +57,7 @@ public static class DebugCommands if (string.IsNullOrWhiteSpace(url)) { OutputFormatter.WriteError( - "No management URL specified. Use --url, set SCADALINK_MANAGEMENT_URL, or add 'managementUrl' to ~/.scadabridge/config.json.", + "No management URL specified. Use --url, set SCADABRIDGE_MANAGEMENT_URL, or add 'managementUrl' to ~/.scadabridge/config.json.", "NO_URL"); return 1; } @@ -76,7 +76,7 @@ public static class DebugCommands if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password)) { OutputFormatter.WriteError( - "Credentials required. Use --username/--password or set SCADALINK_USERNAME/SCADALINK_PASSWORD.", + "Credentials required. Use --username/--password or set SCADABRIDGE_USERNAME/SCADABRIDGE_PASSWORD.", "NO_CREDENTIALS"); return 1; } diff --git a/src/ZB.MOM.WW.ScadaBridge.CLI/README.md b/src/ZB.MOM.WW.ScadaBridge.CLI/README.md index c41ee97f..76706512 100644 --- a/src/ZB.MOM.WW.ScadaBridge.CLI/README.md +++ b/src/ZB.MOM.WW.ScadaBridge.CLI/README.md @@ -15,7 +15,7 @@ The output binary is `scadabridge` (or `scadabridge.exe` on Windows). Every command requires a connection to a running Central node. The management URL can be supplied three ways, evaluated in this priority order: 1. `--url` flag on the command line -2. `SCADALINK_MANAGEMENT_URL` environment variable +2. `SCADABRIDGE_MANAGEMENT_URL` environment variable 3. `managementUrl` field in `~/.scadabridge/config.json` ```sh @@ -57,10 +57,10 @@ For the Docker test environment, see `docker/README.md` for a ready-to-use confi | Variable | Description | |----------|-------------| -| `SCADALINK_MANAGEMENT_URL` | Management API URL (overrides config file) | -| `SCADALINK_FORMAT` | Default output format (overrides config file) | -| `SCADALINK_USERNAME` | LDAP username (fallback when `--username` is not supplied) | -| `SCADALINK_PASSWORD` | LDAP password (fallback when `--password` is not supplied). Preferred over `--password` on the command line, which leaks into process listings and shell history. | +| `SCADABRIDGE_MANAGEMENT_URL` | Management API URL (overrides config file) | +| `SCADABRIDGE_FORMAT` | Default output format (overrides config file) | +| `SCADABRIDGE_USERNAME` | LDAP username (fallback when `--username` is not supplied) | +| `SCADABRIDGE_PASSWORD` | LDAP password (fallback when `--password` is not supplied). Preferred over `--password` on the command line, which leaks into process listings and shell history. | ## Output diff --git a/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/DesignTimeDbContextFactory.cs b/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/DesignTimeDbContextFactory.cs index eda23de3..8c4eb1a1 100644 --- a/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/DesignTimeDbContextFactory.cs +++ b/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/DesignTimeDbContextFactory.cs @@ -8,7 +8,7 @@ namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase; /// Factory for creating DbContext instances at design time (used by dotnet ef tooling). /// Resolves the connection string from the Host's appsettings files, or — for environments /// where those files are not present — from the -/// SCADALINK_DESIGNTIME_CONNECTIONSTRING environment variable. +/// SCADABRIDGE_DESIGNTIME_CONNECTIONSTRING environment variable. /// /// /// There is deliberately no hardcoded fallback connection string. A credential literal in @@ -19,7 +19,7 @@ namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase; /// public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory { - private const string EnvironmentVariableName = "SCADALINK_DESIGNTIME_CONNECTIONSTRING"; + private const string EnvironmentVariableName = "SCADABRIDGE_DESIGNTIME_CONNECTIONSTRING"; private const string ConfigurationKey = "ScadaBridge:Database:ConfigurationDb"; /// diff --git a/src/ZB.MOM.WW.ScadaBridge.Host/Program.cs b/src/ZB.MOM.WW.ScadaBridge.Host/Program.cs index aee16d7e..79a65f69 100644 --- a/src/ZB.MOM.WW.ScadaBridge.Host/Program.cs +++ b/src/ZB.MOM.WW.ScadaBridge.Host/Program.cs @@ -22,9 +22,9 @@ using ZB.MOM.WW.ScadaBridge.TemplateEngine; using ZB.MOM.WW.ScadaBridge.Transport; using Serilog; -// SCADALINK_CONFIG determines which role-specific config to load (Central or Site) +// SCADABRIDGE_CONFIG determines which role-specific config to load (Central or Site) // DOTNET_ENVIRONMENT/ASPNETCORE_ENVIRONMENT stay as "Development" for dev tooling (static assets, EF migrations, etc.) -var scadabridgeConfig = Environment.GetEnvironmentVariable("SCADALINK_CONFIG") +var scadabridgeConfig = Environment.GetEnvironmentVariable("SCADABRIDGE_CONFIG") ?? Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "Production"; diff --git a/src/ZB.MOM.WW.ScadaBridge.Host/Properties/launchSettings.json b/src/ZB.MOM.WW.ScadaBridge.Host/Properties/launchSettings.json index d0043619..34821c3a 100644 --- a/src/ZB.MOM.WW.ScadaBridge.Host/Properties/launchSettings.json +++ b/src/ZB.MOM.WW.ScadaBridge.Host/Properties/launchSettings.json @@ -9,7 +9,7 @@ "environmentVariables": { "DOTNET_ENVIRONMENT": "Development", "ASPNETCORE_ENVIRONMENT": "Development", - "SCADALINK_CONFIG": "Central" + "SCADABRIDGE_CONFIG": "Central" } }, "ScadaBridge Site": { @@ -19,7 +19,7 @@ "environmentVariables": { "DOTNET_ENVIRONMENT": "Development", "ASPNETCORE_ENVIRONMENT": "Development", - "SCADALINK_CONFIG": "Site" + "SCADABRIDGE_CONFIG": "Site" } } } diff --git a/src/ZB.MOM.WW.ScadaBridge.Host/appsettings.Central.json b/src/ZB.MOM.WW.ScadaBridge.Host/appsettings.Central.json index efee2da5..c53ec978 100644 --- a/src/ZB.MOM.WW.ScadaBridge.Host/appsettings.Central.json +++ b/src/ZB.MOM.WW.ScadaBridge.Host/appsettings.Central.json @@ -20,7 +20,7 @@ }, "_secrets": "Host-003: Secrets are NOT committed in this file. Supply them via environment variables, which the Host's configuration builder (AddEnvironmentVariables) overlays over this file. Required: ScadaBridge__Database__ConfigurationDb, ScadaBridge__Security__LdapServiceAccountPassword, ScadaBridge__Security__JwtSigningKey. The ${...} placeholders below are intentionally non-functional and must be overridden per environment.", "Database": { - "ConfigurationDb": "${SCADALINK_CONFIGURATIONDB_CONNECTION_STRING}" + "ConfigurationDb": "${SCADABRIDGE_CONFIGURATIONDB_CONNECTION_STRING}" }, "Security": { "LdapServer": "localhost", @@ -29,8 +29,8 @@ "AllowInsecureLdap": true, "LdapSearchBase": "dc=scadabridge,dc=local", "LdapServiceAccountDn": "cn=admin,dc=scadabridge,dc=local", - "LdapServiceAccountPassword": "${SCADALINK_LDAP_SERVICE_ACCOUNT_PASSWORD}", - "JwtSigningKey": "${SCADALINK_JWT_SIGNING_KEY}", + "LdapServiceAccountPassword": "${SCADABRIDGE_LDAP_SERVICE_ACCOUNT_PASSWORD}", + "JwtSigningKey": "${SCADABRIDGE_JWT_SIGNING_KEY}", "JwtExpiryMinutes": 15, "IdleTimeoutMinutes": 30 }, diff --git a/src/ZB.MOM.WW.ScadaBridge.Transport/Export/BundleExporter.cs b/src/ZB.MOM.WW.ScadaBridge.Transport/Export/BundleExporter.cs index 119f947d..01efb9ed 100644 --- a/src/ZB.MOM.WW.ScadaBridge.Transport/Export/BundleExporter.cs +++ b/src/ZB.MOM.WW.ScadaBridge.Transport/Export/BundleExporter.cs @@ -115,7 +115,7 @@ public sealed class BundleExporter : IBundleExporter var templateManifest = _manifestBuilder.Build( sourceEnvironment: sourceEnvironment, exportedBy: user, - scadaLinkVersion: assemblyVersion, + scadaBridgeVersion: assemblyVersion, encryption: encryptionSeed, summary: summary, contents: resolved.ContentManifest, diff --git a/src/ZB.MOM.WW.ScadaBridge.Transport/Serialization/ManifestBuilder.cs b/src/ZB.MOM.WW.ScadaBridge.Transport/Serialization/ManifestBuilder.cs index b8c08838..856bbb5b 100644 --- a/src/ZB.MOM.WW.ScadaBridge.Transport/Serialization/ManifestBuilder.cs +++ b/src/ZB.MOM.WW.ScadaBridge.Transport/Serialization/ManifestBuilder.cs @@ -20,7 +20,7 @@ public sealed class ManifestBuilder /// /// Environment label identifying where the bundle was exported from. /// Username of the operator who performed the export. - /// ScadaBridge version string stamped in the manifest. + /// ScadaBridge version string stamped in the manifest. /// Encryption metadata when the content is encrypted; null for plain bundles. /// High-level summary of artifact counts. /// Per-entry content table describing each artifact in the bundle. @@ -29,7 +29,7 @@ public sealed class ManifestBuilder public BundleManifest Build( string sourceEnvironment, string exportedBy, - string scadaLinkVersion, + string scadaBridgeVersion, EncryptionMetadata? encryption, BundleSummary summary, IReadOnlyList contents, @@ -37,7 +37,7 @@ public sealed class ManifestBuilder { ArgumentNullException.ThrowIfNull(sourceEnvironment); ArgumentNullException.ThrowIfNull(exportedBy); - ArgumentNullException.ThrowIfNull(scadaLinkVersion); + ArgumentNullException.ThrowIfNull(scadaBridgeVersion); ArgumentNullException.ThrowIfNull(summary); ArgumentNullException.ThrowIfNull(contents); ArgumentNullException.ThrowIfNull(contentBytes); @@ -50,7 +50,7 @@ public sealed class ManifestBuilder CreatedAtUtc: DateTimeOffset.UtcNow, SourceEnvironment: sourceEnvironment, ExportedBy: exportedBy, - ScadaBridgeVersion: scadaLinkVersion, + ScadaBridgeVersion: scadaBridgeVersion, ContentHash: contentHash, Encryption: encryption, Summary: summary, diff --git a/tests/ZB.MOM.WW.ScadaBridge.CLI.Tests/CliConfigTests.cs b/tests/ZB.MOM.WW.ScadaBridge.CLI.Tests/CliConfigTests.cs index 4c952abf..b6040472 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.CLI.Tests/CliConfigTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.CLI.Tests/CliConfigTests.cs @@ -8,13 +8,13 @@ public class CliConfigTests [Fact] public void Load_DefaultFormat_IsJson() { - var origUrl = Environment.GetEnvironmentVariable("SCADALINK_MANAGEMENT_URL"); - var origFormat = Environment.GetEnvironmentVariable("SCADALINK_FORMAT"); + var origUrl = Environment.GetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL"); + var origFormat = Environment.GetEnvironmentVariable("SCADABRIDGE_FORMAT"); try { - Environment.SetEnvironmentVariable("SCADALINK_MANAGEMENT_URL", null); - Environment.SetEnvironmentVariable("SCADALINK_FORMAT", null); + Environment.SetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL", null); + Environment.SetEnvironmentVariable("SCADABRIDGE_FORMAT", null); var config = CliConfig.Load(); @@ -23,18 +23,18 @@ public class CliConfigTests } finally { - Environment.SetEnvironmentVariable("SCADALINK_MANAGEMENT_URL", origUrl); - Environment.SetEnvironmentVariable("SCADALINK_FORMAT", origFormat); + Environment.SetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL", origUrl); + Environment.SetEnvironmentVariable("SCADABRIDGE_FORMAT", origFormat); } } [Fact] public void Load_ManagementUrl_FromEnvironment() { - var orig = Environment.GetEnvironmentVariable("SCADALINK_MANAGEMENT_URL"); + var orig = Environment.GetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL"); try { - Environment.SetEnvironmentVariable("SCADALINK_MANAGEMENT_URL", "http://central:5000"); + Environment.SetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL", "http://central:5000"); var config = CliConfig.Load(); @@ -42,17 +42,17 @@ public class CliConfigTests } finally { - Environment.SetEnvironmentVariable("SCADALINK_MANAGEMENT_URL", orig); + Environment.SetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL", orig); } } [Fact] public void Load_Format_FromEnvironment() { - var orig = Environment.GetEnvironmentVariable("SCADALINK_FORMAT"); + var orig = Environment.GetEnvironmentVariable("SCADABRIDGE_FORMAT"); try { - Environment.SetEnvironmentVariable("SCADALINK_FORMAT", "table"); + Environment.SetEnvironmentVariable("SCADABRIDGE_FORMAT", "table"); var config = CliConfig.Load(); @@ -60,7 +60,7 @@ public class CliConfigTests } finally { - Environment.SetEnvironmentVariable("SCADALINK_FORMAT", orig); + Environment.SetEnvironmentVariable("SCADABRIDGE_FORMAT", orig); } } @@ -81,19 +81,19 @@ public class CliConfigTests var origHome = Environment.GetEnvironmentVariable("HOME"); var origUserProfile = Environment.GetEnvironmentVariable("USERPROFILE"); - var origUrl = Environment.GetEnvironmentVariable("SCADALINK_MANAGEMENT_URL"); - var origFormat = Environment.GetEnvironmentVariable("SCADALINK_FORMAT"); - var origUser = Environment.GetEnvironmentVariable("SCADALINK_USERNAME"); - var origPass = Environment.GetEnvironmentVariable("SCADALINK_PASSWORD"); + var origUrl = Environment.GetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL"); + var origFormat = Environment.GetEnvironmentVariable("SCADABRIDGE_FORMAT"); + var origUser = Environment.GetEnvironmentVariable("SCADABRIDGE_USERNAME"); + var origPass = Environment.GetEnvironmentVariable("SCADABRIDGE_PASSWORD"); var origStderr = Console.Error; try { Environment.SetEnvironmentVariable("HOME", tempHome); Environment.SetEnvironmentVariable("USERPROFILE", tempHome); - Environment.SetEnvironmentVariable("SCADALINK_MANAGEMENT_URL", null); - Environment.SetEnvironmentVariable("SCADALINK_FORMAT", null); - Environment.SetEnvironmentVariable("SCADALINK_USERNAME", null); - Environment.SetEnvironmentVariable("SCADALINK_PASSWORD", null); + Environment.SetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL", null); + Environment.SetEnvironmentVariable("SCADABRIDGE_FORMAT", null); + Environment.SetEnvironmentVariable("SCADABRIDGE_USERNAME", null); + Environment.SetEnvironmentVariable("SCADABRIDGE_PASSWORD", null); var stderrCapture = new StringWriter(); Console.SetError(stderrCapture); @@ -112,10 +112,10 @@ public class CliConfigTests Console.SetError(origStderr); Environment.SetEnvironmentVariable("HOME", origHome); Environment.SetEnvironmentVariable("USERPROFILE", origUserProfile); - Environment.SetEnvironmentVariable("SCADALINK_MANAGEMENT_URL", origUrl); - Environment.SetEnvironmentVariable("SCADALINK_FORMAT", origFormat); - Environment.SetEnvironmentVariable("SCADALINK_USERNAME", origUser); - Environment.SetEnvironmentVariable("SCADALINK_PASSWORD", origPass); + Environment.SetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL", origUrl); + Environment.SetEnvironmentVariable("SCADABRIDGE_FORMAT", origFormat); + Environment.SetEnvironmentVariable("SCADABRIDGE_USERNAME", origUser); + Environment.SetEnvironmentVariable("SCADABRIDGE_PASSWORD", origPass); try { Directory.Delete(tempHome, recursive: true); } catch { /* best-effort cleanup */ } } } diff --git a/tests/ZB.MOM.WW.ScadaBridge.CLI.Tests/CredentialResolutionTests.cs b/tests/ZB.MOM.WW.ScadaBridge.CLI.Tests/CredentialResolutionTests.cs index 9a4b9cee..b6dd459a 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.CLI.Tests/CredentialResolutionTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.CLI.Tests/CredentialResolutionTests.cs @@ -5,7 +5,7 @@ namespace ZB.MOM.WW.ScadaBridge.CLI.Tests; /// /// Regression tests for CLI-006 — credentials could only be supplied via the /// --password command-line option, which leaks into process listings and -/// shell history. A SCADALINK_PASSWORD / SCADALINK_USERNAME environment +/// shell history. A SCADABRIDGE_PASSWORD / SCADABRIDGE_USERNAME environment /// fallback gives CI/CD a safer alternative. /// [Collection("Environment")] @@ -14,10 +14,10 @@ public class CredentialResolutionTests [Fact] public void Load_Password_FromEnvironment() { - var orig = Environment.GetEnvironmentVariable("SCADALINK_PASSWORD"); + var orig = Environment.GetEnvironmentVariable("SCADABRIDGE_PASSWORD"); try { - Environment.SetEnvironmentVariable("SCADALINK_PASSWORD", "s3cret"); + Environment.SetEnvironmentVariable("SCADABRIDGE_PASSWORD", "s3cret"); var config = CliConfig.Load(); @@ -25,17 +25,17 @@ public class CredentialResolutionTests } finally { - Environment.SetEnvironmentVariable("SCADALINK_PASSWORD", orig); + Environment.SetEnvironmentVariable("SCADABRIDGE_PASSWORD", orig); } } [Fact] public void Load_Username_FromEnvironment() { - var orig = Environment.GetEnvironmentVariable("SCADALINK_USERNAME"); + var orig = Environment.GetEnvironmentVariable("SCADABRIDGE_USERNAME"); try { - Environment.SetEnvironmentVariable("SCADALINK_USERNAME", "ci-user"); + Environment.SetEnvironmentVariable("SCADABRIDGE_USERNAME", "ci-user"); var config = CliConfig.Load(); @@ -43,19 +43,19 @@ public class CredentialResolutionTests } finally { - Environment.SetEnvironmentVariable("SCADALINK_USERNAME", orig); + Environment.SetEnvironmentVariable("SCADABRIDGE_USERNAME", orig); } } [Fact] public void Load_NoCredentialEnvVars_LeavesCredentialsNull() { - var origUser = Environment.GetEnvironmentVariable("SCADALINK_USERNAME"); - var origPass = Environment.GetEnvironmentVariable("SCADALINK_PASSWORD"); + var origUser = Environment.GetEnvironmentVariable("SCADABRIDGE_USERNAME"); + var origPass = Environment.GetEnvironmentVariable("SCADABRIDGE_PASSWORD"); try { - Environment.SetEnvironmentVariable("SCADALINK_USERNAME", null); - Environment.SetEnvironmentVariable("SCADALINK_PASSWORD", null); + Environment.SetEnvironmentVariable("SCADABRIDGE_USERNAME", null); + Environment.SetEnvironmentVariable("SCADABRIDGE_PASSWORD", null); var config = CliConfig.Load(); @@ -64,8 +64,8 @@ public class CredentialResolutionTests } finally { - Environment.SetEnvironmentVariable("SCADALINK_USERNAME", origUser); - Environment.SetEnvironmentVariable("SCADALINK_PASSWORD", origPass); + Environment.SetEnvironmentVariable("SCADABRIDGE_USERNAME", origUser); + Environment.SetEnvironmentVariable("SCADABRIDGE_PASSWORD", origPass); } } } diff --git a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Audit/AuditDataSeeder.cs b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Audit/AuditDataSeeder.cs index 2997cdbe..81b9f06d 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Audit/AuditDataSeeder.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Audit/AuditDataSeeder.cs @@ -25,7 +25,7 @@ namespace ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Audit; /// Connection string mirrors the Docker cluster's scadabridge_app account /// from docker/central-node-a/appsettings.Central.json, with the host /// pointed at the host-exposed port (localhost:1433). The -/// SCADALINK_PLAYWRIGHT_DB env var lets CI override the connection +/// SCADABRIDGE_PLAYWRIGHT_DB env var lets CI override the connection /// without recompiling. /// /// @@ -34,11 +34,11 @@ internal static class AuditDataSeeder private const string DefaultConnectionString = "Server=localhost,1433;Database=ScadaBridgeConfig;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true;Encrypt=false;Connect Timeout=5"; - private const string EnvVar = "SCADALINK_PLAYWRIGHT_DB"; + private const string EnvVar = "SCADABRIDGE_PLAYWRIGHT_DB"; /// /// Connection string for the running cluster's configuration DB. Resolved - /// from SCADALINK_PLAYWRIGHT_DB when set, otherwise the local docker + /// from SCADABRIDGE_PLAYWRIGHT_DB when set, otherwise the local docker /// dev defaults. /// public static string ConnectionString diff --git a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Audit/AuditGridColumnTests.cs b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Audit/AuditGridColumnTests.cs index 3a690158..079d0cb4 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Audit/AuditGridColumnTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Audit/AuditGridColumnTests.cs @@ -30,7 +30,7 @@ public class AuditGridColumnTests /// Skip reason shared by the DB-seeding tests when MSSQL is down. private const string DbUnavailableSkipReason = "AuditDataSeeder cannot reach MSSQL at localhost:1433 — bring up infra/docker-compose and docker/deploy.sh, " + - "or set SCADALINK_PLAYWRIGHT_DB to a reachable connection string."; + "or set SCADABRIDGE_PLAYWRIGHT_DB to a reachable connection string."; private readonly PlaywrightFixture _fixture; diff --git a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Audit/AuditLogPageTests.cs b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Audit/AuditLogPageTests.cs index 65e55a4f..a74533ef 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Audit/AuditLogPageTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Audit/AuditLogPageTests.cs @@ -64,7 +64,7 @@ public class AuditLogPageTests { throw new InvalidOperationException( "AuditDataSeeder cannot reach MSSQL at localhost:1433 — bring up infra/docker-compose and docker/deploy.sh, " + - "or set SCADALINK_PLAYWRIGHT_DB to a reachable connection string."); + "or set SCADABRIDGE_PLAYWRIGHT_DB to a reachable connection string."); } var runId = Guid.NewGuid().ToString("N"); diff --git a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/SiteCalls/SiteCallDataSeeder.cs b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/SiteCalls/SiteCallDataSeeder.cs index e430cd13..ef1d8e2b 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/SiteCalls/SiteCallDataSeeder.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/SiteCalls/SiteCallDataSeeder.cs @@ -28,11 +28,11 @@ internal static class SiteCallDataSeeder private const string DefaultConnectionString = "Server=localhost,1433;Database=ScadaBridgeConfig;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true;Encrypt=false;Connect Timeout=5"; - private const string EnvVar = "SCADALINK_PLAYWRIGHT_DB"; + private const string EnvVar = "SCADABRIDGE_PLAYWRIGHT_DB"; /// /// Connection string for the running cluster's configuration DB. Resolved - /// from SCADALINK_PLAYWRIGHT_DB when set, otherwise the local docker + /// from SCADABRIDGE_PLAYWRIGHT_DB when set, otherwise the local docker /// dev defaults. /// public static string ConnectionString diff --git a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/SiteCalls/SiteCallsPageTests.cs b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/SiteCalls/SiteCallsPageTests.cs index 36bf7a66..ead5e963 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/SiteCalls/SiteCallsPageTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/SiteCalls/SiteCallsPageTests.cs @@ -101,7 +101,7 @@ public class SiteCallsPageTests /// Skip reason shared by the DB-seeding tests when MSSQL is down. private const string DbUnavailableSkipReason = "SiteCallDataSeeder cannot reach MSSQL at localhost:1433 — bring up infra/docker-compose and docker/deploy.sh, " + - "or set SCADALINK_PLAYWRIGHT_DB to a reachable connection string."; + "or set SCADABRIDGE_PLAYWRIGHT_DB to a reachable connection string."; [SkippableFact] public async Task FilterNarrowing_ChannelFilterShrinksGrid() diff --git a/tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/DesignTimeDbContextFactoryTests.cs b/tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/DesignTimeDbContextFactoryTests.cs index 00bacb49..c4bb7a58 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/DesignTimeDbContextFactoryTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/DesignTimeDbContextFactoryTests.cs @@ -4,7 +4,7 @@ namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests; public class DesignTimeDbContextFactoryTests : IDisposable { - private const string EnvVar = "SCADALINK_DESIGNTIME_CONNECTIONSTRING"; + private const string EnvVar = "SCADABRIDGE_DESIGNTIME_CONNECTIONSTRING"; private readonly string? _originalEnv; public DesignTimeDbContextFactoryTests() diff --git a/tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/Migrations/MsSqlMigrationFixture.cs b/tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/Migrations/MsSqlMigrationFixture.cs index f0722bbb..abc2e368 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/Migrations/MsSqlMigrationFixture.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/Migrations/MsSqlMigrationFixture.cs @@ -33,7 +33,7 @@ public sealed class MsSqlMigrationFixture : IDisposable private const string DefaultAdminConnectionString = "Server=localhost,1433;User Id=sa;Password=ScadaBridge_Dev1#;TrustServerCertificate=true;Encrypt=false;Connect Timeout=3"; - private const string AdminEnvVar = "SCADALINK_MSSQL_TEST_CONN"; + private const string AdminEnvVar = "SCADABRIDGE_MSSQL_TEST_CONN"; public string DatabaseName { get; } diff --git a/tests/ZB.MOM.WW.ScadaBridge.PerformanceTests/AuditLog/HotPathLatencyTests.cs b/tests/ZB.MOM.WW.ScadaBridge.PerformanceTests/AuditLog/HotPathLatencyTests.cs index 3ffc91f6..44e81dc7 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.PerformanceTests/AuditLog/HotPathLatencyTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.PerformanceTests/AuditLog/HotPathLatencyTests.cs @@ -110,10 +110,10 @@ public class HotPathLatencyTests var p95Us = MeasureP95Microseconds(MeasureIterations, () => _ = filter.Apply(evt)); // Default budget 50 µs (spec target). Override via env for slow CI: - // SCADALINK_AUDIT_FILTER_4KB_P95_US — interpret as the regression + // SCADABRIDGE_AUDIT_FILTER_4KB_P95_US — interpret as the regression // guard threshold. Print the observed value so a missed budget gives // useful telemetry on the test output. - var threshold = GetThresholdMicroseconds("SCADALINK_AUDIT_FILTER_4KB_P95_US", 50d); + var threshold = GetThresholdMicroseconds("SCADABRIDGE_AUDIT_FILTER_4KB_P95_US", 50d); Assert.True(p95Us < threshold, $"4KB body filter p95 = {p95Us:F1} µs; threshold = {threshold:F1} µs"); } @@ -137,7 +137,7 @@ public class HotPathLatencyTests var p95Us = MeasureP95Microseconds(MeasureIterations, () => _ = filter.Apply(evt)); - var threshold = GetThresholdMicroseconds("SCADALINK_AUDIT_FILTER_RAW_P95_US", 10d); + var threshold = GetThresholdMicroseconds("SCADABRIDGE_AUDIT_FILTER_RAW_P95_US", 10d); Assert.True(p95Us < threshold, $"Raw-event filter p95 = {p95Us:F1} µs; threshold = {threshold:F1} µs"); } diff --git a/tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/Import/BundleImporterLoadTests.cs b/tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/Import/BundleImporterLoadTests.cs index ccbccb8a..c3a68047 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/Import/BundleImporterLoadTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/Import/BundleImporterLoadTests.cs @@ -130,7 +130,7 @@ public sealed class BundleImporterLoadTests var manifest = builder.Build( sourceEnvironment: "dev", exportedBy: "alice", - scadaLinkVersion: "1.0.0", + scadaBridgeVersion: "1.0.0", encryption: null, summary: new BundleSummary(content.Templates.Count, 0, 0, 0, 0, 0, 0, 0, 0), contents: Array.Empty(), @@ -152,7 +152,7 @@ public sealed class BundleImporterLoadTests var manifest = builder.Build( sourceEnvironment: "dev", exportedBy: "alice", - scadaLinkVersion: "1.0.0", + scadaBridgeVersion: "1.0.0", encryption: seed, summary: new BundleSummary(content.Templates.Count, 0, 0, 0, 0, 0, 0, 0, 0), contents: Array.Empty(), @@ -471,7 +471,7 @@ public sealed class BundleImporterLoadTests var manifest = rig.ManifestBuilder.Build( sourceEnvironment: "dev", exportedBy: "alice", - scadaLinkVersion: "1.0.0", + scadaBridgeVersion: "1.0.0", encryption: null, summary: new BundleSummary(1, 0, 0, 0, 0, 0, 0, 0, 0), contents: Array.Empty(), diff --git a/tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/Serialization/BundleSerializerTests.cs b/tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/Serialization/BundleSerializerTests.cs index 6f7a9113..fcdaa364 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/Serialization/BundleSerializerTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/Serialization/BundleSerializerTests.cs @@ -28,7 +28,7 @@ public sealed class BundleSerializerTests new ManifestBuilder().Build( sourceEnvironment: "test-env", exportedBy: "tester", - scadaLinkVersion: "1.0.0", + scadaBridgeVersion: "1.0.0", encryption: encryption, summary: new BundleSummary(0, 1, 1, 0, 0, 0, 0, 0, 0), contents: Array.Empty(), diff --git a/tools/scrub-scadalink-refs.sh b/tools/scrub-scadalink-refs.sh new file mode 100755 index 00000000..ceac430e --- /dev/null +++ b/tools/scrub-scadalink-refs.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# One-time scrub of residual ScadaLink/scadalink references → ScadaBridge. +# Operates on git-tracked TEXT files only (git grep -I skips binaries), +# minus carve-out migration records whose before→after meaning must survive. +# Substitutions are applied most-specific-first so a broad rule cannot +# double-replace an earlier result. Idempotent: re-running is a no-op. +set -euo pipefail +cd "$(git rev-parse --show-toplevel)" + +# Carve-outs (migration records): prior rename tooling/design, the DB-rename +# helper, this script itself, and the rename design + plan docs (which document +# the old→new mapping and would be self-corrupted by the substitution). +EXCLUDES_RE='^(tools/rename-to-scadabridge\.sh|tools/scrub-scadalink-refs\.sh|docker/rename-databases\.sh|docs/plans/2026-05-28-scadabridge-rename-design\.md|docs/plans/2026-05-31-folder-repo-rename-scadabridge-design\.md|docs/plans/2026-05-31-folder-repo-rename-scadabridge-plan\.md)$' + +files=() +while IFS= read -r f; do + [[ "$f" =~ $EXCLUDES_RE ]] && continue + files+=("$f") +done < <(git grep -liI 'scadalink' -- .) + +if [[ ${#files[@]} -eq 0 ]]; then + echo "No files to scrub." + exit 0 +fi + +printf 'Scrubbing %d file(s):\n' "${#files[@]}" +printf ' %s\n' "${files[@]}" + +sed -i '' \ + -e 's/ScadaLink\.Host\.exe/ZB.MOM.WW.ScadaBridge.Host.exe/g' \ + -e 's/ScadaLink__/ScadaBridge__/g' \ + -e 's/SCADALINK_/SCADABRIDGE_/g' \ + -e 's/scadaLinkVersion/scadaBridgeVersion/g' \ + -e 's/scadalink_app/scadabridge_app/g' \ + -e 's/ScadaLink/ScadaBridge/g' \ + -e 's/scadalink/scadabridge/g' \ + "${files[@]}" + +echo "Done."