83 lines
3.6 KiB
C#
83 lines
3.6 KiB
C#
using FinalFactory.Rendezvous.Contracts;
|
|
using FinalFactory.Rendezvous.Server.Observability;
|
|
using FinalFactory.Rendezvous.Server.Provisioning;
|
|
using FinalFactory.Rendezvous.Server.State;
|
|
|
|
namespace FinalFactory.Rendezvous.Server.Operations;
|
|
|
|
internal sealed class OperatorService(
|
|
InMemoryEphemeralRendezvousStore store,
|
|
ProvisioningRuntime provisioning,
|
|
RendezvousReadiness readiness,
|
|
AuditTrail audit,
|
|
IWallClock clock)
|
|
{
|
|
public OperatorStatusResponse GetStatus()
|
|
{
|
|
ReadinessSnapshot readinessSnapshot = readiness.GetSnapshot();
|
|
EphemeralStoreSnapshot storeSnapshot = store.GetSnapshot();
|
|
return new OperatorStatusResponse
|
|
{
|
|
Status = readinessSnapshot.IsReady ? "ready" : "not-ready",
|
|
Compatibility = ReleaseCompatibility.CreateResponse(),
|
|
Readiness = new OperatorReadinessResponse
|
|
{
|
|
HttpListener = readinessSnapshot.HttpListenerReady,
|
|
UdpIpv4Listener = readinessSnapshot.UdpIpv4ListenerReady,
|
|
UdpIpv6Listener = readinessSnapshot.UdpIpv6ListenerReady,
|
|
Provisioning = readinessSnapshot.ProvisioningReady,
|
|
Store = readinessSnapshot.StoreAvailable,
|
|
Draining = readinessSnapshot.Draining,
|
|
},
|
|
Store = new OperatorStoreResponse
|
|
{
|
|
ActiveListings = storeSnapshot.ActiveListings,
|
|
FreshPresenceBindings = storeSnapshot.FreshPresenceBindings,
|
|
ActiveJoinAttempts = storeSnapshot.ActiveJoinAttempts,
|
|
RetainedOutcomeReports = storeSnapshot.RetainedOutcomeReports,
|
|
ReplayMarkers = storeSnapshot.ReplayMarkers,
|
|
PrincipalRevocations = storeSnapshot.PrincipalRevocations,
|
|
IdempotencyEntries = storeSnapshot.IdempotencyEntries,
|
|
MaintenanceSweeps = storeSnapshot.MaintenanceSweeps,
|
|
ExpiryChurn = storeSnapshot.ExpiryChurn,
|
|
},
|
|
Tenants = provisioning.Policies.EnabledPolicies
|
|
.OrderBy(static policy => policy.GameId.Value, StringComparer.Ordinal)
|
|
.ThenBy(static policy => policy.EnvironmentId.Value, StringComparer.Ordinal)
|
|
.Select(static policy => new OperatorTenantResponse
|
|
{
|
|
GameId = policy.GameId.Value,
|
|
EnvironmentId = policy.EnvironmentId.Value,
|
|
Status = "enabled",
|
|
})
|
|
.ToArray(),
|
|
SigningKeys = provisioning.SigningKeys.GetStatuses(clock.UtcNow)
|
|
.Select(static key => new OperatorSigningKeyResponse
|
|
{
|
|
KeyId = key.KeyId,
|
|
Status = key.Status,
|
|
SignUntil = key.SignUntil,
|
|
VerifyUntil = key.VerifyUntil,
|
|
GameId = key.GameId,
|
|
EnvironmentId = key.EnvironmentId,
|
|
CredentialKinds = key.CredentialKinds,
|
|
})
|
|
.ToArray(),
|
|
AuditCounts = audit.GetAggregateCounts(),
|
|
};
|
|
}
|
|
|
|
public StoreResult<bool> RevokeListing(
|
|
SessionListingId listingId,
|
|
CancellationToken cancellationToken) => store.RevokeListing(listingId, cancellationToken);
|
|
|
|
public StoreResult<int> RevokePrincipal(
|
|
string subject,
|
|
TimeSpan lifetime,
|
|
CancellationToken cancellationToken) => store.RevokePrincipal(subject, lifetime, cancellationToken);
|
|
|
|
public bool RevokeSigningKey(string keyId) => provisioning.SigningKeys.Revoke(keyId);
|
|
|
|
public void BeginDrain(CancellationToken cancellationToken) => store.BeginDrain(cancellationToken);
|
|
}
|