Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion cscglobal-caplugin.Tests/CSCGlobalCAPluginTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1048,10 +1048,14 @@ public async Task Enroll_New_WithDnsValidatorFactoryButEmailMethod_DoesNotAttemp
[EnrollmentConfigConstants.DomainControlValidationMethod] = "EMAIL"
});

await plugin.Enroll("csr", "CN=test", new Dictionary<string, string[]>(), productInfo,
var result = await plugin.Enroll("csr", "CN=test", new Dictionary<string, string[]>(), productInfo,
RequestFormat.PKCS10, EnrollmentType.New);

mockFactory.Verify(f => f.ResolveDomainValidator(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
// The DcvAutoPublish step must explain *why* it was a no-op for a non-CNAME method,
// rather than showing a bare [OK] under a CNAME-sounding step name.
var publishStep = result.EnrollmentContext.Single(e => e.Key.Contains("DcvAutoPublish"));
Assert.Contains("not CNAME", publishStep.Value);
}

[Fact]
Expand Down
18 changes: 10 additions & 8 deletions cscglobal-caplugin/CSCGlobalCAPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -698,10 +698,7 @@ await flow.StepAsync("SubmitRegistrationToCSC", async () =>
var enrollResult = _requestManager.GetEnrollmentResult(enrollmentResponse);
flow.Step("MapResult", $"Status={enrollResult?.Status}, ID={enrollResult?.CARequestID ?? "(null)"}");

await flow.StepAsync("PublishCnameDcv", async () =>
{
await TryPublishCnameDcvAsync(productInfo, enrollResult);
});
await flow.StepAsync("DcvAutoPublish", () => TryPublishCnameDcvAsync(productInfo, enrollResult));

EnrollmentResult? newPolled = null;
await flow.StepAsync("PollForIssuance", async () =>
Expand Down Expand Up @@ -1388,19 +1385,21 @@ record = null;
/// resolves for its domain. No-op if the factory wasn't injected, the cert isn't using CNAME
/// validation, or the response contains no CNAME details. Failures are logged but never thrown —
/// manual publishing remains a fallback so the enrollment result is still returned to Keyfactor.
/// Returns a short description of what happened (published/skipped/why), surfaced as the
/// flow step's detail so a no-op for non-CNAME methods doesn't look unexplained.
/// </summary>
private async Task TryPublishCnameDcvAsync(EnrollmentProductInfo productInfo, EnrollmentResult? enrollResult)
private async Task<string> TryPublishCnameDcvAsync(EnrollmentProductInfo productInfo, EnrollmentResult? enrollResult)
{
if (_validatorFactory == null)
{
Logger.LogTrace("TryPublishCnameDcvAsync: no IDomainValidatorFactory was injected, skipping auto-publish.");
return;
return "skipped - no DNS validator factory injected";
}

if (enrollResult?.EnrollmentContext == null || enrollResult.EnrollmentContext.Count == 0)
{
Logger.LogTrace("TryPublishCnameDcvAsync: no CNAME entries in EnrollmentContext, skipping.");
return;
return "skipped - no DCV entries returned by CSC";
}

var dcvMethod = productInfo?.ProductParameters != null
Expand All @@ -1412,7 +1411,7 @@ private async Task TryPublishCnameDcvAsync(EnrollmentProductInfo productInfo, En
!string.Equals(dcvMethod, "CNAME", StringComparison.OrdinalIgnoreCase))
{
Logger.LogTrace("TryPublishCnameDcvAsync: DCV method '{Method}' is not CNAME, skipping auto-publish.", dcvMethod ?? "(null)");
return;
return $"skipped - DCV method is '{dcvMethod ?? "(none)"}', not CNAME";
}

Logger.LogInformation(
Expand Down Expand Up @@ -1498,6 +1497,9 @@ private async Task TryPublishCnameDcvAsync(EnrollmentProductInfo productInfo, En
Logger.LogInformation(
"TryPublishCnameDcvAsync: complete. Published={Published}, Failed={Failed}, Unresolved={Unresolved}",
successCount, failCount, unresolvedCount);

return $"published {successCount}, failed {failCount}, unresolved {unresolvedCount} " +
$"of {enrollResult.EnrollmentContext.Count} CNAME record(s)";
}

//Trying to fix leaf extraction
Expand Down
36 changes: 36 additions & 0 deletions cscglobal-caplugin/FlowLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
}

/// <summary>Record a completed step.</summary>
public FlowLogger Step(string name, string detail = null)

Check warning on line 58 in cscglobal-caplugin/FlowLogger.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Cannot convert null literal to non-nullable reference type.

Check warning on line 58 in cscglobal-caplugin/FlowLogger.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Cannot convert null literal to non-nullable reference type.

Check warning on line 58 in cscglobal-caplugin/FlowLogger.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Cannot convert null literal to non-nullable reference type.
{
var step = new FlowStep { Name = name, Status = FlowStepStatus.Success, Detail = detail };
AddStep(step);
Expand All @@ -65,7 +65,7 @@
}

/// <summary>Record a step that executes an action and times it.</summary>
public FlowLogger Step(string name, Action action, string detail = null)

Check warning on line 68 in cscglobal-caplugin/FlowLogger.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Cannot convert null literal to non-nullable reference type.

Check warning on line 68 in cscglobal-caplugin/FlowLogger.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Cannot convert null literal to non-nullable reference type.

Check warning on line 68 in cscglobal-caplugin/FlowLogger.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Cannot convert null literal to non-nullable reference type.
{
var sw = Stopwatch.StartNew();
var step = new FlowStep { Name = name, Detail = detail };
Expand Down Expand Up @@ -95,7 +95,7 @@
}

/// <summary>Record an async step that executes and times it.</summary>
public async Task<FlowLogger> StepAsync(string name, Func<Task> action, string detail = null)

Check warning on line 98 in cscglobal-caplugin/FlowLogger.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Cannot convert null literal to non-nullable reference type.

Check warning on line 98 in cscglobal-caplugin/FlowLogger.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Cannot convert null literal to non-nullable reference type.

Check warning on line 98 in cscglobal-caplugin/FlowLogger.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Cannot convert null literal to non-nullable reference type.
{
var sw = Stopwatch.StartNew();
var step = new FlowStep { Name = name, Detail = detail };
Expand Down Expand Up @@ -124,8 +124,44 @@
return this;
}

/// <summary>
/// Record an async step whose own return value becomes the step's detail - unlike the
/// <paramref name="detail" /> parameter on the other overload (which is evaluated before
/// the action runs and so can't reflect anything the action decided), this reflects what
/// actually happened during execution (e.g. why a conditional step was a no-op).
/// </summary>
public async Task<FlowLogger> StepAsync(string name, Func<Task<string>> action)
{
var sw = Stopwatch.StartNew();
var step = new FlowStep { Name = name };
try
{
_logger.LogTrace(" [{FlowName}] {StepName} ...", _flowName, name);
var detail = await action();
sw.Stop();
step.Status = FlowStepStatus.Success;
step.ElapsedMs = sw.ElapsedMilliseconds;
step.Detail = detail;
AddStep(step);
_logger.LogTrace(" [{FlowName}] {StepName} ... OK ({Elapsed}ms){Detail}",
_flowName, name, sw.ElapsedMilliseconds, detail != null ? $" {detail}" : "");
}
catch (Exception ex)
{
sw.Stop();
step.Status = FlowStepStatus.Failed;
step.ElapsedMs = sw.ElapsedMilliseconds;
step.Detail = ex.Message;
AddStep(step);
_logger.LogTrace(" [{FlowName}] {StepName} ... FAILED ({Elapsed}ms): {Error}",
_flowName, name, sw.ElapsedMilliseconds, ex.Message);
throw;
}
return this;
}

/// <summary>Record a failed step without throwing.</summary>
public FlowLogger Fail(string name, string reason = null)

Check warning on line 164 in cscglobal-caplugin/FlowLogger.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Cannot convert null literal to non-nullable reference type.

Check warning on line 164 in cscglobal-caplugin/FlowLogger.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Cannot convert null literal to non-nullable reference type.

Check warning on line 164 in cscglobal-caplugin/FlowLogger.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Cannot convert null literal to non-nullable reference type.
{
var step = new FlowStep { Name = name, Status = FlowStepStatus.Failed, Detail = reason };
AddStep(step);
Expand All @@ -135,7 +171,7 @@
}

/// <summary>Record a skipped step.</summary>
public FlowLogger Skip(string name, string reason = null)

Check warning on line 174 in cscglobal-caplugin/FlowLogger.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Cannot convert null literal to non-nullable reference type.

Check warning on line 174 in cscglobal-caplugin/FlowLogger.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Cannot convert null literal to non-nullable reference type.

Check warning on line 174 in cscglobal-caplugin/FlowLogger.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Cannot convert null literal to non-nullable reference type.
{
var step = new FlowStep { Name = name, Status = FlowStepStatus.Skipped, Detail = reason };
AddStep(step);
Expand Down
Loading