Skip to content

Commit

Permalink
feat(repeater): adopt self-deploying repeaters
Browse files Browse the repository at this point in the history
closes #174
  • Loading branch information
ostridm committed Jun 17, 2024
1 parent 4606a14 commit 9b215af
Show file tree
Hide file tree
Showing 28 changed files with 76 additions and 280 deletions.
22 changes: 0 additions & 22 deletions src/SecTester.Repeater/Api/CreateRepeaterRequest.cs

This file was deleted.

34 changes: 0 additions & 34 deletions src/SecTester.Repeater/Api/DefaultRepeaters.cs

This file was deleted.

13 changes: 0 additions & 13 deletions src/SecTester.Repeater/Api/DeleteRepeaterRequest.cs

This file was deleted.

10 changes: 0 additions & 10 deletions src/SecTester.Repeater/Api/IRepeaters.cs

This file was deleted.

8 changes: 0 additions & 8 deletions src/SecTester.Repeater/Api/RepeaterIdentity.cs

This file was deleted.

4 changes: 2 additions & 2 deletions src/SecTester.Repeater/Bus/DefaultRepeaterBusFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public DefaultRepeaterBusFactory(Configuration config, ILoggerFactory loggerFact
_scopeFactory = scopeFactory ?? throw new ArgumentNullException(nameof(scopeFactory));
}

public IRepeaterBus Create(string repeaterId)
public IRepeaterBus Create(string? namePrefix = default)
{
if (_config.Credentials is null)
{
Expand All @@ -39,7 +39,7 @@ public IRepeaterBus Create(string repeaterId)
ReconnectionDelayMax = options.ReconnectionDelayMax,
ConnectionTimeout = options.ConnectionTimeout,
Transport = TransportProtocol.WebSocket,
Auth = new { token = _config.Credentials.Token, domain = repeaterId }
Auth = new { token = _config.Credentials.Token, domain = namePrefix ?? System.Net.Dns.GetHostName() }
})
{
Serializer = new SocketIOMessagePackSerializer()
Expand Down
2 changes: 1 addition & 1 deletion src/SecTester.Repeater/Bus/IRepeaterBus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ public interface IRepeaterBus : IAsyncDisposable
event Action<Version> UpgradeAvailable;

Task Connect();
Task Deploy(string repeaterId, CancellationToken? cancellationToken = null);
Task<string> Deploy(string? repeaterId, CancellationToken? cancellationToken = null);
}
2 changes: 1 addition & 1 deletion src/SecTester.Repeater/Bus/IRepeaterBusFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ namespace SecTester.Repeater.Bus;

public interface IRepeaterBusFactory
{
IRepeaterBus Create(string repeaterId);
IRepeaterBus Create(string? namePrefix = default);
}
5 changes: 3 additions & 2 deletions src/SecTester.Repeater/Bus/RepeaterInfo.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using System;
using MessagePack;

namespace SecTester.Repeater.Bus;

[MessagePackObject]
public sealed record RepeaterInfo
public sealed record RepeaterInfo(string RepeaterId)
{
[Key("repeaterId")]
public string RepeaterId { get; set; } = null!;
public string RepeaterId { get; init; } = RepeaterId ?? throw new ArgumentNullException(nameof(RepeaterId));
}
15 changes: 13 additions & 2 deletions src/SecTester.Repeater/Bus/SocketIoRepeaterBus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,21 +90,32 @@ public async ValueTask DisposeAsync()
GC.SuppressFinalize(this);
}

