This repository was archived by the owner on Mar 31, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathCatalogDataToCsvDriver.cs
More file actions
129 lines (115 loc) · 5.7 KB
/
CatalogDataToCsvDriver.cs
File metadata and controls
129 lines (115 loc) · 5.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Text.RegularExpressions;
namespace NuGet.Insights.Worker.CatalogDataToCsv
{
public class CatalogDataToCsvDriver :
ICatalogLeafToCsvDriver<PackageDeprecationRecord, PackageVulnerabilityRecord, CatalogLeafItemRecord>,
ICsvResultStorage<PackageDeprecationRecord>,
ICsvResultStorage<PackageVulnerabilityRecord>,
ICsvResultStorage<CatalogLeafItemRecord>
{
private readonly CatalogClient _catalogClient;
private readonly IOptions<NuGetInsightsWorkerSettings> _options;
public CatalogDataToCsvDriver(
CatalogClient catalogClient,
IOptions<NuGetInsightsWorkerSettings> options)
{
_catalogClient = catalogClient;
_options = options;
}
public bool SingleMessagePerId => false;
string ICsvResultStorage<PackageDeprecationRecord>.ResultContainerName => _options.Value.PackageDeprecationContainerName;
string ICsvResultStorage<PackageVulnerabilityRecord>.ResultContainerName => _options.Value.PackageVulnerabilityContainerName;
string ICsvResultStorage<CatalogLeafItemRecord>.ResultContainerName => _options.Value.CatalogLeafItemContainerName;
public Task InitializeAsync()
{
return Task.CompletedTask;
}
public Task DestroyAsync()
{
return Task.CompletedTask;
}
public async Task<DriverResult<CsvRecordSets<PackageDeprecationRecord, PackageVulnerabilityRecord, CatalogLeafItemRecord>>> ProcessLeafAsync(
CatalogLeafScan leafScan)
{
(var deprecation, var vulnerabilities, var leafRecord) = await ProcessLeafInternalAsync(leafScan);
return DriverResult.Success(new CsvRecordSets<PackageDeprecationRecord, PackageVulnerabilityRecord, CatalogLeafItemRecord>(
[deprecation],
vulnerabilities,
[leafRecord]));
}
private async Task<(PackageDeprecationRecord, IReadOnlyList<PackageVulnerabilityRecord>, CatalogLeafItemRecord)> ProcessLeafInternalAsync(
CatalogLeafScan leafScan)
{
var scanId = Guid.NewGuid();
var scanTimestamp = DateTimeOffset.UtcNow;
if (leafScan.LeafType == CatalogLeafType.PackageDelete)
{
var leaf = (PackageDeleteCatalogLeaf)await _catalogClient.GetCatalogLeafAsync(leafScan.LeafType, leafScan.Url);
return (
new PackageDeprecationRecord(scanId, scanTimestamp, leaf),
new[] { new PackageVulnerabilityRecord(scanId, scanTimestamp, leaf) },
new CatalogLeafItemRecord(leaf, leafScan.PageUrl)
);
}
else
{
var leaf = (PackageDetailsCatalogLeaf)await _catalogClient.GetCatalogLeafAsync(leafScan.LeafType, leafScan.Url);
return (
GetDeprecation(scanId, scanTimestamp, leaf),
GetVulnerabilities(scanId, scanTimestamp, leaf),
new CatalogLeafItemRecord(leaf, leafScan.PageUrl)
);
}
}
private PackageDeprecationRecord GetDeprecation(Guid scanId, DateTimeOffset scanTimestamp, PackageDetailsCatalogLeaf leaf)
{
if (leaf.Deprecation is null)
{
return new PackageDeprecationRecord(scanId, scanTimestamp, leaf)
{
ResultType = PackageDeprecationResultType.NotDeprecated,
};
}
return new PackageDeprecationRecord(scanId, scanTimestamp, leaf)
{
ResultType = PackageDeprecationResultType.Deprecated,
Message = leaf.Deprecation.Message,
Reasons = KustoDynamicSerializer.Serialize(leaf.Deprecation.Reasons),
AlternatePackageId = leaf.Deprecation.AlternatePackage?.Id,
AlternateVersionRange = leaf.Deprecation.AlternatePackage?.Range,
};
}
private List<PackageVulnerabilityRecord> GetVulnerabilities(Guid scanId, DateTimeOffset scanTimestamp, PackageDetailsCatalogLeaf leaf)
{
var output = new List<PackageVulnerabilityRecord>();
if (leaf.Vulnerabilities is null || leaf.Vulnerabilities.Count == 0)
{
output.Add(new PackageVulnerabilityRecord(scanId, scanTimestamp, leaf)
{
ResultType = PackageVulnerabilityResultType.NotVulnerable,
});
}
else
{
foreach (var vulnerability in leaf.Vulnerabilities)
{
var match = Regex.Match(vulnerability.AtId, @"#vulnerability/GitHub/(?<GitHubDatabaseKey>\d+)$");
if (!match.Success)
{
throw new InvalidDataException($"The vulnerability @id '{vulnerability.AtId}' value does not have a recognized GitHub database key.");
}
output.Add(new PackageVulnerabilityRecord(scanId, scanTimestamp, leaf)
{
ResultType = PackageVulnerabilityResultType.Vulnerable,
GitHubDatabaseKey = int.Parse(match.Groups["GitHubDatabaseKey"].Value, CultureInfo.InvariantCulture),
AdvisoryUrl = vulnerability.AdvisoryUrl,
Severity = int.Parse(vulnerability.Severity, CultureInfo.InvariantCulture),
});
}
}
return output;
}
}
}