fix: Make improvements by Code Review

pull/140/head
NaiJi ✨ 2022-11-23 11:55:28 +04:00
parent a70e793360
commit 8c6b56f61d
11 changed files with 192 additions and 181 deletions

View File

@ -271,7 +271,7 @@
"connect_to_server": "Подключите сервер", "connect_to_server": "Подключите сервер",
"place_where_data": "Здесь будут жить ваши данные и SelfPrivacy-сервисы:", "place_where_data": "Здесь будут жить ваши данные и SelfPrivacy-сервисы:",
"how": "Как получить API Token", "how": "Как получить API Token",
"provider_bad_key_error": "Provider API key is invalid", "provider_bad_key_error": "API ключ провайдера неверен",
"choose_location_type": "Выберите локацию и тип вашего сервера:", "choose_location_type": "Выберите локацию и тип вашего сервера:",
"back_to_locations": "Назад к доступным локациям!", "back_to_locations": "Назад к доступным локациям!",
"no_locations_found": "Не найдено локаций. Убедитесь, что ваш аккаунт доступен.", "no_locations_found": "Не найдено локаций. Убедитесь, что ваш аккаунт доступен.",

View File

@ -7,19 +7,21 @@ import 'package:selfprivacy/logic/api_maps/staging_options.dart';
abstract class ApiMap { abstract class ApiMap {
Future<GraphQLClient> getClient() async { Future<GraphQLClient> getClient() async {
final HttpClient httpClient = HttpClient(); IOClient? ioClient;
if (StagingOptions.stagingAcme) { if (StagingOptions.stagingAcme) {
final HttpClient httpClient = HttpClient();
httpClient.badCertificateCallback = ( httpClient.badCertificateCallback = (
final cert, final cert,
final host, final host,
final port, final port,
) => ) =>
true; true;
ioClient = IOClient(httpClient);
} }
final httpLink = HttpLink( final httpLink = HttpLink(
'https://api.$rootAddress/graphql', 'https://api.$rootAddress/graphql',
httpClient: IOClient(httpClient), httpClient: ioClient,
); );
final String token = _getApiToken(); final String token = _getApiToken();

View File

@ -90,7 +90,7 @@ class ServerApi extends ApiMap
} }
Future<ServerProvider> getServerProviderType() async { Future<ServerProvider> getServerProviderType() async {
QueryResult response; QueryResult<Query$SystemServerProvider> response;
ServerProvider providerType = ServerProvider.unknown; ServerProvider providerType = ServerProvider.unknown;
try { try {
@ -99,15 +99,9 @@ class ServerApi extends ApiMap
if (response.hasException) { if (response.hasException) {
print(response.exception.toString()); print(response.exception.toString());
} }
final rawProviderValue = response.data!['system']['provider']['provider']; providerType = ServerProvider.fromGraphQL(
switch (rawProviderValue) { response.parsedData!.system.provider.provider,
case 'HETZNER': );
providerType = ServerProvider.hetzner;
break;
case 'DIGITALOCEAN':
providerType = ServerProvider.digitalOcean;
break;
}
} catch (e) { } catch (e) {
print(e); print(e);
} }

View File

@ -56,7 +56,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
String get infectProviderName => 'digitalocean'; String get infectProviderName => 'digitalocean';
@override @override
String get appearanceProviderName => 'Digital Ocean'; String get displayProviderName => 'Digital Ocean';
@override @override
Future<bool> isApiTokenValid(final String token) async { Future<bool> isApiTokenValid(final String token) async {
@ -102,32 +102,32 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
Future<ServerVolume?> createVolume() async { Future<ServerVolume?> createVolume() async {
ServerVolume? volume; ServerVolume? volume;
final Response dbCreateResponse; final Response createVolumeResponse;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
final List<ServerVolume> volumes = await getVolumes(); final List<ServerVolume> volumes = await getVolumes();
await Future.delayed(const Duration(seconds: 6)); await Future.delayed(const Duration(seconds: 6));
dbCreateResponse = await client.post( createVolumeResponse = await client.post(
'/volumes', '/volumes',
data: { data: {
'size_gigabytes': 10, 'size_gigabytes': 10,
'name': 'volume${StringGenerators.dbStorageName()}', 'name': 'volume${StringGenerators.storageName()}',
'labels': {'labelkey': 'value'}, 'labels': {'labelkey': 'value'},
'region': region, 'region': region,
'filesystem_type': 'ext4', 'filesystem_type': 'ext4',
}, },
); );
final dbId = dbCreateResponse.data['volume']['id']; final volumeId = createVolumeResponse.data['volume']['id'];
final dbSize = dbCreateResponse.data['volume']['size_gigabytes']; final volumeSize = createVolumeResponse.data['volume']['size_gigabytes'];
final dbName = dbCreateResponse.data['volume']['name']; final volumeName = createVolumeResponse.data['volume']['name'];
volume = ServerVolume( volume = ServerVolume(
id: volumes.length, id: volumes.length,
name: dbName, name: volumeName,
sizeByte: dbSize, sizeByte: volumeSize,
serverId: null, serverId: null,
linuxDevice: 'scsi-0DO_Volume_$dbName', linuxDevice: '/dev/disk/by-id/scsi-0DO_Volume_$volumeName',
uuid: dbId, uuid: volumeId,
); );
} catch (e) { } catch (e) {
print(e); print(e);
@ -142,29 +142,29 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
Future<List<ServerVolume>> getVolumes({final String? status}) async { Future<List<ServerVolume>> getVolumes({final String? status}) async {
final List<ServerVolume> volumes = []; final List<ServerVolume> volumes = [];
final Response dbGetResponse; final Response getVolumesResponse;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
dbGetResponse = await client.get( getVolumesResponse = await client.get(
'/volumes', '/volumes',
queryParameters: { queryParameters: {
'status': status, 'status': status,
}, },
); );
final List<dynamic> rawVolumes = dbGetResponse.data['volumes']; final List<dynamic> rawVolumes = getVolumesResponse.data['volumes'];
int id = 0; int id = 0;
for (final rawVolume in rawVolumes) { for (final rawVolume in rawVolumes) {
final dbId = rawVolume['id']; final volumeId = rawVolume['id'];
final int dbSize = rawVolume['size_gigabytes'] * 1024 * 1024 * 1024; final int volumeSize = rawVolume['size_gigabytes'] * 1024 * 1024 * 1024;
final dbDropletIds = rawVolume['droplet_ids']; final volumeDropletIds = rawVolume['droplet_ids'];
final String dbName = rawVolume['name']; final String volumeName = rawVolume['name'];
final volume = ServerVolume( final volume = ServerVolume(
id: id++, id: id++,
name: dbName, name: volumeName,
sizeByte: dbSize, sizeByte: volumeSize,
serverId: dbDropletIds.isNotEmpty ? dbDropletIds[0] : null, serverId: volumeDropletIds.isNotEmpty ? volumeDropletIds[0] : null,
linuxDevice: 'scsi-0DO_Volume_$dbName', linuxDevice: 'scsi-0DO_Volume_$volumeName',
uuid: dbId, uuid: volumeId,
); );
volumes.add(volume); volumes.add(volume);
} }
@ -178,24 +178,24 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
} }
Future<ServerVolume?> getVolume(final String volumeUuid) async { Future<ServerVolume?> getVolume(final String volumeUuid) async {
ServerVolume? neededVolume; ServerVolume? requestedVolume;
final List<ServerVolume> volumes = await getVolumes(); final List<ServerVolume> volumes = await getVolumes();
for (final volume in volumes) { for (final volume in volumes) {
if (volume.uuid == volumeUuid) { if (volume.uuid == volumeUuid) {
neededVolume = volume; requestedVolume = volume;
} }
} }
return neededVolume; return requestedVolume;
} }
@override @override
Future<void> deleteVolume(final ServerVolume volume) async { 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/${volume.uuid}');
} catch (e) { } catch (e) {
print(e); print(e);
} finally { } finally {
@ -210,10 +210,10 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
) async { ) async {
bool success = false; bool success = false;
final Response dbPostResponse; final Response attachVolumeResponse;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
dbPostResponse = await client.post( attachVolumeResponse = await client.post(
'/volumes/actions', '/volumes/actions',
data: { data: {
'type': 'attach', 'type': 'attach',
@ -222,7 +222,8 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
'droplet_id': serverId, 'droplet_id': serverId,
}, },
); );
success = dbPostResponse.data['action']['status'].toString() != 'error'; success =
attachVolumeResponse.data['action']['status'].toString() != 'error';
} catch (e) { } catch (e) {
print(e); print(e);
} finally { } finally {
@ -236,10 +237,10 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
Future<bool> detachVolume(final ServerVolume volume) async { Future<bool> detachVolume(final ServerVolume volume) async {
bool success = false; bool success = false;
final Response dbPostResponse; final Response detachVolumeResponse;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
dbPostResponse = await client.post( detachVolumeResponse = await client.post(
'/volumes/actions', '/volumes/actions',
data: { data: {
'type': 'detach', 'type': 'detach',
@ -248,7 +249,8 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
'region': region, 'region': region,
}, },
); );
success = dbPostResponse.data['action']['status'].toString() != 'error'; success =
detachVolumeResponse.data['action']['status'].toString() != 'error';
} catch (e) { } catch (e) {
print(e); print(e);
} finally { } finally {
@ -265,10 +267,10 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
) async { ) async {
bool success = false; bool success = false;
final Response dbPostResponse; final Response resizeVolumeResponse;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
dbPostResponse = await client.post( resizeVolumeResponse = await client.post(
'/volumes/actions', '/volumes/actions',
data: { data: {
'type': 'resize', 'type': 'resize',
@ -277,7 +279,8 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
'region': region, 'region': region,
}, },
); );
success = dbPostResponse.data['action']['status'].toString() != 'error'; success =
resizeVolumeResponse.data['action']['status'].toString() != 'error';
} catch (e) { } catch (e) {
print(e); print(e);
} finally { } finally {
@ -450,7 +453,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
return server.copyWith(startTime: DateTime.now()); return server.copyWith(startTime: DateTime.now());
} }
/// Digital Ocean returns a map of lists of /proc/state values, /// Digital Ocean returns a map of lists of /proc/stat values,
/// so here we are trying to implement average CPU /// so here we are trying to implement average CPU
/// load calculation for each point in time on a given interval. /// load calculation for each point in time on a given interval.
/// ///
@ -500,63 +503,63 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
const int step = 15; const int step = 15;
final Dio client = await getClient(); final Dio client = await getClient();
//try { try {
Response response = await client.get( Response response = await client.get(
'/monitoring/metrics/droplet/bandwidth', '/monitoring/metrics/droplet/bandwidth',
queryParameters: { queryParameters: {
'start': '${(start.microsecondsSinceEpoch / 1000000).round()}', 'start': '${(start.microsecondsSinceEpoch / 1000000).round()}',
'end': '${(end.microsecondsSinceEpoch / 1000000).round()}', 'end': '${(end.microsecondsSinceEpoch / 1000000).round()}',
'host_id': '$serverId', 'host_id': '$serverId',
'interface': 'public', 'interface': 'public',
'direction': 'inbound', 'direction': 'inbound',
}, },
); );
final List inbound = response.data['data']['result'][0]['values']; final List inbound = response.data['data']['result'][0]['values'];
response = await client.get( response = await client.get(
'/monitoring/metrics/droplet/bandwidth', '/monitoring/metrics/droplet/bandwidth',
queryParameters: { queryParameters: {
'start': '${(start.microsecondsSinceEpoch / 1000000).round()}', 'start': '${(start.microsecondsSinceEpoch / 1000000).round()}',
'end': '${(end.microsecondsSinceEpoch / 1000000).round()}', 'end': '${(end.microsecondsSinceEpoch / 1000000).round()}',
'host_id': '$serverId', 'host_id': '$serverId',
'interface': 'public', 'interface': 'public',
'direction': 'outbound', 'direction': 'outbound',
}, },
); );
final List outbound = response.data['data']['result'][0]['values']; final List outbound = response.data['data']['result'][0]['values'];
response = await client.get( response = await client.get(
'/monitoring/metrics/droplet/cpu', '/monitoring/metrics/droplet/cpu',
queryParameters: { queryParameters: {
'start': '${(start.microsecondsSinceEpoch / 1000000).round()}', 'start': '${(start.microsecondsSinceEpoch / 1000000).round()}',
'end': '${(end.microsecondsSinceEpoch / 1000000).round()}', 'end': '${(end.microsecondsSinceEpoch / 1000000).round()}',
'host_id': '$serverId', 'host_id': '$serverId',
}, },
); );
metrics = ServerMetrics( metrics = ServerMetrics(
bandwidthIn: inbound bandwidthIn: inbound
.map( .map(
(final el) => TimeSeriesData(el[0], double.parse(el[1]) * 100000), (final el) => TimeSeriesData(el[0], double.parse(el[1]) * 100000),
) )
.toList(), .toList(),
bandwidthOut: outbound bandwidthOut: outbound
.map( .map(
(final el) => TimeSeriesData(el[0], double.parse(el[1]) * 100000), (final el) => TimeSeriesData(el[0], double.parse(el[1]) * 100000),
) )
.toList(), .toList(),
cpu: calculateCpuLoadMetrics(response.data['data']['result']), cpu: calculateCpuLoadMetrics(response.data['data']['result']),
start: start, start: start,
end: end, end: end,
stepsInSecond: step, stepsInSecond: step,
); );
/* } catch (e) { } catch (e) {
print(e); print(e);
} finally { } finally {
close(client); close(client);
}*/ }
return metrics; return metrics;
} }
@ -604,7 +607,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
ServerMetadataEntity( ServerMetadataEntity(
type: MetadataType.other, type: MetadataType.other,
name: 'server.provider'.tr(), name: 'server.provider'.tr(),
value: appearanceProviderName, value: displayProviderName,
), ),
]; ];
} catch (e) { } catch (e) {

View File

@ -57,7 +57,7 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
String get infectProviderName => 'hetzner'; String get infectProviderName => 'hetzner';
@override @override
String get appearanceProviderName => 'Hetzner'; String get displayProviderName => 'Hetzner';
@override @override
Future<bool> isApiTokenValid(final String token) async { Future<bool> isApiTokenValid(final String token) async {
@ -102,12 +102,12 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
Future<Price?> getPricePerGb() async { Future<Price?> getPricePerGb() async {
double? price; double? price;
final Response dbGetResponse; final Response pricingResponse;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
dbGetResponse = await client.get('/pricing'); pricingResponse = await client.get('/pricing');
final volume = dbGetResponse.data['pricing']['volume']; final volume = pricingResponse.data['pricing']['volume'];
final volumePrice = volume['price_per_gb_month']['gross']; final volumePrice = volume['price_per_gb_month']['gross'];
price = double.parse(volumePrice); price = double.parse(volumePrice);
} catch (e) { } catch (e) {
@ -128,31 +128,31 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
Future<ServerVolume?> createVolume() async { Future<ServerVolume?> createVolume() async {
ServerVolume? volume; ServerVolume? volume;
final Response dbCreateResponse; final Response createVolumeResponse;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
dbCreateResponse = await client.post( createVolumeResponse = await client.post(
'/volumes', '/volumes',
data: { data: {
'size': 10, 'size': 10,
'name': StringGenerators.dbStorageName(), 'name': StringGenerators.storageName(),
'labels': {'labelkey': 'value'}, 'labels': {'labelkey': 'value'},
'location': region, 'location': region,
'automount': false, 'automount': false,
'format': 'ext4' 'format': 'ext4'
}, },
); );
final dbId = dbCreateResponse.data['volume']['id']; final volumeId = createVolumeResponse.data['volume']['id'];
final dbSize = dbCreateResponse.data['volume']['size']; final volumeSize = createVolumeResponse.data['volume']['size'];
final dbServer = dbCreateResponse.data['volume']['server']; final volumeServer = createVolumeResponse.data['volume']['server'];
final dbName = dbCreateResponse.data['volume']['name']; final volumeName = createVolumeResponse.data['volume']['name'];
final dbDevice = dbCreateResponse.data['volume']['linux_device']; final volumeDevice = createVolumeResponse.data['volume']['linux_device'];
volume = ServerVolume( volume = ServerVolume(
id: dbId, id: volumeId,
name: dbName, name: volumeName,
sizeByte: dbSize, sizeByte: volumeSize,
serverId: dbServer, serverId: volumeServer,
linuxDevice: dbDevice, linuxDevice: volumeDevice,
); );
} catch (e) { } catch (e) {
print(e); print(e);
@ -167,28 +167,28 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
Future<List<ServerVolume>> getVolumes({final String? status}) async { Future<List<ServerVolume>> getVolumes({final String? status}) async {
final List<ServerVolume> volumes = []; final List<ServerVolume> volumes = [];
final Response dbGetResponse; final Response getVolumesResonse;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
dbGetResponse = await client.get( getVolumesResonse = await client.get(
'/volumes', '/volumes',
queryParameters: { queryParameters: {
'status': status, 'status': status,
}, },
); );
final List<dynamic> rawVolumes = dbGetResponse.data['volumes']; final List<dynamic> rawVolumes = getVolumesResonse.data['volumes'];
for (final rawVolume in rawVolumes) { for (final rawVolume in rawVolumes) {
final int dbId = rawVolume['id']; final int volumeId = rawVolume['id'];
final int dbSize = rawVolume['size'] * 1024 * 1024 * 1024; final int volumeSize = rawVolume['size'] * 1024 * 1024 * 1024;
final dbServer = rawVolume['server']; final volumeServer = rawVolume['server'];
final String dbName = rawVolume['name']; final String volumeName = rawVolume['name'];
final dbDevice = rawVolume['linux_device']; final volumeDevice = rawVolume['linux_device'];
final volume = ServerVolume( final volume = ServerVolume(
id: dbId, id: volumeId,
name: dbName, name: volumeName,
sizeByte: dbSize, sizeByte: volumeSize,
serverId: dbServer, serverId: volumeServer,
linuxDevice: dbDevice, linuxDevice: volumeDevice,
); );
volumes.add(volume); volumes.add(volume);
} }
@ -206,21 +206,21 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
) async { ) async {
ServerVolume? volume; ServerVolume? volume;
final Response dbGetResponse; final Response getVolumeResponse;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
dbGetResponse = await client.get('/volumes/$volumeId'); getVolumeResponse = await client.get('/volumes/$volumeId');
final int dbId = dbGetResponse.data['volume']['id']; final int responseVolumeId = getVolumeResponse.data['volume']['id'];
final int dbSize = dbGetResponse.data['volume']['size']; final int volumeSize = getVolumeResponse.data['volume']['size'];
final int dbServer = dbGetResponse.data['volume']['server']; final int volumeServer = getVolumeResponse.data['volume']['server'];
final String dbName = dbGetResponse.data['volume']['name']; final String volumeName = getVolumeResponse.data['volume']['name'];
final dbDevice = dbGetResponse.data['volume']['linux_device']; final volumeDevice = getVolumeResponse.data['volume']['linux_device'];
volume = ServerVolume( volume = ServerVolume(
id: dbId, id: responseVolumeId,
name: dbName, name: volumeName,
sizeByte: dbSize, sizeByte: volumeSize,
serverId: dbServer, serverId: volumeServer,
linuxDevice: dbDevice, linuxDevice: volumeDevice,
); );
} catch (e) { } catch (e) {
print(e); print(e);
@ -250,17 +250,18 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
) async { ) async {
bool success = false; bool success = false;
final Response dbPostResponse; final Response attachVolumeResponse;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
dbPostResponse = await client.post( attachVolumeResponse = await client.post(
'/volumes/${volume.id}/actions/attach', '/volumes/${volume.id}/actions/attach',
data: { data: {
'automount': true, 'automount': true,
'server': serverId, 'server': serverId,
}, },
); );
success = dbPostResponse.data['action']['status'].toString() != 'error'; success =
attachVolumeResponse.data['action']['status'].toString() != 'error';
} catch (e) { } catch (e) {
print(e); print(e);
} finally { } finally {
@ -274,13 +275,14 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
Future<bool> detachVolume(final ServerVolume volume) async { Future<bool> detachVolume(final ServerVolume volume) async {
bool success = false; bool success = false;
final Response dbPostResponse; final Response detachVolumeResponse;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
dbPostResponse = await client.post( detachVolumeResponse = await client.post(
'/volumes/${volume.id}/actions/detach', '/volumes/${volume.id}/actions/detach',
); );
success = dbPostResponse.data['action']['status'].toString() != 'error'; success =
detachVolumeResponse.data['action']['status'].toString() != 'error';
} catch (e) { } catch (e) {
print(e); print(e);
} finally { } finally {
@ -297,16 +299,17 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
) async { ) async {
bool success = false; bool success = false;
final Response dbPostResponse; final Response resizeVolumeResponse;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
dbPostResponse = await client.post( resizeVolumeResponse = await client.post(
'/volumes/${volume.id}/actions/resize', '/volumes/${volume.id}/actions/resize',
data: { data: {
'size': size.gibibyte, 'size': size.gibibyte,
}, },
); );
success = dbPostResponse.data['action']['status'].toString() != 'error'; success =
resizeVolumeResponse.data['action']['status'].toString() != 'error';
} catch (e) { } catch (e) {
print(e); print(e);
} finally { } finally {
@ -334,7 +337,7 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
dnsApiToken: dnsApiToken, dnsApiToken: dnsApiToken,
rootUser: rootUser, rootUser: rootUser,
domainName: domainName, domainName: domainName,
dataBase: newVolume, volume: newVolume,
serverType: serverType, serverType: serverType,
); );
@ -345,13 +348,13 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
required final String dnsApiToken, required final String dnsApiToken,
required final User rootUser, required final User rootUser,
required final String domainName, required final String domainName,
required final ServerVolume dataBase, required final ServerVolume volume,
required final String serverType, required final String serverType,
}) async { }) async {
final Dio client = await getClient(); final Dio client = await getClient();
final String dbPassword = StringGenerators.dbPassword(); final String dbPassword = StringGenerators.dbPassword();
final int dbId = dataBase.id; final int volumeId = volume.id;
final String apiToken = StringGenerators.apiToken(); final String apiToken = StringGenerators.apiToken();
final String hostname = getHostnameFromDomain(domainName); final String hostname = getHostnameFromDomain(domainName);
@ -373,7 +376,7 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
'server_type': serverType, 'server_type': serverType,
'start_after_create': false, 'start_after_create': false,
'image': 'ubuntu-20.04', 'image': 'ubuntu-20.04',
'volumes': [dbId], 'volumes': [volumeId],
'networks': [], 'networks': [],
'user_data': userdataString, 'user_data': userdataString,
'labels': {}, 'labels': {},
@ -391,7 +394,7 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
id: serverCreateResponse.data['server']['id'], id: serverCreateResponse.data['server']['id'],
ip4: serverCreateResponse.data['server']['public_net']['ipv4']['ip'], ip4: serverCreateResponse.data['server']['public_net']['ipv4']['ip'],
createTime: DateTime.now(), createTime: DateTime.now(),
volume: dataBase, volume: volume,
apiToken: apiToken, apiToken: apiToken,
provider: ServerProvider.hetzner, provider: ServerProvider.hetzner,
); );
@ -407,7 +410,7 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
if (!success) { if (!success) {
await Future.delayed(const Duration(seconds: 10)); await Future.delayed(const Duration(seconds: 10));
await deleteVolume(dataBase); await deleteVolume(volume);
} }
if (hetznerError != null) { if (hetznerError != null) {
@ -621,7 +624,7 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
ServerMetadataEntity( ServerMetadataEntity(
type: MetadataType.other, type: MetadataType.other,
name: 'server.provider'.tr(), name: 'server.provider'.tr(),
value: appearanceProviderName, value: displayProviderName,
), ),
]; ];
} catch (e) { } catch (e) {

View File

@ -54,5 +54,5 @@ abstract class ServerProviderApi extends ApiMap {
/// Actual provider name to render on information page for user, /// Actual provider name to render on information page for user,
/// for example 'Digital Ocean' for Digital Ocean /// for example 'Digital Ocean' for Digital Ocean
String get appearanceProviderName; String get displayProviderName;
} }

View File

@ -1,4 +1,5 @@
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/schema.graphql.dart';
part 'server_details.g.dart'; part 'server_details.g.dart';
@ -82,5 +83,16 @@ enum ServerProvider {
@HiveField(1) @HiveField(1)
hetzner, hetzner,
@HiveField(2) @HiveField(2)
digitalOcean, digitalOcean;
factory ServerProvider.fromGraphQL(final Enum$ServerProvider provider) {
switch (provider) {
case Enum$ServerProvider.HETZNER:
return hetzner;
case Enum$ServerProvider.DIGITALOCEAN:
return digitalOcean;
default:
return unknown;
}
}
} }

View File

@ -1,12 +1,20 @@
enum MetadataType { import 'package:flutter/material.dart';
id,
status,
cpu,
ram,
cost,
location,
other, enum MetadataType {
id(icon: Icons.numbers_outlined),
status(icon: Icons.mode_standby_outlined),
cpu(icon: Icons.memory_outlined),
ram(icon: Icons.memory_outlined),
cost(icon: Icons.payments_outlined),
location(icon: Icons.location_on_outlined),
other(icon: Icons.info_outlined);
const MetadataType({
required this.icon,
});
final IconData icon;
} }
class ServerMetadataEntity { class ServerMetadataEntity {

View File

@ -10,7 +10,6 @@ import 'package:selfprivacy/logic/cubit/server_installation/server_installation_
import 'package:selfprivacy/logic/cubit/server_volumes/server_volume_cubit.dart'; import 'package:selfprivacy/logic/cubit/server_volumes/server_volume_cubit.dart';
import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart'; import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart';
import 'package:selfprivacy/logic/models/job.dart'; import 'package:selfprivacy/logic/models/job.dart';
import 'package:selfprivacy/logic/models/server_metadata.dart';
import 'package:selfprivacy/ui/components/brand_button/segmented_buttons.dart'; import 'package:selfprivacy/ui/components/brand_button/segmented_buttons.dart';
import 'package:selfprivacy/ui/components/brand_cards/filled_card.dart'; import 'package:selfprivacy/ui/components/brand_cards/filled_card.dart';
import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.dart'; import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.dart';

View File

@ -1,16 +1,6 @@
part of 'server_details_screen.dart'; part of 'server_details_screen.dart';
class _TextDetails extends StatelessWidget { class _TextDetails extends StatelessWidget {
final Map<MetadataType, IconData> metadataToIcon = const {
MetadataType.id: Icons.numbers_outlined,
MetadataType.status: Icons.mode_standby_outlined,
MetadataType.cpu: Icons.memory_outlined,
MetadataType.ram: Icons.memory_outlined,
MetadataType.cost: Icons.euro_outlined,
MetadataType.location: Icons.location_on_outlined,
MetadataType.other: Icons.info_outlined,
};
@override @override
Widget build(final BuildContext context) { Widget build(final BuildContext context) {
final details = context.watch<ServerDetailsCubit>().state; final details = context.watch<ServerDetailsCubit>().state;
@ -36,7 +26,7 @@ class _TextDetails extends StatelessWidget {
...details.metadata ...details.metadata
.map( .map(
(final metadata) => ListTileOnSurfaceVariant( (final metadata) => ListTileOnSurfaceVariant(
leadingIcon: metadataToIcon[metadata.type], leadingIcon: metadata.type.icon,
title: metadata.name, title: metadata.name,
subtitle: metadata.value, subtitle: metadata.value,
), ),

View File

@ -101,7 +101,7 @@ class StringGenerators {
hasSymbols: true, hasSymbols: true,
); );
static StringGeneratorFunction dbStorageName = () => getRandomString( static StringGeneratorFunction storageName = () => getRandomString(
6, 6,
hasLowercaseLetters: true, hasLowercaseLetters: true,
hasUppercaseLetters: false, hasUppercaseLetters: false,