sprints completion. new product advisories prepared

This commit is contained in:
master
2026-01-16 16:30:03 +02:00
parent a927d924e3
commit 4ca3ce8fb4
255 changed files with 42434 additions and 1020 deletions

View File

@@ -0,0 +1,179 @@
// -----------------------------------------------------------------------------
// LocalRbacBundleExtensions.cs
// Sprint: SPRINT_20260112_018_AUTH_local_rbac_fallback
// Task: RBAC-010
// Description: Extensions for including local RBAC policy in offline kit bundles.
// -----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using StellaOps.AirGap.Bundle.Models;
namespace StellaOps.AirGap.Bundle.Services;
/// <summary>
/// Extension methods for including local RBAC policy in offline kit bundles.
/// </summary>
public static class LocalRbacBundleExtensions
{
/// <summary>
/// Default policy file name in the offline kit.
/// </summary>
public const string DefaultPolicyFileName = "local-policy.yaml";
/// <summary>
/// Default policy directory in the offline kit.
/// </summary>
public const string DefaultPolicyDirectory = "authority";
/// <summary>
/// Creates a policy build config for including local RBAC policy in an offline kit bundle.
/// </summary>
/// <param name="sourcePolicyPath">Source path to the local RBAC policy file (YAML or JSON).</param>
/// <param name="version">Policy version string.</param>
/// <param name="relativePath">Optional relative path in the bundle (defaults to "authority/local-policy.yaml").</param>
/// <returns>PolicyBuildConfig ready for inclusion in BundleBuildRequest.</returns>
public static PolicyBuildConfig CreateLocalRbacPolicyConfig(
string sourcePolicyPath,
string version,
string? relativePath = null)
{
ArgumentNullException.ThrowIfNull(sourcePolicyPath);
ArgumentException.ThrowIfNullOrWhiteSpace(version);
if (!File.Exists(sourcePolicyPath))
{
throw new FileNotFoundException(
"Local RBAC policy file not found. Ensure the policy file exists before building the offline kit.",
sourcePolicyPath);
}
var fileName = Path.GetFileName(sourcePolicyPath);
var targetPath = relativePath ?? Path.Combine(DefaultPolicyDirectory, fileName);
return new PolicyBuildConfig(
PolicyId: "local-rbac-policy",
Name: "Local RBAC Policy",
Version: version,
SourcePath: sourcePolicyPath,
RelativePath: targetPath,
Type: PolicyType.LocalRbac);
}
/// <summary>
/// Adds local RBAC policies to a list of policy build configs.
/// </summary>
/// <param name="policies">Existing list of policy build configs.</param>
/// <param name="sourcePolicyPath">Source path to the local RBAC policy file.</param>
/// <param name="version">Policy version string.</param>
/// <returns>New list with the local RBAC policy added.</returns>
public static IReadOnlyList<PolicyBuildConfig> WithLocalRbacPolicy(
this IReadOnlyList<PolicyBuildConfig> policies,
string sourcePolicyPath,
string version)
{
var list = new List<PolicyBuildConfig>(policies);
list.Add(CreateLocalRbacPolicyConfig(sourcePolicyPath, version));
return list;
}
/// <summary>
/// Checks if a bundle manifest contains local RBAC policy.
/// </summary>
/// <param name="manifest">Bundle manifest to check.</param>
/// <returns>True if the manifest contains local RBAC policy.</returns>
public static bool HasLocalRbacPolicy(this BundleManifest manifest)
{
ArgumentNullException.ThrowIfNull(manifest);
foreach (var policy in manifest.Policies)
{
if (policy.Type == PolicyType.LocalRbac)
{
return true;
}
}
return false;
}
/// <summary>
/// Gets the local RBAC policy component from a bundle manifest.
/// </summary>
/// <param name="manifest">Bundle manifest to search.</param>
/// <returns>The local RBAC policy component, or null if not found.</returns>
public static PolicyComponent? GetLocalRbacPolicy(this BundleManifest manifest)
{
ArgumentNullException.ThrowIfNull(manifest);
foreach (var policy in manifest.Policies)
{
if (policy.Type == PolicyType.LocalRbac)
{
return policy;
}
}
return null;
}
/// <summary>
/// Extracts and installs local RBAC policy from a bundle to the target path.
/// </summary>
/// <param name="bundlePath">Path to the extracted bundle.</param>
/// <param name="manifest">Bundle manifest.</param>
/// <param name="targetPolicyPath">Target path to install the policy file.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>True if the policy was installed successfully.</returns>
public static async Task<bool> InstallLocalRbacPolicyAsync(
string bundlePath,
BundleManifest manifest,
string targetPolicyPath,
CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrWhiteSpace(bundlePath);
ArgumentNullException.ThrowIfNull(manifest);
ArgumentException.ThrowIfNullOrWhiteSpace(targetPolicyPath);
var policy = manifest.GetLocalRbacPolicy();
if (policy is null)
{
return false;
}
var sourcePath = Path.Combine(bundlePath, policy.RelativePath);
if (!File.Exists(sourcePath))
{
throw new FileNotFoundException(
$"Local RBAC policy not found in bundle at expected path: {policy.RelativePath}",
sourcePath);
}
// Ensure target directory exists
var targetDir = Path.GetDirectoryName(targetPolicyPath);
if (!string.IsNullOrEmpty(targetDir))
{
Directory.CreateDirectory(targetDir);
}
// Copy with verification
await using var sourceStream = File.OpenRead(sourcePath);
await using var targetStream = File.Create(targetPolicyPath);
await sourceStream.CopyToAsync(targetStream, cancellationToken).ConfigureAwait(false);
return true;
}
}
/// <summary>
/// Result of local RBAC policy installation from an offline kit.
/// </summary>
public sealed record LocalRbacInstallResult(
bool Success,
string? InstalledPath,
string? PolicyVersion,
string? PolicyDigest,
string? Error);