Skip to content

Commit 65da0c0

Browse files
authored
Change VerifyGitHubVulnerabilities into a job (#9298)
Progress on NuGet/Engineering#4512
1 parent 4a96d3c commit 65da0c0

11 files changed

Lines changed: 176 additions & 59 deletions

File tree

src/GitHubVulnerabilities2Db/GitHubVulnerabilities2Db.csproj

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,6 @@
9494
<Version>2.106.0</Version>
9595
</PackageReference>
9696
</ItemGroup>
97-
<ItemGroup>
98-
<Content Include="Scripts\nssm.exe" />
99-
</ItemGroup>
10097
<ItemGroup>
10198
<ProjectReference Include="..\NuGet.Services.Entities\NuGet.Services.Entities.csproj">
10299
<Project>{6262f4fc-29be-4226-b676-db391c89d396}</Project>

src/VerifyGitHubVulnerabilities/Job.cs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,30 @@ namespace VerifyGitHubVulnerabilities
2525
{
2626
class Job : JsonConfigurationJob
2727
{
28-
private readonly HttpClient _client = new HttpClient();
29-
3028
public override async Task Run()
3129
{
32-
Console.WriteLine("Fetching vulnerabilities from GitHub...");
30+
var telemetryClient = _serviceProvider.GetRequiredService<NuGet.Services.Logging.ITelemetryClient>();
31+
32+
Logger.LogInformation("Fetching vulnerabilities from GitHub...");
3333
var advisoryQueryService = _serviceProvider.GetRequiredService<IAdvisoryQueryService>();
3434
var advisories = await advisoryQueryService.GetAdvisoriesSinceAsync(DateTimeOffset.MinValue, CancellationToken.None);
35-
Console.WriteLine($" FOUND {advisories.Count} advisories.");
35+
Logger.LogInformation("Found {Count} advisories.", advisories.Count);
3636

37-
Console.WriteLine("Fetching vulnerabilities from DB...");
37+
Logger.LogInformation("Fetching vulnerabilities from DB...");
3838
var ingestor = _serviceProvider.GetRequiredService<IAdvisoryIngestor>();
3939
await ingestor.IngestAsync(advisories.OrderBy(x => x.DatabaseId).ToList());
4040

4141
var verifier = _serviceProvider.GetRequiredService<IPackageVulnerabilitiesVerifier>();
42-
Console.WriteLine(verifier.HasErrors ?
43-
"DB does not match GitHub API - see stderr output for details" :
44-
"DB/metadata matches GitHub API!");
42+
if (verifier.HasErrors)
43+
{
44+
Logger.LogError("DB/metadata does not match GitHub API - see error logs for details");
45+
telemetryClient.TrackMetric(nameof(VerifyGitHubVulnerabilities) + ".DataIsInconsistent", 1);
46+
}
47+
else
48+
{
49+
Logger.LogInformation("DB/metadata matches GitHub API!");
50+
telemetryClient.TrackMetric(nameof(VerifyGitHubVulnerabilities) + ".DataIsConsistent", 1);
51+
}
4552
}
4653

4754
protected override void ConfigureJobServices(IServiceCollection services, IConfigurationRoot configurationRoot)
@@ -95,7 +102,7 @@ protected void ConfigureGalleryServices(ContainerBuilder containerBuilder)
95102
protected void ConfigureQueryServices(ContainerBuilder containerBuilder)
96103
{
97104
containerBuilder
98-
.RegisterInstance(_client)
105+
.RegisterInstance(new HttpClient())
99106
.As<HttpClient>();
100107

101108
containerBuilder

src/VerifyGitHubVulnerabilities/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class Program
1010
static void Main(string[] args)
1111
{
1212
var job = new Job();
13-
JobRunner.RunOnce(job, args).Wait();
13+
JobRunner.Run(job, args).Wait();
1414
}
1515
}
1616
}

src/VerifyGitHubVulnerabilities/README.md

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,23 @@
11
## Overview
22

3-
This is a run-once job for taking a current snapshot of the whole of GitHub's security advisory collection (pertaining to the `NUGET` ecosystem) and comparing it with the vulnerability records in the gallery database. It's designed to be run on an ad hoc basis (not an ongoing monitoring job), from the command line, with all status message streamed to `stdout` and all vulnerability differences streamed to `stderr`.
3+
This is a recurring, monitoring job for taking a current snapshot of the whole of GitHub's security advisory collection (pertaining to the `NUGET` ecosystem) and comparing it with the vulnerability records in the gallery database. It's designed to interact with GitHub, the NuGet Gallery DB, and V3 metadata endpoints in a read-only manner. It just reports problems when it finds them.
44

5-
## Running the job
5+
## Running the job locally
66

77
A typical command line will look like this:
88

99
```
10-
verifygithubvulnerabilities.exe -Configuration appsettings.json -InstrumentationKey <key> -HeartbeatIntervalSeconds 60 2>c:\errors.txt
10+
VerifyGitHubVulnerabilities.exe -Configuration appsettings.json -InstrumentationKey <key> -HeartbeatIntervalSeconds 60
1111
```
1212

13-
- the `2>` will direct `stderr` to a text file (a `1>` would similarly direct `stdout` but it's probably useful to have that print to console)
14-
- the contents of the `appsettings.json` file will be similar (identical is fine--there are just some extra unneeded settings in them) to the settings files used for `GitHubVulnerabilities2Db`.
15-
1613
### Using DEV resources
1714

1815
The easiest way to run the tool if you are on the nuget.org team is to use the DEV environment resources:
1916

2017
1. Install the certificate used to authenticate as our client AAD app registration into your `CurrentUser` certificate store.
2118
1. Clone our internal [`NuGetDeployment`](https://nuget.visualstudio.com/DefaultCollection/NuGetMicrosoft/_git/NuGetDeploymentp) repository.
22-
1. Take a copy of the [DEV GitHubVulnerabilities2Db appsettings.json](https://nuget.visualstudio.com/NuGetMicrosoft/_git/NuGetDeployment?path=%2Fsrc%2FJobs%2FNuGet.Jobs.Cloud%2FJobs%2FGitHubVulnerabilities2Db%2FDEV%2Fnorthcentralus%2Fappsettings.json) file and place it in the same directory as the `verifygithubvulnerabilities.exe`. This will use our secrets to authenticate to the SQL server (this file also contains a reference to the secret used for the access token to GitHub).
23-
1. Set the following property, in the `appsettings.json`, under the `"Initialization"` object: `"NuGetV3Index": "https://apidev.nugettest.org/v3/index.json"`.
24-
1. Overwrite the Gallery DB `"ConnectionString"` property to be the connection string from [DEV USSC (read-only) gallery config](https://nuget.visualstudio.com/NuGetMicrosoft/_git/NuGetDeployment?path=/src/Gallery/ExpressV2/ServiceSpecs/Parameters.AS/DEV/USSC/NuGet.Gallery.Parameters.json&version=GBmaster). This provides an additional protection to ensure the job runs as read-only.
25-
2. Run as per above.
19+
1. Take a copy of the [DEV VerifyGitHubVulnerabilities appsettings.json](https://nuget.visualstudio.com/NuGetMicrosoft/_git/NuGetDeployment?path=%2Fsrc%2FJobs%2FNuGet.Jobs.Cloud%2FJobs%VerifyGitHubVulnerabilities%2FDEV%2Fnorthcentralus%2Fappsettings.json) file and place it in the same directory as the `VerifyGitHubVulnerabilities.exe`. This will use our secrets to authenticate to the SQL server (this file also contains a reference to the secret used for the access token to GitHub).
20+
1. Run as per above.
2621

2722
## Algorithm
2823

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
Function Uninstall-NuGetService() {
2+
Param ([string]$ServiceName)
3+
4+
if (Get-Service $ServiceName -ErrorAction SilentlyContinue)
5+
{
6+
Write-Host Removing service $ServiceName...
7+
Stop-Service $ServiceName -Force
8+
sc.exe delete $ServiceName
9+
Write-Host Removed service $ServiceName.
10+
} else {
11+
Write-Host Skipping removal of service $ServiceName - no such service exists.
12+
}
13+
}
14+
15+
Function Install-NuGetService() {
16+
Param (
17+
[string]$ServiceName,
18+
[string]$ServiceTitle,
19+
[string]$ScriptToRun,
20+
[Parameter(Mandatory=$false)][string]$Username,
21+
[Parameter(Mandatory=$false)][string]$Password
22+
)
23+
24+
Write-Host Installing service $ServiceName...
25+
26+
$installService = "nssm install $ServiceName $ScriptToRun"
27+
cmd /C $installService
28+
29+
Set-Service -Name $ServiceName -DisplayName "$ServiceTitle - $ServiceName" -Description "Runs $ServiceTitle." -StartupType Automatic
30+
sc.exe failure $ServiceName reset= 30 actions= restart/5000
31+
32+
if ($Username) {
33+
Write-Host Running service under specific credentials.
34+
sc.exe config "$ServiceName" obj= "$Username" password= "$Password"
35+
}
36+
37+
# Run service
38+
net start $ServiceName
39+
40+
Write-Host Installed service $ServiceName.
41+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
. .\Functions.ps1
2+
3+
$jobsToInstall = $OctopusParameters["Jobs.ServiceNames"].Split("{,}")
4+
5+
Write-Host Installing services...
6+
7+
$currentDirectory = [string](Get-Location)
8+
9+
$jobsToInstall.Split("{;}") | %{
10+
$serviceName = $_
11+
$serviceTitle = $OctopusParameters["Jobs.$serviceName.Title"]
12+
$serviceUsername = $OctopusParameters["Jobs.$serviceName.Username"]
13+
$servicePassword = $OctopusParameters["Jobs.$serviceName.Password"]
14+
$scriptToRun = $OctopusParameters["Jobs.$serviceName.Script"]
15+
$scriptToRun = "$currentDirectory\$scriptToRun"
16+
17+
Install-NuGetService -ServiceName $serviceName -ServiceTitle $serviceTitle -ScriptToRun $scriptToRun -Username $serviceUsername -Password $servicePassword
18+
}
19+
20+
Write-Host Installed services.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
. .\Functions.ps1
2+
3+
$jobsToInstall = $OctopusParameters["Jobs.ServiceNames"].Split("{,}")
4+
5+
Write-Host Removing services...
6+
7+
$jobsToInstall.Split("{;}") | %{
8+
Uninstall-NuGetService -ServiceName $_
9+
}
10+
11+
Write-Host Removed services.
324 KB
Binary file not shown.

0 commit comments

Comments
 (0)