refactor: scrub residual ScadaLink refs → ScadaBridge (env vars, config keys, assembly name, SQL login)
Renames the 13 SCADALINK_* runtime env vars → SCADABRIDGE_*, the ScadaLink__ .NET config keys → ScadaBridge__, the stale ScadaLink.Host.exe assembly name → ZB.MOM.WW.ScadaBridge.Host.exe, the scadalink_app SQL login → scadabridge_app, and residual identifiers/comments/docs. Migration records (prior rename tooling/design, DB-rename helper, this scrub script) carved out. Adds tools/scrub-scadalink-refs.sh.
This commit is contained in:
@@ -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
|
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
|
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
|
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
|
`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
|
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,
|
**substantial design-document drift**: `Component-CLI.md` describes a name-keyed,
|
||||||
@@ -126,7 +126,7 @@ _Re-review (2026-05-28, `1eb6e97`):_
|
|||||||
|
|
||||||
## Findings
|
## 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**
|
**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
|
`CliConfig.DefaultFormat`, and `Component-CLI.md` documents a format-precedence chain
|
||||||
(command-line option → env var → config file). However, every command resolves the format
|
(command-line option → env var → config file). However, every command resolves the format
|
||||||
with `var format = result.GetValue(formatOption) ?? "json";` and `formatOption` is created
|
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
|
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
|
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
|
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.
|
documented behaviour silently does not work.
|
||||||
|
|
||||||
**Recommendation**
|
**Recommendation**
|
||||||
@@ -312,14 +312,14 @@ wrong element types, and JSON null).
|
|||||||
Credentials are supplied only via `--username` / `--password`. A password on the command
|
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/<pid>/cmdline`) and is
|
line is visible to any local user via the process list (`ps`, `/proc/<pid>/cmdline`) and is
|
||||||
typically persisted into shell history. Unlike the management URL — which can also come
|
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
|
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
|
explicitly intended for CI/CD automation this materially increases the chance of credential
|
||||||
leakage.
|
leakage.
|
||||||
|
|
||||||
**Recommendation**
|
**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
|
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
|
is discouraged. Optionally prompt interactively when stdin is a TTY and no password was
|
||||||
supplied.
|
supplied.
|
||||||
@@ -327,7 +327,7 @@ supplied.
|
|||||||
**Resolution**
|
**Resolution**
|
||||||
|
|
||||||
Resolved 2026-05-16 (commit pending). Root cause confirmed — credentials had no
|
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`
|
fallbacks: `CliConfig.Load` now reads them into new `CliConfig.Username` / `Password`
|
||||||
properties (credentials are sourced from environment variables only, never the config
|
properties (credentials are sourced from environment variables only, never the config
|
||||||
file, so they are not persisted). `CommandHelpers.ResolveCredential` resolves precedence
|
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
|
enable/disable`) are removed; previously-omitted commands (`instance alarm-override
|
||||||
set/delete/list`, `external-system method` subgroup, `site deploy-artifacts`) are added.
|
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
|
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).
|
env vars (see CLI-006).
|
||||||
|
|
||||||
### CLI-008 — `--format` value is not validated
|
### 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` = authorization failure," so this is a contract regression.
|
||||||
2. **Error-message phrasing drift.** The two duplicated error paths
|
2. **Error-message phrasing drift.** The two duplicated error paths
|
||||||
(`bundle:258-260`, `:264-266`) emit shorter messages that omit the
|
(`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.
|
give — confusing if the user is trying to debug what's missing.
|
||||||
|
|
||||||
**Recommendation**
|
**Recommendation**
|
||||||
|
|||||||
@@ -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
|
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
|
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
|
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)
|
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
|
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
|
`ZB.MOM.WW.ScadaBridge.Host` directory exists, so the factory degrades cleanly instead of throwing
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ services:
|
|||||||
image: scadabridge:latest
|
image: scadabridge:latest
|
||||||
container_name: scadabridge-env2-central-a
|
container_name: scadabridge-env2-central-a
|
||||||
environment:
|
environment:
|
||||||
SCADALINK_CONFIG: Central
|
SCADABRIDGE_CONFIG: Central
|
||||||
ASPNETCORE_ENVIRONMENT: Development
|
ASPNETCORE_ENVIRONMENT: Development
|
||||||
ASPNETCORE_URLS: "http://+:5000"
|
ASPNETCORE_URLS: "http://+:5000"
|
||||||
ports:
|
ports:
|
||||||
@@ -20,7 +20,7 @@ services:
|
|||||||
image: scadabridge:latest
|
image: scadabridge:latest
|
||||||
container_name: scadabridge-env2-central-b
|
container_name: scadabridge-env2-central-b
|
||||||
environment:
|
environment:
|
||||||
SCADALINK_CONFIG: Central
|
SCADABRIDGE_CONFIG: Central
|
||||||
ASPNETCORE_ENVIRONMENT: Development
|
ASPNETCORE_ENVIRONMENT: Development
|
||||||
ASPNETCORE_URLS: "http://+:5000"
|
ASPNETCORE_URLS: "http://+:5000"
|
||||||
ports:
|
ports:
|
||||||
@@ -37,7 +37,7 @@ services:
|
|||||||
image: scadabridge:latest
|
image: scadabridge:latest
|
||||||
container_name: scadabridge-env2-site-x-a
|
container_name: scadabridge-env2-site-x-a
|
||||||
environment:
|
environment:
|
||||||
SCADALINK_CONFIG: Site
|
SCADABRIDGE_CONFIG: Site
|
||||||
ports:
|
ports:
|
||||||
- "9121:8082" # Akka remoting
|
- "9121:8082" # Akka remoting
|
||||||
- "9123:8083" # gRPC streaming
|
- "9123:8083" # gRPC streaming
|
||||||
@@ -53,7 +53,7 @@ services:
|
|||||||
image: scadabridge:latest
|
image: scadabridge:latest
|
||||||
container_name: scadabridge-env2-site-x-b
|
container_name: scadabridge-env2-site-x-b
|
||||||
environment:
|
environment:
|
||||||
SCADALINK_CONFIG: Site
|
SCADABRIDGE_CONFIG: Site
|
||||||
ports:
|
ports:
|
||||||
- "9122:8082" # Akka remoting
|
- "9122:8082" # Akka remoting
|
||||||
- "9124:8083" # gRPC streaming
|
- "9124:8083" # gRPC streaming
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ services:
|
|||||||
image: scadabridge:latest
|
image: scadabridge:latest
|
||||||
container_name: scadabridge-central-a
|
container_name: scadabridge-central-a
|
||||||
environment:
|
environment:
|
||||||
SCADALINK_CONFIG: Central
|
SCADABRIDGE_CONFIG: Central
|
||||||
ASPNETCORE_ENVIRONMENT: Development
|
ASPNETCORE_ENVIRONMENT: Development
|
||||||
ASPNETCORE_URLS: "http://+:5000"
|
ASPNETCORE_URLS: "http://+:5000"
|
||||||
ports:
|
ports:
|
||||||
@@ -20,7 +20,7 @@ services:
|
|||||||
image: scadabridge:latest
|
image: scadabridge:latest
|
||||||
container_name: scadabridge-central-b
|
container_name: scadabridge-central-b
|
||||||
environment:
|
environment:
|
||||||
SCADALINK_CONFIG: Central
|
SCADABRIDGE_CONFIG: Central
|
||||||
ASPNETCORE_ENVIRONMENT: Development
|
ASPNETCORE_ENVIRONMENT: Development
|
||||||
ASPNETCORE_URLS: "http://+:5000"
|
ASPNETCORE_URLS: "http://+:5000"
|
||||||
ports:
|
ports:
|
||||||
@@ -37,7 +37,7 @@ services:
|
|||||||
image: scadabridge:latest
|
image: scadabridge:latest
|
||||||
container_name: scadabridge-site-a-a
|
container_name: scadabridge-site-a-a
|
||||||
environment:
|
environment:
|
||||||
SCADALINK_CONFIG: Site
|
SCADABRIDGE_CONFIG: Site
|
||||||
ports:
|
ports:
|
||||||
- "9021:8082" # Akka remoting (host access for debugging)
|
- "9021:8082" # Akka remoting (host access for debugging)
|
||||||
- "9023:8083" # gRPC streaming
|
- "9023:8083" # gRPC streaming
|
||||||
@@ -53,7 +53,7 @@ services:
|
|||||||
image: scadabridge:latest
|
image: scadabridge:latest
|
||||||
container_name: scadabridge-site-a-b
|
container_name: scadabridge-site-a-b
|
||||||
environment:
|
environment:
|
||||||
SCADALINK_CONFIG: Site
|
SCADABRIDGE_CONFIG: Site
|
||||||
ports:
|
ports:
|
||||||
- "9022:8082" # Akka remoting
|
- "9022:8082" # Akka remoting
|
||||||
- "9024:8083" # gRPC streaming
|
- "9024:8083" # gRPC streaming
|
||||||
@@ -69,7 +69,7 @@ services:
|
|||||||
image: scadabridge:latest
|
image: scadabridge:latest
|
||||||
container_name: scadabridge-site-b-a
|
container_name: scadabridge-site-b-a
|
||||||
environment:
|
environment:
|
||||||
SCADALINK_CONFIG: Site
|
SCADABRIDGE_CONFIG: Site
|
||||||
ports:
|
ports:
|
||||||
- "9031:8082" # Akka remoting
|
- "9031:8082" # Akka remoting
|
||||||
- "9033:8083" # gRPC streaming
|
- "9033:8083" # gRPC streaming
|
||||||
@@ -85,7 +85,7 @@ services:
|
|||||||
image: scadabridge:latest
|
image: scadabridge:latest
|
||||||
container_name: scadabridge-site-b-b
|
container_name: scadabridge-site-b-b
|
||||||
environment:
|
environment:
|
||||||
SCADALINK_CONFIG: Site
|
SCADABRIDGE_CONFIG: Site
|
||||||
ports:
|
ports:
|
||||||
- "9032:8082" # Akka remoting
|
- "9032:8082" # Akka remoting
|
||||||
- "9034:8083" # gRPC streaming
|
- "9034:8083" # gRPC streaming
|
||||||
@@ -101,7 +101,7 @@ services:
|
|||||||
image: scadabridge:latest
|
image: scadabridge:latest
|
||||||
container_name: scadabridge-site-c-a
|
container_name: scadabridge-site-c-a
|
||||||
environment:
|
environment:
|
||||||
SCADALINK_CONFIG: Site
|
SCADABRIDGE_CONFIG: Site
|
||||||
ports:
|
ports:
|
||||||
- "9041:8082" # Akka remoting
|
- "9041:8082" # Akka remoting
|
||||||
- "9043:8083" # gRPC streaming
|
- "9043:8083" # gRPC streaming
|
||||||
@@ -117,7 +117,7 @@ services:
|
|||||||
image: scadabridge:latest
|
image: scadabridge:latest
|
||||||
container_name: scadabridge-site-c-b
|
container_name: scadabridge-site-c-b
|
||||||
environment:
|
environment:
|
||||||
SCADALINK_CONFIG: Site
|
SCADABRIDGE_CONFIG: Site
|
||||||
ports:
|
ports:
|
||||||
- "9042:8082" # Akka remoting
|
- "9042:8082" # Akka remoting
|
||||||
- "9044:8083" # gRPC streaming
|
- "9044:8083" # gRPC streaming
|
||||||
|
|||||||
@@ -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_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.)
|
- `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.
|
- `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:
|
Integration test assertions:
|
||||||
- `sys.partition_functions` contains `pf_AuditLog_Month`.
|
- `sys.partition_functions` contains `pf_AuditLog_Month`.
|
||||||
@@ -191,10 +191,10 @@ Integration test assertions:
|
|||||||
|
|
||||||
**Notes for the implementer:**
|
**Notes for the implementer:**
|
||||||
- Use `Microsoft.Data.SqlClient` directly in the test fixture (not EF) to issue raw SQL for grant assertions.
|
- 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_<guid>` (created per fixture, dropped on dispose).
|
- Test database name: `ScadaBridgeAuditMigrationTest_<guid>` (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.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ services:
|
|||||||
image: scadabridge:latest
|
image: scadabridge:latest
|
||||||
container_name: scadabridge-env2-central-a
|
container_name: scadabridge-env2-central-a
|
||||||
environment:
|
environment:
|
||||||
SCADALINK_CONFIG: Central
|
SCADABRIDGE_CONFIG: Central
|
||||||
ASPNETCORE_ENVIRONMENT: Development
|
ASPNETCORE_ENVIRONMENT: Development
|
||||||
ASPNETCORE_URLS: "http://+:5000"
|
ASPNETCORE_URLS: "http://+:5000"
|
||||||
ports:
|
ports:
|
||||||
@@ -431,7 +431,7 @@ services:
|
|||||||
image: scadabridge:latest
|
image: scadabridge:latest
|
||||||
container_name: scadabridge-env2-central-b
|
container_name: scadabridge-env2-central-b
|
||||||
environment:
|
environment:
|
||||||
SCADALINK_CONFIG: Central
|
SCADABRIDGE_CONFIG: Central
|
||||||
ASPNETCORE_ENVIRONMENT: Development
|
ASPNETCORE_ENVIRONMENT: Development
|
||||||
ASPNETCORE_URLS: "http://+:5000"
|
ASPNETCORE_URLS: "http://+:5000"
|
||||||
ports:
|
ports:
|
||||||
@@ -448,7 +448,7 @@ services:
|
|||||||
image: scadabridge:latest
|
image: scadabridge:latest
|
||||||
container_name: scadabridge-env2-site-x-a
|
container_name: scadabridge-env2-site-x-a
|
||||||
environment:
|
environment:
|
||||||
SCADALINK_CONFIG: Site
|
SCADABRIDGE_CONFIG: Site
|
||||||
ports:
|
ports:
|
||||||
- "9121:8082" # Akka remoting
|
- "9121:8082" # Akka remoting
|
||||||
- "9123:8083" # gRPC streaming
|
- "9123:8083" # gRPC streaming
|
||||||
@@ -464,7 +464,7 @@ services:
|
|||||||
image: scadabridge:latest
|
image: scadabridge:latest
|
||||||
container_name: scadabridge-env2-site-x-b
|
container_name: scadabridge-env2-site-x-b
|
||||||
environment:
|
environment:
|
||||||
SCADALINK_CONFIG: Site
|
SCADABRIDGE_CONFIG: Site
|
||||||
ports:
|
ports:
|
||||||
- "9122:8082" # Akka remoting
|
- "9122:8082" # Akka remoting
|
||||||
- "9124:8083" # gRPC streaming
|
- "9124:8083" # gRPC streaming
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ Exactly one of `content.json` or `content.enc` is present.
|
|||||||
"createdAtUtc": "2026-05-24T12:34:56Z",
|
"createdAtUtc": "2026-05-24T12:34:56Z",
|
||||||
"sourceEnvironment": "dev-cluster-a",
|
"sourceEnvironment": "dev-cluster-a",
|
||||||
"exportedBy": "alice@corp.example",
|
"exportedBy": "alice@corp.example",
|
||||||
"scadaLinkVersion": "1.4.2",
|
"scadaBridgeVersion": "1.4.2",
|
||||||
"contentHash": "sha256:...",
|
"contentHash": "sha256:...",
|
||||||
"encryption": {
|
"encryption": {
|
||||||
"algorithm": "AES-256-GCM",
|
"algorithm": "AES-256-GCM",
|
||||||
|
|||||||
@@ -734,7 +734,7 @@ Tests:
|
|||||||
|
|
||||||
**Step 2-5:** Run-fail → implement → run-pass → commit.
|
**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`).
|
`ManifestValidator.Validate(BundleManifest manifest, byte[] contentBytes)` returns a `ValidationResult` enum (`Ok | UnsupportedFormatVersion | ContentHashMismatch | MalformedManifest`).
|
||||||
|
|
||||||
|
|||||||
@@ -59,20 +59,24 @@ They are read by code (`Environment.GetEnvironmentVariable(...)` in Host/CLI/tes
|
|||||||
Scrubbing these would destroy their before→after meaning:
|
Scrubbing these would destroy their before→after meaning:
|
||||||
|
|
||||||
- `tools/rename-to-scadabridge.sh` — prior rename tooling.
|
- `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] ...`).
|
- `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-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-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
|
### Completeness gate
|
||||||
|
|
||||||
Must return only the four carve-outs:
|
Must return only the six carve-outs:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git grep -niE "scadalink" -- . \
|
git grep -niE "scadalink" -- . \
|
||||||
':!tools/rename-to-scadabridge.sh' \
|
':!tools/rename-to-scadabridge.sh' \
|
||||||
|
':!tools/scrub-scadalink-refs.sh' \
|
||||||
':!docker/rename-databases.sh' \
|
':!docker/rename-databases.sh' \
|
||||||
':!docs/plans/2026-05-28-scadabridge-rename-design.md' \
|
':!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
|
## Section 3 — Collision folder
|
||||||
|
|||||||
@@ -310,9 +310,9 @@ Configuration is resolved in the following priority order (highest wins):
|
|||||||
|
|
||||||
1. **Command-line options**: `--url`, `--username`, `--password`, `--format`.
|
1. **Command-line options**: `--url`, `--username`, `--password`, `--format`.
|
||||||
2. **Environment variables**:
|
2. **Environment variables**:
|
||||||
- `SCADALINK_MANAGEMENT_URL` — Management API URL (e.g., `http://central-host:5000`).
|
- `SCADABRIDGE_MANAGEMENT_URL` — Management API URL (e.g., `http://central-host:5000`).
|
||||||
- `SCADALINK_FORMAT` — Default output format (`json` or `table`).
|
- `SCADABRIDGE_FORMAT` — Default output format (`json` or `table`).
|
||||||
- `SCADALINK_USERNAME` / `SCADALINK_PASSWORD` — LDAP credentials. Preferred over
|
- `SCADABRIDGE_USERNAME` / `SCADABRIDGE_PASSWORD` — LDAP credentials. Preferred over
|
||||||
`--password` on the command line, which is visible in process listings and shell
|
`--password` on the command line, which is visible in process listings and shell
|
||||||
history. Credentials are never read from the config file.
|
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).
|
3. **Configuration file**: `~/.scadabridge/config.json` — Persistent defaults for management URL and output format only (never credentials).
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ Exactly one of `content.json` or `content.enc` is present.
|
|||||||
"createdAtUtc": "2026-05-24T12:34:56Z",
|
"createdAtUtc": "2026-05-24T12:34:56Z",
|
||||||
"sourceEnvironment": "dev-cluster-a",
|
"sourceEnvironment": "dev-cluster-a",
|
||||||
"exportedBy": "alice@corp.example",
|
"exportedBy": "alice@corp.example",
|
||||||
"scadaLinkVersion": "1.4.2",
|
"scadaBridgeVersion": "1.4.2",
|
||||||
"contentHash": "sha256:...",
|
"contentHash": "sha256:...",
|
||||||
"encryption": {
|
"encryption": {
|
||||||
"algorithm": "AES-256-GCM",
|
"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",
|
"createdAtUtc": "2026-05-24T12:34:56Z",
|
||||||
"sourceEnvironment": "dev-cluster-a",
|
"sourceEnvironment": "dev-cluster-a",
|
||||||
"exportedBy": "alice@corp.example",
|
"exportedBy": "alice@corp.example",
|
||||||
"scadaLinkVersion": "1.4.2",
|
"scadaBridgeVersion": "1.4.2",
|
||||||
"contentHash": "sha256:abc123...",
|
"contentHash": "sha256:abc123...",
|
||||||
"encryption": {
|
"encryption": {
|
||||||
"algorithm": "AES-256-GCM",
|
"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. |
|
| `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. |
|
| `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. |
|
| `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:<hex>` — SHA-256 of the raw `content.json` or `content.enc` bytes (pre-encryption). Verified on upload before any decryption. |
|
| `contentHash` | `sha256:<hex>` — 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` | 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. |
|
| `encryption.algorithm` | Always `"AES-256-GCM"` in v1. |
|
||||||
|
|||||||
@@ -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.
|
- 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.
|
- 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.
|
- 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.
|
- 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
|
## 14. General Conventions
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ public class CliConfig
|
|||||||
public string DefaultFormat { get; set; } = "json";
|
public string DefaultFormat { get; set; } = "json";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// LDAP username from the <c>SCADALINK_USERNAME</c> environment variable, if set.
|
/// LDAP username from the <c>SCADABRIDGE_USERNAME</c> environment variable, if set.
|
||||||
/// Credentials are intentionally only sourced from environment variables (or the
|
/// Credentials are intentionally only sourced from environment variables (or the
|
||||||
/// command line) — never from the config file — so they are not persisted to disk.
|
/// command line) — never from the config file — so they are not persisted to disk.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Username { get; set; }
|
public string? Username { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// LDAP password from the <c>SCADALINK_PASSWORD</c> environment variable, if set.
|
/// LDAP password from the <c>SCADABRIDGE_PASSWORD</c> environment variable, if set.
|
||||||
/// Provides a safer alternative to <c>--password</c>, which leaks into process
|
/// Provides a safer alternative to <c>--password</c>, which leaks into process
|
||||||
/// listings and shell history.
|
/// listings and shell history.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -69,20 +69,20 @@ public class CliConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Override from environment variables
|
// Override from environment variables
|
||||||
var envUrl = Environment.GetEnvironmentVariable("SCADALINK_MANAGEMENT_URL");
|
var envUrl = Environment.GetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL");
|
||||||
if (!string.IsNullOrEmpty(envUrl))
|
if (!string.IsNullOrEmpty(envUrl))
|
||||||
config.ManagementUrl = envUrl;
|
config.ManagementUrl = envUrl;
|
||||||
|
|
||||||
var envFormat = Environment.GetEnvironmentVariable("SCADALINK_FORMAT");
|
var envFormat = Environment.GetEnvironmentVariable("SCADABRIDGE_FORMAT");
|
||||||
if (!string.IsNullOrEmpty(envFormat))
|
if (!string.IsNullOrEmpty(envFormat))
|
||||||
config.DefaultFormat = envFormat;
|
config.DefaultFormat = envFormat;
|
||||||
|
|
||||||
// Credentials from environment variables only (never the config file).
|
// 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))
|
if (!string.IsNullOrEmpty(envUsername))
|
||||||
config.Username = envUsername;
|
config.Username = envUsername;
|
||||||
|
|
||||||
var envPassword = Environment.GetEnvironmentVariable("SCADALINK_PASSWORD");
|
var envPassword = Environment.GetEnvironmentVariable("SCADABRIDGE_PASSWORD");
|
||||||
if (!string.IsNullOrEmpty(envPassword))
|
if (!string.IsNullOrEmpty(envPassword))
|
||||||
config.Password = envPassword;
|
config.Password = envPassword;
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public static class AuditCommandHelpers
|
|||||||
if (string.IsNullOrWhiteSpace(url))
|
if (string.IsNullOrWhiteSpace(url))
|
||||||
{
|
{
|
||||||
return AuditConnection.Fail(
|
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");
|
"NO_URL");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ public static class AuditCommandHelpers
|
|||||||
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
|
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
|
||||||
{
|
{
|
||||||
return AuditConnection.Fail(
|
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");
|
"NO_CREDENTIALS");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ internal static class CommandHelpers
|
|||||||
if (string.IsNullOrWhiteSpace(url))
|
if (string.IsNullOrWhiteSpace(url))
|
||||||
{
|
{
|
||||||
OutputFormatter.WriteError(
|
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");
|
"NO_URL");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -65,14 +65,14 @@ internal static class CommandHelpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Resolve credentials: command-line options take precedence, then the
|
// 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 username = ResolveCredential(result.GetValue(usernameOption), config.Username);
|
||||||
var password = ResolveCredential(result.GetValue(passwordOption), config.Password);
|
var password = ResolveCredential(result.GetValue(passwordOption), config.Password);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
|
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
|
||||||
{
|
{
|
||||||
OutputFormatter.WriteError(
|
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");
|
"NO_CREDENTIALS");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public static class DebugCommands
|
|||||||
if (string.IsNullOrWhiteSpace(url))
|
if (string.IsNullOrWhiteSpace(url))
|
||||||
{
|
{
|
||||||
OutputFormatter.WriteError(
|
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");
|
"NO_URL");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ public static class DebugCommands
|
|||||||
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
|
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
|
||||||
{
|
{
|
||||||
OutputFormatter.WriteError(
|
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");
|
"NO_CREDENTIALS");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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:
|
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
|
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`
|
3. `managementUrl` field in `~/.scadabridge/config.json`
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -57,10 +57,10 @@ For the Docker test environment, see `docker/README.md` for a ready-to-use confi
|
|||||||
|
|
||||||
| Variable | Description |
|
| Variable | Description |
|
||||||
|----------|-------------|
|
|----------|-------------|
|
||||||
| `SCADALINK_MANAGEMENT_URL` | Management API URL (overrides config file) |
|
| `SCADABRIDGE_MANAGEMENT_URL` | Management API URL (overrides config file) |
|
||||||
| `SCADALINK_FORMAT` | Default output format (overrides config file) |
|
| `SCADABRIDGE_FORMAT` | Default output format (overrides config file) |
|
||||||
| `SCADALINK_USERNAME` | LDAP username (fallback when `--username` is not supplied) |
|
| `SCADABRIDGE_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_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
|
## Output
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase;
|
|||||||
/// Factory for creating DbContext instances at design time (used by dotnet ef tooling).
|
/// 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
|
/// Resolves the connection string from the Host's appsettings files, or — for environments
|
||||||
/// where those files are not present — from the
|
/// where those files are not present — from the
|
||||||
/// <c>SCADALINK_DESIGNTIME_CONNECTIONSTRING</c> environment variable.
|
/// <c>SCADABRIDGE_DESIGNTIME_CONNECTIONSTRING</c> environment variable.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// There is deliberately no hardcoded fallback connection string. A credential literal in
|
/// There is deliberately no hardcoded fallback connection string. A credential literal in
|
||||||
@@ -19,7 +19,7 @@ namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase;
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<ScadaBridgeDbContext>
|
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<ScadaBridgeDbContext>
|
||||||
{
|
{
|
||||||
private const string EnvironmentVariableName = "SCADALINK_DESIGNTIME_CONNECTIONSTRING";
|
private const string EnvironmentVariableName = "SCADABRIDGE_DESIGNTIME_CONNECTIONSTRING";
|
||||||
private const string ConfigurationKey = "ScadaBridge:Database:ConfigurationDb";
|
private const string ConfigurationKey = "ScadaBridge:Database:ConfigurationDb";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ using ZB.MOM.WW.ScadaBridge.TemplateEngine;
|
|||||||
using ZB.MOM.WW.ScadaBridge.Transport;
|
using ZB.MOM.WW.ScadaBridge.Transport;
|
||||||
using Serilog;
|
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.)
|
// 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")
|
?? Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT")
|
||||||
?? "Production";
|
?? "Production";
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"DOTNET_ENVIRONMENT": "Development",
|
"DOTNET_ENVIRONMENT": "Development",
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development",
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||||
"SCADALINK_CONFIG": "Central"
|
"SCADABRIDGE_CONFIG": "Central"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ScadaBridge Site": {
|
"ScadaBridge Site": {
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"DOTNET_ENVIRONMENT": "Development",
|
"DOTNET_ENVIRONMENT": "Development",
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development",
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||||
"SCADALINK_CONFIG": "Site"
|
"SCADABRIDGE_CONFIG": "Site"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.",
|
"_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": {
|
"Database": {
|
||||||
"ConfigurationDb": "${SCADALINK_CONFIGURATIONDB_CONNECTION_STRING}"
|
"ConfigurationDb": "${SCADABRIDGE_CONFIGURATIONDB_CONNECTION_STRING}"
|
||||||
},
|
},
|
||||||
"Security": {
|
"Security": {
|
||||||
"LdapServer": "localhost",
|
"LdapServer": "localhost",
|
||||||
@@ -29,8 +29,8 @@
|
|||||||
"AllowInsecureLdap": true,
|
"AllowInsecureLdap": true,
|
||||||
"LdapSearchBase": "dc=scadabridge,dc=local",
|
"LdapSearchBase": "dc=scadabridge,dc=local",
|
||||||
"LdapServiceAccountDn": "cn=admin,dc=scadabridge,dc=local",
|
"LdapServiceAccountDn": "cn=admin,dc=scadabridge,dc=local",
|
||||||
"LdapServiceAccountPassword": "${SCADALINK_LDAP_SERVICE_ACCOUNT_PASSWORD}",
|
"LdapServiceAccountPassword": "${SCADABRIDGE_LDAP_SERVICE_ACCOUNT_PASSWORD}",
|
||||||
"JwtSigningKey": "${SCADALINK_JWT_SIGNING_KEY}",
|
"JwtSigningKey": "${SCADABRIDGE_JWT_SIGNING_KEY}",
|
||||||
"JwtExpiryMinutes": 15,
|
"JwtExpiryMinutes": 15,
|
||||||
"IdleTimeoutMinutes": 30
|
"IdleTimeoutMinutes": 30
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ public sealed class BundleExporter : IBundleExporter
|
|||||||
var templateManifest = _manifestBuilder.Build(
|
var templateManifest = _manifestBuilder.Build(
|
||||||
sourceEnvironment: sourceEnvironment,
|
sourceEnvironment: sourceEnvironment,
|
||||||
exportedBy: user,
|
exportedBy: user,
|
||||||
scadaLinkVersion: assemblyVersion,
|
scadaBridgeVersion: assemblyVersion,
|
||||||
encryption: encryptionSeed,
|
encryption: encryptionSeed,
|
||||||
summary: summary,
|
summary: summary,
|
||||||
contents: resolved.ContentManifest,
|
contents: resolved.ContentManifest,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public sealed class ManifestBuilder
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sourceEnvironment">Environment label identifying where the bundle was exported from.</param>
|
/// <param name="sourceEnvironment">Environment label identifying where the bundle was exported from.</param>
|
||||||
/// <param name="exportedBy">Username of the operator who performed the export.</param>
|
/// <param name="exportedBy">Username of the operator who performed the export.</param>
|
||||||
/// <param name="scadaLinkVersion">ScadaBridge version string stamped in the manifest.</param>
|
/// <param name="scadaBridgeVersion">ScadaBridge version string stamped in the manifest.</param>
|
||||||
/// <param name="encryption">Encryption metadata when the content is encrypted; null for plain bundles.</param>
|
/// <param name="encryption">Encryption metadata when the content is encrypted; null for plain bundles.</param>
|
||||||
/// <param name="summary">High-level summary of artifact counts.</param>
|
/// <param name="summary">High-level summary of artifact counts.</param>
|
||||||
/// <param name="contents">Per-entry content table describing each artifact in the bundle.</param>
|
/// <param name="contents">Per-entry content table describing each artifact in the bundle.</param>
|
||||||
@@ -29,7 +29,7 @@ public sealed class ManifestBuilder
|
|||||||
public BundleManifest Build(
|
public BundleManifest Build(
|
||||||
string sourceEnvironment,
|
string sourceEnvironment,
|
||||||
string exportedBy,
|
string exportedBy,
|
||||||
string scadaLinkVersion,
|
string scadaBridgeVersion,
|
||||||
EncryptionMetadata? encryption,
|
EncryptionMetadata? encryption,
|
||||||
BundleSummary summary,
|
BundleSummary summary,
|
||||||
IReadOnlyList<ManifestContentEntry> contents,
|
IReadOnlyList<ManifestContentEntry> contents,
|
||||||
@@ -37,7 +37,7 @@ public sealed class ManifestBuilder
|
|||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(sourceEnvironment);
|
ArgumentNullException.ThrowIfNull(sourceEnvironment);
|
||||||
ArgumentNullException.ThrowIfNull(exportedBy);
|
ArgumentNullException.ThrowIfNull(exportedBy);
|
||||||
ArgumentNullException.ThrowIfNull(scadaLinkVersion);
|
ArgumentNullException.ThrowIfNull(scadaBridgeVersion);
|
||||||
ArgumentNullException.ThrowIfNull(summary);
|
ArgumentNullException.ThrowIfNull(summary);
|
||||||
ArgumentNullException.ThrowIfNull(contents);
|
ArgumentNullException.ThrowIfNull(contents);
|
||||||
ArgumentNullException.ThrowIfNull(contentBytes);
|
ArgumentNullException.ThrowIfNull(contentBytes);
|
||||||
@@ -50,7 +50,7 @@ public sealed class ManifestBuilder
|
|||||||
CreatedAtUtc: DateTimeOffset.UtcNow,
|
CreatedAtUtc: DateTimeOffset.UtcNow,
|
||||||
SourceEnvironment: sourceEnvironment,
|
SourceEnvironment: sourceEnvironment,
|
||||||
ExportedBy: exportedBy,
|
ExportedBy: exportedBy,
|
||||||
ScadaBridgeVersion: scadaLinkVersion,
|
ScadaBridgeVersion: scadaBridgeVersion,
|
||||||
ContentHash: contentHash,
|
ContentHash: contentHash,
|
||||||
Encryption: encryption,
|
Encryption: encryption,
|
||||||
Summary: summary,
|
Summary: summary,
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ public class CliConfigTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void Load_DefaultFormat_IsJson()
|
public void Load_DefaultFormat_IsJson()
|
||||||
{
|
{
|
||||||
var origUrl = Environment.GetEnvironmentVariable("SCADALINK_MANAGEMENT_URL");
|
var origUrl = Environment.GetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL");
|
||||||
var origFormat = Environment.GetEnvironmentVariable("SCADALINK_FORMAT");
|
var origFormat = Environment.GetEnvironmentVariable("SCADABRIDGE_FORMAT");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_MANAGEMENT_URL", null);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL", null);
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_FORMAT", null);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_FORMAT", null);
|
||||||
|
|
||||||
var config = CliConfig.Load();
|
var config = CliConfig.Load();
|
||||||
|
|
||||||
@@ -23,18 +23,18 @@ public class CliConfigTests
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_MANAGEMENT_URL", origUrl);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL", origUrl);
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_FORMAT", origFormat);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_FORMAT", origFormat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Load_ManagementUrl_FromEnvironment()
|
public void Load_ManagementUrl_FromEnvironment()
|
||||||
{
|
{
|
||||||
var orig = Environment.GetEnvironmentVariable("SCADALINK_MANAGEMENT_URL");
|
var orig = Environment.GetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_MANAGEMENT_URL", "http://central:5000");
|
Environment.SetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL", "http://central:5000");
|
||||||
|
|
||||||
var config = CliConfig.Load();
|
var config = CliConfig.Load();
|
||||||
|
|
||||||
@@ -42,17 +42,17 @@ public class CliConfigTests
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_MANAGEMENT_URL", orig);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL", orig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Load_Format_FromEnvironment()
|
public void Load_Format_FromEnvironment()
|
||||||
{
|
{
|
||||||
var orig = Environment.GetEnvironmentVariable("SCADALINK_FORMAT");
|
var orig = Environment.GetEnvironmentVariable("SCADABRIDGE_FORMAT");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_FORMAT", "table");
|
Environment.SetEnvironmentVariable("SCADABRIDGE_FORMAT", "table");
|
||||||
|
|
||||||
var config = CliConfig.Load();
|
var config = CliConfig.Load();
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ public class CliConfigTests
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_FORMAT", orig);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_FORMAT", orig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,19 +81,19 @@ public class CliConfigTests
|
|||||||
|
|
||||||
var origHome = Environment.GetEnvironmentVariable("HOME");
|
var origHome = Environment.GetEnvironmentVariable("HOME");
|
||||||
var origUserProfile = Environment.GetEnvironmentVariable("USERPROFILE");
|
var origUserProfile = Environment.GetEnvironmentVariable("USERPROFILE");
|
||||||
var origUrl = Environment.GetEnvironmentVariable("SCADALINK_MANAGEMENT_URL");
|
var origUrl = Environment.GetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL");
|
||||||
var origFormat = Environment.GetEnvironmentVariable("SCADALINK_FORMAT");
|
var origFormat = Environment.GetEnvironmentVariable("SCADABRIDGE_FORMAT");
|
||||||
var origUser = Environment.GetEnvironmentVariable("SCADALINK_USERNAME");
|
var origUser = Environment.GetEnvironmentVariable("SCADABRIDGE_USERNAME");
|
||||||
var origPass = Environment.GetEnvironmentVariable("SCADALINK_PASSWORD");
|
var origPass = Environment.GetEnvironmentVariable("SCADABRIDGE_PASSWORD");
|
||||||
var origStderr = Console.Error;
|
var origStderr = Console.Error;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Environment.SetEnvironmentVariable("HOME", tempHome);
|
Environment.SetEnvironmentVariable("HOME", tempHome);
|
||||||
Environment.SetEnvironmentVariable("USERPROFILE", tempHome);
|
Environment.SetEnvironmentVariable("USERPROFILE", tempHome);
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_MANAGEMENT_URL", null);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL", null);
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_FORMAT", null);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_FORMAT", null);
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_USERNAME", null);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_USERNAME", null);
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_PASSWORD", null);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_PASSWORD", null);
|
||||||
|
|
||||||
var stderrCapture = new StringWriter();
|
var stderrCapture = new StringWriter();
|
||||||
Console.SetError(stderrCapture);
|
Console.SetError(stderrCapture);
|
||||||
@@ -112,10 +112,10 @@ public class CliConfigTests
|
|||||||
Console.SetError(origStderr);
|
Console.SetError(origStderr);
|
||||||
Environment.SetEnvironmentVariable("HOME", origHome);
|
Environment.SetEnvironmentVariable("HOME", origHome);
|
||||||
Environment.SetEnvironmentVariable("USERPROFILE", origUserProfile);
|
Environment.SetEnvironmentVariable("USERPROFILE", origUserProfile);
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_MANAGEMENT_URL", origUrl);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_MANAGEMENT_URL", origUrl);
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_FORMAT", origFormat);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_FORMAT", origFormat);
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_USERNAME", origUser);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_USERNAME", origUser);
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_PASSWORD", origPass);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_PASSWORD", origPass);
|
||||||
try { Directory.Delete(tempHome, recursive: true); } catch { /* best-effort cleanup */ }
|
try { Directory.Delete(tempHome, recursive: true); } catch { /* best-effort cleanup */ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace ZB.MOM.WW.ScadaBridge.CLI.Tests;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Regression tests for CLI-006 — credentials could only be supplied via the
|
/// Regression tests for CLI-006 — credentials could only be supplied via the
|
||||||
/// <c>--password</c> command-line option, which leaks into process listings and
|
/// <c>--password</c> command-line option, which leaks into process listings and
|
||||||
/// shell history. A <c>SCADALINK_PASSWORD</c> / <c>SCADALINK_USERNAME</c> environment
|
/// shell history. A <c>SCADABRIDGE_PASSWORD</c> / <c>SCADABRIDGE_USERNAME</c> environment
|
||||||
/// fallback gives CI/CD a safer alternative.
|
/// fallback gives CI/CD a safer alternative.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Collection("Environment")]
|
[Collection("Environment")]
|
||||||
@@ -14,10 +14,10 @@ public class CredentialResolutionTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void Load_Password_FromEnvironment()
|
public void Load_Password_FromEnvironment()
|
||||||
{
|
{
|
||||||
var orig = Environment.GetEnvironmentVariable("SCADALINK_PASSWORD");
|
var orig = Environment.GetEnvironmentVariable("SCADABRIDGE_PASSWORD");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_PASSWORD", "s3cret");
|
Environment.SetEnvironmentVariable("SCADABRIDGE_PASSWORD", "s3cret");
|
||||||
|
|
||||||
var config = CliConfig.Load();
|
var config = CliConfig.Load();
|
||||||
|
|
||||||
@@ -25,17 +25,17 @@ public class CredentialResolutionTests
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_PASSWORD", orig);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_PASSWORD", orig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Load_Username_FromEnvironment()
|
public void Load_Username_FromEnvironment()
|
||||||
{
|
{
|
||||||
var orig = Environment.GetEnvironmentVariable("SCADALINK_USERNAME");
|
var orig = Environment.GetEnvironmentVariable("SCADABRIDGE_USERNAME");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_USERNAME", "ci-user");
|
Environment.SetEnvironmentVariable("SCADABRIDGE_USERNAME", "ci-user");
|
||||||
|
|
||||||
var config = CliConfig.Load();
|
var config = CliConfig.Load();
|
||||||
|
|
||||||
@@ -43,19 +43,19 @@ public class CredentialResolutionTests
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_USERNAME", orig);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_USERNAME", orig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Load_NoCredentialEnvVars_LeavesCredentialsNull()
|
public void Load_NoCredentialEnvVars_LeavesCredentialsNull()
|
||||||
{
|
{
|
||||||
var origUser = Environment.GetEnvironmentVariable("SCADALINK_USERNAME");
|
var origUser = Environment.GetEnvironmentVariable("SCADABRIDGE_USERNAME");
|
||||||
var origPass = Environment.GetEnvironmentVariable("SCADALINK_PASSWORD");
|
var origPass = Environment.GetEnvironmentVariable("SCADABRIDGE_PASSWORD");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_USERNAME", null);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_USERNAME", null);
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_PASSWORD", null);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_PASSWORD", null);
|
||||||
|
|
||||||
var config = CliConfig.Load();
|
var config = CliConfig.Load();
|
||||||
|
|
||||||
@@ -64,8 +64,8 @@ public class CredentialResolutionTests
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_USERNAME", origUser);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_USERNAME", origUser);
|
||||||
Environment.SetEnvironmentVariable("SCADALINK_PASSWORD", origPass);
|
Environment.SetEnvironmentVariable("SCADABRIDGE_PASSWORD", origPass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Audit;
|
|||||||
/// Connection string mirrors the Docker cluster's <c>scadabridge_app</c> account
|
/// Connection string mirrors the Docker cluster's <c>scadabridge_app</c> account
|
||||||
/// from <c>docker/central-node-a/appsettings.Central.json</c>, with the host
|
/// from <c>docker/central-node-a/appsettings.Central.json</c>, with the host
|
||||||
/// pointed at the host-exposed port (<c>localhost:1433</c>). The
|
/// pointed at the host-exposed port (<c>localhost:1433</c>). The
|
||||||
/// <c>SCADALINK_PLAYWRIGHT_DB</c> env var lets CI override the connection
|
/// <c>SCADABRIDGE_PLAYWRIGHT_DB</c> env var lets CI override the connection
|
||||||
/// without recompiling.
|
/// without recompiling.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -34,11 +34,11 @@ internal static class AuditDataSeeder
|
|||||||
private const string DefaultConnectionString =
|
private const string DefaultConnectionString =
|
||||||
"Server=localhost,1433;Database=ScadaBridgeConfig;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true;Encrypt=false;Connect Timeout=5";
|
"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";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Connection string for the running cluster's configuration DB. Resolved
|
/// Connection string for the running cluster's configuration DB. Resolved
|
||||||
/// from <c>SCADALINK_PLAYWRIGHT_DB</c> when set, otherwise the local docker
|
/// from <c>SCADABRIDGE_PLAYWRIGHT_DB</c> when set, otherwise the local docker
|
||||||
/// dev defaults.
|
/// dev defaults.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string ConnectionString
|
public static string ConnectionString
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class AuditGridColumnTests
|
|||||||
/// <summary>Skip reason shared by the DB-seeding tests when MSSQL is down.</summary>
|
/// <summary>Skip reason shared by the DB-seeding tests when MSSQL is down.</summary>
|
||||||
private const string DbUnavailableSkipReason =
|
private const string DbUnavailableSkipReason =
|
||||||
"AuditDataSeeder cannot reach MSSQL at localhost:1433 — bring up infra/docker-compose and docker/deploy.sh, " +
|
"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;
|
private readonly PlaywrightFixture _fixture;
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public class AuditLogPageTests
|
|||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
throw new InvalidOperationException(
|
||||||
"AuditDataSeeder cannot reach MSSQL at localhost:1433 — bring up infra/docker-compose and docker/deploy.sh, " +
|
"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");
|
var runId = Guid.NewGuid().ToString("N");
|
||||||
|
|||||||
+2
-2
@@ -28,11 +28,11 @@ internal static class SiteCallDataSeeder
|
|||||||
private const string DefaultConnectionString =
|
private const string DefaultConnectionString =
|
||||||
"Server=localhost,1433;Database=ScadaBridgeConfig;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true;Encrypt=false;Connect Timeout=5";
|
"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";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Connection string for the running cluster's configuration DB. Resolved
|
/// Connection string for the running cluster's configuration DB. Resolved
|
||||||
/// from <c>SCADALINK_PLAYWRIGHT_DB</c> when set, otherwise the local docker
|
/// from <c>SCADABRIDGE_PLAYWRIGHT_DB</c> when set, otherwise the local docker
|
||||||
/// dev defaults.
|
/// dev defaults.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string ConnectionString
|
public static string ConnectionString
|
||||||
|
|||||||
+1
-1
@@ -101,7 +101,7 @@ public class SiteCallsPageTests
|
|||||||
/// <summary>Skip reason shared by the DB-seeding tests when MSSQL is down.</summary>
|
/// <summary>Skip reason shared by the DB-seeding tests when MSSQL is down.</summary>
|
||||||
private const string DbUnavailableSkipReason =
|
private const string DbUnavailableSkipReason =
|
||||||
"SiteCallDataSeeder cannot reach MSSQL at localhost:1433 — bring up infra/docker-compose and docker/deploy.sh, " +
|
"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]
|
[SkippableFact]
|
||||||
public async Task FilterNarrowing_ChannelFilterShrinksGrid()
|
public async Task FilterNarrowing_ChannelFilterShrinksGrid()
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests;
|
|||||||
|
|
||||||
public class DesignTimeDbContextFactoryTests : IDisposable
|
public class DesignTimeDbContextFactoryTests : IDisposable
|
||||||
{
|
{
|
||||||
private const string EnvVar = "SCADALINK_DESIGNTIME_CONNECTIONSTRING";
|
private const string EnvVar = "SCADABRIDGE_DESIGNTIME_CONNECTIONSTRING";
|
||||||
private readonly string? _originalEnv;
|
private readonly string? _originalEnv;
|
||||||
|
|
||||||
public DesignTimeDbContextFactoryTests()
|
public DesignTimeDbContextFactoryTests()
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ public sealed class MsSqlMigrationFixture : IDisposable
|
|||||||
private const string DefaultAdminConnectionString =
|
private const string DefaultAdminConnectionString =
|
||||||
"Server=localhost,1433;User Id=sa;Password=ScadaBridge_Dev1#;TrustServerCertificate=true;Encrypt=false;Connect Timeout=3";
|
"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; }
|
public string DatabaseName { get; }
|
||||||
|
|
||||||
|
|||||||
@@ -110,10 +110,10 @@ public class HotPathLatencyTests
|
|||||||
var p95Us = MeasureP95Microseconds(MeasureIterations, () => _ = filter.Apply(evt));
|
var p95Us = MeasureP95Microseconds(MeasureIterations, () => _ = filter.Apply(evt));
|
||||||
|
|
||||||
// Default budget 50 µs (spec target). Override via env for slow CI:
|
// 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
|
// guard threshold. Print the observed value so a missed budget gives
|
||||||
// useful telemetry on the test output.
|
// 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,
|
Assert.True(p95Us < threshold,
|
||||||
$"4KB body filter p95 = {p95Us:F1} µs; threshold = {threshold:F1} µs");
|
$"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 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,
|
Assert.True(p95Us < threshold,
|
||||||
$"Raw-event filter p95 = {p95Us:F1} µs; threshold = {threshold:F1} µs");
|
$"Raw-event filter p95 = {p95Us:F1} µs; threshold = {threshold:F1} µs");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ public sealed class BundleImporterLoadTests
|
|||||||
var manifest = builder.Build(
|
var manifest = builder.Build(
|
||||||
sourceEnvironment: "dev",
|
sourceEnvironment: "dev",
|
||||||
exportedBy: "alice",
|
exportedBy: "alice",
|
||||||
scadaLinkVersion: "1.0.0",
|
scadaBridgeVersion: "1.0.0",
|
||||||
encryption: null,
|
encryption: null,
|
||||||
summary: new BundleSummary(content.Templates.Count, 0, 0, 0, 0, 0, 0, 0, 0),
|
summary: new BundleSummary(content.Templates.Count, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||||
contents: Array.Empty<ManifestContentEntry>(),
|
contents: Array.Empty<ManifestContentEntry>(),
|
||||||
@@ -152,7 +152,7 @@ public sealed class BundleImporterLoadTests
|
|||||||
var manifest = builder.Build(
|
var manifest = builder.Build(
|
||||||
sourceEnvironment: "dev",
|
sourceEnvironment: "dev",
|
||||||
exportedBy: "alice",
|
exportedBy: "alice",
|
||||||
scadaLinkVersion: "1.0.0",
|
scadaBridgeVersion: "1.0.0",
|
||||||
encryption: seed,
|
encryption: seed,
|
||||||
summary: new BundleSummary(content.Templates.Count, 0, 0, 0, 0, 0, 0, 0, 0),
|
summary: new BundleSummary(content.Templates.Count, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||||
contents: Array.Empty<ManifestContentEntry>(),
|
contents: Array.Empty<ManifestContentEntry>(),
|
||||||
@@ -471,7 +471,7 @@ public sealed class BundleImporterLoadTests
|
|||||||
var manifest = rig.ManifestBuilder.Build(
|
var manifest = rig.ManifestBuilder.Build(
|
||||||
sourceEnvironment: "dev",
|
sourceEnvironment: "dev",
|
||||||
exportedBy: "alice",
|
exportedBy: "alice",
|
||||||
scadaLinkVersion: "1.0.0",
|
scadaBridgeVersion: "1.0.0",
|
||||||
encryption: null,
|
encryption: null,
|
||||||
summary: new BundleSummary(1, 0, 0, 0, 0, 0, 0, 0, 0),
|
summary: new BundleSummary(1, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||||
contents: Array.Empty<ManifestContentEntry>(),
|
contents: Array.Empty<ManifestContentEntry>(),
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public sealed class BundleSerializerTests
|
|||||||
new ManifestBuilder().Build(
|
new ManifestBuilder().Build(
|
||||||
sourceEnvironment: "test-env",
|
sourceEnvironment: "test-env",
|
||||||
exportedBy: "tester",
|
exportedBy: "tester",
|
||||||
scadaLinkVersion: "1.0.0",
|
scadaBridgeVersion: "1.0.0",
|
||||||
encryption: encryption,
|
encryption: encryption,
|
||||||
summary: new BundleSummary(0, 1, 1, 0, 0, 0, 0, 0, 0),
|
summary: new BundleSummary(0, 1, 1, 0, 0, 0, 0, 0, 0),
|
||||||
contents: Array.Empty<ManifestContentEntry>(),
|
contents: Array.Empty<ManifestContentEntry>(),
|
||||||
|
|||||||
Executable
+39
@@ -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."
|
||||||
Reference in New Issue
Block a user