mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-03-12 09:44:08 +00:00
chore: Implement server deletion for hetzner on provider layer
This commit is contained in:
parent
76536f8115
commit
bc9ab447f0
2 changed files with 85 additions and 35 deletions
lib/logic
|
@ -244,15 +244,25 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteVolume(final ServerVolume volume) async {
|
Future<GenericResult<void>> deleteVolume(final int volumeId) async {
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
try {
|
try {
|
||||||
await client.delete('/volumes/${volume.id}');
|
await client.delete('/volumes/$volumeId');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
|
return GenericResult(
|
||||||
|
success: false,
|
||||||
|
data: null,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
client.close();
|
client.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return GenericResult(
|
||||||
|
success: true,
|
||||||
|
data: null,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<GenericResult<bool>> attachVolume(
|
Future<GenericResult<bool>> attachVolume(
|
||||||
|
@ -287,24 +297,32 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> detachVolume(final ServerVolume volume) async {
|
Future<GenericResult<bool>> detachVolume(final int volumeId) async {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
final Response detachVolumeResponse;
|
final Response detachVolumeResponse;
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
try {
|
try {
|
||||||
detachVolumeResponse = await client.post(
|
detachVolumeResponse = await client.post(
|
||||||
'/volumes/${volume.id}/actions/detach',
|
'/volumes/$volumeId/actions/detach',
|
||||||
);
|
);
|
||||||
success =
|
success =
|
||||||
detachVolumeResponse.data['action']['status'].toString() != 'error';
|
detachVolumeResponse.data['action']['status'].toString() != 'error';
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
|
return GenericResult(
|
||||||
|
success: false,
|
||||||
|
data: false,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
client.close();
|
client.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return GenericResult(
|
||||||
|
success: false,
|
||||||
|
data: success,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> resizeVolume(
|
Future<bool> resizeVolume(
|
||||||
|
@ -398,46 +416,24 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<GenericResult<bool>> deleteServer({
|
Future<GenericResult<void>> deleteServer({
|
||||||
required final String domainName,
|
required final int serverId,
|
||||||
}) async {
|
}) async {
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
try {
|
try {
|
||||||
final String hostname = getHostnameFromDomain(domainName);
|
await client.delete('/servers/$serverId');
|
||||||
|
|
||||||
final Response serversReponse = await client.get('/servers');
|
|
||||||
final List servers = serversReponse.data['servers'];
|
|
||||||
final Map server =
|
|
||||||
servers.firstWhere((final el) => el['name'] == hostname);
|
|
||||||
final List volumes = server['volumes'];
|
|
||||||
final List<Future> laterFutures = <Future>[];
|
|
||||||
|
|
||||||
for (final volumeId in volumes) {
|
|
||||||
await client.post('/volumes/$volumeId/actions/detach');
|
|
||||||
}
|
|
||||||
await Future.delayed(const Duration(seconds: 10));
|
|
||||||
|
|
||||||
for (final volumeId in volumes) {
|
|
||||||
laterFutures.add(client.delete('/volumes/$volumeId'));
|
|
||||||
}
|
|
||||||
laterFutures.add(client.delete('/servers/${server['id']}'));
|
|
||||||
|
|
||||||
await Future.wait(laterFutures);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
return GenericResult(
|
return GenericResult(
|
||||||
success: false,
|
success: false,
|
||||||
data: false,
|
data: null,
|
||||||
message: e.toString(),
|
message: e.toString(),
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
close(client);
|
close(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GenericResult(
|
return GenericResult(success: true, data: null);
|
||||||
success: true,
|
|
||||||
data: true,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<GenericResult<void>> restart(final int serverId) async {
|
Future<GenericResult<void>> restart(final int serverId) async {
|
||||||
|
|
|
@ -455,7 +455,7 @@ class HetznerServerProvider extends ServerProvider {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!serverResult.success || serverResult.data == null) {
|
if (!serverResult.success || serverResult.data == null) {
|
||||||
await _adapter.api().deleteVolume(volume);
|
await _adapter.api().deleteVolume(volume.id);
|
||||||
await Future.delayed(const Duration(seconds: 5));
|
await Future.delayed(const Duration(seconds: 5));
|
||||||
if (serverResult.message != null &&
|
if (serverResult.message != null &&
|
||||||
serverResult.message == 'uniqueness_error') {
|
serverResult.message == 'uniqueness_error') {
|
||||||
|
@ -549,7 +549,7 @@ class HetznerServerProvider extends ServerProvider {
|
||||||
CallbackDialogueChoice(
|
CallbackDialogueChoice(
|
||||||
title: 'basis.try_again'.tr(),
|
title: 'basis.try_again'.tr(),
|
||||||
callback: () async {
|
callback: () async {
|
||||||
await _adapter.api().deleteVolume(volume);
|
await _adapter.api().deleteVolume(volume.id);
|
||||||
await Future.delayed(const Duration(seconds: 5));
|
await Future.delayed(const Duration(seconds: 5));
|
||||||
final deletion = await deleteServer(hostname);
|
final deletion = await deleteServer(hostname);
|
||||||
if (deletion.success) {
|
if (deletion.success) {
|
||||||
|
@ -576,5 +576,59 @@ class HetznerServerProvider extends ServerProvider {
|
||||||
|
|
||||||
Future<GenericResult<CallbackDialogueBranching?>> deleteServer(
|
Future<GenericResult<CallbackDialogueBranching?>> deleteServer(
|
||||||
final String hostname,
|
final String hostname,
|
||||||
) async {}
|
) async {
|
||||||
|
final serversResult = await _adapter.api().getServers();
|
||||||
|
try {
|
||||||
|
final servers = serversResult.data;
|
||||||
|
HetznerServerInfo? foundServer;
|
||||||
|
for (final server in servers) {
|
||||||
|
if (server.name == hostname) {
|
||||||
|
foundServer = server;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final volumeId in foundServer!.volumes) {
|
||||||
|
await _adapter.api().detachVolume(volumeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Future.delayed(const Duration(seconds: 10));
|
||||||
|
final List<Future> laterFutures = <Future>[];
|
||||||
|
|
||||||
|
for (final volumeId in foundServer.volumes) {
|
||||||
|
laterFutures.add(_adapter.api().deleteVolume(volumeId));
|
||||||
|
}
|
||||||
|
laterFutures.add(_adapter.api().deleteVolume(foundServer.id));
|
||||||
|
|
||||||
|
await Future.wait(laterFutures);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
return GenericResult(
|
||||||
|
success: false,
|
||||||
|
data: CallbackDialogueBranching(
|
||||||
|
choices: [
|
||||||
|
CallbackDialogueChoice(
|
||||||
|
title: 'basis.cancel'.tr(),
|
||||||
|
callback: null,
|
||||||
|
),
|
||||||
|
CallbackDialogueChoice(
|
||||||
|
title: 'basis.try_again'.tr(),
|
||||||
|
callback: () async {
|
||||||
|
await Future.delayed(const Duration(seconds: 5));
|
||||||
|
return deleteServer(hostname);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
description: 'modals.try_again'.tr(),
|
||||||
|
title: 'modals.server_deletion_error'.tr(),
|
||||||
|
),
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GenericResult(
|
||||||
|
success: true,
|
||||||
|
data: null,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue