mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-14 11:08:06 +00:00
Fix execution of TimerProxy (#2133)
* Fix execution of timerProxy - fixed behavior of Container.SaveBlob (file was not being overwritten) - added support for default value in the entity converter - fix scaleset size data type - added initialization of Subnet - renamed TestHook Info to _Info to prevent clashing of name function mame - added target framework to ApiServiceProject to help local debugging * fix unit tests * fix unit tests * remove unused property * fix typo * removing partial class TimerProxy
This commit is contained in:
@ -3,6 +3,7 @@
|
||||
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
|
||||
<OutputType>Exe</OutputType>
|
||||
<WarningLevel>5</WarningLevel>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.ResourceManager.Monitor" Version="1.0.0-beta.2" />
|
||||
|
@ -195,7 +195,7 @@ public record EventScalesetFailed(
|
||||
public record EventScalesetResizeScheduled(
|
||||
Guid ScalesetId,
|
||||
PoolName PoolName,
|
||||
int size
|
||||
long size
|
||||
) : BaseEvent();
|
||||
|
||||
|
||||
|
@ -310,12 +310,13 @@ public record InstanceConfig
|
||||
(
|
||||
[PartitionKey, RowKey] string InstanceName,
|
||||
Guid[]? Admins,
|
||||
bool? AllowPoolManagement,
|
||||
|
||||
string[] AllowedAadTenants,
|
||||
NetworkConfig NetworkConfig,
|
||||
NetworkSecurityGroupConfig ProxyNsgConfig,
|
||||
[DefaultValue(InitMethod.DefaultConstructor)] NetworkConfig NetworkConfig,
|
||||
[DefaultValue(InitMethod.DefaultConstructor)] NetworkSecurityGroupConfig ProxyNsgConfig,
|
||||
AzureVmExtensionConfig? Extensions,
|
||||
string ProxyVmSku,
|
||||
string? ProxyVmSku,
|
||||
bool AllowPoolManagement = true,
|
||||
IDictionary<Endpoint, ApiAccessRule>? ApiAccessRules = null,
|
||||
IDictionary<PrincipalId, GroupId[]>? GroupMembership = null,
|
||||
IDictionary<string, string>? VmTags = null,
|
||||
@ -325,13 +326,13 @@ public record InstanceConfig
|
||||
public InstanceConfig(string instanceName) : this(
|
||||
instanceName,
|
||||
null,
|
||||
true,
|
||||
Array.Empty<string>(),
|
||||
new NetworkConfig(),
|
||||
new NetworkSecurityGroupConfig(),
|
||||
null,
|
||||
"Standard_B2s") { }
|
||||
public InstanceConfig() : this(String.Empty) { }
|
||||
"Standard_B2s",
|
||||
true
|
||||
) { }
|
||||
|
||||
public static List<Guid>? CheckAdmins(List<Guid>? value) {
|
||||
if (value is not null && value.Count == 0) {
|
||||
@ -341,6 +342,8 @@ public record InstanceConfig
|
||||
}
|
||||
}
|
||||
|
||||
public InstanceConfig() : this(String.Empty) { }
|
||||
|
||||
//# At the moment, this only checks allowed_aad_tenants, however adding
|
||||
//# support for 3rd party JWT validation is anticipated in a future release.
|
||||
public ResultVoid<List<string>> CheckInstanceConfig() {
|
||||
@ -373,12 +376,12 @@ public record Scaleset(
|
||||
string VmSku,
|
||||
string Image,
|
||||
Region Region,
|
||||
int Size,
|
||||
bool SpotInstance,
|
||||
long Size,
|
||||
bool? SpotInstances,
|
||||
bool EphemeralOsDisks,
|
||||
bool NeedsConfigUpdate,
|
||||
Error? Error,
|
||||
List<ScalesetNodeState> Nodes,
|
||||
List<ScalesetNodeState>? Nodes,
|
||||
Guid? ClientId,
|
||||
Guid? ClientObjectId,
|
||||
Dictionary<string, string> Tags
|
||||
|
@ -112,6 +112,7 @@ public class Program {
|
||||
.AddScoped<IOnefuzzContext, OnefuzzContext>()
|
||||
.AddScoped<IEndpointAuthorization, EndpointAuthorization>()
|
||||
.AddScoped<INodeMessageOperations, NodeMessageOperations>()
|
||||
.AddScoped<ISubnet, Subnet>()
|
||||
|
||||
.AddSingleton<ICreds, Creds>()
|
||||
.AddSingleton<IServiceConfig, ServiceConfiguration>()
|
||||
|
@ -26,7 +26,7 @@ public class TestHooks {
|
||||
_logAnalytics = logAnalytics;
|
||||
}
|
||||
|
||||
[Function("Info")]
|
||||
[Function("_Info")]
|
||||
public async Task<HttpResponseData> Info([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "testhooks/info")] HttpRequestData req) {
|
||||
_log.Info("Creating function info response");
|
||||
var response = req.CreateResponse();
|
||||
|
@ -2,8 +2,7 @@
|
||||
|
||||
namespace Microsoft.OneFuzz.Service;
|
||||
|
||||
|
||||
public partial class TimerProxy {
|
||||
public class TimerProxy {
|
||||
private readonly ILogTracer _logger;
|
||||
private readonly IOnefuzzContext _context;
|
||||
|
||||
|
@ -145,7 +145,7 @@ public class Containers : IContainers {
|
||||
|
||||
public async Async.Task SaveBlob(Container container, string name, string data, StorageType storageType) {
|
||||
var client = await FindContainer(container, storageType) ?? throw new Exception($"unable to find container: {container.ContainerName} - {storageType}");
|
||||
await client.UploadBlobAsync(name, new BinaryData(data));
|
||||
await client.GetBlobClient(name).UploadAsync(new BinaryData(data), overwrite: true);
|
||||
}
|
||||
|
||||
public Async.Task<Guid> GetInstanceId() => _getInstanceId.Value;
|
||||
|
@ -2,9 +2,7 @@
|
||||
|
||||
namespace Microsoft.OneFuzz.Service;
|
||||
|
||||
|
||||
public partial class TimerProxy {
|
||||
public class Network {
|
||||
public class Network {
|
||||
private readonly string _name;
|
||||
private readonly string _group;
|
||||
private readonly string _region;
|
||||
@ -50,7 +48,4 @@ public partial class TimerProxy {
|
||||
internal Async.Task<VirtualNetworkResource?> GetVnet() {
|
||||
return _context.Subnet.GetVnet(_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -20,6 +20,21 @@ public abstract record EntityBase {
|
||||
public abstract record StatefulEntityBase<T>([property: JsonIgnore] T State) : EntityBase() where T : Enum;
|
||||
|
||||
|
||||
|
||||
/// How the value is populated
|
||||
public enum InitMethod {
|
||||
//T() will be used
|
||||
DefaultConstructor,
|
||||
}
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
public class DefaultValueAttribute : Attribute {
|
||||
|
||||
public InitMethod InitMethod { get; }
|
||||
public DefaultValueAttribute(InitMethod initMethod) {
|
||||
InitMethod = initMethod;
|
||||
}
|
||||
}
|
||||
|
||||
/// Indicates that the enum cases should no be renamed
|
||||
[AttributeUsage(AttributeTargets.Enum)]
|
||||
public class SerializeValueAttribute : Attribute { }
|
||||
@ -56,7 +71,15 @@ public enum EntityPropertyKind {
|
||||
RowKey,
|
||||
Column
|
||||
}
|
||||
public record EntityProperty(string name, string columnName, Type type, EntityPropertyKind kind, (TypeDiscrimnatorAttribute, ITypeProvider)? discriminator);
|
||||
public record EntityProperty(
|
||||
string name,
|
||||
string columnName,
|
||||
Type type,
|
||||
EntityPropertyKind kind,
|
||||
(TypeDiscrimnatorAttribute, ITypeProvider)? discriminator,
|
||||
DefaultValueAttribute? defaultValue,
|
||||
ParameterInfo parameterInfo
|
||||
);
|
||||
public record EntityInfo(Type type, ILookup<string, EntityProperty> properties, Func<object?[], object> constructor);
|
||||
|
||||
class OnefuzzNamingPolicy : JsonNamingPolicy {
|
||||
@ -108,6 +131,8 @@ public class EntityConverter {
|
||||
var isPartitionkey = parameterInfo.GetCustomAttribute(typeof(PartitionKeyAttribute)) != null;
|
||||
|
||||
var discriminatorAttribute = typeof(T).GetProperty(name)?.GetCustomAttribute<TypeDiscrimnatorAttribute>();
|
||||
var defaultValueAttribute = parameterInfo.GetCustomAttribute<DefaultValueAttribute>();
|
||||
|
||||
|
||||
(TypeDiscrimnatorAttribute, ITypeProvider)? discriminator = null;
|
||||
if (discriminatorAttribute != null) {
|
||||
@ -117,16 +142,16 @@ public class EntityConverter {
|
||||
|
||||
|
||||
if (isPartitionkey) {
|
||||
yield return new EntityProperty(name, "PartitionKey", parameterType, EntityPropertyKind.PartitionKey, discriminator);
|
||||
yield return new EntityProperty(name, "PartitionKey", parameterType, EntityPropertyKind.PartitionKey, discriminator, defaultValueAttribute, parameterInfo);
|
||||
}
|
||||
|
||||
if (isRowkey) {
|
||||
yield return new EntityProperty(name, "RowKey", parameterType, EntityPropertyKind.RowKey, discriminator);
|
||||
yield return new EntityProperty(name, "RowKey", parameterType, EntityPropertyKind.RowKey, discriminator, defaultValueAttribute, parameterInfo);
|
||||
}
|
||||
|
||||
if (!isPartitionkey && !isRowkey) {
|
||||
var columnName = typeof(T).GetProperty(name)?.GetCustomAttribute<JsonPropertyNameAttribute>()?.Name ?? CaseConverter.PascalToSnake(name);
|
||||
yield return new EntityProperty(name, columnName, parameterType, EntityPropertyKind.Column, discriminator);
|
||||
yield return new EntityProperty(name, columnName, parameterType, EntityPropertyKind.Column, discriminator, defaultValueAttribute, parameterInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,7 +243,15 @@ public class EntityConverter {
|
||||
var fieldName = ef.columnName;
|
||||
var obj = entity[fieldName];
|
||||
if (obj == null) {
|
||||
return null;
|
||||
|
||||
if (ef.parameterInfo.HasDefaultValue) {
|
||||
return ef.parameterInfo.DefaultValue;
|
||||
}
|
||||
|
||||
return ef.defaultValue switch {
|
||||
DefaultValueAttribute { InitMethod: InitMethod.DefaultConstructor } => Activator.CreateInstance(ef.type),
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
var objType = obj.GetType();
|
||||
|
||||
|
@ -164,7 +164,7 @@ namespace Tests {
|
||||
|
||||
public static Gen<InstanceConfig> InstanceConfig() {
|
||||
return Arb.Generate<Tuple<
|
||||
Tuple<string, Guid[]?, bool?, string[], NetworkConfig, NetworkSecurityGroupConfig, AzureVmExtensionConfig?>,
|
||||
Tuple<string, Guid[]?, bool, string[], NetworkConfig, NetworkSecurityGroupConfig, AzureVmExtensionConfig?>,
|
||||
Tuple<string, IDictionary<string, ApiAccessRule>?, IDictionary<Guid, Guid[]>?, IDictionary<string, string>?, IDictionary<string, string>?>>>().Select(
|
||||
arg =>
|
||||
new InstanceConfig(
|
||||
@ -221,7 +221,7 @@ namespace Tests {
|
||||
Region: arg.Item1.Item6,
|
||||
|
||||
Size: arg.Item2.Item1,
|
||||
SpotInstance: arg.Item2.Item2,
|
||||
SpotInstances: arg.Item2.Item2,
|
||||
EphemeralOsDisks: arg.Item2.Item3,
|
||||
NeedsConfigUpdate: arg.Item2.Item4,
|
||||
Error: arg.Item2.Item5,
|
||||
|
@ -380,6 +380,24 @@ namespace Tests {
|
||||
}
|
||||
|
||||
|
||||
class TestClass {
|
||||
public string Name { get; }
|
||||
public TestClass() {
|
||||
Name = "testName";
|
||||
}
|
||||
}
|
||||
record TestIinit([DefaultValue(InitMethod.DefaultConstructor)] TestClass testClass, string test = "default_test") : EntityBase();
|
||||
|
||||
[Fact]
|
||||
public void TestInitValue() {
|
||||
var entityConverter = new EntityConverter();
|
||||
var tableEntity = new TableEntity();
|
||||
var actual = entityConverter.ToRecord<TestIinit>(tableEntity);
|
||||
|
||||
Assert.Equal("testName", actual.testClass.Name);
|
||||
Assert.Equal("default_test", actual.test);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user