mirror of
https://github.com/MAKS-IT-COM/maksit-certs-ui.git
synced 2025-12-31 12:10:03 +01:00
(feature): implementing cache persistance
This commit is contained in:
parent
a661489b4f
commit
4359d317c0
@ -12,6 +12,13 @@ public class CertificateCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class RegistrationCache {
|
public class RegistrationCache {
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Field used to identify cache by account id
|
||||||
|
/// </summary>
|
||||||
|
public Guid AccountId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public Dictionary<string, CertificateCache>? CachedCerts { get; set; }
|
public Dictionary<string, CertificateCache>? CachedCerts { get; set; }
|
||||||
public byte[]? AccountKey { get; set; }
|
public byte[]? AccountKey { get; set; }
|
||||||
public string? Id { get; set; }
|
public string? Id { get; set; }
|
||||||
|
|||||||
@ -17,8 +17,8 @@ namespace MaksIT.LetsEncrypt.Services;
|
|||||||
|
|
||||||
public interface ILetsEncryptService {
|
public interface ILetsEncryptService {
|
||||||
Task<IDomainResult> ConfigureClient(Guid sessionId, string url);
|
Task<IDomainResult> ConfigureClient(Guid sessionId, string url);
|
||||||
Task<IDomainResult> Init(Guid sessionId, string[] contacts, RegistrationCache? registrationCache);
|
Task<IDomainResult> Init(Guid sessionId,Guid accountId, string[] contacts, RegistrationCache? registrationCache);
|
||||||
RegistrationCache? GetRegistrationCache(Guid sessionId);
|
(RegistrationCache?, IDomainResult) GetRegistrationCache(Guid sessionId);
|
||||||
(string?, IDomainResult) GetTermsOfServiceUri(Guid sessionId);
|
(string?, IDomainResult) GetTermsOfServiceUri(Guid sessionId);
|
||||||
Task<(Dictionary<string, string>?, IDomainResult)> NewOrder(Guid sessionId, string[] hostnames, string challengeType);
|
Task<(Dictionary<string, string>?, IDomainResult)> NewOrder(Guid sessionId, string[] hostnames, string challengeType);
|
||||||
Task<IDomainResult> CompleteChallenges(Guid sessionId);
|
Task<IDomainResult> CompleteChallenges(Guid sessionId);
|
||||||
@ -30,7 +30,7 @@ public interface ILetsEncryptService {
|
|||||||
public class LetsEncryptService : ILetsEncryptService {
|
public class LetsEncryptService : ILetsEncryptService {
|
||||||
private readonly ILogger<LetsEncryptService> _logger;
|
private readonly ILogger<LetsEncryptService> _logger;
|
||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly IMemoryCache _cache;
|
private readonly IMemoryCache _memoryCache;
|
||||||
|
|
||||||
public LetsEncryptService(
|
public LetsEncryptService(
|
||||||
ILogger<LetsEncryptService> logger,
|
ILogger<LetsEncryptService> logger,
|
||||||
@ -38,13 +38,13 @@ public class LetsEncryptService : ILetsEncryptService {
|
|||||||
IMemoryCache cache) {
|
IMemoryCache cache) {
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_cache = cache;
|
_memoryCache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
private State GetOrCreateState(Guid sessionId) {
|
private State GetOrCreateState(Guid sessionId) {
|
||||||
if (!_cache.TryGetValue(sessionId, out State state)) {
|
if (!_memoryCache.TryGetValue(sessionId, out State state)) {
|
||||||
state = new State();
|
state = new State();
|
||||||
_cache.Set(sessionId, state, TimeSpan.FromHours(1));
|
_memoryCache.Set(sessionId, state, TimeSpan.FromHours(1));
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ public class LetsEncryptService : ILetsEncryptService {
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Init
|
#region Init
|
||||||
public async Task<IDomainResult> Init(Guid sessionId, string[] contacts, RegistrationCache? cache) {
|
public async Task<IDomainResult> Init(Guid sessionId, Guid accountId, string[] contacts, RegistrationCache? cache) {
|
||||||
if (sessionId == Guid.Empty) {
|
if (sessionId == Guid.Empty) {
|
||||||
_logger.LogError("Invalid sessionId");
|
_logger.LogError("Invalid sessionId");
|
||||||
return IDomainResult.Failed();
|
return IDomainResult.Failed();
|
||||||
@ -119,6 +119,8 @@ public class LetsEncryptService : ILetsEncryptService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.Cache = new RegistrationCache {
|
state.Cache = new RegistrationCache {
|
||||||
|
AccountId = accountId,
|
||||||
|
|
||||||
Location = account.Result.Location,
|
Location = account.Result.Location,
|
||||||
AccountKey = accountKey.ExportCspBlob(true),
|
AccountKey = accountKey.ExportCspBlob(true),
|
||||||
Id = account.Result.Id,
|
Id = account.Result.Id,
|
||||||
@ -135,12 +137,15 @@ public class LetsEncryptService : ILetsEncryptService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public RegistrationCache? GetRegistrationCache(Guid sessionId) {
|
public (RegistrationCache?, IDomainResult) GetRegistrationCache(Guid sessionId) {
|
||||||
var state = GetOrCreateState(sessionId);
|
var state = GetOrCreateState(sessionId);
|
||||||
return state.Cache;
|
|
||||||
|
if(state?.Cache == null)
|
||||||
|
return IDomainResult.Failed<RegistrationCache?>();
|
||||||
|
|
||||||
|
return IDomainResult.Success(state.Cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region GetTermsOfService
|
#region GetTermsOfService
|
||||||
|
|||||||
18
src/LetsEncryptServer/BackgroundServices/AutoRenewal.cs
Normal file
18
src/LetsEncryptServer/BackgroundServices/AutoRenewal.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
namespace LetsEncryptServer.BackgroundServices {
|
||||||
|
public class AutoRenewal : BackgroundService {
|
||||||
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
|
||||||
|
while (!stoppingToken.IsCancellationRequested) {
|
||||||
|
// Your background task logic here
|
||||||
|
Console.WriteLine("Background service is running.");
|
||||||
|
|
||||||
|
// Simulate some work by delaying for 5 seconds
|
||||||
|
await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Task StopAsync(CancellationToken stoppingToken) {
|
||||||
|
Console.WriteLine("Background service is stopping.");
|
||||||
|
return base.StopAsync(stoppingToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -27,6 +27,7 @@ builder.Services.AddMemoryCache();
|
|||||||
|
|
||||||
builder.Services.AddHttpClient<ILetsEncryptService, LetsEncryptService>();
|
builder.Services.AddHttpClient<ILetsEncryptService, LetsEncryptService>();
|
||||||
builder.Services.AddScoped<ICertsFlowService, CertsFlowService>();
|
builder.Services.AddScoped<ICertsFlowService, CertsFlowService>();
|
||||||
|
builder.Services.AddSingleton<ICacheService, CacheService>();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
|||||||
123
src/LetsEncryptServer/Services/CacheService.cs
Normal file
123
src/LetsEncryptServer/Services/CacheService.cs
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
using DomainResults.Common;
|
||||||
|
|
||||||
|
using MaksIT.LetsEncrypt.Entities;
|
||||||
|
|
||||||
|
namespace MaksIT.LetsEncryptServer.Services;
|
||||||
|
|
||||||
|
public interface ICacheService {
|
||||||
|
Task<(RegistrationCache?, IDomainResult)> LoadFromCacheAsync(Guid accountId);
|
||||||
|
Task<IDomainResult> SaveToCacheAsync(Guid accountId, RegistrationCache cache);
|
||||||
|
Task<IDomainResult> DeleteFromCacheAsync(Guid accountId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CacheService : ICacheService, IDisposable {
|
||||||
|
|
||||||
|
private readonly ILogger<CacheService> _logger;
|
||||||
|
private readonly string _cacheDirectory;
|
||||||
|
private readonly SemaphoreSlim _cacheLock = new SemaphoreSlim(1, 1);
|
||||||
|
|
||||||
|
public CacheService(
|
||||||
|
ILogger<CacheService> logger
|
||||||
|
) {
|
||||||
|
_logger = logger;
|
||||||
|
_cacheDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "cache");
|
||||||
|
|
||||||
|
if (!Directory.Exists(_cacheDirectory)) {
|
||||||
|
Directory.CreateDirectory(_cacheDirectory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetCacheFilePath(Guid accountId) {
|
||||||
|
return Path.Combine(_cacheDirectory, $"{accountId}.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<(RegistrationCache?, IDomainResult)> LoadFromCacheAsync(Guid accountId) {
|
||||||
|
var cacheFilePath = GetCacheFilePath(accountId);
|
||||||
|
|
||||||
|
await _cacheLock.WaitAsync();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!File.Exists(cacheFilePath)) {
|
||||||
|
var message = $"Cache file not found for account {accountId}";
|
||||||
|
_logger.LogWarning(message);
|
||||||
|
|
||||||
|
return IDomainResult.Failed<RegistrationCache>(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
var json = await File.ReadAllTextAsync(cacheFilePath);
|
||||||
|
if (string.IsNullOrEmpty(json)) {
|
||||||
|
var message = $"Cache file is empty for account {accountId}";
|
||||||
|
_logger.LogWarning(message);
|
||||||
|
|
||||||
|
return IDomainResult.Failed<RegistrationCache>(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
var cache = JsonSerializer.Deserialize<RegistrationCache>(json);
|
||||||
|
return IDomainResult.Success(cache);
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
var message = "Error reading cache file for account {accountId}";
|
||||||
|
_logger.LogError(ex, message);
|
||||||
|
|
||||||
|
return IDomainResult.Failed<RegistrationCache?>(message);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
_cacheLock.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IDomainResult> SaveToCacheAsync(Guid accountId, RegistrationCache cache) {
|
||||||
|
var cacheFilePath = GetCacheFilePath(accountId);
|
||||||
|
await _cacheLock.WaitAsync();
|
||||||
|
|
||||||
|
try {
|
||||||
|
var json = JsonSerializer.Serialize(cache);
|
||||||
|
await File.WriteAllTextAsync(cacheFilePath, json);
|
||||||
|
|
||||||
|
_logger.LogInformation($"Cache file saved for account {accountId}");
|
||||||
|
|
||||||
|
return DomainResult.Success();
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
var message = "Error writing cache file for account {accountId}";
|
||||||
|
_logger.LogError(ex, message);
|
||||||
|
|
||||||
|
return IDomainResult.Failed(message);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
_cacheLock.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IDomainResult> DeleteFromCacheAsync(Guid accountId) {
|
||||||
|
var cacheFilePath = GetCacheFilePath(accountId);
|
||||||
|
await _cacheLock.WaitAsync();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (File.Exists(cacheFilePath)) {
|
||||||
|
File.Delete(cacheFilePath);
|
||||||
|
_logger.LogInformation($"Cache file deleted for account {accountId}");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_logger.LogWarning($"Cache file not found for account {accountId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return IDomainResult.Success();
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
var message = $"Error deleting cache file for account {accountId}";
|
||||||
|
_logger.LogError(ex, message);
|
||||||
|
|
||||||
|
return IDomainResult.Failed(message);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
_cacheLock.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose() {
|
||||||
|
_cacheLock?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -32,17 +32,22 @@ public class CertsFlowService : ICertsFlowService {
|
|||||||
private readonly Configuration _appSettings;
|
private readonly Configuration _appSettings;
|
||||||
private readonly ILogger<CertsFlowService> _logger;
|
private readonly ILogger<CertsFlowService> _logger;
|
||||||
private readonly ILetsEncryptService _letsEncryptService;
|
private readonly ILetsEncryptService _letsEncryptService;
|
||||||
private readonly string _acmePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "acme");
|
private readonly ICacheService _cacheService;
|
||||||
|
|
||||||
|
private readonly string _acmePath;
|
||||||
|
|
||||||
public CertsFlowService(
|
public CertsFlowService(
|
||||||
IOptions<Configuration> appSettings,
|
IOptions<Configuration> appSettings,
|
||||||
ILogger<CertsFlowService> logger,
|
ILogger<CertsFlowService> logger,
|
||||||
ILetsEncryptService letsEncryptService
|
ILetsEncryptService letsEncryptService,
|
||||||
|
ICacheService cashService
|
||||||
) {
|
) {
|
||||||
_appSettings = appSettings.Value;
|
_appSettings = appSettings.Value;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_letsEncryptService = letsEncryptService;
|
_letsEncryptService = letsEncryptService;
|
||||||
|
_cacheService = cashService;
|
||||||
|
|
||||||
|
_acmePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "acme");
|
||||||
if (!Directory.Exists(_acmePath))
|
if (!Directory.Exists(_acmePath))
|
||||||
Directory.CreateDirectory(_acmePath);
|
Directory.CreateDirectory(_acmePath);
|
||||||
}
|
}
|
||||||
@ -70,12 +75,22 @@ public class CertsFlowService : ICertsFlowService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(Guid?, IDomainResult)> InitAsync(Guid sessionId, Guid? accountId, InitRequest requestData) {
|
public async Task<(Guid?, IDomainResult)> InitAsync(Guid sessionId, Guid? accountId, InitRequest requestData) {
|
||||||
var cache = default(RegistrationCache);
|
RegistrationCache? cache = null;
|
||||||
|
|
||||||
if (accountId == null) {
|
if (accountId == null) {
|
||||||
accountId = Guid.NewGuid();
|
accountId = Guid.NewGuid();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
var (loadedCache, loadCaceResutl) = await _cacheService.LoadFromCacheAsync(accountId.Value);
|
||||||
|
if (!loadCaceResutl.IsSuccess || loadCaceResutl == null) {
|
||||||
|
accountId = Guid.NewGuid();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cache = loadedCache;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var result = await _letsEncryptService.Init(sessionId, requestData.Contacts, cache);
|
var result = await _letsEncryptService.Init(sessionId, accountId.Value, requestData.Contacts, cache);
|
||||||
return result.IsSuccess ? IDomainResult.Success<Guid>(accountId.Value) : (null, result);
|
return result.IsSuccess ? IDomainResult.Success<Guid>(accountId.Value) : (null, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,6 +126,15 @@ public class CertsFlowService : ICertsFlowService {
|
|||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Persist the cache
|
||||||
|
var (cache, getCacheResult) = _letsEncryptService.GetRegistrationCache(sessionId);
|
||||||
|
if (!getCacheResult.IsSuccess || cache == null)
|
||||||
|
return getCacheResult;
|
||||||
|
|
||||||
|
var saveResult = await _cacheService.SaveToCacheAsync(cache.AccountId, cache);
|
||||||
|
if(!saveResult.IsSuccess)
|
||||||
|
return saveResult;
|
||||||
|
|
||||||
return IDomainResult.Success();
|
return IDomainResult.Success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,98 +202,9 @@ public class CertsFlowService : ICertsFlowService {
|
|||||||
return IDomainResult.Success();
|
return IDomainResult.Success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
abort ssl cert <certfile> : abort a transaction for a certificate file
|
|
||||||
add acl [@<ver>] <acl> <pattern> : add an acl entry
|
|
||||||
add map [@<ver>] <map> <key> <val> : add a map entry (payload supported instead of key/val)
|
|
||||||
add ssl crt-list <list> <cert> [opts]* : add to crt-list file <list> a line <cert> or a payload
|
|
||||||
clear acl [@<ver>] <acl> : clear the contents of this acl
|
|
||||||
clear counters [all] : clear max statistics counters (or all counters)
|
|
||||||
clear map [@<ver>] <map> : clear the contents of this map
|
|
||||||
clear table <table> [<filter>]* : remove an entry from a table (filter: data/key)
|
|
||||||
commit acl @<ver> <acl> : commit the ACL at this version
|
|
||||||
commit map @<ver> <map> : commit the map at this version
|
|
||||||
commit ssl cert <certfile> : commit a certificate file
|
|
||||||
del acl <acl> [<key>|#<ref>] : delete acl entries matching <key>
|
|
||||||
del map <map> [<key>|#<ref>] : delete map entries matching <key>
|
|
||||||
del ssl cert <certfile> : delete an unused certificate file
|
|
||||||
del ssl crt-list <list> <cert[:line]> : delete a line <cert> from crt-list file <list>
|
|
||||||
disable agent : disable agent checks
|
|
||||||
disable dynamic-cookie backend <bk> : disable dynamic cookies on a specific backend
|
|
||||||
disable frontend <frontend> : temporarily disable specific frontend
|
|
||||||
disable health : disable health checks
|
|
||||||
disable server (DEPRECATED) : disable a server for maintenance (use 'set server' instead)
|
|
||||||
enable agent : enable agent checks
|
|
||||||
enable dynamic-cookie backend <bk> : enable dynamic cookies on a specific backend
|
|
||||||
enable frontend <frontend> : re-enable specific frontend
|
|
||||||
enable health : enable health checks
|
|
||||||
enable server (DEPRECATED) : enable a disabled server (use 'set server' instead)
|
|
||||||
get acl <acl> <value> : report the patterns matching a sample for an ACL
|
|
||||||
get map <acl> <value> : report the keys and values matching a sample for a map
|
|
||||||
get var <name> : retrieve contents of a process-wide variable
|
|
||||||
get weight <bk>/<srv> : report a server's current weight
|
|
||||||
new ssl cert <certfile> : create a new certificate file to be used in a crt-list or a directory
|
|
||||||
operator : lower the level of the current CLI session to operator
|
|
||||||
prepare acl <acl> : prepare a new version for atomic ACL replacement
|
|
||||||
prepare map <acl> : prepare a new version for atomic map replacement
|
|
||||||
set dynamic-cookie-key backend <bk> <k> : change a backend secret key for dynamic cookies
|
|
||||||
set map <map> [<key>|#<ref>] <value> : modify a map entry
|
|
||||||
set maxconn frontend <frontend> <value> : change a frontend's maxconn setting
|
|
||||||
set maxconn global <value> : change the per-process maxconn setting
|
|
||||||
set maxconn server <bk>/<srv> : change a server's maxconn setting
|
|
||||||
set profiling <what> {auto|on|off} : enable/disable resource profiling (tasks,memory)
|
|
||||||
set rate-limit <setting> <value> : change a rate limiting value
|
|
||||||
set server <bk>/<srv> [opts] : change a server's state, weight, address or ssl
|
|
||||||
set severity-output [none|number|string]: set presence of severity level in feedback information
|
|
||||||
set ssl cert <certfile> <payload> : replace a certificate file
|
|
||||||
set ssl ocsp-response <resp|payload> : update a certificate's OCSP Response from a base64-encode DER
|
|
||||||
set ssl tls-key [id|file] <key> : set the next TLS key for the <id> or <file> listener to <key>
|
|
||||||
set table <table> key <k> [data.* <v>]* : update or create a table entry's data
|
|
||||||
set timeout [cli] <delay> : change a timeout setting
|
|
||||||
set weight <bk>/<srv> (DEPRECATED) : change a server's weight (use 'set server' instead)
|
|
||||||
show acl [@<ver>] <acl>] : report available acls or dump an acl's contents
|
|
||||||
show activity : show per-thread activity stats (for support/developers)
|
|
||||||
show backend : list backends in the current running config
|
|
||||||
show cache : show cache status
|
|
||||||
show cli level : display the level of the current CLI session
|
|
||||||
show cli sockets : dump list of cli sockets
|
|
||||||
show env [var] : dump environment variables known to the process
|
|
||||||
show errors [<px>] [request|response] : report last request and/or response errors for each proxy
|
|
||||||
show events [<sink>] [-w] [-n] : show event sink state
|
|
||||||
show fd [num] : dump list of file descriptors in use or a specific one
|
|
||||||
show info [desc|json|typed|float]* : report information about the running process
|
|
||||||
show libs : show loaded object files and libraries
|
|
||||||
show map [@ver] [map] : report available maps or dump a map's contents
|
|
||||||
show peers [dict|-] [section] : dump some information about all the peers or this peers section
|
|
||||||
show pools : report information about the memory pools usage
|
|
||||||
show profiling [<what>|<#lines>|byaddr]*: show profiling state (all,status,tasks,memory)
|
|
||||||
show resolvers [id] : dumps counters from all resolvers section and associated name servers
|
|
||||||
show schema json : report schema used for stats
|
|
||||||
show servers conn [<backend>] : dump server connections status (all or for a single backend)
|
|
||||||
show servers state [<backend>] : dump volatile server information (all or for a single backend)
|
|
||||||
show sess [id] : report the list of current sessions or dump this exact session
|
|
||||||
show ssl cert [<certfile>] : display the SSL certificates used in memory, or the details of a file
|
|
||||||
show ssl crt-list [-n] [<list>] : show the list of crt-lists or the content of a crt-list file <list>
|
|
||||||
show startup-logs : report logs emitted during HAProxy startup
|
|
||||||
show stat [desc|json|no-maint|typed|up]*: report counters for each proxy and server
|
|
||||||
show table <table> [<filter>]* : report table usage stats or dump this table's contents (filter: data/key)
|
|
||||||
show tasks : show running tasks
|
|
||||||
show threads : show some threads debugging information
|
|
||||||
show tls-keys [id|*] : show tls keys references or dump tls ticket keys when id specified
|
|
||||||
show trace [<module>] : show live tracing state
|
|
||||||
show version : show version of the current process
|
|
||||||
shutdown frontend <frontend> : stop a specific frontend
|
|
||||||
shutdown session [id] : kill a specific session
|
|
||||||
shutdown sessions server <bk>/<srv> : kill sessions on a server
|
|
||||||
trace [<module>|0] [cmd [args...]] : manage live tracing (empty to list, 0 to stop all)
|
|
||||||
user : lower the level of the current CLI session to user
|
|
||||||
help [<command>] : list matching or all commands
|
|
||||||
prompt : toggle interactive mode with prompt
|
|
||||||
quit : disconnect
|
|
||||||
*/
|
|
||||||
private IDomainResult NotifyHaproxy(IEnumerable<string> certFiles) {
|
private IDomainResult NotifyHaproxy(IEnumerable<string> certFiles) {
|
||||||
var server = _appSettings.Server;
|
var server = _appSettings.Server;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
using (var client = new TcpClient(server.Ip, server.SocketPort))
|
using (var client = new TcpClient(server.Ip, server.SocketPort))
|
||||||
using (var networkStream = client.GetStream())
|
using (var networkStream = client.GetStream())
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user