up
This commit is contained in:
@@ -105,12 +105,15 @@ internal static class Program
|
||||
services.AddSingleton<IScannerExecutor, ScannerExecutor>();
|
||||
services.AddSingleton<IScannerInstaller, ScannerInstaller>();
|
||||
|
||||
await using var serviceProvider = services.BuildServiceProvider();
|
||||
using var cts = new CancellationTokenSource();
|
||||
Console.CancelKeyPress += (_, eventArgs) =>
|
||||
{
|
||||
eventArgs.Cancel = true;
|
||||
cts.Cancel();
|
||||
await using var serviceProvider = services.BuildServiceProvider();
|
||||
var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
|
||||
var startupLogger = loggerFactory.CreateLogger("StellaOps.Cli.Startup");
|
||||
AuthorityDiagnosticsReporter.Emit(configuration, startupLogger);
|
||||
using var cts = new CancellationTokenSource();
|
||||
Console.CancelKeyPress += (_, eventArgs) =>
|
||||
{
|
||||
eventArgs.Cancel = true;
|
||||
cts.Cancel();
|
||||
};
|
||||
|
||||
var rootCommand = CommandFactory.Create(serviceProvider, options, cts.Token);
|
||||
|
||||
123
src/StellaOps.Cli/Services/AuthorityDiagnosticsReporter.cs
Normal file
123
src/StellaOps.Cli/Services/AuthorityDiagnosticsReporter.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
# TASKS
|
||||
| Task | Owner(s) | Depends on | Notes |
|
||||
|---|---|---|---|
|
||||
|Bootstrap configuration fallback (env → appsettings{{.json/.yaml}})|DevEx/CLI|Core|**DONE** – CLI loads `API_KEY`/`STELLAOPS_BACKEND_URL` from environment or local settings, defaulting to empty strings when unset.|
|
||||
|Introduce command host & routing skeleton|DevEx/CLI|Configuration|**DONE** – System.CommandLine (v2.0.0-beta5) router stitched with `scanner`, `scan`, `db`, and `config` verbs.|
|
||||
|Scanner artifact download/install commands|Ops Integrator|Backend contracts|**DONE** – `scanner download` caches bundles, validates SHA-256 (plus optional RSA signature), installs via `docker load`, persists metadata, and retries with exponential backoff.|
|
||||
|Scan execution & result upload workflow|Ops Integrator, QA|Scanner cmd|**DONE** – `scan run` drives container scans against directories, emits artefacts in `ResultsDirectory`, auto-uploads on success, and `scan upload` covers manual retries.|
|
||||
If you are working on this file you need to read docs/ARCHITECTURE_VEXER.md and ./AGENTS.md).
|
||||
# TASKS
|
||||
| Task | Owner(s) | Depends on | Notes |
|
||||
|---|---|---|---|
|
||||
|Bootstrap configuration fallback (env → appsettings{{.json/.yaml}})|DevEx/CLI|Core|**DONE** – CLI loads `API_KEY`/`STELLAOPS_BACKEND_URL` from environment or local settings, defaulting to empty strings when unset.|
|
||||
|Introduce command host & routing skeleton|DevEx/CLI|Configuration|**DONE** – System.CommandLine (v2.0.0-beta5) router stitched with `scanner`, `scan`, `db`, and `config` verbs.|
|
||||
|Scanner artifact download/install commands|Ops Integrator|Backend contracts|**DONE** – `scanner download` caches bundles, validates SHA-256 (plus optional RSA signature), installs via `docker load`, persists metadata, and retries with exponential backoff.|
|
||||
|Scan execution & result upload workflow|Ops Integrator, QA|Scanner cmd|**DONE** – `scan run` drives container scans against directories, emits artefacts in `ResultsDirectory`, auto-uploads on success, and `scan upload` covers manual retries.|
|
||||
|Feedser DB operations passthrough|DevEx/CLI|Backend, Feedser APIs|**DONE** – `db fetch|merge|export` trigger `/jobs/*` endpoints with parameter binding and consistent exit codes.|
|
||||
|CLI observability & tests|QA|Command host|**DONE** – Added console logging defaults & configuration bootstrap tests; future metrics hooks tracked separately.|
|
||||
|Authority auth commands|DevEx/CLI|Auth libraries|**DONE** – `auth login/logout/status` wrap the shared auth client, manage token cache, and surface status messages.|
|
||||
@@ -12,4 +13,7 @@
|
||||
|Authority whoami command|DevEx/CLI|Authority auth commands|**DONE (2025-10-10)** – Added `auth whoami` verb that displays subject/audience/expiry from cached tokens and handles opaque tokens gracefully.|
|
||||
|Expose auth client resilience settings|DevEx/CLI|Auth libraries LIB5|**DONE (2025-10-10)** – CLI options now bind resilience knobs, `AddStellaOpsAuthClient` honours them, and tests cover env overrides.|
|
||||
|Document advanced Authority tuning|Docs/CLI|Expose auth client resilience settings|**DONE (2025-10-10)** – docs/09 and docs/10 describe retry/offline settings with env examples and point to the integration guide.|
|
||||
|Surface password policy diagnostics in CLI output|DevEx/CLI, Security Guild|AUTHSEC-CRYPTO-02-004|**TODO** – Bubble analyzer warnings during CLI startup (plugin load) and add tests/docs guiding operators to remediate weakened policies.|
|
||||
|Surface password policy diagnostics in CLI output|DevEx/CLI, Security Guild|AUTHSEC-CRYPTO-02-004|**DONE (2025-10-15)** – CLI startup runs the Authority plug-in analyzer, logs weakened password policy warnings with manifest paths, added unit tests (`dotnet test src/StellaOps.Cli.Tests`) and updated docs/09 with remediation guidance.|
|
||||
|VEXER-CLI-01-001 – Add `vexer` command group|DevEx/CLI|VEXER-WEB-01-001|TODO – Introduce `vexer` verb hierarchy (init/pull/resume/list-providers/export/verify/reconcile) forwarding to WebService with token auth and consistent exit codes.|
|
||||
|VEXER-CLI-01-002 – Export download & attestation UX|DevEx/CLI|VEXER-CLI-01-001, VEXER-EXPORT-01-001|TODO – Display export metadata (sha256, size, Rekor link), support optional artifact download path, and handle cache hits gracefully.|
|
||||
|VEXER-CLI-01-003 – CLI docs & examples for Vexer|Docs/CLI|VEXER-CLI-01-001|TODO – Update docs/09_API_CLI_REFERENCE.md and quickstart snippets to cover Vexer verbs, offline guidance, and attestation verification workflow.|
|
||||
|
||||
Reference in New Issue
Block a user