Skip to content

Commit 8645eff

Browse files
Moved DNS Resolving away from initialize
1 parent b0f7c77 commit 8645eff

1 file changed

Lines changed: 43 additions & 35 deletions

File tree

AcmeCaPlugin/AcmeCaPlugin.cs

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ public class AcmeCaPlugin : IAnyCAPlugin
6161
{
6262
private static readonly ILogger _logger = LogHandler.GetClassLogger<AcmeCaPlugin>();
6363
private IAnyCAPluginConfigProvider Config { get; set; }
64-
private IDomainValidator _domainValidator;
6564
private readonly IDomainValidatorFactory _validatorFactory;
6665

6766
// Constants for better maintainability
@@ -88,7 +87,7 @@ public void Initialize(IAnyCAPluginConfigProvider configProvider, ICertificateDa
8887
_logger.MethodEntry();
8988
Config = configProvider ?? throw new ArgumentNullException(nameof(configProvider));
9089

91-
// Factory is now required - all DNS providers are externalized as plugins
90+
// Validate that factory is available - validators will be resolved per-domain during enrollment
9291
if (_validatorFactory == null)
9392
{
9493
var errorMsg = "IDomainValidatorFactory is required. DNS providers are now loaded as external plugins. " +
@@ -97,28 +96,7 @@ public void Initialize(IAnyCAPluginConfigProvider configProvider, ICertificateDa
9796
throw new InvalidOperationException(errorMsg);
9897
}
9998

100-
_logger.LogInformation("Resolving domain validator from plugin system");
101-
102-
// Resolve domain validator from plugin system
103-
_domainValidator = _validatorFactory.ResolveDomainValidator(
104-
domain: "*", // Wildcard - let the factory choose based on configuration
105-
validationType: DNS_CHALLENGE_TYPE
106-
);
107-
108-
if (_domainValidator == null)
109-
{
110-
var errorMsg = $"Failed to resolve domain validator for type '{DNS_CHALLENGE_TYPE}'. " +
111-
"Ensure the appropriate DNS provider plugin is deployed and configured.";
112-
_logger.LogError(errorMsg);
113-
throw new InvalidOperationException(errorMsg);
114-
}
115-
116-
// Initialize the validator with configuration
117-
var domainValidatorConfig = new DomainValidatorConfigProvider(configProvider.CAConnectionData);
118-
_domainValidator.Initialize(domainValidatorConfig);
119-
120-
_logger.LogInformation("Successfully initialized domain validator from plugin: {ValidatorType}",
121-
_domainValidator.GetType().FullName);
99+
_logger.LogInformation("IDomainValidatorFactory available - domain validators will be resolved per-domain during enrollment");
122100

123101
_logger.MethodExit();
124102
}
@@ -527,9 +505,9 @@ private async Task ProcessAuthorizations(AcmeClient acmeClient, OrderDetails ord
527505
}
528506

529507
var dnsVerifier = new DnsVerificationHelper(_logger, config.DnsVerificationServer);
530-
var pendingChallenges = new List<(Authorization authz, Challenge challenge, Dns01ChallengeValidationDetails validation)>();
508+
var pendingChallenges = new List<(Authorization authz, Challenge challenge, Dns01ChallengeValidationDetails validation, IDomainValidator validator)>();
531509

532-
// First pass: Create all DNS records using IDomainValidator
510+
// First pass: Create all DNS records using per-domain IDomainValidator
533511
foreach (var authzUrl in payload.Authorizations)
534512
{
535513
var authz = await acmeClient.GetAuthorizationAsync(authzUrl);
@@ -548,23 +526,42 @@ private async Task ProcessAuthorizations(AcmeClient acmeClient, OrderDetails ord
548526
if (validation == null)
549527
throw new InvalidOperationException($"Failed to decode {DNS_CHALLENGE_TYPE} challenge validation details");
550528

551-
// Use IDomainValidator instead of DnsProviderFactory directly
552-
var result = await _domainValidator.StageValidation(
529+
// Resolve domain validator for this specific domain
530+
var domain = authz.Identifier.Value;
531+
_logger.LogInformation("Resolving domain validator for domain: {Domain}", domain);
532+
533+
var domainValidator = _validatorFactory.ResolveDomainValidator(domain, DNS_CHALLENGE_TYPE);
534+
if (domainValidator == null)
535+
{
536+
throw new InvalidOperationException(
537+
$"Failed to resolve domain validator for domain '{domain}'. " +
538+
"Ensure the appropriate DNS provider plugin is deployed and configured for this domain's zone.");
539+
}
540+
541+
// Initialize the validator with configuration
542+
var domainValidatorConfig = new DomainValidatorConfigProvider(Config.CAConnectionData);
543+
domainValidator.Initialize(domainValidatorConfig);
544+
545+
_logger.LogInformation("Using domain validator: {ValidatorType} for domain: {Domain}",
546+
domainValidator.GetType().Name, domain);
547+
548+
// Stage the DNS validation
549+
var result = await domainValidator.StageValidation(
553550
validation.DnsRecordName,
554551
validation.DnsRecordValue,
555552
CancellationToken.None);
556553

557554
if (!result.Success)
558-
throw new InvalidOperationException($"Failed to stage DNS validation: {result.ErrorMessage}");
555+
throw new InvalidOperationException($"Failed to stage DNS validation for {domain}: {result.ErrorMessage}");
559556

560557
_logger.LogInformation("Created DNS record {RecordName} for domain {Domain}",
561-
validation.DnsRecordName, authz.Identifier.Value);
558+
validation.DnsRecordName, domain);
562559

563-
pendingChallenges.Add((authz, challenge, validation));
560+
pendingChallenges.Add((authz, challenge, validation, domainValidator));
564561
}
565562

566563
// Second pass: Wait for DNS propagation and submit challenges
567-
foreach (var (authz, challenge, validation) in pendingChallenges)
564+
foreach (var (authz, challenge, validation, validator) in pendingChallenges)
568565
{
569566
// Skip external DNS verification for Infoblox since it cannot ping external DNS providers
570567
bool isInfoblox = config.DnsProvider?.Trim().Equals("infoblox", StringComparison.OrdinalIgnoreCase) ?? false;
@@ -601,10 +598,21 @@ private async Task ProcessAuthorizations(AcmeClient acmeClient, OrderDetails ord
601598
await acmeClient.AnswerChallengeAsync(challenge);
602599
}
603600

604-
// Optional: Cleanup after challenges complete
605-
foreach (var (authz, challenge, validation) in pendingChallenges)
601+
// Cleanup: Remove DNS records using the per-domain validators
602+
foreach (var (authz, challenge, validation, validator) in pendingChallenges)
606603
{
607-
await _domainValidator.CleanupValidation(validation.DnsRecordName, CancellationToken.None);
604+
try
605+
{
606+
await validator.CleanupValidation(validation.DnsRecordName, CancellationToken.None);
607+
_logger.LogInformation("Cleaned up DNS record {RecordName} for domain {Domain}",
608+
validation.DnsRecordName, authz.Identifier.Value);
609+
}
610+
catch (Exception ex)
611+
{
612+
_logger.LogWarning(ex, "Failed to cleanup DNS record {RecordName} for domain {Domain}",
613+
validation.DnsRecordName, authz.Identifier.Value);
614+
// Continue cleanup for other domains even if one fails
615+
}
608616
}
609617
}
610618

0 commit comments

Comments
 (0)