Skip to content
This repository was archived by the owner on Nov 1, 2023. It is now read-only.

Commit 84fbc0a

Browse files
authored
Merge branch 'main' into dependabot/cargo/src/agent/iced-x86-1.20.0
2 parents 5a99041 + 956474e commit 84fbc0a

37 files changed

+448
-300
lines changed

src/ApiService/ApiService/Functions/Containers.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ private async Async.Task<HttpResponseData> Get(HttpRequestData req) {
4141
req,
4242
Error.Create(
4343
ErrorCode.INVALID_REQUEST,
44-
"invalid container"),
44+
$"invalid container '{get.Name}'"),
4545
context: get.Name.String);
4646
}
4747

@@ -75,13 +75,7 @@ private async Async.Task<HttpResponseData> Delete(HttpRequestData req) {
7575

7676
var delete = request.OkV;
7777
_logger.LogInformation("deleting {ContainerName}", delete.Name);
78-
var container = await _context.Containers.FindContainer(delete.Name, StorageType.Corpus);
79-
80-
var deleted = false;
81-
if (container is not null) {
82-
deleted = await container.DeleteIfExistsAsync();
83-
}
84-
78+
var deleted = await _context.Containers.DeleteContainerIfExists(delete.Name, StorageType.Corpus);
8579
return await RequestHandling.Ok(req, deleted);
8680
}
8781

src/ApiService/ApiService/Functions/Events.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
using Microsoft.Azure.Functions.Worker;
22
using Microsoft.Azure.Functions.Worker.Http;
3-
using Microsoft.Extensions.Logging;
43
using Microsoft.OneFuzz.Service.Auth;
54
namespace Microsoft.OneFuzz.Service.Functions;
65

