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

Add support for feature flags #2620

Merged
merged 14 commits into from
Dec 5, 2022
1 change: 1 addition & 0 deletions src/ApiService/ApiService/ApiService.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.0.0-preview3" />
<PackageReference Include="Semver" Version="2.1.0" />
<PackageReference Include="Azure.Security.KeyVault.Secrets" Version="4.3.0" />
<PackageReference Include="Microsoft.Azure.AppConfiguration.Functions.Worker" Version="5.1.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Storage" Version="5.0.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.EventGrid" Version="2.1.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.0.13" />
Expand Down
5 changes: 5 additions & 0 deletions src/ApiService/ApiService/FeatureFlags.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Microsoft.OneFuzz.Service;

public static class FeatureFlagConstants {
public const string EnableJinjaConvert = "EnableJinjaConvert";
}
1 change: 1 addition & 0 deletions src/ApiService/ApiService/Functions/AgentCanSchedule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class AgentCanSchedule {
private readonly IEndpointAuthorization _auth;
private readonly IOnefuzzContext _context;


public AgentCanSchedule(ILogTracer log, IEndpointAuthorization auth, IOnefuzzContext context) {
_log = log;
_auth = auth;
Expand Down
10 changes: 10 additions & 0 deletions src/ApiService/ApiService/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Microsoft.ApplicationInsights.DependencyCollector;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Middleware;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Graph;
Expand Down Expand Up @@ -47,13 +48,22 @@ public static async Async.Task Main() {

using var host =
new HostBuilder()
.ConfigureAppConfiguration(builder => {
var _ = builder.AddAzureAppConfiguration(options => {
var _ = options.Connect(new Uri(configuration.AppConfigurationEndpoint!), new ManagedIdentityCredential())
.ConfigureRefresh(refreshOptions =>
refreshOptions.SetCacheExpiration(TimeSpan.FromMinutes(1)));
});
})
.ConfigureFunctionsWorkerDefaults(builder => {
builder.UseMiddleware<LoggingMiddleware>();
builder.AddApplicationInsights(options => {
options.ConnectionString = $"InstrumentationKey={configuration.ApplicationInsightsInstrumentationKey}";
});
builder.UseAzureAppConfiguration();
})
.ConfigureServices((context, services) => {
services.AddAzureAppConfiguration();
tevoinea marked this conversation as resolved.
Show resolved Hide resolved
services.Configure<JsonSerializerOptions>(options => {
options = EntityConverter.GetJsonSerializerOptions();
});
Expand Down
3 changes: 3 additions & 0 deletions src/ApiService/ApiService/ServiceConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public interface IServiceConfig {

public string? ApplicationInsightsAppId { get; }
public string? ApplicationInsightsInstrumentationKey { get; }
public string? AppConfigurationEndpoint { get; }
public string? AzureSignalRConnectionString { get; }
public string? AzureSignalRServiceTransportType { get; }

Expand Down Expand Up @@ -82,6 +83,8 @@ public ServiceConfiguration() {
public string? ApplicationInsightsAppId => GetEnv("APPINSIGHTS_APPID");
public string? ApplicationInsightsInstrumentationKey => GetEnv("APPINSIGHTS_INSTRUMENTATIONKEY");

public string? AppConfigurationEndpoint => GetEnv("APPCONFIGURATION_ENDPOINT");
tevoinea marked this conversation as resolved.
Show resolved Hide resolved

public string? AzureSignalRConnectionString => GetEnv("AzureSignalRConnectionString");
public string? AzureSignalRServiceTransportType => GetEnv("AzureSignalRServiceTransportType");

Expand Down
8 changes: 7 additions & 1 deletion src/ApiService/ApiService/onefuzzlib/OnefuzzContext.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Microsoft.OneFuzz.Service.OneFuzzLib.Orm;
using Microsoft.Extensions.Configuration;
using Microsoft.OneFuzz.Service.OneFuzzLib.Orm;


namespace Microsoft.OneFuzz.Service;

Expand Down Expand Up @@ -46,6 +48,8 @@ public interface IOnefuzzContext {
ITeams Teams { get; }
IGithubIssues GithubIssues { get; }
IAdo Ado { get; }

IConfiguration AppConfiguration { get; }
}

public class OnefuzzContext : IOnefuzzContext {
Expand Down Expand Up @@ -95,4 +99,6 @@ public OnefuzzContext(IServiceProvider serviceProvider) {
public ITeams Teams => _serviceProvider.GetRequiredService<ITeams>();
public IGithubIssues GithubIssues => _serviceProvider.GetRequiredService<IGithubIssues>();
public IAdo Ado => _serviceProvider.GetRequiredService<IAdo>();

public IConfiguration AppConfiguration => _serviceProvider.GetRequiredService<IConfiguration>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ protected class Renderer {
private readonly Uri _targetUrl;
private readonly Uri _inputUrl;
private readonly Uri _reportUrl;
private readonly bool _shouldConvertJinja;

public static async Async.Task<Renderer> ConstructRenderer(
IOnefuzzContext context,
Expand Down Expand Up @@ -64,6 +65,10 @@ public static async Async.Task<Renderer> ConstructRenderer(
inputUrl = new Uri(context.Containers.AuthDownloadUrl(report.InputBlob.Container, report.InputBlob.Name));
}

if (!bool.TryParse(context.AppConfiguration[FeatureFlagConstants.EnableJinjaConvert], out var convertJinja)) {
convertJinja = true;
}

return new Renderer(
container,
filename,
Expand All @@ -72,7 +77,8 @@ public static async Async.Task<Renderer> ConstructRenderer(
checkedJob,
targetUrl,
inputUrl!, // TODO: incorrect
reportUrl);
reportUrl,
convertJinja);
}
public Renderer(
Container container,
Expand All @@ -82,7 +88,8 @@ public Renderer(
Job job,
Uri targetUrl,
Uri inputUrl,
Uri reportUrl) {
Uri reportUrl,
bool shouldConvertJinja) {
_report = report;
_container = container;
_filename = filename;
Expand All @@ -91,13 +98,15 @@ public Renderer(
_reportUrl = reportUrl;
_targetUrl = targetUrl;
_inputUrl = inputUrl;
_shouldConvertJinja = shouldConvertJinja;
}

// TODO: This function is fallible but the python
// implementation doesn't have that so I'm trying to match it.
// We should probably propagate any errors up
public async Async.Task<string> Render(string templateString, Uri instanceUrl) {
templateString = JinjaTemplateAdapter.IsJinjaTemplate(templateString) ? JinjaTemplateAdapter.AdaptForScriban(templateString) : templateString;
templateString = _shouldConvertJinja && JinjaTemplateAdapter.IsJinjaTemplate(templateString)
? JinjaTemplateAdapter.AdaptForScriban(templateString) : templateString;
var template = Template.Parse(templateString);
if (template != null) {
return await template.RenderAsync(new {
Expand Down
34 changes: 34 additions & 0 deletions src/ApiService/ApiService/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,16 @@
"resolved": "0.12.2",
"contentHash": "JgMAGj8ekeAzKkagubXqf1UqgfHq89GyA1UQYWbkAe441uRr2Rh2rktkx5Z0LPwmD/aOqu9cxjekD2GZjP8rbw=="
},
"Microsoft.Azure.AppConfiguration.Functions.Worker": {
"type": "Direct",
"requested": "[5.1.0, )",
"resolved": "5.1.0",
"contentHash": "80TryM3UKI/uwWM1wpUY7oSj/arQgwijevmJ41AQZmmRmiMjWGweHVSVDRz9jxDz/uVyvxrrYXEGL2qTQXT1xw==",
"dependencies": {
"Microsoft.Azure.Functions.Worker": "1.6.0",
"Microsoft.Extensions.Configuration.AzureAppConfiguration": "5.1.0"
}
},
"Microsoft.Azure.Functions.Worker": {
"type": "Direct",
"requested": "[1.10.0, )",
Expand Down Expand Up @@ -355,6 +365,16 @@
"resolved": "2.0.0",
"contentHash": "rXkSI9t4vP2EaPhuchsWiD3elcLNth3UOZAlGohGmuckpkiOr57oMHuzM5WDzz7MJd+ZewE27/WfrZhhhFDHzA=="
},
"Azure.Data.AppConfiguration": {
"type": "Transitive",
"resolved": "1.2.0",
"contentHash": "KA1dAM9TuDsq0CRFd+3cJTYUAzA2z9N8t9/xKdDbP9URuReq/NDFcKYr7GW2W9xzVGDtCHlD5j5am/+zLLBdSg==",
"dependencies": {
"Azure.Core": "1.20.0",
"Microsoft.Bcl.AsyncInterfaces": "1.0.0",
"System.Text.Json": "4.6.0"
}
},
"Azure.Storage.Common": {
"type": "Transitive",
"resolved": "12.12.0",
Expand Down Expand Up @@ -641,6 +661,20 @@
"Microsoft.Extensions.Primitives": "5.0.0"
}
},
"Microsoft.Extensions.Configuration.AzureAppConfiguration": {
"type": "Transitive",
"resolved": "5.1.0",
"contentHash": "FoAfgvT/rjL/+c7BP7q0LrJIdc4Hu6SH56BTIUbwCwVjHoUw4dpgGtLQULi5GmMjdbdAxyLQSnbwpOEWuBy+RA==",
"dependencies": {
"Azure.Data.AppConfiguration": "1.2.0",
"Azure.Messaging.EventGrid": "4.7.0",
"Azure.Security.KeyVault.Secrets": "4.0.1",
"Microsoft.Extensions.Configuration": "3.1.18",
"Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.18",
"Microsoft.Extensions.Logging": "3.1.18",
"System.Text.Json": "4.6.0"
}
},
"Microsoft.Extensions.Configuration.Binder": {
"type": "Transitive",
"resolved": "5.0.0",
Expand Down
3 changes: 2 additions & 1 deletion src/ApiService/IntegrationTests/Fakes/TestContext.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Microsoft.OneFuzz.Service;
using Microsoft.OneFuzz.Service.OneFuzzLib.Orm;
Expand Down Expand Up @@ -120,6 +121,6 @@ public Async.Task InsertAll(params EntityBase[] objs)
public ITeams Teams => throw new NotImplementedException();
public IGithubIssues GithubIssues => throw new NotImplementedException();
public IAdo Ado => throw new NotImplementedException();

public IConfiguration AppConfiguration => throw new NotImplementedException();

}
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,5 @@ public TestServiceConfiguration(string tablePrefix) {
public string? OneFuzzResourceGroup => throw new NotImplementedException();

public string? OneFuzzAllowOutdatedAgent => throw new NotImplementedException();
public string? AppConfigurationEndpoint => throw new NotImplementedException();
}
34 changes: 34 additions & 0 deletions src/ApiService/IntegrationTests/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@
"System.Threading.Tasks.Extensions": "4.5.4"
}
},
"Azure.Data.AppConfiguration": {
"type": "Transitive",
"resolved": "1.2.0",
"contentHash": "KA1dAM9TuDsq0CRFd+3cJTYUAzA2z9N8t9/xKdDbP9URuReq/NDFcKYr7GW2W9xzVGDtCHlD5j5am/+zLLBdSg==",
"dependencies": {
"Azure.Core": "1.20.0",
"Microsoft.Bcl.AsyncInterfaces": "1.0.0",
"System.Text.Json": "4.6.0"
}
},
"Azure.Data.Tables": {
"type": "Transitive",
"resolved": "12.5.0",
Expand Down Expand Up @@ -365,6 +375,15 @@
"resolved": "5.0.8",
"contentHash": "ZI9S2NGjuOKXN3PxJcF8EKVwd1cqpWyUSqiVoH8gqq5tlHaXULwPmoR0DBOFON4sEFETRWI69f5RQ3tJWw205A=="
},
"Microsoft.Azure.AppConfiguration.Functions.Worker": {
"type": "Transitive",
"resolved": "5.1.0",
"contentHash": "80TryM3UKI/uwWM1wpUY7oSj/arQgwijevmJ41AQZmmRmiMjWGweHVSVDRz9jxDz/uVyvxrrYXEGL2qTQXT1xw==",
"dependencies": {
"Microsoft.Azure.Functions.Worker": "1.6.0",
"Microsoft.Extensions.Configuration.AzureAppConfiguration": "5.1.0"
}
},
"Microsoft.Azure.Functions.Worker": {
"type": "Transitive",
"resolved": "1.10.0",
Expand Down Expand Up @@ -598,6 +617,20 @@
"Microsoft.Extensions.Primitives": "5.0.0"
}
},
"Microsoft.Extensions.Configuration.AzureAppConfiguration": {
"type": "Transitive",
"resolved": "5.1.0",
"contentHash": "FoAfgvT/rjL/+c7BP7q0LrJIdc4Hu6SH56BTIUbwCwVjHoUw4dpgGtLQULi5GmMjdbdAxyLQSnbwpOEWuBy+RA==",
"dependencies": {
"Azure.Data.AppConfiguration": "1.2.0",
"Azure.Messaging.EventGrid": "4.7.0",
"Azure.Security.KeyVault.Secrets": "4.0.1",
"Microsoft.Extensions.Configuration": "3.1.18",
"Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.18",
"Microsoft.Extensions.Logging": "3.1.18",
"System.Text.Json": "4.6.0"
}
},
"Microsoft.Extensions.Configuration.Binder": {
"type": "Transitive",
"resolved": "5.0.0",
Expand Down Expand Up @@ -2419,6 +2452,7 @@
"Azure.Storage.Blobs": "12.13.0",
"Azure.Storage.Queues": "12.11.0",
"Faithlife.Utility": "0.12.2",
"Microsoft.Azure.AppConfiguration.Functions.Worker": "5.1.0",
"Microsoft.Azure.Functions.Worker": "1.10.0",
"Microsoft.Azure.Functions.Worker.ApplicationInsights": "1.0.0-preview3",
"Microsoft.Azure.Functions.Worker.Extensions.EventGrid": "2.1.0",
Expand Down
34 changes: 34 additions & 0 deletions src/ApiService/Tests/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@
"System.Threading.Tasks.Extensions": "4.5.4"
}
},
"Azure.Data.AppConfiguration": {
"type": "Transitive",
"resolved": "1.2.0",
"contentHash": "KA1dAM9TuDsq0CRFd+3cJTYUAzA2z9N8t9/xKdDbP9URuReq/NDFcKYr7GW2W9xzVGDtCHlD5j5am/+zLLBdSg==",
"dependencies": {
"Azure.Core": "1.20.0",
"Microsoft.Bcl.AsyncInterfaces": "1.0.0",
"System.Text.Json": "4.6.0"
}
},
"Azure.Data.Tables": {
"type": "Transitive",
"resolved": "12.5.0",
Expand Down Expand Up @@ -414,6 +424,15 @@
"resolved": "5.0.8",
"contentHash": "ZI9S2NGjuOKXN3PxJcF8EKVwd1cqpWyUSqiVoH8gqq5tlHaXULwPmoR0DBOFON4sEFETRWI69f5RQ3tJWw205A=="
},
"Microsoft.Azure.AppConfiguration.Functions.Worker": {
"type": "Transitive",
"resolved": "5.1.0",
"contentHash": "80TryM3UKI/uwWM1wpUY7oSj/arQgwijevmJ41AQZmmRmiMjWGweHVSVDRz9jxDz/uVyvxrrYXEGL2qTQXT1xw==",
"dependencies": {
"Microsoft.Azure.Functions.Worker": "1.6.0",
"Microsoft.Extensions.Configuration.AzureAppConfiguration": "5.1.0"
}
},
"Microsoft.Azure.Functions.Worker": {
"type": "Transitive",
"resolved": "1.10.0",
Expand Down Expand Up @@ -647,6 +666,20 @@
"Microsoft.Extensions.Primitives": "5.0.0"
}
},
"Microsoft.Extensions.Configuration.AzureAppConfiguration": {
"type": "Transitive",
"resolved": "5.1.0",
"contentHash": "FoAfgvT/rjL/+c7BP7q0LrJIdc4Hu6SH56BTIUbwCwVjHoUw4dpgGtLQULi5GmMjdbdAxyLQSnbwpOEWuBy+RA==",
"dependencies": {
"Azure.Data.AppConfiguration": "1.2.0",
"Azure.Messaging.EventGrid": "4.7.0",
"Azure.Security.KeyVault.Secrets": "4.0.1",
"Microsoft.Extensions.Configuration": "3.1.18",
"Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.18",
"Microsoft.Extensions.Logging": "3.1.18",
"System.Text.Json": "4.6.0"
}
},
"Microsoft.Extensions.Configuration.Binder": {
"type": "Transitive",
"resolved": "5.0.0",
Expand Down Expand Up @@ -2546,6 +2579,7 @@
"Azure.Storage.Blobs": "12.13.0",
"Azure.Storage.Queues": "12.11.0",
"Faithlife.Utility": "0.12.2",
"Microsoft.Azure.AppConfiguration.Functions.Worker": "5.1.0",
"Microsoft.Azure.Functions.Worker": "1.10.0",
"Microsoft.Azure.Functions.Worker.ApplicationInsights": "1.0.0-preview3",
"Microsoft.Azure.Functions.Worker.Extensions.EventGrid": "2.1.0",
Expand Down
Loading