124 lines
3.7 KiB
C#
124 lines
3.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.Logging;
|
|
using StellaOps.Authority.Plugins.Abstractions;
|
|
using StellaOps.Configuration;
|
|
|
|
namespace StellaOps.Cli.Services;
|
|
|
|
/// <summary>
|
|
/// Emits Authority configuration diagnostics discovered during CLI startup.
|
|
/// </summary>
|
|
internal static class AuthorityDiagnosticsReporter
|
|
{
|
|
public static void Emit(IConfiguration configuration, ILogger logger)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(configuration);
|
|
ArgumentNullException.ThrowIfNull(logger);
|
|
|
|
var basePath = Directory.GetCurrentDirectory();
|
|
EmitInternal(configuration, logger, basePath);
|
|
}
|
|
|
|
internal static void Emit(IConfiguration configuration, ILogger logger, string basePath)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(configuration);
|
|
ArgumentNullException.ThrowIfNull(logger);
|
|
ArgumentNullException.ThrowIfNull(basePath);
|
|
|
|
EmitInternal(configuration, logger, basePath);
|
|
}
|
|
|
|
private static void EmitInternal(IConfiguration configuration, ILogger logger, string basePath)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(basePath))
|
|
{
|
|
basePath = Directory.GetCurrentDirectory();
|
|
}
|
|
|
|
var authoritySection = configuration.GetSection("Authority");
|
|
if (!authoritySection.Exists())
|
|
{
|
|
return;
|
|
}
|
|
|
|
var authorityOptions = new StellaOpsAuthorityOptions();
|
|
authoritySection.Bind(authorityOptions);
|
|
|
|
if (authorityOptions.Plugins.Descriptors.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var resolvedBasePath = Path.GetFullPath(basePath);
|
|
IReadOnlyList<AuthorityPluginContext> contexts;
|
|
|
|
try
|
|
{
|
|
contexts = AuthorityPluginConfigurationLoader.Load(authorityOptions, resolvedBasePath);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.LogDebug(ex, "Failed to load Authority plug-in configuration for diagnostics.");
|
|
return;
|
|
}
|
|
|
|
if (contexts.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
IReadOnlyList<AuthorityConfigurationDiagnostic> diagnostics;
|
|
try
|
|
{
|
|
diagnostics = AuthorityPluginConfigurationAnalyzer.Analyze(contexts);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.LogDebug(ex, "Failed to analyze Authority plug-in configuration for diagnostics.");
|
|
return;
|
|
}
|
|
|
|
if (diagnostics.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var contextLookup = new Dictionary<string, AuthorityPluginContext>(StringComparer.OrdinalIgnoreCase);
|
|
foreach (var context in contexts)
|
|
{
|
|
if (context?.Manifest?.Name is { Length: > 0 } name && !contextLookup.ContainsKey(name))
|
|
{
|
|
contextLookup[name] = context;
|
|
}
|
|
}
|
|
|
|
foreach (var diagnostic in diagnostics)
|
|
{
|
|
var level = diagnostic.Severity switch
|
|
{
|
|
AuthorityConfigurationDiagnosticSeverity.Error => LogLevel.Error,
|
|
AuthorityConfigurationDiagnosticSeverity.Warning => LogLevel.Warning,
|
|
_ => LogLevel.Information
|
|
};
|
|
|
|
if (!logger.IsEnabled(level))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (contextLookup.TryGetValue(diagnostic.PluginName, out var context) &&
|
|
context?.Manifest?.ConfigPath is { Length: > 0 } configPath)
|
|
{
|
|
logger.Log(level, "{DiagnosticMessage} (config: {ConfigPath})", diagnostic.Message, configPath);
|
|
}
|
|
else
|
|
{
|
|
logger.Log(level, "{DiagnosticMessage}", diagnostic.Message);
|
|
}
|
|
}
|
|
}
|
|
}
|