Skip to content

Commit 6dbf4a1

Browse files
bhillkeyfactorKeyfactor
andauthored
feat: add Infoblox support to ACME
This change adds support for the Infoblox ACME DNS provider. --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> signed-off-by: Morgan Gangwere <Morgan.gangwere@keyfactor.com>
1 parent b28cc5b commit 6dbf4a1

File tree

9 files changed

+456
-20
lines changed

9 files changed

+456
-20
lines changed

AcmeCaPlugin/AcmeCaPlugin.cs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ private async Task ProcessAuthorizations(AcmeClient acmeClient, OrderDetails ord
370370
if (validation == null)
371371
throw new InvalidOperationException($"Failed to decode {DNS_CHALLENGE_TYPE} challenge validation details");
372372

373-
// Create DNS record
373+
// Create DNS record (will throw exception with details if it fails)
374374
var dnsProvider = DnsProviderFactory.Create(config, _logger);
375375
await dnsProvider.CreateRecordAsync(validation.DnsRecordName, validation.DnsRecordValue);
376376

@@ -383,22 +383,34 @@ private async Task ProcessAuthorizations(AcmeClient acmeClient, OrderDetails ord
383383
// Second pass: Wait for DNS propagation and submit challenges
384384
foreach (var (authz, challenge, validation) in pendingChallenges)
385385
{
386-
_logger.LogInformation("Waiting for DNS propagation for {Domain}...", authz.Identifier.Value);
386+
// Skip external DNS verification for Infoblox since it cannot ping external DNS providers
387+
bool isInfoblox = config.DnsProvider?.Trim().Equals("infoblox", StringComparison.OrdinalIgnoreCase) ?? false;
387388

388-
// Wait for DNS propagation with verification
389-
var propagated = await dnsVerifier.WaitForDnsPropagationAsync(
390-
validation.DnsRecordName,
391-
validation.DnsRecordValue,
392-
minimumServers: 3 // Require at least 3 DNS servers to confirm
393-
);
394-
395-
if (!propagated)
389+
if (isInfoblox)
390+
{
391+
_logger.LogInformation("Skipping external DNS propagation check for Infoblox provider for {Domain}. Adding short delay...", authz.Identifier.Value);
392+
// Add a short delay to allow Infoblox to process the record internally
393+
await Task.Delay(TimeSpan.FromSeconds(5));
394+
}
395+
else
396396
{
397-
_logger.LogWarning("DNS record may not have fully propagated for {Domain}. Proceeding anyway...",
398-
authz.Identifier.Value);
397+
_logger.LogInformation("Waiting for DNS propagation for {Domain}...", authz.Identifier.Value);
399398

400-
// Optional: Add a final delay as fallback
401-
await Task.Delay(TimeSpan.FromSeconds(30));
399+
// Wait for DNS propagation with verification
400+
var propagated = await dnsVerifier.WaitForDnsPropagationAsync(
401+
validation.DnsRecordName,
402+
validation.DnsRecordValue,
403+
minimumServers: 3 // Require at least 3 DNS servers to confirm
404+
);
405+
406+
if (!propagated)
407+
{
408+
_logger.LogWarning("DNS record may not have fully propagated for {Domain}. Proceeding anyway...",
409+
authz.Identifier.Value);
410+
411+
// Optional: Add a final delay as fallback
412+
await Task.Delay(TimeSpan.FromSeconds(30));
413+
}
402414
}
403415

404416
// Submit challenge response

AcmeCaPlugin/AcmeCaPluginConfig.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public static Dictionary<string, PropertyConfigInfo> GetPluginAnnotations()
4646
},
4747
["DnsProvider"] = new PropertyConfigInfo()
4848
{
49-
Comments = "DNS Provider to use for ACME DNS-01 challenges (options Google, Cloudflare, AwsRoute53, Azure, Ns1)",
49+
Comments = "DNS Provider to use for ACME DNS-01 challenges (options Google, Cloudflare, AwsRoute53, Azure, Ns1, Infoblox)",
5050
Hidden = false,
5151
DefaultValue = "Google",
5252
Type = "String"
@@ -130,6 +130,30 @@ public static Dictionary<string, PropertyConfigInfo> GetPluginAnnotations()
130130
Type = "String"
131131
}
132132

133+
//Infoblox DNS
134+
,
135+
["Infoblox_Host"] = new PropertyConfigInfo()
136+
{
137+
Comments = "Infoblox DNS: API URL (e.g., https://infoblox.example.com/wapi/v2.12) only if using Infoblox DNS (Optional)",
138+
Hidden = false,
139+
DefaultValue = "",
140+
Type = "String"
141+
},
142+
["Infoblox_Username"] = new PropertyConfigInfo()
143+
{
144+
Comments = "Infoblox DNS: Username for authentication only if using Infoblox DNS (Optional)",
145+
Hidden = false,
146+
DefaultValue = "",
147+
Type = "String"
148+
},
149+
["Infoblox_Password"] = new PropertyConfigInfo()
150+
{
151+
Comments = "Infoblox DNS: Password for authentication only if using Infoblox DNS (Optional)",
152+
Hidden = true,
153+
DefaultValue = "",
154+
Type = "Secret"
155+
}
156+
133157
};
134158
}
135159

AcmeCaPlugin/AcmeClientConfig.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,12 @@ public class AcmeClientConfig
3434
//IBM NS1 DNS Ns1_ApiKey
3535
public string Ns1_ApiKey { get; set; } = null;
3636

37+
// Infoblox DNS
38+
public string Infoblox_Host { get; set; } = null;
39+
public string Infoblox_Username { get; set; } = null;
40+
public string Infoblox_Password { get; set; } = null;
41+
public string Infoblox_WapiVersion { get; set; } = "2.12";
42+
public bool Infoblox_IgnoreSslErrors { get; set; } = false;
43+
3744
}
3845
}

AcmeCaPlugin/Clients/DNS/DnsProviderFactory.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ public static IDnsProvider Create(AcmeClientConfig config, ILogger logger)
3939
return new Ns1DnsProvider(
4040
config.Ns1_ApiKey
4141
);
42+
case "infoblox":
43+
return new InfobloxDnsProvider(
44+
config.Infoblox_Host,
45+
config.Infoblox_Username,
46+
config.Infoblox_Password,
47+
config.Infoblox_WapiVersion,
48+
config.Infoblox_IgnoreSslErrors,
49+
logger
50+
);
4251
default:
4352
throw new NotSupportedException($"DNS provider '{config.DnsProvider}' is not supported.");
4453
}

0 commit comments

Comments
 (0)