chore: Implement basic Digital Ocean server models

pull/213/head
NaiJi ✨ 2023-06-07 03:22:27 -03:00
parent f42e415633
commit 140acaee49
5 changed files with 128 additions and 33 deletions

View File

@ -7,7 +7,7 @@ import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_pro
import 'package:selfprivacy/logic/api_maps/staging_options.dart'; import 'package:selfprivacy/logic/api_maps/staging_options.dart';
import 'package:selfprivacy/logic/models/disk_size.dart'; import 'package:selfprivacy/logic/models/disk_size.dart';
import 'package:selfprivacy/logic/models/hive/user.dart'; import 'package:selfprivacy/logic/models/hive/user.dart';
import 'package:selfprivacy/logic/models/server_provider_location.dart'; import 'package:selfprivacy/logic/models/json/digital_ocean_server_info.dart';
import 'package:selfprivacy/utils/password_generator.dart'; import 'package:selfprivacy/utils/password_generator.dart';
class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi { class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
@ -98,7 +98,8 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
); );
} }
Future<GenericResult> createVolume() async { Future<GenericResult<DigitalOceanVolume?>> createVolume() async {
DigitalOceanVolume? volume;
Response? createVolumeResponse; Response? createVolumeResponse;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
@ -114,6 +115,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
'filesystem_type': 'ext4', 'filesystem_type': 'ext4',
}, },
); );
volume = DigitalOceanVolume.fromJson(createVolumeResponse.data['volume']);
} catch (e) { } catch (e) {
print(e); print(e);
return GenericResult( return GenericResult(
@ -126,15 +128,17 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
} }
return GenericResult( return GenericResult(
data: createVolumeResponse.data, data: volume,
success: true, success: true,
code: createVolumeResponse.statusCode, code: createVolumeResponse.statusCode,
message: createVolumeResponse.statusMessage, message: createVolumeResponse.statusMessage,
); );
} }
Future<GenericResult<List>> getVolumes({final String? status}) async { Future<GenericResult<List<DigitalOceanVolume>>> getVolumes({
List volumes = []; final String? status,
}) async {
final List<DigitalOceanVolume> volumes = [];
Response? getVolumesResponse; Response? getVolumesResponse;
final Dio client = await getClient(); final Dio client = await getClient();
@ -145,7 +149,9 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
'status': status, 'status': status,
}, },
); );
volumes = getVolumesResponse.data['volumes']; for (final volume in getVolumesResponse.data['volumes']) {
volumes.add(DigitalOceanVolume.fromJson(volume));
}
} catch (e) { } catch (e) {
print(e); print(e);
return GenericResult( return GenericResult(
@ -159,7 +165,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
return GenericResult( return GenericResult(
data: volumes, data: volumes,
success: false, success: true,
); );
} }
@ -297,7 +303,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
); );
} }
Future<GenericResult> createServer({ Future<GenericResult<int?>> createServer({
required final String dnsApiToken, required final String dnsApiToken,
required final String dnsProviderType, required final String dnsProviderType,
required final String serverApiToken, required final String serverApiToken,
@ -310,6 +316,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
}) async { }) async {
final String stagingAcme = StagingOptions.stagingAcme ? 'true' : 'false'; final String stagingAcme = StagingOptions.stagingAcme ? 'true' : 'false';
int? dropletId;
Response? serverCreateResponse; Response? serverCreateResponse;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
@ -331,6 +338,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
'/droplets', '/droplets',
data: data, data: data,
); );
dropletId = serverCreateResponse.data['droplet']['id'];
} catch (e) { } catch (e) {
print(e); print(e);
return GenericResult( return GenericResult(
@ -343,7 +351,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
} }
return GenericResult( return GenericResult(
data: serverCreateResponse, data: dropletId,
success: true, success: true,
code: serverCreateResponse.statusCode, code: serverCreateResponse.statusCode,
message: serverCreateResponse.statusMessage, message: serverCreateResponse.statusMessage,
@ -502,8 +510,9 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
return GenericResult(success: true, data: servers); return GenericResult(success: true, data: servers);
} }
Future<GenericResult<List>> getAvailableLocations() async { Future<GenericResult<List<DigitalOceanLocation>>>
List<ServerProviderLocation> locations = []; getAvailableLocations() async {
final List<DigitalOceanLocation> locations = [];
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
@ -511,7 +520,9 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
'/regions', '/regions',
); );
locations = response.data!['regions']; for (final region in response.data!['regions']) {
locations.add(DigitalOceanLocation.fromJson(region));
}
} catch (e) { } catch (e) {
print(e); print(e);
return GenericResult( return GenericResult(

View File

@ -0,0 +1,39 @@
import 'package:json_annotation/json_annotation.dart';
part 'digital_ocean_server_info.g.dart';
@JsonSerializable()
class DigitalOceanVolume {
DigitalOceanVolume(
this.id,
this.name,
this.sizeGigabytes,
this.dropletIds,
);
final String id;
final String name;
@JsonKey(name: 'droplet_ids')
final List<int> dropletIds;
@JsonKey(name: 'size_gigabytes')
final int sizeGigabytes;
static DigitalOceanVolume fromJson(final Map<String, dynamic> json) =>
_$DigitalOceanVolumeFromJson(json);
}
@JsonSerializable()
class DigitalOceanLocation {
DigitalOceanLocation(
this.slug,
this.name,
);
final String slug;
final String name;
static DigitalOceanLocation fromJson(final Map<String, dynamic> json) =>
_$DigitalOceanLocationFromJson(json);
}

View File

@ -0,0 +1,37 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'digital_ocean_server_info.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
DigitalOceanVolume _$DigitalOceanVolumeFromJson(Map<String, dynamic> json) =>
DigitalOceanVolume(
json['id'] as String,
json['name'] as String,
json['size_gigabytes'] as int,
(json['droplet_ids'] as List<dynamic>).map((e) => e as int).toList(),
);
Map<String, dynamic> _$DigitalOceanVolumeToJson(DigitalOceanVolume instance) =>
<String, dynamic>{
'id': instance.id,
'name': instance.name,
'droplet_ids': instance.dropletIds,
'size_gigabytes': instance.sizeGigabytes,
};
DigitalOceanLocation _$DigitalOceanLocationFromJson(
Map<String, dynamic> json) =>
DigitalOceanLocation(
json['slug'] as String,
json['name'] as String,
);
Map<String, dynamic> _$DigitalOceanLocationToJson(
DigitalOceanLocation instance) =>
<String, dynamic>{
'slug': instance.slug,
'name': instance.name,
};

View File

@ -81,6 +81,8 @@ HetznerServerTypeInfo _$HetznerServerTypeInfoFromJson(
(json['prices'] as List<dynamic>) (json['prices'] as List<dynamic>)
.map((e) => HetznerPriceInfo.fromJson(e as Map<String, dynamic>)) .map((e) => HetznerPriceInfo.fromJson(e as Map<String, dynamic>))
.toList(), .toList(),
json['name'] as String,
json['description'] as String,
); );
Map<String, dynamic> _$HetznerServerTypeInfoToJson( Map<String, dynamic> _$HetznerServerTypeInfoToJson(
@ -89,6 +91,8 @@ Map<String, dynamic> _$HetznerServerTypeInfoToJson(
'cores': instance.cores, 'cores': instance.cores,
'memory': instance.memory, 'memory': instance.memory,
'disk': instance.disk, 'disk': instance.disk,
'name': instance.name,
'description': instance.description,
'prices': instance.prices, 'prices': instance.prices,
}; };
@ -96,12 +100,14 @@ HetznerPriceInfo _$HetznerPriceInfoFromJson(Map<String, dynamic> json) =>
HetznerPriceInfo( HetznerPriceInfo(
HetznerPriceInfo.getPrice(json['price_hourly'] as Map), HetznerPriceInfo.getPrice(json['price_hourly'] as Map),
HetznerPriceInfo.getPrice(json['price_monthly'] as Map), HetznerPriceInfo.getPrice(json['price_monthly'] as Map),
json['location'] as String,
); );
Map<String, dynamic> _$HetznerPriceInfoToJson(HetznerPriceInfo instance) => Map<String, dynamic> _$HetznerPriceInfoToJson(HetznerPriceInfo instance) =>
<String, dynamic>{ <String, dynamic>{
'price_hourly': instance.hourly, 'price_hourly': instance.hourly,
'price_monthly': instance.monthly, 'price_monthly': instance.monthly,
'location': instance.location,
}; };
HetznerLocation _$HetznerLocationFromJson(Map<String, dynamic> json) => HetznerLocation _$HetznerLocationFromJson(Map<String, dynamic> json) =>
@ -110,10 +116,12 @@ HetznerLocation _$HetznerLocationFromJson(Map<String, dynamic> json) =>
json['city'] as String, json['city'] as String,
json['description'] as String, json['description'] as String,
json['network_zone'] as String, json['network_zone'] as String,
json['name'] as String,
); );
Map<String, dynamic> _$HetznerLocationToJson(HetznerLocation instance) => Map<String, dynamic> _$HetznerLocationToJson(HetznerLocation instance) =>
<String, dynamic>{ <String, dynamic>{
'name': instance.name,
'country': instance.country, 'country': instance.country,
'city': instance.city, 'city': instance.city,
'description': instance.description, 'description': instance.description,

View File

@ -6,6 +6,7 @@ import 'package:selfprivacy/logic/models/callback_dialogue_branching.dart';
import 'package:selfprivacy/logic/models/disk_size.dart'; import 'package:selfprivacy/logic/models/disk_size.dart';
import 'package:selfprivacy/logic/models/hive/server_details.dart'; import 'package:selfprivacy/logic/models/hive/server_details.dart';
import 'package:selfprivacy/logic/models/hive/server_domain.dart'; import 'package:selfprivacy/logic/models/hive/server_domain.dart';
import 'package:selfprivacy/logic/models/json/digital_ocean_server_info.dart';
import 'package:selfprivacy/logic/models/metrics.dart'; import 'package:selfprivacy/logic/models/metrics.dart';
import 'package:selfprivacy/logic/models/price.dart'; import 'package:selfprivacy/logic/models/price.dart';
import 'package:selfprivacy/logic/models/server_basic_info.dart'; import 'package:selfprivacy/logic/models/server_basic_info.dart';
@ -179,10 +180,13 @@ class DigitalOceanServerProvider extends ServerProvider {
} }
try { try {
final int dropletId = serverResult.data['droplet']['id']; final int dropletId = serverResult.data!;
final ServerVolume? newVolume = (await createVolume()).data; final newVolume = (await createVolume()).data;
final bool attachedVolume = final bool attachedVolume = (await _adapter.api().attachVolume(
(await attachVolume(newVolume!, dropletId)).data; newVolume!.name,
dropletId,
))
.data;
String? ipv4; String? ipv4;
int attempts = 0; int attempts = 0;
@ -253,15 +257,15 @@ class DigitalOceanServerProvider extends ServerProvider {
); );
} }
final List rawLocations = result.data; final List<DigitalOceanLocation> rawLocations = result.data;
for (final rawLocation in rawLocations) { for (final rawLocation in rawLocations) {
ServerProviderLocation? location; ServerProviderLocation? location;
try { try {
location = ServerProviderLocation( location = ServerProviderLocation(
title: rawLocation['slug'], title: rawLocation.slug,
description: rawLocation['name'], description: rawLocation.name,
flag: getEmojiFlag(rawLocation['slug']), flag: getEmojiFlag(rawLocation.slug),
identifier: rawLocation['slug'], identifier: rawLocation.slug,
); );
} catch (e) { } catch (e) {
continue; continue;
@ -638,17 +642,15 @@ class DigitalOceanServerProvider extends ServerProvider {
try { try {
int id = 0; int id = 0;
for (final rawVolume in result.data) { for (final rawVolume in result.data) {
final volumeId = rawVolume['id']; final String volumeName = rawVolume.name;
final int volumeSize = rawVolume['size_gigabytes'] * 1024 * 1024 * 1024;
final volumeDropletIds = rawVolume['droplet_ids'];
final String volumeName = rawVolume['name'];
final volume = ServerVolume( final volume = ServerVolume(
id: id++, id: id++,
name: volumeName, name: volumeName,
sizeByte: volumeSize, sizeByte: rawVolume.sizeGigabytes * 1024 * 1024 * 1024,
serverId: volumeDropletIds.isNotEmpty ? volumeDropletIds[0] : null, serverId:
rawVolume.dropletIds.isNotEmpty ? rawVolume.dropletIds[0] : null,
linuxDevice: 'scsi-0DO_Volume_$volumeName', linuxDevice: 'scsi-0DO_Volume_$volumeName',
uuid: volumeId, uuid: rawVolume.id,
); );
volumes.add(volume); volumes.add(volume);
} }
@ -693,16 +695,14 @@ class DigitalOceanServerProvider extends ServerProvider {
); );
} }
final volumeId = result.data['volume']['id']; final String volumeName = result.data!.name;
final volumeSize = result.data['volume']['size_gigabytes'];
final volumeName = result.data['volume']['name'];
volume = ServerVolume( volume = ServerVolume(
id: getVolumesResult.data.length, id: getVolumesResult.data.length,
name: volumeName, name: volumeName,
sizeByte: volumeSize, sizeByte: result.data!.sizeGigabytes,
serverId: null, serverId: null,
linuxDevice: '/dev/disk/by-id/scsi-0DO_Volume_$volumeName', linuxDevice: '/dev/disk/by-id/scsi-0DO_Volume_$volumeName',
uuid: volumeId, uuid: result.data!.id,
); );
return GenericResult( return GenericResult(