76
public class EventsFunction {
8-
private readonly ILogger _log;
97
private readonly IOnefuzzContext _context;
108

11-
public EventsFunction(ILogger<EventsFunction> log, IOnefuzzContext context) {
9+
public EventsFunction(IOnefuzzContext context) {
1210
_context = context;
13-
_log = log;
1411
}
1512

1613
[Function("Events")]

src/ApiService/ApiService/OneFuzzTypes/Enums.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public enum ErrorCode {
88
INVALID_PERMISSION = 451,
99
MISSING_EULA_AGREEMENT = 452,
1010
INVALID_JOB = 453,
11-
INVALID_TASK = INVALID_JOB,
11+
INVALID_TASK = 493,
1212
UNABLE_TO_ADD_TASK_TO_JOB = 454,
1313
INVALID_CONTAINER = 455,
1414
UNABLE_TO_RESIZE = 456,

src/ApiService/ApiService/OneFuzzTypes/Model.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ public static Error Create(ErrorCode code, params string[] errors)
173173
=> new(code, errors.ToList());
174174

175175
public sealed override string ToString() {
176-
var errorsString = Errors != null ? string.Concat("; ", Errors) : string.Empty;
176+
var errorsString = Errors != null ? string.Join("; ", Errors) : string.Empty;
177177
return $"Error {{ Code = {Code}, Errors = {errorsString} }}";
178178
}
179179
};
@@ -767,6 +767,11 @@ public record ClientCredentials
767767
string ClientSecret
768768
);
769769

770+
public record ContainerInformation(
771+
[PartitionKey] StorageType Type,
772+
[RowKey] Container Name,
773+
string ResourceId // full ARM resource ID for the container
774+
) : EntityBase;
770775

771776
public record AgentConfig(
772777
ClientCredentials? ClientCredentials,

src/ApiService/ApiService/OneFuzzTypes/ReturnTypes.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
namespace Microsoft.OneFuzz.Service {
44

5+
public static class Result {
6+
public readonly record struct OkPlaceholder();
7+
public readonly record struct OkPlaceholder<T>(T Value);
8+
public readonly record struct ErrPlaceholder<T>(T Value);
9+
10+
public static OkPlaceholder Ok() => new();
11+
public static OkPlaceholder<T> Ok<T>(T value) => new(value);
12+
public static ErrPlaceholder<T> Error<T>(T value) => new(value);
13+
}
14+
515
public readonly struct ResultVoid<T_Error> {
616
public static ResultVoid<T_Error> Ok() => new();
717
public static ResultVoid<T_Error> Error(T_Error err) => new(err);
@@ -13,15 +23,16 @@ public readonly struct ResultVoid<T_Error> {
1323
public bool IsOk { get; }
1424

1525
public T_Error? ErrorV { get; }
16-
}
1726

27+
public static implicit operator ResultVoid<T_Error>(Result.OkPlaceholder _ok) => Ok();
28+
public static implicit operator ResultVoid<T_Error>(Result.ErrPlaceholder<T_Error> err) => Error(err.Value);
29+
}
1830

1931
public readonly struct Result<T_Ok, T_Error> {
2032
public static Result<T_Ok, T_Error> Ok(T_Ok ok) => new(ok);
2133
public static Result<T_Ok, T_Error> Error(T_Error err) => new(err);
2234

2335
private Result(T_Ok ok) => (OkV, ErrorV, IsOk) = (ok, default, true);
24-
2536
private Result(T_Error error) => (ErrorV, OkV, IsOk) = (error, default, false);
2637

2738
[MemberNotNullWhen(returnValue: true, member: nameof(OkV))]
@@ -31,6 +42,9 @@ public readonly struct Result<T_Ok, T_Error> {
3142
public T_Error? ErrorV { get; }
3243

3344
public T_Ok? OkV { get; }
45+
46+
public static implicit operator Result<T_Ok, T_Error>(Result.OkPlaceholder<T_Ok> ok) => Ok(ok.Value);
47+
public static implicit operator Result<T_Ok, T_Error>(Result.ErrPlaceholder<T_Error> err) => Error(err.Value);
3448
}
3549

3650
public static class OneFuzzResult {
@@ -61,6 +75,8 @@ public readonly struct OneFuzzResult<T_Ok> {
6175

6276
// Allow simple conversion of Errors to Results.
6377
public static implicit operator OneFuzzResult<T_Ok>(Error err) => new(err);
78+
public static implicit operator OneFuzzResult<T_Ok>(Result.OkPlaceholder<T_Ok> ok) => Ok(ok.Value);
79+
public static implicit operator OneFuzzResult<T_Ok>(Result.ErrPlaceholder<Error> err) => Error(err.Value);
6480
}
6581

6682
public readonly struct OneFuzzResultVoid {
@@ -83,5 +99,7 @@ public readonly struct OneFuzzResultVoid {
8399

84100
// Allow simple conversion of Errors to Results.
85101
public static implicit operator OneFuzzResultVoid(Error err) => new(err);
102+
public static implicit operator OneFuzzResultVoid(Result.OkPlaceholder _ok) => Ok;
103+
public static implicit operator OneFuzzResultVoid(Result.ErrPlaceholder<Error> err) => Error(err.Value);
86104
}
87105
}

src/ApiService/ApiService/Program.cs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,19 @@ public static async Async.Task Main() {
7070
.ConfigureAppConfiguration(builder => {
7171
// Using a connection string in dev allows us to run the functions locally.
7272
if (!string.IsNullOrEmpty(configuration.AppConfigurationConnectionString)) {
73-
var _ = builder.AddAzureAppConfiguration(options => {
74-
var _ = options
73+
builder.AddAzureAppConfiguration(options => {
74+
options
7575
.Connect(configuration.AppConfigurationConnectionString)
7676
.UseFeatureFlags(ffOptions => ffOptions.CacheExpirationInterval = TimeSpan.FromSeconds(30));
7777
});
78-
} else {
79-
var _ = builder.AddAzureAppConfiguration(options => {
80-
var _ = options
81-
.Connect(new Uri(configuration.AppConfigurationEndpoint!), new DefaultAzureCredential())
78+
} else if (!string.IsNullOrEmpty(configuration.AppConfigurationEndpoint)) {
79+
builder.AddAzureAppConfiguration(options => {
80+
options
81+
.Connect(new Uri(configuration.AppConfigurationEndpoint), new DefaultAzureCredential())
8282
.UseFeatureFlags(ffOptions => ffOptions.CacheExpirationInterval = TimeSpan.FromMinutes(1));
8383
});
84+
} else {
85+
throw new InvalidOperationException($"One of APPCONFIGURATION_CONNECTION_STRING or APPCONFIGURATION_ENDPOINT must be set");
8486
}
8587
})
8688
.ConfigureServices((context, services) => {
@@ -201,13 +203,10 @@ public static async Async.Task SetupStorage(IStorage storage, IServiceConfig ser
201203
}
202204
}
203205

204-
var storageAccount = serviceConfig.OneFuzzFuncStorage;
205-
if (storageAccount is not null) {
206-
var tableClient = await storage.GetTableServiceClientForAccount(storageAccount);
207-
await Async.Task.WhenAll(toCreate.Select(async t => {
208-
// don't care if it was created or not
209-
_ = await tableClient.CreateTableIfNotExistsAsync(serviceConfig.OneFuzzStoragePrefix + t.Name);
210-
}));
211-
}
206+
var tableClient = await storage.GetTableServiceClientForAccount(serviceConfig.OneFuzzFuncStorage);
207+
await Async.Task.WhenAll(toCreate.Select(async t => {
208+
// don't care if it was created or not
209+
_ = await tableClient.CreateTableIfNotExistsAsync(serviceConfig.OneFuzzStoragePrefix + t.Name);
210+
}));
212211
}
213212
}

src/ApiService/ApiService/ServiceConfiguration.cs

Lines changed: 55 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -10,57 +10,51 @@ public enum LogDestination {
1010

1111

1212
public interface IServiceConfig {
13-
public LogDestination[] LogDestinations { get; set; }
14-
13+
#region Parameters for logging & application insights
14+
public LogDestination[] LogDestinations { get; }
1515
public ApplicationInsights.DataContracts.SeverityLevel LogSeverityLevel { get; }
16-
1716
public string? ApplicationInsightsAppId { get; }
1817
public string? ApplicationInsightsInstrumentationKey { get; }
18+
#endregion
19+
20+
#region Parameters for feature flags
1921
public string? AppConfigurationEndpoint { get; }
2022
public string? AppConfigurationConnectionString { get; }
21-
public string? AzureSignalRConnectionString { get; }
22-
public string? AzureSignalRServiceTransportType { get; }
23-
24-
public string? AzureWebJobDisableHomePage { get; }
25-
public string? AzureWebJobStorage { get; }
23+
#endregion
2624

27-
public string? DiagnosticsAzureBlobContainerSasUrl { get; }
28-
public string? DiagnosticsAzureBlobRetentionDays { get; }
25+
#region Auth parameters for CLI app
2926
public string? CliAppId { get; }
3027
public string? Authority { get; }
3128
public string? TenantDomain { get; }
3229
public string? MultiTenantDomain { get; }
33-
public ResourceIdentifier? OneFuzzDataStorage { get; }
34-
public ResourceIdentifier? OneFuzzFuncStorage { get; }
35-
public string? OneFuzzInstance { get; }
36-
public string? OneFuzzInstanceName { get; }
37-
public string? OneFuzzEndpoint { get; }
38-
public string? OneFuzzKeyvault { get; }
39-
30+
#endregion
31+
32+
public ResourceIdentifier OneFuzzResourceGroup { get; }
33+
public ResourceIdentifier OneFuzzDataStorage { get; }
34+
public ResourceIdentifier OneFuzzFuncStorage { get; }
35+
public Uri OneFuzzInstance { get; }
36+
public string OneFuzzInstanceName { get; }
37+
public Uri? OneFuzzEndpoint { get; }
38+
public string OneFuzzKeyvault { get; }
4039
public string? OneFuzzMonitor { get; }
4140
public string? OneFuzzOwner { get; }
42-
43-
public string? OneFuzzResourceGroup { get; }
4441
public string? OneFuzzTelemetry { get; }
45-
4642
public string OneFuzzVersion { get; }
47-
4843
public string? OneFuzzAllowOutdatedAgent { get; }
4944

5045
// Prefix to add to the name of any tables & containers created. This allows
5146
// multiple instances to run against the same storage account, which
5247
// is useful for things like integration testing.
5348
public string OneFuzzStoragePrefix { get; }
54-
55-
public Uri OneFuzzBaseAddress { get; }
5649
}
5750

5851
public class ServiceConfiguration : IServiceConfig {
5952

6053
// Version is baked into the assembly by the build process:
61-
private static readonly string? _oneFuzzVersion =
54+
private static readonly string _oneFuzzVersion =
6255
Assembly.GetExecutingAssembly()
63-
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
56+
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion
57+
?? throw new InvalidOperationException("Unable to read OneFuzz version from assembly");
6458

6559
public ServiceConfiguration() {
6660
#if DEBUG
@@ -72,78 +66,57 @@ public ServiceConfiguration() {
7266

7367
private static string? GetEnv(string name) {
7468
var v = Environment.GetEnvironmentVariable(name);
75-
if (String.IsNullOrEmpty(v))
76-
return null;
77-
78-
return v;
69+
return string.IsNullOrEmpty(v) ? null : v;
7970
}
8071

72+
private static string MustGetEnv(string name)
73+
=> GetEnv(name) ?? throw new InvalidOperationException($"Environment variable {name} is required to be set");
74+
8175
//TODO: Add environment variable to control where to write logs to
82-
public LogDestination[] LogDestinations { get; set; }
76+
public LogDestination[] LogDestinations { get; private set; }
8377

8478
//TODO: Get this from Environment variable
8579
public ApplicationInsights.DataContracts.SeverityLevel LogSeverityLevel => ApplicationInsights.DataContracts.SeverityLevel.Verbose;
8680

87-
public string? ApplicationInsightsAppId => GetEnv("APPINSIGHTS_APPID");
88-
public string? ApplicationInsightsInstrumentationKey => GetEnv("APPINSIGHTS_INSTRUMENTATIONKEY");
81+
public string? ApplicationInsightsAppId { get; } = GetEnv("APPINSIGHTS_APPID");
8982

90-
public string? AppConfigurationEndpoint => GetEnv("APPCONFIGURATION_ENDPOINT");
83+
public string? ApplicationInsightsInstrumentationKey { get; } = GetEnv("APPINSIGHTS_INSTRUMENTATIONKEY");
9184

92-
public string? AppConfigurationConnectionString => GetEnv("APPCONFIGURATION_CONNECTION_STRING");
85+
public string? AppConfigurationEndpoint { get; } = GetEnv("APPCONFIGURATION_ENDPOINT");
9386

94-
public string? AzureSignalRConnectionString => GetEnv("AzureSignalRConnectionString");
95-
public string? AzureSignalRServiceTransportType => GetEnv("AzureSignalRServiceTransportType");
87+
public string? AppConfigurationConnectionString { get; } = GetEnv("APPCONFIGURATION_CONNECTION_STRING");
9688

97-
public string? AzureWebJobDisableHomePage { get => GetEnv("AzureWebJobsDisableHomepage"); }
98-
public string? AzureWebJobStorage { get => GetEnv("AzureWebJobsStorage"); }
89+
public string? CliAppId { get; } = GetEnv("CLI_APP_ID");
9990

100-
public string? DiagnosticsAzureBlobContainerSasUrl { get => GetEnv("DIAGNOSTICS_AZUREBLOBCONTAINERSASURL"); }
101-
public string? DiagnosticsAzureBlobRetentionDays { get => GetEnv("DIAGNOSTICS_AZUREBLOBRETENTIONINDAYS"); }
102-
public string? CliAppId { get => GetEnv("CLI_APP_ID"); }
103-
public string? Authority { get => GetEnv("AUTHORITY"); }
104-
public string? TenantDomain { get => GetEnv("TENANT_DOMAIN"); }
105-
public string? MultiTenantDomain { get => GetEnv("MULTI_TENANT_DOMAIN"); }
91+
public string? Authority { get; } = GetEnv("AUTHORITY");
10692

107-
public ResourceIdentifier? OneFuzzDataStorage {
108-
get {
109-
var env = GetEnv("ONEFUZZ_DATA_STORAGE");
110-
return env is null ? null : new ResourceIdentifier(env);
111-
}
112-
}
93+
public string? TenantDomain { get; } = GetEnv("TENANT_DOMAIN");
11394

114-
public ResourceIdentifier? OneFuzzFuncStorage {
115-
get {
116-
var env = GetEnv("ONEFUZZ_FUNC_STORAGE");
117-
return env is null ? null : new ResourceIdentifier(env);
118-
}
119-
}
95+
public string? MultiTenantDomain { get; } = GetEnv("MULTI_TENANT_DOMAIN");
12096

121-
public string? OneFuzzInstance { get => GetEnv("ONEFUZZ_INSTANCE"); }
122-
public string? OneFuzzInstanceName { get => GetEnv("ONEFUZZ_INSTANCE_NAME"); }
123-
public string? OneFuzzEndpoint { get => GetEnv("ONEFUZZ_ENDPOINT"); }
124-
public string? OneFuzzKeyvault { get => GetEnv("ONEFUZZ_KEYVAULT"); }
125-
public string? OneFuzzMonitor { get => GetEnv("ONEFUZZ_MONITOR"); }
126-
public string? OneFuzzOwner { get => GetEnv("ONEFUZZ_OWNER"); }
127-
public string? OneFuzzResourceGroup { get => GetEnv("ONEFUZZ_RESOURCE_GROUP"); }
128-
public string? OneFuzzTelemetry { get => GetEnv("ONEFUZZ_TELEMETRY"); }
129-
130-
public string OneFuzzVersion {
131-
get {
132-
// version can be overridden by config:
133-
return GetEnv("ONEFUZZ_VERSION")
134-
?? _oneFuzzVersion
135-
?? throw new InvalidOperationException("Unable to read OneFuzz version from assembly");
136-
}
137-
}
97+
public ResourceIdentifier OneFuzzDataStorage { get; } = new(MustGetEnv("ONEFUZZ_DATA_STORAGE"));
13898

139-
public string? OneFuzzAllowOutdatedAgent => GetEnv("ONEFUZZ_ALLOW_OUTDATED_AGENT");
140-
public string OneFuzzStoragePrefix => ""; // in production we never prefix the tables
99+
public ResourceIdentifier OneFuzzFuncStorage { get; } = new(MustGetEnv("ONEFUZZ_FUNC_STORAGE"));
141100

142-
public Uri OneFuzzBaseAddress {
143-
get {
144-
var hostName = Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME");
145-
var scheme = Environment.GetEnvironmentVariable("HTTPS") != null ? "https" : "http";
146-
return new Uri($"{scheme}://{hostName}");
147-
}
148-
}
101+
public Uri OneFuzzInstance { get; } = new Uri(MustGetEnv("ONEFUZZ_INSTANCE"));
102+
103+
public string OneFuzzInstanceName { get; } = MustGetEnv("ONEFUZZ_INSTANCE_NAME");
104+
105+
public Uri? OneFuzzEndpoint { get; } = GetEnv("ONEFUZZ_ENDPOINT") is string value ? new Uri(value) : null;
106+
107+
public string OneFuzzKeyvault { get; } = MustGetEnv("ONEFUZZ_KEYVAULT");
108+
109+
public string? OneFuzzMonitor { get; } = GetEnv("ONEFUZZ_MONITOR");
110+
111+
public string? OneFuzzOwner { get; } = GetEnv("ONEFUZZ_OWNER");
112+
113+
public ResourceIdentifier OneFuzzResourceGroup { get; } = new(MustGetEnv("ONEFUZZ_RESOURCE_GROUP"));
114+
115+
public string? OneFuzzTelemetry { get; } = GetEnv("ONEFUZZ_TELEMETRY");
116+
117+
public string OneFuzzVersion { get; } = GetEnv("ONEFUZZ_VERSION") ?? _oneFuzzVersion;
118+
119+
public string? OneFuzzAllowOutdatedAgent { get; } = GetEnv("ONEFUZZ_ALLOW_OUTDATED_AGENT");
120+
121+
public string OneFuzzStoragePrefix => ""; // in production we never prefix the tables
149122
}

src/ApiService/ApiService/onefuzzlib/ConfigOperations.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ public ConfigOperations(ILogger<ConfigOperations> log, IOnefuzzContext context,
2626
public Task<InstanceConfig> Fetch()
2727
=> _cache.GetOrCreateAsync(_instanceConfigCacheKey, async entry => {
2828
entry = entry.SetAbsoluteExpiration(TimeSpan.FromMinutes(1)); // cached for 1 minute
29-
var key = _context.ServiceConfiguration.OneFuzzInstanceName ?? throw new Exception("Environment variable ONEFUZZ_INSTANCE_NAME is not set");
29+
var key = _context.ServiceConfiguration.OneFuzzInstanceName;
3030
return await GetEntityAsync(key, key);
3131
})!; // NULLABLE: only this class inserts _instanceConfigCacheKey so it cannot be null
3232

3333
public async Async.Task Save(InstanceConfig config, bool isNew = false, bool requireEtag = false) {
34-
var newConfig = config with { InstanceName = _context.ServiceConfiguration.OneFuzzInstanceName ?? throw new Exception("Environment variable ONEFUZZ_INSTANCE_NAME is not set") };
34+
var newConfig = config with { InstanceName = _context.ServiceConfiguration.OneFuzzInstanceName };
3535
ResultVoid<(HttpStatusCode Status, string Reason)> r;
3636
if (isNew) {
3737
r = await Insert(newConfig);

0 commit comments

Comments
 (0)