public async Task Deploy(string repeaterId, CancellationToken? cancellationToken = null)
public async Task<string> Deploy(string? repeaterId, CancellationToken? cancellationToken = null)
{
try
{
var tcs = new TaskCompletionSource<RepeaterInfo>();

_connection.On("deployed", response => tcs.TrySetResult(response.GetValue<RepeaterInfo>()));

await _connection.EmitAsync("deploy", new RepeaterInfo { RepeaterId = repeaterId }).ConfigureAwait(false);
var args = string.IsNullOrWhiteSpace(repeaterId) ? Array.Empty<object>() : new object[] { new RepeaterInfo(repeaterId!) };

await _connection
.EmitAsync("deploy", args)
.ConfigureAwait(false);

using var _ = cancellationToken?.Register(() => tcs.TrySetCanceled());

var result = await tcs.Task.ConfigureAwait(false);

_logger.LogDebug("Repeater ({RepeaterId}) deployed", result?.RepeaterId);

if (null == result || string.IsNullOrWhiteSpace(result.RepeaterId))
{
throw new InvalidOperationException("An error occured while repeater is being deployed");
}

return result.RepeaterId;
}
finally
{
Expand Down
13 changes: 4 additions & 9 deletions src/SecTester.Repeater/DefaultRepeaterFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using Microsoft.Extensions.Logging;
using SecTester.Core;
using SecTester.Core.Logger;
using SecTester.Repeater.Api;
using SecTester.Repeater.Bus;

namespace SecTester.Repeater;
Expand All @@ -12,30 +11,26 @@ public class DefaultRepeaterFactory : IRepeaterFactory
{
private readonly Configuration _configuration;
private readonly IRepeaterBusFactory _busFactory;
private readonly IRepeaters _repeaters;
private readonly ILoggerFactory _loggerFactory;
private readonly IAnsiCodeColorizer _ansiCodeColorizer;
private readonly RequestRunnerResolver _requestRunnerResolver;

public DefaultRepeaterFactory(IRepeaters repeaters, IRepeaterBusFactory busFactory, Configuration configuration, ILoggerFactory loggerFactory, IAnsiCodeColorizer ansiCodeColorizer, RequestRunnerResolver requestRunnerResolver)
public DefaultRepeaterFactory(IRepeaterBusFactory busFactory, Configuration configuration, ILoggerFactory loggerFactory, IAnsiCodeColorizer ansiCodeColorizer, RequestRunnerResolver requestRunnerResolver)
{
_repeaters = repeaters ?? throw new ArgumentNullException(nameof(repeaters));
_loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
_busFactory = busFactory ?? throw new ArgumentNullException(nameof(busFactory));
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
_ansiCodeColorizer = ansiCodeColorizer ?? throw new ArgumentNullException(nameof(ansiCodeColorizer));
_requestRunnerResolver = requestRunnerResolver ?? throw new ArgumentNullException(nameof(requestRunnerResolver));
}

public async Task<IRepeater> CreateRepeater(RepeaterOptions? options = default)
public Task<IRepeater> CreateRepeater(RepeaterOptions? options = default)
{
options ??= new RepeaterOptions();

var repeaterId = await _repeaters.CreateRepeater($"{options.NamePrefix}-{Guid.NewGuid()}", options.Description).ConfigureAwait(false);

var bus = _busFactory.Create(repeaterId);
var bus = _busFactory.Create(options.NamePrefix);
var version = new Version(_configuration.RepeaterVersion);

return new Repeater(repeaterId, bus, version, _loggerFactory.CreateLogger<Repeater>(), _ansiCodeColorizer, _requestRunnerResolver);
return Task.FromResult<IRepeater>(new Repeater(bus, version, _loggerFactory.CreateLogger<Repeater>(), _ansiCodeColorizer, _requestRunnerResolver));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using Microsoft.Extensions.DependencyInjection;
using SecTester.Core.Extensions;
using SecTester.Core.Utils;
using SecTester.Repeater.Api;
using SecTester.Repeater.Bus;
using SecTester.Repeater.Runners;

Expand All @@ -22,7 +21,6 @@ public static IServiceCollection AddSecTesterRepeater(this IServiceCollection co
.AddHttpCommandDispatcher()
.AddSingleton<IRepeaterBusFactory, DefaultRepeaterBusFactory>()
.AddScoped<IRepeaterFactory, DefaultRepeaterFactory>()
.AddScoped<IRepeaters, DefaultRepeaters>()
.AddScoped<ITimerProvider, SystemTimerProvider>()
.AddScoped<IRequestRunner, HttpRequestRunner>()
.AddScoped<RequestRunnerResolver>(sp =>
Expand Down
30 changes: 0 additions & 30 deletions src/SecTester.Repeater/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,36 +44,6 @@ The `CreateRepeater` method accepts the options described below:
| Option | Description |
| :--------------------- | ----------------------------------------------------------------------------------------------------- |
| `namePrefix` | Enter a name prefix that will be used as a constant part of the unique name. By default, `sectester`. |
| `description` | Set a short description of the Repeater. |
| `requestRunnerOptions` | Custom the request runner settings that will be used to execute requests to your application. |

The default `requestRunnerOptions` is as follows:

```json
{
"timeout": 30000,
"maxContentLength": 100,
"reuseConnection": false,
"allowedMimes": [
"text/html",
"text/plain",
"text/css",
"text/javascript",
"text/markdown",
"text/xml",
"application/javascript",
"application/x-javascript",
"application/json",
"application/xml",
"application/x-www-form-urlencoded",
"application/msgpack",
"application/ld+json",
"application/graphql"
]
}
```

The `RequestRunnerOptions` exposes the following options that can used to customize the request runner's behavior: [RequestRunnerOptions.cs](https://github.com/NeuraLegion/sectester-net/blob/master/src/SecTester.Repeater/Runners/RequestRunnerOptions.cs)

The `Repeater` instance provides the `Start` method. This method is required to establish a connection with the Bright cloud engine and interact with other services.

Expand Down
10 changes: 4 additions & 6 deletions src/SecTester.Repeater/Repeater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace SecTester.Repeater;

public delegate IRequestRunner? RequestRunnerResolver(Protocol key);


public class Repeater : IRepeater
{
private readonly IRepeaterBus _bus;
Expand All @@ -21,10 +20,9 @@ public class Repeater : IRepeater
private readonly IAnsiCodeColorizer _ansiCodeColorizer;
private readonly RequestRunnerResolver _requestRunnersAccessor;

public Repeater(string repeaterId, IRepeaterBus bus, Version version, ILogger<Repeater> logger,
public Repeater(IRepeaterBus bus, Version version, ILogger<Repeater> logger,
IAnsiCodeColorizer ansiCodeColorizer, RequestRunnerResolver requestRunnersAccessor)
{
RepeaterId = repeaterId ?? throw new ArgumentNullException(nameof(repeaterId));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_version = version ?? throw new ArgumentNullException(nameof(version));
_bus = bus ?? throw new ArgumentNullException(nameof(bus));
Expand All @@ -33,7 +31,7 @@ public Repeater(string repeaterId, IRepeaterBus bus, Version version, ILogger<Re
}

public RunningStatus Status { get; private set; } = RunningStatus.Off;
public string RepeaterId { get; }
public string RepeaterId { get; private set; } = string.Empty;

public async ValueTask DisposeAsync()
{
Expand All @@ -60,7 +58,7 @@ public async Task Start(CancellationToken cancellationToken = default)
SubscribeToEvents();

await _bus.Connect().ConfigureAwait(false);
await _bus.Deploy(RepeaterId, cancellationToken).ConfigureAwait(false);
RepeaterId = await _bus.Deploy(RepeaterId, cancellationToken).ConfigureAwait(false);

Status = RunningStatus.Running;
}
Expand Down Expand Up @@ -94,7 +92,7 @@ public async Task Stop(CancellationToken cancellationToken = default)
}
}

public async Task<OutgoingResponse> HandleIncomingRequest(IncomingRequest message)
private async Task<OutgoingResponse> HandleIncomingRequest(IncomingRequest message)
{
var runner = _requestRunnersAccessor(message.Protocol);

Expand Down
4 changes: 1 addition & 3 deletions src/SecTester.Repeater/RepeaterOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace SecTester.Repeater;
public record RepeaterOptions
{
private const int MaxPrefixLength = 44;
private readonly string _namePrefix = "sectester";
private readonly string _namePrefix = System.Net.Dns.GetHostName();

public string NamePrefix
{
Expand All @@ -19,6 +19,4 @@ public string NamePrefix
_namePrefix = value;
}
}

public string? Description { get; init; }
}
1 change: 0 additions & 1 deletion src/SecTester.Repeater/SecTester.Repeater.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
</ItemGroup>

<ItemGroup>
<Folder Include="Api"/>
<Folder Include="Bus" />
<Folder Include="Extensions" />
<Folder Include="Internal" />
Expand Down
6 changes: 1 addition & 5 deletions src/SecTester.Runner/SecRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using SecTester.Core;
using SecTester.Core.Extensions;
using SecTester.Repeater;
using SecTester.Repeater.Api;
using SecTester.Repeater.Extensions;
using SecTester.Reporter;
using SecTester.Scan;
Expand All @@ -18,17 +17,15 @@ public class SecRunner : IAsyncDisposable
private readonly Configuration _configuration;
private readonly IFormatter _formatter;
private readonly IRepeaterFactory _repeaterFactory;
private readonly IRepeaters _repeatersManager;
private readonly IScanFactory _scanFactory;
private IRepeater? _repeater;

public SecRunner(Configuration configuration, IRepeaterFactory repeaterFactory, IScanFactory scanFactory, IRepeaters repeatersManager,
public SecRunner(Configuration configuration, IRepeaterFactory repeaterFactory, IScanFactory scanFactory,
IFormatter formatter)
{
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
_repeaterFactory = repeaterFactory ?? throw new ArgumentNullException(nameof(repeaterFactory));
_scanFactory = scanFactory ?? throw new ArgumentNullException(nameof(scanFactory));
_repeatersManager = repeatersManager ?? throw new ArgumentNullException(nameof(repeatersManager));
_formatter = formatter ?? throw new ArgumentNullException(nameof(formatter));
}

Expand Down Expand Up @@ -80,7 +77,6 @@ public async Task Clear(CancellationToken cancellationToken = default)
if (_repeater is not null)
{
await _repeater.Stop(cancellationToken).ConfigureAwait(false);
await _repeatersManager.DeleteRepeater(_repeater.RepeaterId).ConfigureAwait(false);
await _repeater.DisposeAsync().ConfigureAwait(false);
}
}
Expand Down
Loading

0 comments on commit 9b215af

Please sign in to comment.