Add audit API client

- cleanup
- generate PCAP API
This commit is contained in:
Peter 2021-02-20 15:18:08 +01:00
parent bb46b7f58a
commit 15106dbfd6
Signed by: prskr
GPG key ID: C1DB5D2E8DB512F9
13 changed files with 151 additions and 58 deletions

View file

@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Grpc.Core;
using Grpc.Net.Client;
using INetMock.Client.Audit.Serialization;
using INetMock.Client.Rpc;
namespace INetMock.Client.Audit.Client
{
public class AuditApiClient : IAuditApiClient
{
private readonly Rpc.Audit.AuditClient _auditClient;
public AuditApiClient(string address, GrpcChannelOptions? options = null) : this(new Uri(address), options)
{
}
public AuditApiClient(Uri address, GrpcChannelOptions? options = null) : this(
GrpcChannel.ForAddress(address, options ?? new GrpcChannelOptions()))
{
}
public AuditApiClient(ChannelBase channel)
{
_auditClient = new Rpc.Audit.AuditClient(channel);
}
public async Task<IEnumerable<string>> ListSinksAsync(CancellationToken token = default)
{
var sinks = await _auditClient.ListSinksAsync(new ListSinksRequest(), Metadata.Empty, null, token);
return sinks.Sinks;
}
public async Task<string> RegisterFileSinkAsync(string targetPath, CancellationToken token = default)
{
var resp = await _auditClient.RegisterFileSinkAsync(
new RegisterFileSinkRequest {TargetPath = targetPath},
Metadata.Empty,
null,
token
);
return resp.ResolvedPath;
}
public async Task<bool> RemoveFileSinkAsync(string targetPath, CancellationToken token = default)
{
var resp = await _auditClient.RemoveFileSinkAsync(new RemoveFileSinkRequest
{
TargetPath = targetPath
},
Metadata.Empty,
null,
token
);
return resp.SinkGotRemoved;
}
public IProtoEventReader EventStreamAsync(string watcherName, CancellationToken token = default)
{
var stream = _auditClient.WatchEvents(
new WatchEventsRequest {WatcherName = watcherName},
Metadata.Empty,
null,
token
);
return new EventServerStreamReader(stream);
}
}
}

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using Google.Protobuf.WellKnownTypes; using Google.Protobuf.WellKnownTypes;
@ -9,11 +8,13 @@ using INetMock.Client.Audit.Details;
namespace INetMock.Client.Audit namespace INetMock.Client.Audit
{ {
public abstract record EventDetails; public abstract record EventDetails;
public record EmptyDetails : EventDetails; public record EmptyDetails : EventDetails;
public record GenericDetails : EventDetails public record GenericDetails : EventDetails
{ {
private readonly Any? _detailsAny; private readonly Any? _detailsAny;
public GenericDetails() public GenericDetails()
{ {
_detailsAny = null; _detailsAny = null;
@ -27,14 +28,16 @@ namespace INetMock.Client.Audit
public static implicit operator HttpDetails(GenericDetails gd) public static implicit operator HttpDetails(GenericDetails gd)
{ {
if (gd._detailsAny == null || gd._detailsAny.Value == null) return new(); if (gd._detailsAny == null || gd._detailsAny.Value == null) return new();
if(!gd._detailsAny.TypeUrl.EndsWith(HTTPDetailsEntity.Descriptor.FullName)) throw new InvalidOperationException(); if (!gd._detailsAny.TypeUrl.EndsWith(HTTPDetailsEntity.Descriptor.FullName))
throw new InvalidOperationException();
return new HttpDetails(gd._detailsAny); return new HttpDetails(gd._detailsAny);
} }
public static implicit operator DnsDetails(GenericDetails gd) public static implicit operator DnsDetails(GenericDetails gd)
{ {
if (gd._detailsAny == null || gd._detailsAny.Value == null) return new(); if (gd._detailsAny == null || gd._detailsAny.Value == null) return new();
if(!gd._detailsAny.TypeUrl.EndsWith(HTTPDetailsEntity.Descriptor.FullName)) throw new InvalidOperationException(); if (!gd._detailsAny.TypeUrl.EndsWith(HTTPDetailsEntity.Descriptor.FullName))
throw new InvalidOperationException();
return new DnsDetails(gd._detailsAny); return new DnsDetails(gd._detailsAny);
} }
} }
@ -43,7 +46,6 @@ namespace INetMock.Client.Audit
{ {
public HttpDetails() public HttpDetails()
{ {
} }
public HttpDetails(Any? any) public HttpDetails(Any? any)
@ -70,7 +72,6 @@ namespace INetMock.Client.Audit
{ {
public DnsDetails() public DnsDetails()
{ {
} }
public DNSOpCode OpCode { get; init; } public DNSOpCode OpCode { get; init; }

View file

@ -7,7 +7,6 @@ namespace INetMock.Client.Audit
{ {
public Event() public Event()
{ {
} }
public Event(EventEntity entity) public Event(EventEntity entity)

View file

@ -1,28 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
using Grpc.Core;
namespace INetMock.Client.Audit
{
public sealed class EventServerStreamReader : IProtoEventReader
{
private readonly IAsyncStreamReader<EventEntity> _asyncEventStream;
public EventServerStreamReader(IAsyncStreamReader<EventEntity> asyncEventStream)
{
_asyncEventStream = asyncEventStream;
}
public async Task<EventEntity?> ReadAsync(CancellationToken token = default)
{
if (!await _asyncEventStream.MoveNext(token)) return null;
return _asyncEventStream.Current;
}
public void Dispose()
{
}
public ValueTask DisposeAsync() => ValueTask.CompletedTask;
}
}

View file

@ -0,0 +1,14 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace INetMock.Client.Audit
{
public interface IAuditApiClient
{
IProtoEventReader EventStreamAsync(string watcherName, CancellationToken token = default);
Task<IEnumerable<string>> ListSinksAsync(CancellationToken token = default);
Task<string> RegisterFileSinkAsync(string targetPath, CancellationToken token = default);
Task<bool> RemoveFileSinkAsync(string targetPath, CancellationToken token = default);
}
}

View file

@ -0,0 +1,30 @@
using System.Threading;
using System.Threading.Tasks;
using Grpc.Core;
namespace INetMock.Client.Audit.Serialization
{
public sealed class EventServerStreamReader : IProtoEventReader
{
private readonly AsyncServerStreamingCall<EventEntity> _asyncEventStream;
public EventServerStreamReader(AsyncServerStreamingCall<EventEntity> asyncEventStream)
{
_asyncEventStream = asyncEventStream;
}
public async Task<EventEntity?> ReadAsync(CancellationToken token = default)
{
if (!await _asyncEventStream.ResponseStream.MoveNext(token)) return null;
return _asyncEventStream.ResponseStream.Current;
}
public void Dispose() => _asyncEventStream.Dispose();
public ValueTask DisposeAsync()
{
_asyncEventStream.Dispose();
return ValueTask.CompletedTask;
}
}
}

View file

@ -3,7 +3,7 @@ using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace INetMock.Client.Audit namespace INetMock.Client.Audit.Serialization
{ {
public sealed class GenericReader : IEventReader<GenericDetails> public sealed class GenericReader : IEventReader<GenericDetails>
{ {
@ -14,7 +14,8 @@ namespace INetMock.Client.Audit
_reader = reader; _reader = reader;
} }
public async IAsyncEnumerable<Event<GenericDetails>> ReadAllAsync([EnumeratorCancellation] CancellationToken token = default) public async IAsyncEnumerable<Event<GenericDetails>> ReadAllAsync(
[EnumeratorCancellation] CancellationToken token = default)
{ {
while (true) while (true)
{ {

View file

@ -5,7 +5,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Google.Protobuf; using Google.Protobuf;
namespace INetMock.Client.Audit namespace INetMock.Client.Audit.Serialization
{ {
public sealed class ProtoReader : IProtoEventReader public sealed class ProtoReader : IProtoEventReader
{ {

View file

@ -3,7 +3,7 @@ using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace INetMock.Client.Audit namespace INetMock.Client.Audit.Serialization
{ {
/// <summary> /// <summary>
/// Configures how the TypedReader proceeds with mismatching entities. /// Configures how the TypedReader proceeds with mismatching entities.

View file

@ -19,5 +19,6 @@
<Protobuf Include="proto/audit/details/http_details.proto" GrpcServices="Client" AdditionalImportDirs="./proto/" /> <Protobuf Include="proto/audit/details/http_details.proto" GrpcServices="Client" AdditionalImportDirs="./proto/" />
<Protobuf Include="proto/rpc/audit.proto" GrpcServices="Client" AdditionalImportDirs="./proto/" /> <Protobuf Include="proto/rpc/audit.proto" GrpcServices="Client" AdditionalImportDirs="./proto/" />
<Protobuf Include="proto/rpc/health.proto" GrpcServices="Client" AdditionalImportDirs="./proto/" /> <Protobuf Include="proto/rpc/health.proto" GrpcServices="Client" AdditionalImportDirs="./proto/" />
<Protobuf Include="proto/rpc/pcap.proto" GrpcServices="Client" AdditionalImportDirs="./proto/" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -1,9 +1,10 @@
using System.IO; using System.IO;
using INetMock.Client.Audit; using INetMock.Client.Audit;
using INetMock.Client.Audit.Serialization;
using INetMock.Client.Test.Hex; using INetMock.Client.Test.Hex;
using Xunit; using Xunit;
namespace INetMock.Client.Test.Audit namespace INetMock.Client.Test.Audit.Serialization
{ {
public class GenericReaderTest public class GenericReaderTest
{ {
@ -23,7 +24,7 @@ namespace INetMock.Client.Test.Audit
public async void TestRead_HttpEvent_Success() public async void TestRead_HttpEvent_Success()
{ {
await using var protoReader = new ProtoReader(new MemoryStream(_httpEventPayloadBytes)); await using var protoReader = new ProtoReader(new MemoryStream(_httpEventPayloadBytes));
await using var reader = new GenericReader(protoReader); await using IEventReader<GenericDetails> reader = new GenericReader(protoReader);
await foreach (var ev in reader.ReadAllAsync()) await foreach (var ev in reader.ReadAllAsync())
{ {
Assert.NotNull(ev); Assert.NotNull(ev);
@ -44,7 +45,7 @@ namespace INetMock.Client.Test.Audit
{ {
await using var memStream = new MemoryStream(_dnsEventPayloadBytes); await using var memStream = new MemoryStream(_dnsEventPayloadBytes);
await using var protoReader = new ProtoReader(new MemoryStream(_dnsEventPayloadBytes)); await using var protoReader = new ProtoReader(new MemoryStream(_dnsEventPayloadBytes));
await using var reader = new GenericReader(protoReader); await using IEventReader<GenericDetails> reader = new GenericReader(protoReader);
await foreach (var ev in reader.ReadAllAsync()) await foreach (var ev in reader.ReadAllAsync())
{ {
Assert.NotNull(ev); Assert.NotNull(ev);

View file

@ -1,9 +1,10 @@
using System.IO; using System.IO;
using INetMock.Client.Audit; using INetMock.Client.Audit;
using INetMock.Client.Audit.Serialization;
using INetMock.Client.Test.Hex; using INetMock.Client.Test.Hex;
using Xunit; using Xunit;
namespace INetMock.Client.Test.Audit namespace INetMock.Client.Test.Audit.Serialization
{ {
public class TypedReaderTest public class TypedReaderTest
{ {
@ -23,7 +24,7 @@ namespace INetMock.Client.Test.Audit
public async void TestRead_HttpEvent_Success() public async void TestRead_HttpEvent_Success()
{ {
await using var protoReader = new ProtoReader(new MemoryStream(_httpEventPayloadBytes)); await using var protoReader = new ProtoReader(new MemoryStream(_httpEventPayloadBytes));
await using var reader = new TypedReader<HttpDetails>(protoReader, DropMode.DropEntity); await using IEventReader<HttpDetails> reader = new TypedReader<HttpDetails>(protoReader, DropMode.DropEntity);
await foreach (var ev in reader.ReadAllAsync()) await foreach (var ev in reader.ReadAllAsync())
{ {
Assert.NotNull(ev); Assert.NotNull(ev);
@ -34,7 +35,7 @@ namespace INetMock.Client.Test.Audit
public async void TestRead_DnsEvent_Success() public async void TestRead_DnsEvent_Success()
{ {
await using var protoReader = new ProtoReader(new MemoryStream(_dnsEventPayloadBytes)); await using var protoReader = new ProtoReader(new MemoryStream(_dnsEventPayloadBytes));
await using var reader = new TypedReader<DnsDetails>(protoReader, DropMode.DropEntity); await using IEventReader<DnsDetails> reader = new TypedReader<DnsDetails>(protoReader, DropMode.DropEntity);
await foreach (var ev in reader.ReadAllAsync()) await foreach (var ev in reader.ReadAllAsync())
{ {
Assert.NotNull(ev); Assert.NotNull(ev);