feat(cluster): refuse to boot a split-topology node on a DPS transport mode

Per-cluster mesh Phase 6 (Task 5). A node carrying a cluster-{ClusterId}
role (RoleParser.IsClusterRole) is in the split topology, where the
Phase 2/3/5 DPS dark-switch branches deliver nothing across the mesh
boundary. SplitTopologyTransportValidator fails host start unless such a
node uses the mesh-crossing transports: MeshTransport:Mode=ClusterClient
always; Telemetry:Mode=Grpc if it has the driver role; TelemetryDial:Mode
=Grpc if it has the admin role. It is a no-op for any node with no
cluster-role (legacy / single-mesh / test). Roles + the three modes are
cross-read from IConfiguration, mirroring ConfigSourceOptionsValidator.
Registered via AddValidatedOptions on MeshTransportOptions with
ValidateOnStart, alongside the sibling validators.

Claude-Session: https://claude.ai/code/session_01GASWkNEi68FSCtvr6rLoEW
This commit is contained in:
Joseph Doherty
2026-07-24 02:13:47 -04:00
parent d98b32640b
commit a886d5e6e0
3 changed files with 312 additions and 0 deletions
@@ -56,6 +56,14 @@ public static class ServiceCollectionExtensions
services.AddValidatedOptions<TelemetryDialOptions, TelemetryDialOptionsValidator>(
configuration, TelemetryDialOptions.SectionName);
// Per-cluster mesh Phase 6: a node carrying a cluster-{ClusterId} role (the split topology)
// must use the mesh-crossing transports — the DPS dark-switch branches cannot cross a split
// mesh and would deliver nothing silently. Hung on MeshTransportOptions (which already has
// ValidateOnStart from its own registration above) so it fires at boot alongside the sibling
// validators; TryAddEnumerable inside AddValidatedOptions keeps the second validator additive.
services.AddValidatedOptions<MeshTransportOptions, SplitTopologyTransportValidator>(
configuration, MeshTransportOptions.SectionName);
services.AddSingleton<IClusterRoleInfo, ClusterRoleInfo>();
return services;