92 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System.Collections.Generic;
 | |
| using System.Linq;
 | |
| using Microsoft.Extensions.Options;
 | |
| using StellaOps.Vexer.Attestation.Extensions;
 | |
| using StellaOps.Vexer.Attestation;
 | |
| using StellaOps.Vexer.Attestation.Transparency;
 | |
| using StellaOps.Vexer.ArtifactStores.S3.Extensions;
 | |
| using StellaOps.Vexer.Export;
 | |
| using StellaOps.Vexer.Storage.Mongo;
 | |
| using StellaOps.Vexer.Connectors.RedHat.CSAF.DependencyInjection;
 | |
| 
 | |
| var builder = WebApplication.CreateBuilder(args);
 | |
| var configuration = builder.Configuration;
 | |
| var services = builder.Services;
 | |
| 
 | |
| services.AddOptions<VexMongoStorageOptions>()
 | |
|     .Bind(configuration.GetSection("Vexer:Storage:Mongo"))
 | |
|     .ValidateOnStart();
 | |
| 
 | |
| services.AddVexerMongoStorage();
 | |
| services.AddVexExportEngine();
 | |
| services.AddVexExportCacheServices();
 | |
| services.AddVexAttestation();
 | |
| services.Configure<VexAttestationClientOptions>(configuration.GetSection("Vexer:Attestation:Client"));
 | |
| services.AddRedHatCsafConnector();
 | |
| 
 | |
| var rekorSection = configuration.GetSection("Vexer:Attestation:Rekor");
 | |
| if (rekorSection.Exists())
 | |
| {
 | |
|     services.AddVexRekorClient(opts => rekorSection.Bind(opts));
 | |
| }
 | |
| 
 | |
| var fileSystemSection = configuration.GetSection("Vexer:Artifacts:FileSystem");
 | |
| if (fileSystemSection.Exists())
 | |
| {
 | |
|     services.AddVexFileSystemArtifactStore(opts => fileSystemSection.Bind(opts));
 | |
| }
 | |
| else
 | |
| {
 | |
|     services.AddVexFileSystemArtifactStore(_ => { });
 | |
| }
 | |
| 
 | |
| var s3Section = configuration.GetSection("Vexer:Artifacts:S3");
 | |
| if (s3Section.Exists())
 | |
| {
 | |
|     services.AddVexS3ArtifactClient(opts => s3Section.GetSection("Client").Bind(opts));
 | |
|     services.AddSingleton<IVexArtifactStore, S3ArtifactStore>(provider =>
 | |
|     {
 | |
|         var options = new S3ArtifactStoreOptions();
 | |
|         s3Section.GetSection("Store").Bind(options);
 | |
|         return new S3ArtifactStore(
 | |
|             provider.GetRequiredService<IS3ArtifactClient>(),
 | |
|             Microsoft.Extensions.Options.Options.Create(options),
 | |
|             provider.GetRequiredService<Microsoft.Extensions.Logging.ILogger<S3ArtifactStore>>());
 | |
|     });
 | |
| }
 | |
| 
 | |
| var offlineSection = configuration.GetSection("Vexer:Artifacts:OfflineBundle");
 | |
| if (offlineSection.Exists())
 | |
| {
 | |
|     services.AddVexOfflineBundleArtifactStore(opts => offlineSection.Bind(opts));
 | |
| }
 | |
| 
 | |
| services.AddEndpointsApiExplorer();
 | |
| services.AddHealthChecks();
 | |
| services.AddSingleton(TimeProvider.System);
 | |
| 
 | |
| var app = builder.Build();
 | |
| 
 | |
| app.MapGet("/vexer/status", async (HttpContext context,
 | |
|     IEnumerable<IVexArtifactStore> artifactStores,
 | |
|     IOptions<VexMongoStorageOptions> mongoOptions,
 | |
|     TimeProvider timeProvider) =>
 | |
| {
 | |
|     var payload = new StatusResponse(
 | |
|         timeProvider.GetUtcNow(),
 | |
|         mongoOptions.Value.RawBucketName,
 | |
|         mongoOptions.Value.GridFsInlineThresholdBytes,
 | |
|         artifactStores.Select(store => store.GetType().Name).ToArray());
 | |
| 
 | |
|     context.Response.ContentType = "application/json";
 | |
|     await System.Text.Json.JsonSerializer.SerializeAsync(context.Response.Body, payload);
 | |
| });
 | |
| 
 | |
| app.MapHealthChecks("/vexer/health");
 | |
| 
 | |
| app.Run();
 | |
| 
 | |
| public partial class Program;
 | |
| 
 | |
| internal sealed record StatusResponse(DateTimeOffset UtcNow, string MongoBucket, int InlineThreshold, string[] ArtifactStores);
 |