diff --git a/lib/logic/api_maps/rest_maps/server_providers/digital_ocean/digital_ocean_api.dart b/lib/logic/api_maps/rest_maps/server_providers/digital_ocean/digital_ocean_api.dart index fabeac24..0d25dc2b 100644 --- a/lib/logic/api_maps/rest_maps/server_providers/digital_ocean/digital_ocean_api.dart +++ b/lib/logic/api_maps/rest_maps/server_providers/digital_ocean/digital_ocean_api.dart @@ -107,13 +107,10 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi { currency: 'USD', ); - Future> createVolume() async { - ServerVolume? volume; - + Future createVolume() async { Response? createVolumeResponse; final Dio client = await getClient(); try { - final List 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> getVolumes({final String? status}) async { - final List volumes = []; + Future> 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 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 getVolume(final String volumeUuid) async { - ServerVolume? requestedVolume; - - final List volumes = await getVolumes(); - - for (final volume in volumes) { - if (volume.uuid == volumeUuid) { - requestedVolume = volume; - } - } - - return requestedVolume; - } - - Future deleteVolume(final ServerVolume volume) async { + Future> 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> 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 detachVolume(final ServerVolume volume) async { + Future> 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 resizeVolume( - final ServerVolume volume, + Future> 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> createServer({ diff --git a/lib/logic/providers/server_providers/digital_ocean.dart b/lib/logic/providers/server_providers/digital_ocean.dart index b8bc3ab1..df7af648 100644 --- a/lib/logic/providers/server_providers/digital_ocean.dart +++ b/lib/logic/providers/server_providers/digital_ocean.dart @@ -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 laterFutures = []; - 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>> getVolumes({ + final String? status, + }) async { + final List 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> 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> 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> deleteVolume( + final ServerVolume volume, + ) async => + _adapter.api().deleteVolume( + volume.uuid!, + ); + + Future> attachVolume( + final ServerVolume volume, + final int serverId, + ) async => + _adapter.api().attachVolume( + volume.name, + serverId, + ); + + Future> detachVolume( + final ServerVolume volume, + ) async => + _adapter.api().detachVolume( + volume.name, + volume.serverId!, + ); + + Future> resizeVolume( + final ServerVolume volume, + final DiskSize size, + ) async => + _adapter.api().resizeVolume( + volume.name, + size, + ); }