chore(host): remove unused Database:MachineDataDb option, validation, config and docs
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
}
|
||||
},
|
||||
"Database": {
|
||||
"_comment": "ConfigurationDb/MachineDataDb (which carry the dev SQL password) are supplied as ScadaBridge__Database__* whole-key env overrides in docker-env2/docker-compose.yml (dev-only-insecure, mirroring docker/docker-compose.yml and the ApiKeyPepper convention). The same dev password already ships committed for the sibling scadabridge-mssql container (infra/docker-compose.yml MSSQL_SA_PASSWORD) — this is consolidation, not new exposure. Env overrides layer over JSON before the ${secret:} expander runs, so the dev cluster boots with no KEK/secret store. Real/prod config uses ${secret:} tokens in src/.../appsettings.Central.json (T4)."
|
||||
"_comment": "ConfigurationDb (which carries the dev SQL password) is supplied as ScadaBridge__Database__* whole-key env overrides in docker-env2/docker-compose.yml (dev-only-insecure, mirroring docker/docker-compose.yml and the ApiKeyPepper convention). The same dev password already ships committed for the sibling scadabridge-mssql container (infra/docker-compose.yml MSSQL_SA_PASSWORD) — this is consolidation, not new exposure. Env overrides layer over JSON before the ${secret:} expander runs, so the dev cluster boots with no KEK/secret store. Real/prod config uses ${secret:} tokens in src/.../appsettings.Central.json (T4)."
|
||||
},
|
||||
"Security": {
|
||||
"Ldap": {
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
}
|
||||
},
|
||||
"Database": {
|
||||
"_comment": "ConfigurationDb/MachineDataDb (which carry the dev SQL password) are supplied as ScadaBridge__Database__* whole-key env overrides in docker-env2/docker-compose.yml (dev-only-insecure, mirroring docker/docker-compose.yml and the ApiKeyPepper convention). The same dev password already ships committed for the sibling scadabridge-mssql container (infra/docker-compose.yml MSSQL_SA_PASSWORD) — this is consolidation, not new exposure. Env overrides layer over JSON before the ${secret:} expander runs, so the dev cluster boots with no KEK/secret store. Real/prod config uses ${secret:} tokens in src/.../appsettings.Central.json (T4)."
|
||||
"_comment": "ConfigurationDb (which carries the dev SQL password) is supplied as ScadaBridge__Database__* whole-key env overrides in docker-env2/docker-compose.yml (dev-only-insecure, mirroring docker/docker-compose.yml and the ApiKeyPepper convention). The same dev password already ships committed for the sibling scadabridge-mssql container (infra/docker-compose.yml MSSQL_SA_PASSWORD) — this is consolidation, not new exposure. Env overrides layer over JSON before the ${secret:} expander runs, so the dev cluster boots with no KEK/secret store. Real/prod config uses ${secret:} tokens in src/.../appsettings.Central.json (T4)."
|
||||
},
|
||||
"Security": {
|
||||
"Ldap": {
|
||||
|
||||
@@ -47,7 +47,6 @@ services:
|
||||
# that SAME shared mssql container. Real deployments use ${secret:} tokens +
|
||||
# a seeded store.
|
||||
ScadaBridge__Database__ConfigurationDb: "Server=scadabridge-mssql,1433;Database=ScadaBridgeConfig2;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true"
|
||||
ScadaBridge__Database__MachineDataDb: "Server=scadabridge-mssql,1433;Database=ScadaBridgeMachineData2;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true"
|
||||
# LDAP bind credential for the redundant local GLAuth pair (scadaproj/infra/glauth-redundant,
|
||||
# host.docker.internal:3893/:3894 — see central-node-a/appsettings.Central.json). Same
|
||||
# value docker/'s central nodes use for the SAME local pair; the shared 10.100.0.35
|
||||
@@ -110,7 +109,6 @@ services:
|
||||
# that SAME shared mssql container. Real deployments use ${secret:} tokens +
|
||||
# a seeded store.
|
||||
ScadaBridge__Database__ConfigurationDb: "Server=scadabridge-mssql,1433;Database=ScadaBridgeConfig2;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true"
|
||||
ScadaBridge__Database__MachineDataDb: "Server=scadabridge-mssql,1433;Database=ScadaBridgeMachineData2;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true"
|
||||
# LDAP bind credential for the redundant local GLAuth pair (scadaproj/infra/glauth-redundant,
|
||||
# host.docker.internal:3893/:3894 — see central-node-b/appsettings.Central.json). Same
|
||||
# value docker/'s central nodes use for the SAME local pair; the shared 10.100.0.35
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
}
|
||||
},
|
||||
"Database": {
|
||||
"_comment": "ConfigurationDb/MachineDataDb (which carry the dev SQL password) are supplied as ScadaBridge__Database__* whole-key env overrides in docker/docker-compose.yml (dev-only-insecure, mirroring the ApiKeyPepper convention). The same dev password already ships committed for the sibling scadabridge-mssql container (infra/docker-compose.yml MSSQL_SA_PASSWORD) \u2014 this is consolidation, not new exposure. Env overrides layer over JSON before the ${secret:} expander runs, so the dev cluster boots with no KEK/secret store. Real/prod config uses ${secret:} tokens in src/.../appsettings.Central.json (T4)."
|
||||
"_comment": "ConfigurationDb (which carries the dev SQL password) is supplied as ScadaBridge__Database__* whole-key env overrides in docker/docker-compose.yml (dev-only-insecure, mirroring the ApiKeyPepper convention). The same dev password already ships committed for the sibling scadabridge-mssql container (infra/docker-compose.yml MSSQL_SA_PASSWORD) \u2014 this is consolidation, not new exposure. Env overrides layer over JSON before the ${secret:} expander runs, so the dev cluster boots with no KEK/secret store. Real/prod config uses ${secret:} tokens in src/.../appsettings.Central.json (T4)."
|
||||
},
|
||||
"Security": {
|
||||
"Ldap": {
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
}
|
||||
},
|
||||
"Database": {
|
||||
"_comment": "ConfigurationDb/MachineDataDb (which carry the dev SQL password) are supplied as ScadaBridge__Database__* whole-key env overrides in docker/docker-compose.yml (dev-only-insecure, mirroring the ApiKeyPepper convention). The same dev password already ships committed for the sibling scadabridge-mssql container (infra/docker-compose.yml MSSQL_SA_PASSWORD) \u2014 this is consolidation, not new exposure. Env overrides layer over JSON before the ${secret:} expander runs, so the dev cluster boots with no KEK/secret store. Real/prod config uses ${secret:} tokens in src/.../appsettings.Central.json (T4)."
|
||||
"_comment": "ConfigurationDb (which carries the dev SQL password) is supplied as ScadaBridge__Database__* whole-key env overrides in docker/docker-compose.yml (dev-only-insecure, mirroring the ApiKeyPepper convention). The same dev password already ships committed for the sibling scadabridge-mssql container (infra/docker-compose.yml MSSQL_SA_PASSWORD) \u2014 this is consolidation, not new exposure. Env overrides layer over JSON before the ${secret:} expander runs, so the dev cluster boots with no KEK/secret store. Real/prod config uses ${secret:} tokens in src/.../appsettings.Central.json (T4)."
|
||||
},
|
||||
"Security": {
|
||||
"Ldap": {
|
||||
|
||||
@@ -107,7 +107,6 @@ services:
|
||||
# (infra/docker-compose.yml MSSQL_SA_PASSWORD) — consolidation, not new exposure. Real
|
||||
# deployments use ${secret:} tokens (src/.../appsettings.Central.json) + a seeded store.
|
||||
ScadaBridge__Database__ConfigurationDb: "Server=scadabridge-mssql,1433;Database=ScadaBridgeConfig;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true"
|
||||
ScadaBridge__Database__MachineDataDb: "Server=scadabridge-mssql,1433;Database=ScadaBridgeMachineData;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true"
|
||||
ScadaBridge__Security__Ldap__ServiceAccountPassword: "serviceaccount123"
|
||||
ScadaBridge__Security__JwtSigningKey: "scadabridge-dev-jwt-signing-key-must-be-at-least-32-characters-long"
|
||||
# DEV-ONLY gRPC control-plane preshared keys, one per site — NOT real secrets.
|
||||
@@ -174,7 +173,6 @@ services:
|
||||
# (infra/docker-compose.yml MSSQL_SA_PASSWORD) — consolidation, not new exposure. Real
|
||||
# deployments use ${secret:} tokens (src/.../appsettings.Central.json) + a seeded store.
|
||||
ScadaBridge__Database__ConfigurationDb: "Server=scadabridge-mssql,1433;Database=ScadaBridgeConfig;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true"
|
||||
ScadaBridge__Database__MachineDataDb: "Server=scadabridge-mssql,1433;Database=ScadaBridgeMachineData;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true"
|
||||
ScadaBridge__Security__Ldap__ServiceAccountPassword: "serviceaccount123"
|
||||
ScadaBridge__Security__JwtSigningKey: "scadabridge-dev-jwt-signing-key-must-be-at-least-32-characters-long"
|
||||
# DEV-ONLY gRPC control-plane preshared keys, one per site — NOT real secrets.
|
||||
|
||||
@@ -58,8 +58,7 @@ C:\ScadaBridge\
|
||||
]
|
||||
},
|
||||
"Database": {
|
||||
"ConfigurationDb": "Server=sqlserver.example.com;Database=ScadaBridge;User Id=scadabridge_svc;Password=<CHANGE_ME>;Encrypt=true;TrustServerCertificate=false",
|
||||
"MachineDataDb": "Server=sqlserver.example.com;Database=ScadaBridge_MachineData;User Id=scadabridge_svc;Password=<CHANGE_ME>;Encrypt=true;TrustServerCertificate=false"
|
||||
"ConfigurationDb": "Server=sqlserver.example.com;Database=ScadaBridge;User Id=scadabridge_svc;Password=<CHANGE_ME>;Encrypt=true;TrustServerCertificate=false"
|
||||
},
|
||||
"Security": {
|
||||
"LdapServer": "ldap.example.com",
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
### Central Node
|
||||
|
||||
- [ ] `ScadaBridge:Database:ConfigurationDb` connection string is valid and tested
|
||||
- [ ] `ScadaBridge:Database:MachineDataDb` connection string is valid and tested
|
||||
- [ ] SQL Server login has `db_owner` role on both databases
|
||||
- [ ] EF Core migrations have been applied (SQL script reviewed and executed)
|
||||
- [ ] `ScadaBridge:Security:JwtSigningKey` is at least 32 characters, randomly generated
|
||||
|
||||
@@ -47,7 +47,7 @@ The Host must bind configuration sections from `appsettings.json` to strongly-ty
|
||||
|---------|--------------|-------|----------|
|
||||
| `ScadaBridge:Node` | `NodeOptions` | Host | Role, NodeHostname, SiteId, RemotingPort, GrpcPort (site: hosts `SiteCommandService` + `SiteStreamGrpcServer`, default 8083), CentralGrpcPort (central: hosts `CentralControlService`, default 8083) |
|
||||
| `ScadaBridge:Cluster` | `ClusterOptions` | ClusterInfrastructure | SeedNodes, SplitBrainResolverStrategy, StableAfter, HeartbeatInterval, FailureDetectionThreshold, MinNrOfMembers |
|
||||
| `ScadaBridge:Database` | `DatabaseOptions` | Host | Central: ConfigurationDb, MachineDataDb connection strings; Site: SQLite paths |
|
||||
| `ScadaBridge:Database` | `DatabaseOptions` | Host | Central: ConfigurationDb connection string; Site: SQLite paths |
|
||||
|
||||
#### Per-Component Sections
|
||||
|
||||
@@ -83,7 +83,7 @@ Before the Akka.NET actor system is created, the Host must validate all required
|
||||
- `NodeConfiguration.RemotingPort` must be in valid port range (1–65535).
|
||||
- Site nodes must have `GrpcPort` in valid port range (1–65535) and different from `RemotingPort`.
|
||||
- Site nodes must have a non-empty `SiteId`.
|
||||
- Central nodes must have non-empty `ConfigurationDb` and `MachineDataDb` connection strings.
|
||||
- Central nodes must have a non-empty `ConfigurationDb` connection string.
|
||||
- Site nodes must have non-empty SQLite path values. Site nodes do **not** require a `ConfigurationDb` connection string — all configuration is received via artifact deployment and read from local SQLite.
|
||||
- At least two seed nodes must be configured.
|
||||
|
||||
|
||||
+1
-2
@@ -71,7 +71,6 @@ that is the same variable, not a separate one).
|
||||
| Variable | In appsettings? | Config key | Purpose | Potential values | Required |
|
||||
|---|---|---|---|---|---|
|
||||
| `ScadaBridge__Database__ConfigurationDb` | Yes — `${secret:sql/scadabridge/configdb-connection}` in `appsettings.Central.json` | `ScadaBridge:Database:ConfigurationDb` | Central config DB connection string (MS SQL). Central-only. | `Server=host,1433;Database=ScadaBridgeConfig;User Id=...;Password=...;TrustServerCertificate=true` | Yes on Central — via env **or** the `${secret}` |
|
||||
| `ScadaBridge__Database__MachineDataDb` | No in shipped src appsettings; present in the deploy overlay (`deploy/wonder-app-vd03/appsettings.Central.json`, as `${...}`). install.ps1 derives it as `<DbName>MachineData`. | `ScadaBridge:Database:MachineDataDb` | Central machine-data DB connection string. Central-only. | connection string | Yes on Central |
|
||||
| `ScadaBridge__Security__JwtSigningKey` | Yes — `${secret:security/scadabridge/jwt-signing-key}` in `appsettings.Central.json` | `ScadaBridge:Security:JwtSigningKey` | HMAC-SHA256 signing key for the cookie-embedded session JWT. | ≥32-char secret | Yes on Central |
|
||||
| `ScadaBridge__Security__Ldap__ServiceAccountPassword` | Yes — `${secret:ldap/scadabridge/service-account-password}` in `appsettings.Central.json` | `ScadaBridge:Security:Ldap:ServiceAccountPassword` | LDAP bind-account password. (Renamed from the old flat `...__LdapServiceAccountPassword`.) | the bind password | Yes on Central if LDAP bind is used |
|
||||
| `ScadaBridge__InboundApi__ApiKeyPepper` | No — env/secret only (not in any shipped appsettings) | `ScadaBridge:InboundApi:ApiKeyPepper` | Per-environment pepper for the inbound API-key peppered-HMAC verifier. Hard Central startup requirement since 2026-06-03. | ≥16-char secret, unique per environment | Yes on Central |
|
||||
@@ -164,7 +163,7 @@ ScadaBridge code — included for completeness when standing up a rig.
|
||||
|
||||
**Central node** (via env, or the `${secret:...}` equivalents + `ZB_SECRETS_MASTER_KEY`):
|
||||
`SCADABRIDGE_CONFIG=Central`, `ScadaBridge__Database__ConfigurationDb`,
|
||||
`ScadaBridge__Database__MachineDataDb`, `ScadaBridge__Security__JwtSigningKey`,
|
||||
`ScadaBridge__Security__JwtSigningKey`,
|
||||
`ScadaBridge__Security__Ldap__ServiceAccountPassword`, `ScadaBridge__InboundApi__ApiKeyPepper`, and
|
||||
for each managed site either the `SB-GRPC-PSK-<siteId>` secret or `ScadaBridge__Communication__SitePsks__<siteId>`.
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@ public class DatabaseOptions
|
||||
{
|
||||
/// <summary>Connection string for the central configuration SQL Server database.</summary>
|
||||
public string? ConfigurationDb { get; set; }
|
||||
/// <summary>Connection string for the central machine-data SQL Server database.</summary>
|
||||
public string? MachineDataDb { get; set; }
|
||||
/// <summary>File system path to the site-local SQLite database directory.</summary>
|
||||
public string? SiteDbPath { get; set; }
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace ZB.MOM.WW.ScadaBridge.Host;
|
||||
|
||||
/// <summary>
|
||||
/// Validates <see cref="DatabaseOptions"/> at host startup (arch-review 08
|
||||
/// round 2 NF4). All three connection settings are nullable and role-dependent
|
||||
/// round 2 NF4). Both connection settings are nullable and role-dependent
|
||||
/// (central needs the SQL Server strings, a site needs only the SQLite path),
|
||||
/// so a <c>null</c> value is valid. A present-but-whitespace value is not — it
|
||||
/// signals a mis-set config key that would fail opaquely at first DB use.
|
||||
@@ -15,7 +15,6 @@ public sealed class DatabaseOptionsValidator : OptionsValidatorBase<DatabaseOpti
|
||||
protected override void Validate(ValidationBuilder builder, DatabaseOptions options)
|
||||
{
|
||||
RequireNotWhitespace(builder, options.ConfigurationDb, nameof(DatabaseOptions.ConfigurationDb));
|
||||
RequireNotWhitespace(builder, options.MachineDataDb, nameof(DatabaseOptions.MachineDataDb));
|
||||
RequireNotWhitespace(builder, options.SiteDbPath, nameof(DatabaseOptions.SiteDbPath));
|
||||
}
|
||||
|
||||
|
||||
@@ -73,9 +73,6 @@ public static class StartupValidator
|
||||
.Require("ScadaBridge:Database:ConfigurationDb",
|
||||
_ => !string.IsNullOrEmpty(configuration.GetSection("ScadaBridge:Database")["ConfigurationDb"]),
|
||||
"connection string required for Central")
|
||||
.Require("ScadaBridge:Database:MachineDataDb",
|
||||
_ => !string.IsNullOrEmpty(configuration.GetSection("ScadaBridge:Database")["MachineDataDb"]),
|
||||
"connection string required for Central")
|
||||
// The LDAP server key moved into the nested Security:Ldap
|
||||
// sub-section (bound to the shared LdapOptions). Validate the nested key so
|
||||
// the pre-host preflight still fails fast on a missing LDAP server for
|
||||
|
||||
@@ -29,7 +29,7 @@ public class CentralActorPathTests : IAsyncLifetime
|
||||
_previousEnv = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT");
|
||||
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", "Central");
|
||||
|
||||
// Supply the pepper, MachineDataDb and the G-4 secret-backed keys
|
||||
// Supply the pepper and the G-4 secret-backed keys
|
||||
// (ConfigurationDb / LDAP service-account password / JWT signing key) as
|
||||
// whole-key env overrides so the pre-host config builder — which calls
|
||||
// AddEnvironmentVariables() before the ${secret:...} expander runs — sees
|
||||
|
||||
@@ -100,7 +100,7 @@ public class CentralAuditWiringTests : IDisposable
|
||||
_previousEnv = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT");
|
||||
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", "Central");
|
||||
|
||||
// Supply the pepper, MachineDataDb and the G-4 secret-backed keys
|
||||
// Supply the pepper and the G-4 secret-backed keys
|
||||
// (ConfigurationDb / LDAP service-account password / JWT signing key) as
|
||||
// whole-key env overrides so the pre-host config builder — which calls
|
||||
// AddEnvironmentVariables() before the ${secret:...} expander runs — sees
|
||||
|
||||
@@ -12,11 +12,6 @@ namespace ZB.MOM.WW.ScadaBridge.Host.Tests;
|
||||
/// StartupValidator preflight (added in 1fcc4f5) does not fail for tests that set
|
||||
/// <c>DOTNET_ENVIRONMENT=Central</c> without an explicit pepper env var.
|
||||
///
|
||||
/// Also supplies <c>ScadaBridge__Database__MachineDataDb</c> so the Central-role
|
||||
/// StartupValidator preflight (a missing MachineDataDb setting) does not
|
||||
/// fail for tests that set <c>DOTNET_ENVIRONMENT=Central</c> without an explicit
|
||||
/// MachineDataDb env var.
|
||||
///
|
||||
/// G-4 (secrets adoption): <c>appsettings.Central.json</c> now carries
|
||||
/// <c>${secret:...}</c> references for the ConfigurationDb connection string, the
|
||||
/// LDAP service-account password and the JWT signing key. The pre-host secrets
|
||||
@@ -44,11 +39,6 @@ internal sealed class CentralDbTestEnvironment : IDisposable
|
||||
|
||||
private const string ConfigKey = "ScadaBridge__Database__ConfigurationDb";
|
||||
|
||||
private const string MachineDataDb =
|
||||
"Server=localhost,1433;Database=ScadaBridgeMachineData;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true";
|
||||
|
||||
private const string MachineDataKey = "ScadaBridge__Database__MachineDataDb";
|
||||
|
||||
// Test-only pepper — satisfies the ≥16-char StartupValidator requirement without
|
||||
// committing a real secret. The env-var name uses the double-underscore delimiter
|
||||
// so AddEnvironmentVariables() maps it to ScadaBridge:InboundApi:ApiKeyPepper.
|
||||
@@ -67,7 +57,6 @@ internal sealed class CentralDbTestEnvironment : IDisposable
|
||||
private const string JwtSigningKeyKey = "ScadaBridge__Security__JwtSigningKey";
|
||||
|
||||
private readonly string? _previousConfig;
|
||||
private readonly string? _previousMachineData;
|
||||
private readonly string? _previousPepper;
|
||||
private readonly string? _previousLdapPassword;
|
||||
private readonly string? _previousJwtSigningKey;
|
||||
@@ -95,9 +84,6 @@ internal sealed class CentralDbTestEnvironment : IDisposable
|
||||
_previousConfig = Environment.GetEnvironmentVariable(ConfigKey);
|
||||
Environment.SetEnvironmentVariable(ConfigKey, ConfigurationDb);
|
||||
|
||||
_previousMachineData = Environment.GetEnvironmentVariable(MachineDataKey);
|
||||
Environment.SetEnvironmentVariable(MachineDataKey, MachineDataDb);
|
||||
|
||||
_previousPepper = Environment.GetEnvironmentVariable(PepperKey);
|
||||
Environment.SetEnvironmentVariable(PepperKey, TestPepper);
|
||||
|
||||
@@ -112,7 +98,6 @@ internal sealed class CentralDbTestEnvironment : IDisposable
|
||||
public void Dispose()
|
||||
{
|
||||
Environment.SetEnvironmentVariable(ConfigKey, _previousConfig);
|
||||
Environment.SetEnvironmentVariable(MachineDataKey, _previousMachineData);
|
||||
Environment.SetEnvironmentVariable(PepperKey, _previousPepper);
|
||||
Environment.SetEnvironmentVariable(LdapPasswordKey, _previousLdapPassword);
|
||||
Environment.SetEnvironmentVariable(JwtSigningKeyKey, _previousJwtSigningKey);
|
||||
|
||||
@@ -96,7 +96,7 @@ public class CentralCompositionRootTests : IDisposable
|
||||
_previousEnv = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT");
|
||||
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", "Central");
|
||||
|
||||
// Supply the pepper, MachineDataDb and the G-4 secret-backed keys
|
||||
// Supply the pepper and the G-4 secret-backed keys
|
||||
// (ConfigurationDb / LDAP service-account password / JWT signing key) as
|
||||
// whole-key env overrides so the pre-host config builder — which calls
|
||||
// AddEnvironmentVariables() before the ${secret:...} expander runs — sees
|
||||
|
||||
@@ -20,7 +20,6 @@ public class StartupValidatorTests
|
||||
["ScadaBridge:Node:NodeHostname"] = "central-node1",
|
||||
["ScadaBridge:Node:RemotingPort"] = "8081",
|
||||
["ScadaBridge:Database:ConfigurationDb"] = "Server=localhost;Database=Config;",
|
||||
["ScadaBridge:Database:MachineDataDb"] = "Server=localhost;Database=MachineData;",
|
||||
["ScadaBridge:Security:Ldap:Server"] = "ldap.example.com",
|
||||
["ScadaBridge:Security:JwtSigningKey"] = "test-signing-key-at-least-32-chars-long",
|
||||
["ScadaBridge:Cluster:SeedNodes:0"] = "akka.tcp://scadabridge@central-node1:8081",
|
||||
@@ -303,24 +302,6 @@ public class StartupValidatorTests
|
||||
Assert.Contains("ConfigurationDb connection string required for Central", ex.Message);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a central node missing machine data database fails validation.</summary>
|
||||
/// <returns>The result.</returns>
|
||||
[Fact]
|
||||
public void Central_MissingMachineDataDb_FailsValidation()
|
||||
{
|
||||
// The host requirements require MachineDataDb to be
|
||||
// validated at startup for Central nodes, and the shipped docker appsettings
|
||||
// (docker/central-node-a/appsettings.Central.json and central-node-b) carry
|
||||
// the key. The earlier decision (which removed the Require) is reversed
|
||||
// here: a missing MachineDataDb must fail fast with a clear error.
|
||||
var values = ValidCentralConfig();
|
||||
values.Remove("ScadaBridge:Database:MachineDataDb");
|
||||
var config = BuildConfig(values);
|
||||
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => StartupValidator.Validate(config));
|
||||
Assert.Contains("MachineDataDb connection string required for Central", ex.Message);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a central node missing LDAP server fails validation.</summary>
|
||||
/// <returns>The result.</returns>
|
||||
[Fact]
|
||||
|
||||
@@ -40,7 +40,6 @@ public class ScadaBridgeWebApplicationFactory : WebApplicationFactory<Program>
|
||||
["ScadaBridge__Cluster__SeedNodes__0"] = "akka.tcp://scadabridge@localhost:8081",
|
||||
["ScadaBridge__Cluster__SeedNodes__1"] = "akka.tcp://scadabridge@localhost:8082",
|
||||
["ScadaBridge__Database__ConfigurationDb"] = "Server=localhost;Database=ScadaBridge_Test;TrustServerCertificate=True",
|
||||
["ScadaBridge__Database__MachineDataDb"] = "Server=localhost;Database=ScadaBridge_MachineData_Test;TrustServerCertificate=True",
|
||||
["ScadaBridge__Database__SkipMigrations"] = "true",
|
||||
["ScadaBridge__Security__JwtSigningKey"] = "integration-test-signing-key-must-be-at-least-32-chars-long",
|
||||
// The inbound API-key pepper is a REQUIRED Central config value (StartupValidator
|
||||
|
||||
@@ -48,7 +48,6 @@ public class StartupValidationTests
|
||||
["ScadaBridge__Cluster__SeedNodes__0"] = "akka.tcp://scadabridge@localhost:8081",
|
||||
["ScadaBridge__Cluster__SeedNodes__1"] = "akka.tcp://scadabridge@localhost:8082",
|
||||
["ScadaBridge__Database__ConfigurationDb"] = "Server=x;Database=x",
|
||||
["ScadaBridge__Database__MachineDataDb"] = "Server=x;Database=x",
|
||||
["ScadaBridge__Security__Ldap__Server"] = "localhost",
|
||||
// Deliberately missing JwtSigningKey
|
||||
});
|
||||
@@ -92,7 +91,6 @@ public class StartupValidationTests
|
||||
"ScadaBridge__Cluster__SeedNodes__0",
|
||||
"ScadaBridge__Cluster__SeedNodes__1",
|
||||
"ScadaBridge__Database__ConfigurationDb",
|
||||
"ScadaBridge__Database__MachineDataDb",
|
||||
"ScadaBridge__Database__SkipMigrations",
|
||||
"ScadaBridge__Security__JwtSigningKey",
|
||||
"ScadaBridge__Security__Ldap__Server",
|
||||
|
||||
Reference in New Issue
Block a user