This commit is contained in:
Vladimir Moushkov
2025-10-15 10:03:56 +03:00
parent ea8226120c
commit ea1106ce7c
276 changed files with 21674 additions and 934 deletions

View File

@@ -0,0 +1,123 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
namespace StellaOps.Feedser.Source.Vndr.Cisco.Internal;
internal static class CiscoCsafParser
{
public static CiscoCsafData Parse(string content)
{
if (string.IsNullOrWhiteSpace(content))
{
return new CiscoCsafData(
Products: new Dictionary<string, CiscoCsafProduct>(0, StringComparer.OrdinalIgnoreCase),
ProductStatuses: new Dictionary<string, IReadOnlyCollection<string>>(0, StringComparer.OrdinalIgnoreCase));
}
using var document = JsonDocument.Parse(content);
var root = document.RootElement;
var products = ParseProducts(root);
var statuses = ParseStatuses(root);
return new CiscoCsafData(products, statuses);
}
private static IReadOnlyDictionary<string, CiscoCsafProduct> ParseProducts(JsonElement root)
{
var dictionary = new Dictionary<string, CiscoCsafProduct>(StringComparer.OrdinalIgnoreCase);
if (!root.TryGetProperty("product_tree", out var productTree))
{
return dictionary;
}
if (productTree.TryGetProperty("full_product_names", out var fullProductNames)
&& fullProductNames.ValueKind == JsonValueKind.Array)
{
foreach (var entry in fullProductNames.EnumerateArray())
{
var productId = entry.TryGetProperty("product_id", out var idElement) && idElement.ValueKind == JsonValueKind.String
? idElement.GetString()
: null;
if (string.IsNullOrWhiteSpace(productId))
{
continue;
}
var name = entry.TryGetProperty("name", out var nameElement) && nameElement.ValueKind == JsonValueKind.String
? nameElement.GetString()
: null;
if (string.IsNullOrWhiteSpace(name))
{
name = productId;
}
dictionary[productId] = new CiscoCsafProduct(productId, name);
}
}
return dictionary;
}
private static IReadOnlyDictionary<string, IReadOnlyCollection<string>> ParseStatuses(JsonElement root)
{
var map = new Dictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase);
if (!root.TryGetProperty("vulnerabilities", out var vulnerabilities)
|| vulnerabilities.ValueKind != JsonValueKind.Array)
{
return map.ToDictionary(
static kvp => kvp.Key,
static kvp => (IReadOnlyCollection<string>)kvp.Value.ToArray(),
StringComparer.OrdinalIgnoreCase);
}
foreach (var vulnerability in vulnerabilities.EnumerateArray())
{
if (!vulnerability.TryGetProperty("product_status", out var productStatus)
|| productStatus.ValueKind != JsonValueKind.Object)
{
continue;
}
foreach (var property in productStatus.EnumerateObject())
{
var statusLabel = property.Name;
if (property.Value.ValueKind != JsonValueKind.Array)
{
continue;
}
foreach (var productIdElement in property.Value.EnumerateArray())
{
if (productIdElement.ValueKind != JsonValueKind.String)
{
continue;
}
var productId = productIdElement.GetString();
if (string.IsNullOrWhiteSpace(productId))
{
continue;
}
if (!map.TryGetValue(productId, out var set))
{
set = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
map[productId] = set;
}
set.Add(statusLabel);
}
}
}
return map.ToDictionary(
static kvp => kvp.Key,
static kvp => (IReadOnlyCollection<string>)kvp.Value.ToArray(),
StringComparer.OrdinalIgnoreCase);
}
}