mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-17 12:28:07 +00:00
[C# Port] Adding new Proxy Update Queue Function. (#1757)
* Adding QueueProxyUpdate. * Setting to serializer. * Updates. * Updating with new ORM model and [model]Operation. * Fixing return type. * Working on changes. * Tested and ready for review. * Formatting. * Removing test code. * Update src/ApiService/Tests/OrmTest.cs Co-authored-by: Cheick Keita <chkeita@microsoft.com> * Fixing tests. * Fixing tests again. * Asserting null in tests. * Adding null param. * Removing whitespace. * syntax error. Co-authored-by: Cheick Keita <chkeita@microsoft.com>
This commit is contained in:
committed by
GitHub
parent
5aceb25843
commit
75039a96eb
@ -26,6 +26,16 @@
|
||||
INVALID_CONFIGURATION = 473,
|
||||
}
|
||||
|
||||
public enum VmState
|
||||
{
|
||||
Init,
|
||||
ExtensionsLaunched,
|
||||
ExtensionsFailed,
|
||||
VmAllocationFailed,
|
||||
Running,
|
||||
Stopping,
|
||||
Stopped
|
||||
}
|
||||
|
||||
public enum WebhookMessageState
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Microsoft.OneFuzz.Service.OneFuzzLib.Orm;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using PoolName = System.String;
|
||||
|
||||
namespace Microsoft.OneFuzz.Service;
|
||||
@ -14,6 +15,12 @@ namespace Microsoft.OneFuzz.Service;
|
||||
/// the "partion key" and "row key" are identified by the [PartitionKey] and [RowKey] attributes
|
||||
/// Guids are mapped to string in the db
|
||||
|
||||
public record Authentication
|
||||
(
|
||||
string Password,
|
||||
string PublicKey,
|
||||
string PrivateKey
|
||||
);
|
||||
|
||||
[SkipRename]
|
||||
public enum HeartbeatType
|
||||
@ -70,6 +77,13 @@ public enum NodeState
|
||||
Halt,
|
||||
}
|
||||
|
||||
public record ProxyHeartbeat
|
||||
(
|
||||
string Region,
|
||||
Guid ProxyId,
|
||||
List<ProxyForward> Forwards,
|
||||
DateTimeOffset TimeStamp
|
||||
);
|
||||
|
||||
public partial record Node
|
||||
(
|
||||
@ -87,6 +101,39 @@ public partial record Node
|
||||
) : EntityBase();
|
||||
|
||||
|
||||
public partial record ProxyForward
|
||||
(
|
||||
[PartitionKey] string Region,
|
||||
[RowKey] int DstPort,
|
||||
int SrcPort,
|
||||
string DstIp
|
||||
) : EntityBase();
|
||||
|
||||
public partial record ProxyConfig
|
||||
(
|
||||
Uri Url,
|
||||
string Notification,
|
||||
string Region,
|
||||
Guid? ProxyId,
|
||||
List<ProxyForward> Forwards,
|
||||
string InstanceTelemetryKey,
|
||||
string MicrosoftTelemetryKey
|
||||
|
||||
);
|
||||
|
||||
public partial record Proxy
|
||||
(
|
||||
[PartitionKey] string Region,
|
||||
[RowKey] Guid ProxyId,
|
||||
DateTimeOffset? CreatedTimestamp,
|
||||
VmState State,
|
||||
Authentication Auth,
|
||||
string? Ip,
|
||||
Error? Error,
|
||||
string Version,
|
||||
ProxyHeartbeat? heartbeat
|
||||
) : EntityBase();
|
||||
|
||||
public record Error(ErrorCode Code, string[]? Errors = null);
|
||||
|
||||
public record UserInfo(Guid? ApplicationId, Guid? ObjectId, String? Upn);
|
||||
|
@ -42,6 +42,7 @@ public class Program
|
||||
.AddSingleton<IQueue, Queue>()
|
||||
.AddSingleton<ICreds>(_ => new Creds())
|
||||
.AddSingleton<IStorage, Storage>()
|
||||
.AddSingleton<IProxyOperations, ProxyOperations>()
|
||||
)
|
||||
.Build();
|
||||
|
||||
|
42
src/ApiService/ApiService/QueueProxyHeartbeat.cs
Normal file
42
src/ApiService/ApiService/QueueProxyHeartbeat.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using Microsoft.Azure.Functions.Worker;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.OneFuzz.Service.OneFuzzLib.Orm;
|
||||
|
||||
namespace Microsoft.OneFuzz.Service;
|
||||
|
||||
public class QueueProxyHearbeat
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private readonly IProxyOperations _proxy;
|
||||
|
||||
public QueueProxyHearbeat(ILoggerFactory loggerFactory, IProxyOperations proxy)
|
||||
{
|
||||
_logger = loggerFactory.CreateLogger<QueueProxyHearbeat>();
|
||||
_proxy = proxy;
|
||||
}
|
||||
|
||||
[Function("QueueProxyHearbeat")]
|
||||
public async Task Run([QueueTrigger("myqueue-items", Connection = "AzureWebJobsStorage")] string msg)
|
||||
{
|
||||
_logger.LogInformation($"heartbeat: {msg}");
|
||||
|
||||
var hb = JsonSerializer.Deserialize<ProxyHeartbeat>(msg, EntityConverter.GetJsonSerializerOptions()).EnsureNotNull($"wrong data {msg}"); ;
|
||||
var newHb = hb with { TimeStamp = DateTimeOffset.UtcNow };
|
||||
|
||||
var proxy = await _proxy.GetByProxyId(newHb.ProxyId);
|
||||
|
||||
if (proxy == null)
|
||||
{
|
||||
_logger.LogWarning($"invalid proxy id: {newHb.ProxyId}");
|
||||
return;
|
||||
}
|
||||
var newProxy = proxy with { heartbeat = newHb };
|
||||
|
||||
await _proxy.Replace(newProxy);
|
||||
|
||||
}
|
||||
}
|
30
src/ApiService/ApiService/onefuzzlib/ProxyOperations.cs
Normal file
30
src/ApiService/ApiService/onefuzzlib/ProxyOperations.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using ApiService.OneFuzzLib.Orm;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.OneFuzz.Service;
|
||||
|
||||
public interface IProxyOperations : IOrm<Proxy>
|
||||
{
|
||||
Task<Proxy?> GetByProxyId(Guid proxyId);
|
||||
}
|
||||
public class ProxyOperations : Orm<Proxy>, IProxyOperations
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public ProxyOperations(ILoggerFactory loggerFactory, IStorage storage)
|
||||
: base(storage)
|
||||
{
|
||||
_logger = loggerFactory.CreateLogger<QueueProxyHearbeat>();
|
||||
}
|
||||
|
||||
public async Task<Proxy?> GetByProxyId(Guid proxyId)
|
||||
{
|
||||
|
||||
var data = QueryAsync(filter: $"RowKey eq '{proxyId}'");
|
||||
|
||||
return await data.FirstOrDefaultAsync();
|
||||
}
|
||||
}
|
@ -245,6 +245,10 @@ public class EntityConverter
|
||||
else
|
||||
{
|
||||
var value = entity.GetString(fieldName);
|
||||
if (value == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return JsonSerializer.Deserialize(value, ef.type, options: _options); ;
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,8 @@ namespace Tests
|
||||
TestEnum TheEnum,
|
||||
TestFlagEnum TheFlag,
|
||||
[property: JsonPropertyName("a__special__name")] string Renamed,
|
||||
TestObject TheObject
|
||||
TestObject TheObject,
|
||||
TestObject? TestNull
|
||||
) : EntityBase();
|
||||
|
||||
|
||||
@ -60,7 +61,8 @@ namespace Tests
|
||||
TheName = "testobject",
|
||||
TheEnum = TestEnum.TheTwo,
|
||||
TheFlag = TestFlagEnum.FlagOne | TestFlagEnum.FlagTwo
|
||||
});
|
||||
},
|
||||
null);
|
||||
var tableEntity = converter.ToTableEntity(entity1);
|
||||
|
||||
Assert.NotNull(tableEntity);
|
||||
@ -97,6 +99,7 @@ namespace Tests
|
||||
{ "the_flag", "flag_one,flag_two"},
|
||||
{ "a__special__name", "renamed"},
|
||||
{ "the_object", "{\"the_name\": \"testName\", \"the_enum\": \"the_one\", \"the_flag\": \"flag_one,flag_two\"}"},
|
||||
{ "test_null", null},
|
||||
};
|
||||
|
||||
var entity1 = converter.ToRecord<Entity1>(tableEntity);
|
||||
@ -109,6 +112,8 @@ namespace Tests
|
||||
Assert.Equal(tableEntity.GetDouble("the_float"), entity1.TheFloat);
|
||||
Assert.Equal(TestEnum.TheTwo, entity1.TheEnum);
|
||||
Assert.Equal(tableEntity.GetString("a__special__name"), entity1.Renamed);
|
||||
Assert.Null(tableEntity.GetString("test_null"));
|
||||
Assert.Null(entity1.TestNull);
|
||||
|
||||
Assert.Equal("testName", entity1.TheObject.TheName);
|
||||
Assert.Equal(TestEnum.TheOne, entity1.TheObject.TheEnum);
|
||||
|
Reference in New Issue
Block a user