chore: Move volume functions to provider layer for Digital Ocean

pull/213/head
NaiJi ✨ 2023-03-21 13:08:46 -03:00
parent dde6f7e80d
commit 4e4b61609f
2 changed files with 215 additions and 67 deletions

View File

@ -107,13 +107,10 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
currency: 'USD',
);
Future<GenericResult<ServerVolume?>> createVolume() async {
ServerVolume? volume;
Future<GenericResult> createVolume() async {
Response? createVolumeResponse;
final Dio client = await getClient();
try {
final List<ServerVolume> volumes = await getVolumes();
await Future.delayed(const Duration(seconds: 6));
createVolumeResponse = await client.post(
@ -126,17 +123,6 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
'filesystem_type': 'ext4',
},
);
final volumeId = createVolumeResponse.data['volume']['id'];
final volumeSize = createVolumeResponse.data['volume']['size_gigabytes'];
final volumeName = createVolumeResponse.data['volume']['name'];
volume = ServerVolume(
id: volumes.length,
name: volumeName,
sizeByte: volumeSize,
serverId: null,
linuxDevice: '/dev/disk/by-id/scsi-0DO_Volume_$volumeName',
uuid: volumeId,
);
} catch (e) {
print(e);
return GenericResult(
@ -149,17 +135,17 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
}
return GenericResult(
data: volume,
data: createVolumeResponse.data,
success: true,
code: createVolumeResponse.statusCode,
message: createVolumeResponse.statusMessage,
);
}
Future<List<ServerVolume>> getVolumes({final String? status}) async {
final List<ServerVolume> volumes = [];
Future<GenericResult<List>> getVolumes({final String? status}) async {
List volumes = [];
final Response getVolumesResponse;
Response? getVolumesResponse;
final Dio client = await getClient();
try {
getVolumesResponse = await client.get(
@ -168,59 +154,47 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
'status': status,
},
);
final List<dynamic> rawVolumes = getVolumesResponse.data['volumes'];
int id = 0;
for (final rawVolume in rawVolumes) {
final volumeId = rawVolume['id'];
final int volumeSize = rawVolume['size_gigabytes'] * 1024 * 1024 * 1024;
final volumeDropletIds = rawVolume['droplet_ids'];
final String volumeName = rawVolume['name'];
final volume = ServerVolume(
id: id++,
name: volumeName,
sizeByte: volumeSize,
serverId: volumeDropletIds.isNotEmpty ? volumeDropletIds[0] : null,
linuxDevice: 'scsi-0DO_Volume_$volumeName',
uuid: volumeId,
);
volumes.add(volume);
}
volumes = getVolumesResponse.data['volumes'];
} catch (e) {
print(e);
return GenericResult(
data: [],
success: false,
message: e.toString(),
);
} finally {
client.close();
}
return volumes;
return GenericResult(
data: volumes,
success: false,
);
}
Future<ServerVolume?> getVolume(final String volumeUuid) async {
ServerVolume? requestedVolume;
final List<ServerVolume> volumes = await getVolumes();
for (final volume in volumes) {
if (volume.uuid == volumeUuid) {
requestedVolume = volume;
}
}
return requestedVolume;
}
Future<void> deleteVolume(final ServerVolume volume) async {
Future<GenericResult<void>> deleteVolume(final String uuid) async {
final Dio client = await getClient();
try {
await client.delete('/volumes/${volume.uuid}');
await client.delete('/volumes/$uuid');
} catch (e) {
print(e);
return GenericResult(
data: null,
success: false,
message: e.toString(),
);
} finally {
client.close();
}
return GenericResult(
data: null,
success: true,
);
}
Future<GenericResult<bool>> attachVolume(
final ServerVolume volume,
final String name,
final int serverId,
) async {
bool success = false;
@ -232,7 +206,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
'/volumes/actions',
data: {
'type': 'attach',
'volume_name': volume.name,
'volume_name': name,
'region': region,
'droplet_id': serverId,
},
@ -258,7 +232,10 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
);
}
Future<bool> detachVolume(final ServerVolume volume) async {
Future<GenericResult<bool>> detachVolume(
final String name,
final int serverId,
) async {
bool success = false;
final Response detachVolumeResponse;
@ -268,8 +245,8 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
'/volumes/actions',
data: {
'type': 'detach',
'volume_name': volume.name,
'droplet_id': volume.serverId,
'volume_name': name,
'droplet_id': serverId,
'region': region,
},
);
@ -277,15 +254,23 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
detachVolumeResponse.data['action']['status'].toString() != 'error';
} catch (e) {
print(e);
return GenericResult(
data: false,
success: false,
message: e.toString(),
);
} finally {
client.close();
}
return success;
return GenericResult(
data: success,
success: true,
);
}
Future<bool> resizeVolume(
final ServerVolume volume,
Future<GenericResult<bool>> resizeVolume(
final String name,
final DiskSize size,
) async {
bool success = false;
@ -297,7 +282,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
'/volumes/actions',
data: {
'type': 'resize',
'volume_name': volume.name,
'volume_name': name,
'size_gigabytes': size.gibibyte,
'region': region,
},
@ -306,11 +291,19 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
resizeVolumeResponse.data['action']['status'].toString() != 'error';
} catch (e) {
print(e);
return GenericResult(
data: false,
success: false,
message: e.toString(),
);
} finally {
client.close();
}
return success;
return GenericResult(
data: success,
success: true,
);
}
Future<GenericResult<ServerHostingDetails?>> createServer({

View File

@ -439,17 +439,20 @@ class DigitalOceanServerProvider extends ServerProvider {
}
}
final volumes = await _adapter.api().getVolumes();
final volumes = await getVolumes();
final ServerVolume volumeToRemove;
volumeToRemove = volumes.firstWhere(
volumeToRemove = volumes.data.firstWhere(
(final el) => el.serverId == foundServer!.id,
);
await _adapter.api().detachVolume(volumeToRemove);
await _adapter.api().detachVolume(
volumeToRemove.name,
volumeToRemove.serverId!,
);
await Future.delayed(const Duration(seconds: 10));
final List<Future> laterFutures = <Future>[];
laterFutures.add(_adapter.api().deleteVolume(volumeToRemove));
laterFutures.add(_adapter.api().deleteVolume(volumeToRemove.uuid!));
laterFutures.add(_adapter.api().deleteServer(foundServer!.id));
await Future.wait(laterFutures);
@ -483,4 +486,156 @@ class DigitalOceanServerProvider extends ServerProvider {
data: null,
);
}
Future<GenericResult<List<ServerVolume>>> getVolumes({
final String? status,
}) async {
final List<ServerVolume> volumes = [];
final result = await _adapter.api().getVolumes();
if (!result.success || result.data.isEmpty) {
return GenericResult(
data: [],
success: false,
code: result.code,
message: result.message,
);
}
try {
int id = 0;
for (final rawVolume in result.data) {
final volumeId = rawVolume['id'];
final int volumeSize = rawVolume['size_gigabytes'] * 1024 * 1024 * 1024;
final volumeDropletIds = rawVolume['droplet_ids'];
final String volumeName = rawVolume['name'];
final volume = ServerVolume(
id: id++,
name: volumeName,
sizeByte: volumeSize,
serverId: volumeDropletIds.isNotEmpty ? volumeDropletIds[0] : null,
linuxDevice: 'scsi-0DO_Volume_$volumeName',
uuid: volumeId,
);
volumes.add(volume);
}
} catch (e) {
print(e);
return GenericResult(
data: [],
success: false,
message: e.toString(),
);
}
return GenericResult(
data: volumes,
success: true,
);
}
Future<GenericResult<ServerVolume?>> createVolume() async {
ServerVolume? volume;
final result = await _adapter.api().createVolume();
if (!result.success || result.data == null) {
return GenericResult(
data: null,
success: false,
code: result.code,
message: result.message,
);
}
final getVolumesResult = await _adapter.api().getVolumes();
if (!getVolumesResult.success || getVolumesResult.data.isEmpty) {
return GenericResult(
data: null,
success: false,
code: result.code,
message: result.message,
);
}
final volumeId = result.data['volume']['id'];
final volumeSize = result.data['volume']['size_gigabytes'];
final volumeName = result.data['volume']['name'];
volume = ServerVolume(
id: getVolumesResult.data.length,
name: volumeName,
sizeByte: volumeSize,
serverId: null,
linuxDevice: '/dev/disk/by-id/scsi-0DO_Volume_$volumeName',
uuid: volumeId,
);
return GenericResult(
data: volume,
success: true,
);
}
Future<GenericResult<ServerVolume?>> getVolume(
final String volumeUuid,
) async {
ServerVolume? requestedVolume;
final result = await getVolumes();
if (!result.success || result.data.isEmpty) {
return GenericResult(
data: null,
success: false,
code: result.code,
message: result.message,
);
}
for (final volume in result.data) {
if (volume.uuid == volumeUuid) {
requestedVolume = volume;
}
}
return GenericResult(
data: requestedVolume,
success: true,
);
}
Future<GenericResult<void>> deleteVolume(
final ServerVolume volume,
) async =>
_adapter.api().deleteVolume(
volume.uuid!,
);
Future<GenericResult<bool>> attachVolume(
final ServerVolume volume,
final int serverId,
) async =>
_adapter.api().attachVolume(
volume.name,
serverId,
);
Future<GenericResult<bool>> detachVolume(
final ServerVolume volume,
) async =>
_adapter.api().detachVolume(
volume.name,
volume.serverId!,
);
Future<GenericResult<bool>> resizeVolume(
final ServerVolume volume,
final DiskSize size,
) async =>
_adapter.api().resizeVolume(
volume.name,
size,
);
}