fix(digital-ocean): Adjust droplet data preparations according to API notation

routes-refactor
NaiJi ✨ 2022-10-27 20:01:22 +04:00
parent cb94248df0
commit 0dc0ba215a
3 changed files with 99 additions and 59 deletions

View File

@ -102,7 +102,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
'/volumes', '/volumes',
data: { data: {
'size_gigabytes': 10, 'size_gigabytes': 10,
'name': StringGenerators.dbStorageName(), 'name': 'volume${StringGenerators.dbStorageName()}',
'labels': {'labelkey': 'value'}, 'labels': {'labelkey': 'value'},
'region': region, 'region': region,
'filesystem_type': 'ext4', 'filesystem_type': 'ext4',
@ -212,12 +212,11 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
'droplet_id': serverId, 'droplet_id': serverId,
}, },
); );
success = success = dbPostResponse.data['action']['status'].toString() != 'error';
dbPostResponse.data['action']['status'].toString() == 'completed';
} catch (e) { } catch (e) {
print(e); print(e);
} finally { } finally {
client.close(); close(client);
} }
return success; return success;
@ -277,6 +276,23 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
return success; return success;
} }
static String getHostnameFromDomain(final String domain) {
// Replace all non-alphanumeric characters with an underscore
String hostname =
domain.split('.')[0].replaceAll(RegExp(r'[^a-zA-Z0-9]'), '-');
if (hostname.endsWith('-')) {
hostname = hostname.substring(0, hostname.length - 1);
}
if (hostname.startsWith('-')) {
hostname = hostname.substring(1);
}
if (hostname.isEmpty) {
hostname = 'selfprivacy-server';
}
return hostname;
}
@override @override
Future<ServerHostingDetails?> createServer({ Future<ServerHostingDetails?> createServer({
required final String dnsApiToken, required final String dnsApiToken,
@ -292,14 +308,16 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
final String base64Password = final String base64Password =
base64.encode(utf8.encode(rootUser.password ?? 'PASS')); base64.encode(utf8.encode(rootUser.password ?? 'PASS'));
final String formattedHostname = getHostnameFromDomain(domainName);
final String userdataString = final String userdataString =
"#cloud-config\nruncmd:\n- curl https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-infect/raw/branch/master/nixos-infect | PROVIDER=digital-ocean NIX_CHANNEL=nixos-21.05 DOMAIN='$domainName' LUSER='${rootUser.login}' ENCODED_PASSWORD='$base64Password' CF_TOKEN=$dnsApiToken DB_PASSWORD=$dbPassword API_TOKEN=$apiToken HOSTNAME=$domainName bash 2>&1 | tee /tmp/infect.log"; "#cloud-config\nruncmd:\n- curl https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-infect/raw/branch/master/nixos-infect | PROVIDER=digital-ocean NIX_CHANNEL=nixos-21.05 DOMAIN='$domainName' LUSER='${rootUser.login}' ENCODED_PASSWORD='$base64Password' CF_TOKEN=$dnsApiToken DB_PASSWORD=$dbPassword API_TOKEN=$apiToken HOSTNAME=$formattedHostname bash 2>&1 | tee /tmp/infect.log";
print(userdataString); print(userdataString);
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
final Map<String, Object> data = { final Map<String, Object> data = {
'name': domainName, 'name': formattedHostname,
'size': serverType, 'size': serverType,
'image': 'ubuntu-20-04-x64', 'image': 'ubuntu-20-04-x64',
'user_data': userdataString, 'user_data': userdataString,
@ -312,14 +330,28 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
data: data, data: data,
); );
final int serverId = serverCreateResponse.data['server']['id']; final int serverId = serverCreateResponse.data['droplet']['id'];
final ServerVolume? newVolume = await createVolume(); final ServerVolume? newVolume = await createVolume();
final bool attachedVolume = await attachVolume(newVolume!, serverId); final bool attachedVolume = await attachVolume(newVolume!, serverId);
if (attachedVolume) { String? ipv4;
int attempts = 0;
while (attempts < 5 && ipv4 == null) {
await Future.delayed(const Duration(seconds: 20));
final List<ServerBasicInfo> servers = await getServers();
for (final server in servers) {
if (server.name == formattedHostname && server.ip != '0.0.0.0') {
ipv4 = server.ip;
break;
}
}
++attempts;
}
if (attachedVolume && ipv4 != null) {
serverDetails = ServerHostingDetails( serverDetails = ServerHostingDetails(
id: serverId, id: serverId,
ip4: serverCreateResponse.data['droplet']['networks']['v4'][0], ip4: ipv4,
createTime: DateTime.now(), createTime: DateTime.now(),
volume: newVolume, volume: newVolume,
apiToken: apiToken, apiToken: apiToken,
@ -452,20 +484,26 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
final Response response = await client.get('/droplets'); final Response response = await client.get('/droplets');
servers = response.data!['droplets'] servers = response.data!['droplets'].map<ServerBasicInfo>(
.where( (final server) {
(final server) => server['networks']['v4'].isNotEmpty, String ipv4 = '0.0.0.0';
) if (server['networks']['v4'].isNotEmpty) {
.map<ServerBasicInfo>( for (final v4 in server['networks']['v4']) {
(final server) => ServerBasicInfo( if (v4['type'].toString() == 'public') {
id: server['id'], ipv4 = v4['ip_address'].toString();
reverseDns: server['name'], }
created: DateTime.now(), }
ip: server['networks']['v4'][0], }
name: server['name'],
), return ServerBasicInfo(
) id: server['id'],
.toList(); reverseDns: server['name'],
created: DateTime.now(),
ip: ipv4,
name: server['name'],
);
},
).toList();
} catch (e) { } catch (e) {
print(e); print(e);
} finally { } finally {
@ -523,14 +561,16 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
'/regions', '/regions',
); );
locations = response.data!['regions'].map<ServerProviderLocation>( locations = response.data!['regions']
(final location) => ServerProviderLocation( .map<ServerProviderLocation>(
title: location['slug'], (final location) => ServerProviderLocation(
description: location['name'], title: location['slug'],
flag: getEmojiFlag(location['slug']), description: location['name'],
identifier: location['slug'], flag: getEmojiFlag(location['slug']),
), identifier: location['slug'],
); ),
)
.toList();
} catch (e) { } catch (e) {
print(e); print(e);
} finally { } finally {
@ -559,7 +599,7 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
ServerType( ServerType(
title: rawSize['description'], title: rawSize['description'],
identifier: rawSize['slug'], identifier: rawSize['slug'],
ram: rawSize['memory'], ram: rawSize['memory'].toDouble(),
cores: rawSize['vcpus'], cores: rawSize['vcpus'],
disk: DiskSize(byte: rawSize['disk'] * 1024 * 1024 * 1024), disk: DiskSize(byte: rawSize['disk'] * 1024 * 1024 * 1024),
price: Price( price: Price(

View File

@ -608,36 +608,36 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
final List<ServerType> types = []; final List<ServerType> types = [];
final Dio client = await getClient(); final Dio client = await getClient();
//try { try {
final Response response = await client.get( final Response response = await client.get(
'/server_types', '/server_types',
); );
final rawTypes = response.data!['server_types']; final rawTypes = response.data!['server_types'];
for (final rawType in rawTypes) { for (final rawType in rawTypes) {
for (final rawPrice in rawType['prices']) { for (final rawPrice in rawType['prices']) {
if (rawPrice['location'].toString() == location.identifier) { if (rawPrice['location'].toString() == location.identifier) {
types.add( types.add(
ServerType( ServerType(
title: rawType['description'], title: rawType['description'],
identifier: rawType['name'], identifier: rawType['name'],
ram: rawType['memory'], ram: rawType['memory'],
cores: rawType['cores'], cores: rawType['cores'],
disk: DiskSize(byte: rawType['disk'] * 1024 * 1024 * 1024), disk: DiskSize(byte: rawType['disk'] * 1024 * 1024 * 1024),
price: Price( price: Price(
value: double.parse(rawPrice['price_monthly']['gross']), value: double.parse(rawPrice['price_monthly']['gross']),
currency: 'EUR', currency: 'EUR',
),
location: location,
), ),
location: location, );
), }
);
} }
} }
} catch (e) {
print(e);
} finally {
close(client);
} }
//} catch (e) {
//print(e);
//} finally {
close(client);
//}
return types; return types;
} }

View File

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