Fixed option to provide a connection string id for test methods
This commit is contained in:
@@ -53,6 +53,10 @@ public sealed record DestinationTestRequestDto
|
||||
/// The backup ID, if known
|
||||
/// </summary>
|
||||
public string? BackupId { get; init; }
|
||||
/// <summary>
|
||||
/// The connection string ID, if known
|
||||
/// </summary>
|
||||
public long? ConnectionStringId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Any additional options to pass to the destination
|
||||
|
||||
@@ -67,9 +67,9 @@ public class SharedRemoteOperation
|
||||
return modules;
|
||||
}
|
||||
|
||||
public static async Task<(string Url, Dictionary<string, string?> Options)> ExpandUrl(Connection connection, IApplicationSettings applicationSettings, string url, string? backupId, CancellationToken cancelToken)
|
||||
public static async Task<(string Url, Dictionary<string, string?> Options)> ExpandUrl(Connection connection, IApplicationSettings applicationSettings, string url, string? backupId, long connectionStringId, CancellationToken cancelToken)
|
||||
{
|
||||
url = UnmaskUrl(connection, url, backupId);
|
||||
url = UnmaskUrl(connection, url, backupId, connectionStringId);
|
||||
var uri = new Library.Utility.Uri(url);
|
||||
var opts = ParseUrlOptions(connection, uri);
|
||||
|
||||
@@ -88,26 +88,26 @@ public class SharedRemoteOperation
|
||||
return (url, opts);
|
||||
}
|
||||
|
||||
public static async Task<BackendTupleDisposeWrapper> GetBackend(Connection connection, IApplicationSettings applicationSettings, string url, string? backupId, CancellationToken cancelToken)
|
||||
public static async Task<BackendTupleDisposeWrapper> GetBackend(Connection connection, IApplicationSettings applicationSettings, string url, string? backupId, long connectionStringId, CancellationToken cancelToken)
|
||||
{
|
||||
(url, var opts) = await ExpandUrl(connection, applicationSettings, url, backupId, cancelToken);
|
||||
(url, var opts) = await ExpandUrl(connection, applicationSettings, url, backupId, connectionStringId, cancelToken);
|
||||
var modules = ConfigureModules(opts);
|
||||
var backend = Library.DynamicLoader.BackendLoader.GetBackend(url, opts);
|
||||
return new BackendTupleDisposeWrapper(backend, modules);
|
||||
}
|
||||
|
||||
public static async Task<SourceProviderTupleDisposeWrapper> GetSourceProviderForTesting(Connection connection, IApplicationSettings applicationSettings, string url, string? backupId, CancellationToken cancelToken)
|
||||
public static async Task<SourceProviderTupleDisposeWrapper> GetSourceProviderForTesting(Connection connection, IApplicationSettings applicationSettings, string url, string? backupId, long connectionStringId, CancellationToken cancelToken)
|
||||
{
|
||||
(url, var opts) = await ExpandUrl(connection, applicationSettings, url, backupId, cancelToken);
|
||||
(url, var opts) = await ExpandUrl(connection, applicationSettings, url, backupId, connectionStringId, cancelToken);
|
||||
var modules = ConfigureModules(opts);
|
||||
var sourceProvider = await Library.DynamicLoader.SourceProviderLoader.GetSourceProviderForTesting(url, "", opts, cancelToken);
|
||||
|
||||
return new SourceProviderTupleDisposeWrapper(sourceProvider, modules);
|
||||
}
|
||||
|
||||
public static async Task<RestoreDestinationProviderTupleDisposeWrapper> GetRestoreDestinationProviderForTesting(Connection connection, IApplicationSettings applicationSettings, string url, string? backupId, CancellationToken cancelToken)
|
||||
public static async Task<RestoreDestinationProviderTupleDisposeWrapper> GetRestoreDestinationProviderForTesting(Connection connection, IApplicationSettings applicationSettings, string url, string? backupId, long connectionStringId, CancellationToken cancelToken)
|
||||
{
|
||||
(url, var opts) = await ExpandUrl(connection, applicationSettings, url, backupId, cancelToken);
|
||||
(url, var opts) = await ExpandUrl(connection, applicationSettings, url, backupId, connectionStringId, cancelToken);
|
||||
var modules = ConfigureModules(opts);
|
||||
var restoreDestinationProvider = await Library.DynamicLoader.RestoreDestinationProviderLoader.GetRestoreDestinationProviderForTesting(url, opts, cancelToken);
|
||||
|
||||
@@ -132,9 +132,17 @@ public class SharedRemoteOperation
|
||||
}
|
||||
}
|
||||
|
||||
private static string UnmaskUrl(Connection connection, string maskedurl, string? backupId)
|
||||
private static string UnmaskUrl(Connection connection, string maskedurl, string? backupId, long connectionStringId)
|
||||
{
|
||||
var previousUrl = !string.IsNullOrWhiteSpace(backupId) ? connection.GetBackup(backupId)?.TargetURL : null;
|
||||
|
||||
string? previousUrl = null;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(backupId))
|
||||
previousUrl = connection.GetBackup(backupId)?.TargetURL;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(previousUrl) && connectionStringId > 0)
|
||||
previousUrl = connection.GetConnectionString(connectionStringId)?.BaseUrl;
|
||||
|
||||
var unmasked = string.IsNullOrWhiteSpace(previousUrl)
|
||||
? maskedurl
|
||||
: QuerystringMasking.Unmask(maskedurl, previousUrl);
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Duplicati.WebserverCore.Endpoints.V1
|
||||
{
|
||||
public class RemoteOperation : IEndpointV1
|
||||
{
|
||||
private record RemoteOperationInput(string path, string? backupId);
|
||||
private record RemoteOperationInput(string path, string? backupId, long? connectionStringId);
|
||||
|
||||
public static void Map(RouteGroupBuilder group)
|
||||
{
|
||||
@@ -40,11 +40,11 @@ namespace Duplicati.WebserverCore.Endpoints.V1
|
||||
.RequireAuthorization();
|
||||
|
||||
group.MapPost("/remoteoperation/test", ([FromServices] Connection connection, [FromServices] IApplicationSettings applicationSettings, [FromQuery] bool? autocreate, [FromQuery] Dto.V2.RemoteDestinationType? type, [FromBody] RemoteOperationInput input, CancellationToken cancelToken)
|
||||
=> ExecuteTest(connection, applicationSettings, input.path, input.backupId, autocreate ?? false, type ?? Dto.V2.RemoteDestinationType.Backend, cancelToken))
|
||||
=> ExecuteTest(connection, applicationSettings, input.path, input.backupId, input.connectionStringId, autocreate ?? false, type ?? Dto.V2.RemoteDestinationType.Backend, cancelToken))
|
||||
.RequireAuthorization();
|
||||
|
||||
group.MapPost("/remoteoperation/create", ([FromServices] Connection connection, [FromServices] IApplicationSettings applicationSettings, [FromBody] RemoteOperationInput input, CancellationToken cancelToken)
|
||||
=> ExecuteCreate(connection, applicationSettings, input.path, input.backupId, cancelToken))
|
||||
=> ExecuteCreate(connection, applicationSettings, input.path, input.backupId, input.connectionStringId, cancelToken))
|
||||
.RequireAuthorization();
|
||||
}
|
||||
|
||||
@@ -54,25 +54,25 @@ namespace Duplicati.WebserverCore.Endpoints.V1
|
||||
return new Dto.GetDbPathDto(!string.IsNullOrWhiteSpace(path), path);
|
||||
}
|
||||
|
||||
private static async Task ExecuteTest(Connection connection, IApplicationSettings applicationSettings, string maskedurl, string? backupId, bool autoCreate, Dto.V2.RemoteDestinationType type, CancellationToken cancelToken)
|
||||
private static async Task ExecuteTest(Connection connection, IApplicationSettings applicationSettings, string maskedurl, string? backupId, long? connectionStringId, bool autoCreate, Dto.V2.RemoteDestinationType type, CancellationToken cancelToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (type == Dto.V2.RemoteDestinationType.SourceProvider)
|
||||
{
|
||||
using var wrapper = await SharedRemoteOperation.GetSourceProviderForTesting(connection, applicationSettings, maskedurl, backupId, cancelToken);
|
||||
using var wrapper = await SharedRemoteOperation.GetSourceProviderForTesting(connection, applicationSettings, maskedurl, backupId, connectionStringId ?? -1, cancelToken);
|
||||
using (var s = wrapper.SourceProvider)
|
||||
await s.Test(cancelToken).ConfigureAwait(false);
|
||||
}
|
||||
else if (type == Dto.V2.RemoteDestinationType.RestoreDestinationProvider)
|
||||
{
|
||||
using var wrapper = await SharedRemoteOperation.GetRestoreDestinationProviderForTesting(connection, applicationSettings, maskedurl, backupId, cancelToken);
|
||||
using var wrapper = await SharedRemoteOperation.GetRestoreDestinationProviderForTesting(connection, applicationSettings, maskedurl, backupId, connectionStringId ?? -1, cancelToken);
|
||||
using (var r = wrapper.RestoreDestinationProvider)
|
||||
await r.Test(cancelToken).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
using var wrapper = await SharedRemoteOperation.GetBackend(connection, applicationSettings, maskedurl, backupId, cancelToken);
|
||||
using var wrapper = await SharedRemoteOperation.GetBackend(connection, applicationSettings, maskedurl, backupId, connectionStringId ?? -1, cancelToken);
|
||||
using (var b = wrapper.Backend)
|
||||
{
|
||||
try { await b.TestAsync(cancelToken).ConfigureAwait(false); }
|
||||
@@ -120,11 +120,11 @@ namespace Duplicati.WebserverCore.Endpoints.V1
|
||||
}
|
||||
|
||||
|
||||
private static async Task ExecuteCreate(Connection connection, IApplicationSettings applicationSettings, string maskedurl, string? backupId, CancellationToken cancelToken)
|
||||
private static async Task ExecuteCreate(Connection connection, IApplicationSettings applicationSettings, string maskedurl, string? backupId, long? connectionStringId, CancellationToken cancelToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var wrapper = await SharedRemoteOperation.GetBackend(connection, applicationSettings, maskedurl, backupId, cancelToken);
|
||||
using var wrapper = await SharedRemoteOperation.GetBackend(connection, applicationSettings, maskedurl, backupId, connectionStringId ?? -1, cancelToken);
|
||||
using (var b = wrapper.Backend)
|
||||
await b.CreateFolderAsync(cancelToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public record WebModules : IEndpointV1
|
||||
var url = options.GetValueOrDefault("url");
|
||||
if (!string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
var (newUrl, opts) = await SharedRemoteOperation.ExpandUrl(connection, applicationSettings, url, options.GetValueOrDefault("backup-id"), cancellationToken);
|
||||
var (newUrl, opts) = await SharedRemoteOperation.ExpandUrl(connection, applicationSettings, url, options.GetValueOrDefault("backup-id"), Library.Utility.Utility.ParseLongOption(options, "connection-string-id", -1), cancellationToken);
|
||||
options["url"] = newUrl;
|
||||
foreach (var k in opts.Keys)
|
||||
options[k] = opts[k];
|
||||
|
||||
@@ -47,7 +47,7 @@ public class DestinationVerify : IEndpointV2
|
||||
{
|
||||
if (destinationType == RemoteDestinationType.SourceProvider)
|
||||
{
|
||||
using var wrapper = await SharedRemoteOperation.GetSourceProviderForTesting(connection, applicationSettings, input.DestinationUrl, input.BackupId, cancelToken);
|
||||
using var wrapper = await SharedRemoteOperation.GetSourceProviderForTesting(connection, applicationSettings, input.DestinationUrl, input.BackupId, input.ConnectionStringId ?? -1, cancelToken);
|
||||
await wrapper.SourceProvider.Test(cancelToken);
|
||||
// Technically we also count folders as files here, but really we just want to know if there is data to backup
|
||||
var anyFiles = await wrapper.SourceProvider.Enumerate(cancelToken).AnyAsync(cancelToken);
|
||||
@@ -60,7 +60,7 @@ public class DestinationVerify : IEndpointV2
|
||||
}
|
||||
else if (destinationType == RemoteDestinationType.RestoreDestinationProvider)
|
||||
{
|
||||
using var wrapper = await SharedRemoteOperation.GetRestoreDestinationProviderForTesting(connection, applicationSettings, input.DestinationUrl, input.BackupId, cancelToken);
|
||||
using var wrapper = await SharedRemoteOperation.GetRestoreDestinationProviderForTesting(connection, applicationSettings, input.DestinationUrl, input.BackupId, input.ConnectionStringId ?? -1, cancelToken);
|
||||
await wrapper.RestoreDestinationProvider.Test(cancelToken);
|
||||
|
||||
return DestinationTestResponseDto.Create(
|
||||
@@ -71,7 +71,7 @@ public class DestinationVerify : IEndpointV2
|
||||
}
|
||||
else
|
||||
{
|
||||
using var wrapper = await SharedRemoteOperation.GetBackend(connection, applicationSettings, input.DestinationUrl, input.BackupId, cancelToken);
|
||||
using var wrapper = await SharedRemoteOperation.GetBackend(connection, applicationSettings, input.DestinationUrl, input.BackupId, input.ConnectionStringId ?? -1, cancelToken);
|
||||
|
||||
using (var b = wrapper.Backend)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user