chore: Move volume functions to provider layer for Digital Ocean
parent
dde6f7e80d
commit
4e4b61609f
|
@ -107,13 +107,10 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
||||||
currency: 'USD',
|
currency: 'USD',
|
||||||
);
|
);
|
||||||
|
|
||||||
Future<GenericResult<ServerVolume?>> createVolume() async {
|
Future<GenericResult> createVolume() async {
|
||||||
ServerVolume? volume;
|
|
||||||
|
|
||||||
Response? createVolumeResponse;
|
Response? createVolumeResponse;
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
try {
|
try {
|
||||||
final List<ServerVolume> volumes = await getVolumes();
|
|
||||||
await Future.delayed(const Duration(seconds: 6));
|
await Future.delayed(const Duration(seconds: 6));
|
||||||
|
|
||||||
createVolumeResponse = await client.post(
|
createVolumeResponse = await client.post(
|
||||||
|
@ -126,17 +123,6 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
||||||
'filesystem_type': 'ext4',
|
'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) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
return GenericResult(
|
return GenericResult(
|
||||||
|
@ -149,17 +135,17 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
return GenericResult(
|
return GenericResult(
|
||||||
data: volume,
|
data: createVolumeResponse.data,
|
||||||
success: true,
|
success: true,
|
||||||
code: createVolumeResponse.statusCode,
|
code: createVolumeResponse.statusCode,
|
||||||
message: createVolumeResponse.statusMessage,
|
message: createVolumeResponse.statusMessage,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<ServerVolume>> getVolumes({final String? status}) async {
|
Future<GenericResult<List>> getVolumes({final String? status}) async {
|
||||||
final List<ServerVolume> volumes = [];
|
List volumes = [];
|
||||||
|
|
||||||
final Response getVolumesResponse;
|
Response? getVolumesResponse;
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
try {
|
try {
|
||||||
getVolumesResponse = await client.get(
|
getVolumesResponse = await client.get(
|
||||||
|
@ -168,59 +154,47 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
||||||
'status': status,
|
'status': status,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
final List<dynamic> rawVolumes = getVolumesResponse.data['volumes'];
|
volumes = 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);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
|
return GenericResult(
|
||||||
|
data: [],
|
||||||
|
success: false,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
client.close();
|
client.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
return volumes;
|
return GenericResult(
|
||||||
|
data: volumes,
|
||||||
|
success: false,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ServerVolume?> getVolume(final String volumeUuid) async {
|
Future<GenericResult<void>> deleteVolume(final String uuid) 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 {
|
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
try {
|
try {
|
||||||
await client.delete('/volumes/${volume.uuid}');
|
await client.delete('/volumes/$uuid');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
|
return GenericResult(
|
||||||
|
data: null,
|
||||||
|
success: false,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
client.close();
|
client.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return GenericResult(
|
||||||
|
data: null,
|
||||||
|
success: true,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<GenericResult<bool>> attachVolume(
|
Future<GenericResult<bool>> attachVolume(
|
||||||
final ServerVolume volume,
|
final String name,
|
||||||
final int serverId,
|
final int serverId,
|
||||||
) async {
|
) async {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
@ -232,7 +206,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
||||||
'/volumes/actions',
|
'/volumes/actions',
|
||||||
data: {
|
data: {
|
||||||
'type': 'attach',
|
'type': 'attach',
|
||||||
'volume_name': volume.name,
|
'volume_name': name,
|
||||||
'region': region,
|
'region': region,
|
||||||
'droplet_id': serverId,
|
'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;
|
bool success = false;
|
||||||
|
|
||||||
final Response detachVolumeResponse;
|
final Response detachVolumeResponse;
|
||||||
|
@ -268,8 +245,8 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
||||||
'/volumes/actions',
|
'/volumes/actions',
|
||||||
data: {
|
data: {
|
||||||
'type': 'detach',
|
'type': 'detach',
|
||||||
'volume_name': volume.name,
|
'volume_name': name,
|
||||||
'droplet_id': volume.serverId,
|
'droplet_id': serverId,
|
||||||
'region': region,
|
'region': region,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -277,15 +254,23 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
||||||
detachVolumeResponse.data['action']['status'].toString() != 'error';
|
detachVolumeResponse.data['action']['status'].toString() != 'error';
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
|
return GenericResult(
|
||||||
|
data: false,
|
||||||
|
success: false,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
client.close();
|
client.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return GenericResult(
|
||||||
|
data: success,
|
||||||
|
success: true,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> resizeVolume(
|
Future<GenericResult<bool>> resizeVolume(
|
||||||
final ServerVolume volume,
|
final String name,
|
||||||
final DiskSize size,
|
final DiskSize size,
|
||||||
) async {
|
) async {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
@ -297,7 +282,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
||||||
'/volumes/actions',
|
'/volumes/actions',
|
||||||
data: {
|
data: {
|
||||||
'type': 'resize',
|
'type': 'resize',
|
||||||
'volume_name': volume.name,
|
'volume_name': name,
|
||||||
'size_gigabytes': size.gibibyte,
|
'size_gigabytes': size.gibibyte,
|
||||||
'region': region,
|
'region': region,
|
||||||
},
|
},
|
||||||
|
@ -306,11 +291,19 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
||||||
resizeVolumeResponse.data['action']['status'].toString() != 'error';
|
resizeVolumeResponse.data['action']['status'].toString() != 'error';
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
|
return GenericResult(
|
||||||
|
data: false,
|
||||||
|
success: false,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
client.close();
|
client.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return GenericResult(
|
||||||
|
data: success,
|
||||||
|
success: true,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<GenericResult<ServerHostingDetails?>> createServer({
|
Future<GenericResult<ServerHostingDetails?>> createServer({
|
||||||
|
|
|
@ -439,17 +439,20 @@ class DigitalOceanServerProvider extends ServerProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final volumes = await _adapter.api().getVolumes();
|
final volumes = await getVolumes();
|
||||||
final ServerVolume volumeToRemove;
|
final ServerVolume volumeToRemove;
|
||||||
volumeToRemove = volumes.firstWhere(
|
volumeToRemove = volumes.data.firstWhere(
|
||||||
(final el) => el.serverId == foundServer!.id,
|
(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));
|
await Future.delayed(const Duration(seconds: 10));
|
||||||
final List<Future> laterFutures = <Future>[];
|
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));
|
laterFutures.add(_adapter.api().deleteServer(foundServer!.id));
|
||||||
|
|
||||||
await Future.wait(laterFutures);
|
await Future.wait(laterFutures);
|
||||||
|
@ -483,4 +486,156 @@ class DigitalOceanServerProvider extends ServerProvider {
|
||||||
data: null,
|
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,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue