Skip to content

Commit 0c1a35a

Browse files
Adds external certificate manager preferences
Adds support for enabling/disabling external certificate managers and setting config/log paths. Initializes certificate managers with provided configuration and logging, and adds default provider preferences if they don't already exist. Refreshes the externally managed certificate cache when certificate manager configuration changes.
1 parent 7a69130 commit 0c1a35a

File tree

7 files changed

+119
-6
lines changed

7 files changed

+119
-6
lines changed

src/Certify.Core/Management/CertifyManager/CertifyManager.ManagedCertificates.cs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ private async Task<List<ManagedCertificate>> GetExternallyManagedCertificates(Ma
8282
{
8383
List<ManagedCertificate> list = [];
8484

85+
var prefs = SettingsManager.ToPreferences();
86+
var providerAdded = false;
87+
8588
// check if we have any external sources of managed certificates
8689
foreach (var p in _pluginManager.CertificateManagerProviders)
8790
{
@@ -91,17 +94,42 @@ private async Task<List<ManagedCertificate>> GetExternallyManagedCertificates(Ma
9194
{
9295
var pluginType = p.GetType();
9396
var providers = p.GetProviders(pluginType);
97+
var loggerAdapter = new LogToILoggerAdapter(_serviceLog);
9498

9599
foreach (var cp in providers)
96100
{
97101
if (cp?.IsEnabled == true)
98102
{
99103
try
100104
{
101-
var certManager = p.GetProvider(pluginType, cp.Id);
102-
var certs = await certManager.GetManagedCertificates(filter);
105+
var providerPrefs = prefs.CertificateManagers.FirstOrDefault(c => c.Id == cp.Id);
106+
107+
if (providerPrefs?.IsEnabled == true || providerPrefs == null)
108+
{
109+
var certManager = p.GetProvider(pluginType, cp.Id);
110+
111+
// Initialize or use the certificate manager with the specified config and log paths
112+
113+
certManager.Init(loggerAdapter, providerPrefs);
103114

104-
list.AddRange(certs);
115+
var certs = await certManager.GetManagedCertificates(filter);
116+
117+
list.AddRange(certs);
118+
119+
if (providerPrefs == null)
120+
{
121+
//add a default provider prefs if not already present
122+
prefs.CertificateManagers.Add(new CertificateManagerPreference
123+
{
124+
Id = cp.Id,
125+
IsEnabled = true,
126+
ConfigPath = "",
127+
LogPath = ""
128+
});
129+
130+
providerAdded = true;
131+
}
132+
}
105133
}
106134
catch (Exception ex)
107135
{
@@ -126,6 +154,19 @@ private async Task<List<ManagedCertificate>> GetExternallyManagedCertificates(Ma
126154
// reset cache
127155
_externallyManagedCertificatesCache = list;
128156
}
157+
158+
if (providerAdded)
159+
{
160+
SettingsManager.FromPreferences(prefs);
161+
try
162+
{
163+
SettingsManager.SaveAppSettings();
164+
}
165+
catch (Exception ex)
166+
{
167+
_serviceLog.Error(ex, "Error saving preferences");
168+
}
169+
}
129170
}
130171

131172
_externallyManagedCacheUpdated = DateTimeOffset.UtcNow;
@@ -946,3 +987,4 @@ private async Task StopHttpChallengeServer()
946987
}
947988
}
948989
}
990+

src/Certify.Core/Management/CertifyManager/CertifyManager.ManagementHub.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,8 @@ public async Task<InstanceCommandResult> PerformHubCommandWithResult(InstanceCom
728728
prefs.RenewalIntervalMode = update.RenewalIntervalMode;
729729
prefs.UseModernPFXAlgs = update.UseModernPFXAlgs;
730730

731+
prefs.CertificateManagers = update.CertificateManagers;
732+
731733
SettingsManager.FromPreferences(prefs);
732734

733735
try
@@ -740,6 +742,9 @@ public async Task<InstanceCommandResult> PerformHubCommandWithResult(InstanceCom
740742
_serviceLog.Error(ex, "Error saving preferences");
741743
val = new ActionResult("Service core settings could not be updated.", false);
742744
}
745+
746+
// cert manager config may have changed, refresh required
747+
_externallyManagedCacheUpdated = DateTimeOffset.MinValue;
743748
}
744749
else
745750
{

src/Certify.Core/Management/SettingsManager.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.IO;
44
using Certify.Models;
5+
using Certify.Models.Config;
56

67
namespace Certify.Management
78
{
@@ -35,6 +36,7 @@ private CoreAppSettings()
3536
EnableExternalCertManagers = true;
3637
UseModernPFXAlgs = false;
3738
NtpServer = "pool.ntp.org";
39+
CertificateManagers = new List<CertificateManagerPreference>();
3840
}
3941

4042
public static CoreAppSettings Current
@@ -185,6 +187,8 @@ public static CoreAppSettings Current
185187
/// If true, ARI checks will not be performed during periodic maintenance
186188
/// </summary>
187189
public bool DisableARIChecks { get; set; }
190+
191+
public List<CertificateManagerPreference> CertificateManagers { get; set; } = new List<CertificateManagerPreference>();
188192
}
189193

190194
public class SettingsManager
@@ -244,6 +248,8 @@ public static bool FromPreferences(Models.Preferences prefs)
244248

245249
CoreAppSettings.Current.EnableIssuerCache = prefs.EnableIssuerCache;
246250

251+
CoreAppSettings.Current.CertificateManagers = prefs.CertificateManagers;
252+
247253
return true;
248254
}
249255

@@ -280,7 +286,8 @@ public static Models.Preferences ToPreferences()
280286
DefaultKeyType = CoreAppSettings.Current.DefaultKeyType,
281287
EnableParallelRenewals = CoreAppSettings.Current.EnableParallelRenewals,
282288
DisableARIChecks = CoreAppSettings.Current.DisableARIChecks,
283-
DefaultACMERetryInterval = CoreAppSettings.Current.DefaultACMERetryInterval
289+
DefaultACMERetryInterval = CoreAppSettings.Current.DefaultACMERetryInterval,
290+
CertificateManagers = CoreAppSettings.Current.CertificateManagers
284291
};
285292

286293
return prefs;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace Certify.Models.Config
2+
{
3+
public class CertificateManagerPreference
4+
{
5+
public string Id { get; set; }
6+
public bool IsEnabled { get; set; }
7+
public string ConfigPath { get; set; }
8+
public string LogPath { get; set; }
9+
}
10+
}

src/Certify.Models/Config/Preferences.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
namespace Certify.Models
1+
using System.Collections.Generic;
2+
using Certify.Models.Config;
3+
4+
namespace Certify.Models
25
{
36
public enum CertificateCleanupMode
47
{
@@ -134,6 +137,11 @@ public class Preferences : BindableBase
134137
/// If true, ARI checks will not be performed during periodic maintenance
135138
/// </summary>
136139
public bool DisableARIChecks { get; set; }
140+
141+
/// <summary>
142+
/// Preferences for external certificate managers (enable/disable, config/log paths)
143+
/// </summary>
144+
public List<CertificateManagerPreference> CertificateManagers { get; set; } = new List<CertificateManagerPreference>();
137145
}
138146

139147
public static class FeatureFlags

src/Certify.Models/Providers/ICertificateManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace Certify.Providers.CertificateManagers
1313
public interface ICertificateManager
1414
{
1515

16-
void Init(ILogger logger, string settingsPath = "", string logPath = "");
16+
void Init(ILogger logger, CertificateManagerPreference prefs);
1717

1818
Task<bool> IsPresent();
1919

src/Certify.Shared/Utils/Loggy.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using Certify.Models.Providers;
23
using Microsoft.Extensions.Logging;
34

45
namespace Certify.Models
@@ -24,4 +25,44 @@ public Loggy(ILogger log)
2425

2526
public void Warning(string template, params object[] propertyValues) => _log?.LogWarning(template, propertyValues);
2627
}
28+
29+
// Create an adapter class to convert ILog to ILogger
30+
public class LogToILoggerAdapter : ILogger
31+
{
32+
private readonly ILog _log;
33+
34+
public LogToILoggerAdapter(ILog log)
35+
{
36+
_log = log;
37+
}
38+
39+
public IDisposable BeginScope<TState>(TState state) => null;
40+
41+
public bool IsEnabled(LogLevel logLevel) => true;
42+
43+
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, string> formatter)
44+
{
45+
var message = formatter(state);
46+
47+
switch (logLevel)
48+
{
49+
case LogLevel.Critical:
50+
case LogLevel.Error:
51+
_log.Error(exception, message);
52+
break;
53+
case LogLevel.Warning:
54+
_log.Warning(message);
55+
break;
56+
case LogLevel.Information:
57+
_log.Information(message);
58+
break;
59+
case LogLevel.Debug:
60+
case LogLevel.Trace:
61+
_log.Debug(message);
62+
break;
63+
}
64+
}
65+
66+
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) => throw new NotImplementedException();
67+
}
2768
}

0 commit comments

Comments
 (0)