Merge origin/main with local pending work and update AGENTS.md references
- Resolve 14 conflicts from popping local stash on top of origin'seed1e88+8d3352fdoc-comment additions (11 mechanical, plus version.rs, DashboardAuthenticatorTests.cs, DashboardGalaxyProjector.cs) - Fix 4 test files that used AGENTS.md as the repo-root sentinel (now use CLAUDE.md, since AGENTS.md was removed in4731ab5) - Redirect 10 doc citations from AGENTS.md to the matching gateway.md sections (Value Model, Status Model, Security, STA Worker Thread Model, gRPC Layer rule, cancellation rule) Verified: solution build clean, x86 worker build clean, 266/266 gateway tests passing, 121/121 worker tests passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ namespace MxGateway.Server.Configuration;
|
||||
|
||||
public sealed record EffectiveGatewayConfiguration(
|
||||
EffectiveAuthenticationConfiguration Authentication,
|
||||
EffectiveLdapConfiguration Ldap,
|
||||
EffectiveWorkerConfiguration Worker,
|
||||
EffectiveSessionConfiguration Sessions,
|
||||
EffectiveEventConfiguration Events,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
namespace MxGateway.Server.Configuration;
|
||||
|
||||
public sealed record EffectiveProtocolConfiguration(uint WorkerProtocolVersion);
|
||||
public sealed record EffectiveProtocolConfiguration(
|
||||
uint WorkerProtocolVersion,
|
||||
int MaxGrpcMessageBytes);
|
||||
|
||||
@@ -3,4 +3,7 @@ namespace MxGateway.Server.Configuration;
|
||||
public sealed record EffectiveSessionConfiguration(
|
||||
int DefaultCommandTimeoutSeconds,
|
||||
int MaxSessions,
|
||||
int MaxPendingCommandsPerSession,
|
||||
int DefaultLeaseSeconds,
|
||||
int LeaseSweepIntervalSeconds,
|
||||
bool AllowMultipleEventSubscribers);
|
||||
|
||||
@@ -19,6 +19,19 @@ public sealed class GatewayConfigurationProvider(IOptions<GatewayOptions> option
|
||||
SqlitePath: value.Authentication.SqlitePath,
|
||||
PepperSecretName: RedactedValue,
|
||||
RunMigrationsOnStartup: value.Authentication.RunMigrationsOnStartup),
|
||||
Ldap: new EffectiveLdapConfiguration(
|
||||
Enabled: value.Ldap.Enabled,
|
||||
Server: value.Ldap.Server,
|
||||
Port: value.Ldap.Port,
|
||||
UseTls: value.Ldap.UseTls,
|
||||
AllowInsecureLdap: value.Ldap.AllowInsecureLdap,
|
||||
SearchBase: value.Ldap.SearchBase,
|
||||
ServiceAccountDn: value.Ldap.ServiceAccountDn,
|
||||
ServiceAccountPassword: RedactedValue,
|
||||
UserNameAttribute: value.Ldap.UserNameAttribute,
|
||||
DisplayNameAttribute: value.Ldap.DisplayNameAttribute,
|
||||
GroupAttribute: value.Ldap.GroupAttribute,
|
||||
RequiredGroup: value.Ldap.RequiredGroup),
|
||||
Worker: new EffectiveWorkerConfiguration(
|
||||
ExecutablePath: value.Worker.ExecutablePath,
|
||||
WorkingDirectory: value.Worker.WorkingDirectory,
|
||||
@@ -31,6 +44,9 @@ public sealed class GatewayConfigurationProvider(IOptions<GatewayOptions> option
|
||||
Sessions: new EffectiveSessionConfiguration(
|
||||
DefaultCommandTimeoutSeconds: value.Sessions.DefaultCommandTimeoutSeconds,
|
||||
MaxSessions: value.Sessions.MaxSessions,
|
||||
MaxPendingCommandsPerSession: value.Sessions.MaxPendingCommandsPerSession,
|
||||
DefaultLeaseSeconds: value.Sessions.DefaultLeaseSeconds,
|
||||
LeaseSweepIntervalSeconds: value.Sessions.LeaseSweepIntervalSeconds,
|
||||
AllowMultipleEventSubscribers: value.Sessions.AllowMultipleEventSubscribers),
|
||||
Events: new EffectiveEventConfiguration(
|
||||
QueueCapacity: value.Events.QueueCapacity,
|
||||
@@ -44,6 +60,8 @@ public sealed class GatewayConfigurationProvider(IOptions<GatewayOptions> option
|
||||
RecentFaultLimit: value.Dashboard.RecentFaultLimit,
|
||||
RecentSessionLimit: value.Dashboard.RecentSessionLimit,
|
||||
ShowTagValues: value.Dashboard.ShowTagValues),
|
||||
Protocol: new EffectiveProtocolConfiguration(value.Protocol.WorkerProtocolVersion));
|
||||
Protocol: new EffectiveProtocolConfiguration(
|
||||
value.Protocol.WorkerProtocolVersion,
|
||||
value.Protocol.MaxGrpcMessageBytes));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ public sealed class GatewayOptions
|
||||
/// </summary>
|
||||
public AuthenticationOptions Authentication { get; init; } = new();
|
||||
|
||||
public LdapOptions Ldap { get; init; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets worker process configuration options.
|
||||
/// </summary>
|
||||
|
||||
@@ -19,6 +19,7 @@ public sealed class GatewayOptionsValidator : IValidateOptions<GatewayOptions>
|
||||
List<string> failures = [];
|
||||
|
||||
ValidateAuthentication(options.Authentication, failures);
|
||||
ValidateLdap(options.Ldap, failures);
|
||||
ValidateWorker(options.Worker, failures);
|
||||
ValidateSessions(options.Sessions, failures);
|
||||
ValidateEvents(options.Events, failures);
|
||||
@@ -55,6 +56,47 @@ public sealed class GatewayOptionsValidator : IValidateOptions<GatewayOptions>
|
||||
}
|
||||
}
|
||||
|
||||
private static void ValidateLdap(LdapOptions options, List<string> failures)
|
||||
{
|
||||
if (!options.Enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AddIfBlank(options.Server, "MxGateway:Ldap:Server is required when LDAP login is enabled.", failures);
|
||||
AddIfBlank(options.SearchBase, "MxGateway:Ldap:SearchBase is required when LDAP login is enabled.", failures);
|
||||
AddIfBlank(
|
||||
options.ServiceAccountDn,
|
||||
"MxGateway:Ldap:ServiceAccountDn is required when LDAP login is enabled.",
|
||||
failures);
|
||||
AddIfBlank(
|
||||
options.ServiceAccountPassword,
|
||||
"MxGateway:Ldap:ServiceAccountPassword is required when LDAP login is enabled.",
|
||||
failures);
|
||||
AddIfBlank(
|
||||
options.UserNameAttribute,
|
||||
"MxGateway:Ldap:UserNameAttribute is required when LDAP login is enabled.",
|
||||
failures);
|
||||
AddIfBlank(
|
||||
options.DisplayNameAttribute,
|
||||
"MxGateway:Ldap:DisplayNameAttribute is required when LDAP login is enabled.",
|
||||
failures);
|
||||
AddIfBlank(
|
||||
options.GroupAttribute,
|
||||
"MxGateway:Ldap:GroupAttribute is required when LDAP login is enabled.",
|
||||
failures);
|
||||
AddIfBlank(
|
||||
options.RequiredGroup,
|
||||
"MxGateway:Ldap:RequiredGroup is required when LDAP login is enabled.",
|
||||
failures);
|
||||
AddIfNotPositive(options.Port, "MxGateway:Ldap:Port must be greater than zero.", failures);
|
||||
|
||||
if (!options.UseTls && !options.AllowInsecureLdap)
|
||||
{
|
||||
failures.Add("MxGateway:Ldap:AllowInsecureLdap must be true when UseTls is false.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void ValidateWorker(WorkerOptions options, List<string> failures)
|
||||
{
|
||||
AddIfBlank(options.ExecutablePath, "MxGateway:Worker:ExecutablePath is required.", failures);
|
||||
@@ -135,6 +177,14 @@ public sealed class GatewayOptionsValidator : IValidateOptions<GatewayOptions>
|
||||
options.MaxPendingCommandsPerSession,
|
||||
"MxGateway:Sessions:MaxPendingCommandsPerSession must be greater than zero.",
|
||||
failures);
|
||||
AddIfNotPositive(
|
||||
options.DefaultLeaseSeconds,
|
||||
"MxGateway:Sessions:DefaultLeaseSeconds must be greater than zero.",
|
||||
failures);
|
||||
AddIfNotPositive(
|
||||
options.LeaseSweepIntervalSeconds,
|
||||
"MxGateway:Sessions:LeaseSweepIntervalSeconds must be greater than zero.",
|
||||
failures);
|
||||
|
||||
if (options.AllowMultipleEventSubscribers)
|
||||
{
|
||||
@@ -185,6 +235,12 @@ public sealed class GatewayOptionsValidator : IValidateOptions<GatewayOptions>
|
||||
failures.Add(
|
||||
$"MxGateway:Protocol:WorkerProtocolVersion must be {GatewayContractInfo.WorkerProtocolVersion}.");
|
||||
}
|
||||
|
||||
if (options.MaxGrpcMessageBytes is < MinimumMaxMessageBytes or > MaximumMaxMessageBytes)
|
||||
{
|
||||
failures.Add(
|
||||
$"MxGateway:Protocol:MaxGrpcMessageBytes must be between {MinimumMaxMessageBytes} and {MaximumMaxMessageBytes}.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddIfBlank(string? value, string message, List<string> failures)
|
||||
|
||||
@@ -11,4 +11,6 @@ public sealed class ProtocolOptions
|
||||
/// Gets or sets the worker protocol version.
|
||||
/// </summary>
|
||||
public uint WorkerProtocolVersion { get; init; } = GatewayContractInfo.WorkerProtocolVersion;
|
||||
|
||||
public int MaxGrpcMessageBytes { get; init; } = 16 * 1024 * 1024;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,10 @@ public sealed class SessionOptions
|
||||
/// </summary>
|
||||
public int MaxPendingCommandsPerSession { get; init; } = 128;
|
||||
|
||||
public int DefaultLeaseSeconds { get; init; } = 1800;
|
||||
|
||||
public int LeaseSweepIntervalSeconds { get; init; } = 30;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether multiple event subscribers are allowed per session.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user