mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-11 10:29:39 +00:00
refactor(rest-api): Move rest api methods according to their business logic files positions
- Rename unmatching functions
This commit is contained in:
parent
5af30bce4d
commit
7ff1e36161
|
@ -92,22 +92,23 @@ class CloudflareApi extends RestApiMap {
|
|||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<List<dynamic>>> getZones(final String domain) async {
|
||||
List zones = [];
|
||||
Future<GenericResult<List>> getDomains() async {
|
||||
final String url = '$rootAddress/zones';
|
||||
List domains = [];
|
||||
|
||||
late final Response? response;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
response = await client.get(
|
||||
'/zones',
|
||||
queryParameters: {'name': domain},
|
||||
url,
|
||||
queryParameters: {'per_page': 50},
|
||||
);
|
||||
zones = response.data['result'];
|
||||
domains = response.data['result'];
|
||||
} catch (e) {
|
||||
print(e);
|
||||
GenericResult(
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: zones,
|
||||
data: domains,
|
||||
code: response?.statusCode,
|
||||
message: response?.statusMessage,
|
||||
);
|
||||
|
@ -115,7 +116,47 @@ class CloudflareApi extends RestApiMap {
|
|||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: zones);
|
||||
return GenericResult(
|
||||
success: true,
|
||||
data: domains,
|
||||
code: response.statusCode,
|
||||
message: response.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> createMultipleDnsRecords({
|
||||
required final ServerDomain domain,
|
||||
required final List<DnsRecord> records,
|
||||
}) async {
|
||||
final String domainZoneId = domain.zoneId;
|
||||
final List<Future> allCreateFutures = <Future>[];
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
for (final DnsRecord record in records) {
|
||||
allCreateFutures.add(
|
||||
client.post(
|
||||
'/zones/$domainZoneId/dns_records',
|
||||
data: record.toJson(),
|
||||
),
|
||||
);
|
||||
}
|
||||
await Future.wait(allCreateFutures);
|
||||
} on DioError catch (e) {
|
||||
print(e.message);
|
||||
rethrow;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> removeSimilarRecords({
|
||||
|
@ -183,58 +224,22 @@ class CloudflareApi extends RestApiMap {
|
|||
return GenericResult(data: allRecords, success: true);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> createMultipleDnsRecords({
|
||||
required final ServerDomain domain,
|
||||
required final List<DnsRecord> records,
|
||||
}) async {
|
||||
final String domainZoneId = domain.zoneId;
|
||||
final List<Future> allCreateFutures = <Future>[];
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
for (final DnsRecord record in records) {
|
||||
allCreateFutures.add(
|
||||
client.post(
|
||||
'/zones/$domainZoneId/dns_records',
|
||||
data: record.toJson(),
|
||||
),
|
||||
);
|
||||
}
|
||||
await Future.wait(allCreateFutures);
|
||||
} on DioError catch (e) {
|
||||
print(e.message);
|
||||
rethrow;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<List>> getDomains() async {
|
||||
final String url = '$rootAddress/zones';
|
||||
List domains = [];
|
||||
Future<GenericResult<List<dynamic>>> getZones(final String domain) async {
|
||||
List zones = [];
|
||||
|
||||
late final Response? response;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
response = await client.get(
|
||||
url,
|
||||
queryParameters: {'per_page': 50},
|
||||
'/zones',
|
||||
queryParameters: {'name': domain},
|
||||
);
|
||||
domains = response.data['result'];
|
||||
zones = response.data['result'];
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
GenericResult(
|
||||
success: false,
|
||||
data: domains,
|
||||
data: zones,
|
||||
code: response?.statusCode,
|
||||
message: response?.statusMessage,
|
||||
);
|
||||
|
@ -242,11 +247,6 @@ class CloudflareApi extends RestApiMap {
|
|||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
success: true,
|
||||
data: domains,
|
||||
code: response.statusCode,
|
||||
message: response.statusMessage,
|
||||
);
|
||||
return GenericResult(success: true, data: zones);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,7 +92,63 @@ class DesecApi extends RestApiMap {
|
|||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> updateRecords({
|
||||
Future<GenericResult<List>> getDomains() async {
|
||||
List domains = [];
|
||||
|
||||
late final Response? response;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
response = await client.get(
|
||||
'',
|
||||
);
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
domains = response.data;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: domains,
|
||||
code: response?.statusCode,
|
||||
message: response?.statusMessage,
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
success: true,
|
||||
data: domains,
|
||||
code: response.statusCode,
|
||||
message: response.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> createMultipleDnsRecords({
|
||||
required final ServerDomain domain,
|
||||
required final List<dynamic> records,
|
||||
}) async {
|
||||
final String domainName = domain.domainName;
|
||||
final String url = '/$domainName/rrsets/';
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await client.post(url, data: records);
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> removeSimilarRecords({
|
||||
required final ServerDomain domain,
|
||||
required final List<dynamic> records,
|
||||
}) async {
|
||||
|
@ -145,60 +201,4 @@ class DesecApi extends RestApiMap {
|
|||
|
||||
return GenericResult(data: allRecords, success: true);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> createRecords({
|
||||
required final ServerDomain domain,
|
||||
required final List<dynamic> records,
|
||||
}) async {
|
||||
final String domainName = domain.domainName;
|
||||
final String url = '/$domainName/rrsets/';
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await client.post(url, data: records);
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<List>> getDomains() async {
|
||||
List domains = [];
|
||||
|
||||
late final Response? response;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
response = await client.get(
|
||||
'',
|
||||
);
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
domains = response.data;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: domains,
|
||||
code: response?.statusCode,
|
||||
message: response?.statusMessage,
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
success: true,
|
||||
data: domains,
|
||||
code: response.statusCode,
|
||||
message: response.statusMessage,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,6 +92,68 @@ class DigitalOceanDnsApi extends RestApiMap {
|
|||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<List>> getDomains() async {
|
||||
List domains = [];
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
final Response response = await client.get('/domains');
|
||||
domains = response.data['domains'];
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: domains,
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(data: domains, success: true);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> createMultipleDnsRecords({
|
||||
required final ServerDomain domain,
|
||||
required final List<DnsRecord> records,
|
||||
}) async {
|
||||
final String domainName = domain.domainName;
|
||||
final List<Future> allCreateFutures = <Future>[];
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
for (final DnsRecord record in records) {
|
||||
allCreateFutures.add(
|
||||
client.post(
|
||||
'/domains/$domainName/records',
|
||||
data: {
|
||||
'type': record.type,
|
||||
'name': record.name,
|
||||
'data': record.content,
|
||||
'ttl': record.ttl,
|
||||
'priority': record.priority,
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
await Future.wait(allCreateFutures);
|
||||
} on DioError catch (e) {
|
||||
print(e.message);
|
||||
rethrow;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> removeSimilarRecords({
|
||||
required final ServerDomain domain,
|
||||
required final List records,
|
||||
|
@ -152,66 +214,4 @@ class DigitalOceanDnsApi extends RestApiMap {
|
|||
|
||||
return GenericResult(data: allRecords, success: true);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> createMultipleDnsRecords({
|
||||
required final ServerDomain domain,
|
||||
required final List<DnsRecord> records,
|
||||
}) async {
|
||||
final String domainName = domain.domainName;
|
||||
final List<Future> allCreateFutures = <Future>[];
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
for (final DnsRecord record in records) {
|
||||
allCreateFutures.add(
|
||||
client.post(
|
||||
'/domains/$domainName/records',
|
||||
data: {
|
||||
'type': record.type,
|
||||
'name': record.name,
|
||||
'data': record.content,
|
||||
'ttl': record.ttl,
|
||||
'priority': record.priority,
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
await Future.wait(allCreateFutures);
|
||||
} on DioError catch (e) {
|
||||
print(e.message);
|
||||
rethrow;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<List>> domainList() async {
|
||||
List domains = [];
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
final Response response = await client.get('/domains');
|
||||
domains = response.data['domains'];
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: domains,
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(data: domains, success: true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,100 @@ class DigitalOceanApi extends RestApiMap {
|
|||
String get infectProviderName => 'digitalocean';
|
||||
String get displayProviderName => 'Digital Ocean';
|
||||
|
||||
Future<GenericResult<List>> getServers() async {
|
||||
List servers = [];
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
final Response response = await client.get('/droplets');
|
||||
servers = response.data['droplets'];
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: servers,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: servers);
|
||||
}
|
||||
|
||||
Future<GenericResult<int?>> createServer({
|
||||
required final String dnsApiToken,
|
||||
required final String dnsProviderType,
|
||||
required final String serverApiToken,
|
||||
required final User rootUser,
|
||||
required final String base64Password,
|
||||
required final String databasePassword,
|
||||
required final String domainName,
|
||||
required final String hostName,
|
||||
required final String serverType,
|
||||
}) async {
|
||||
final String stagingAcme = TlsOptions.stagingAcme ? 'true' : 'false';
|
||||
|
||||
int? dropletId;
|
||||
Response? serverCreateResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
final Map<String, Object> data = {
|
||||
'name': hostName,
|
||||
'size': serverType,
|
||||
'image': 'ubuntu-20-04-x64',
|
||||
'user_data': '#cloud-config\n'
|
||||
'runcmd:\n'
|
||||
'- curl https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-infect/raw/branch/providers/digital-ocean/nixos-infect | '
|
||||
"PROVIDER=$infectProviderName DNS_PROVIDER_TYPE=$dnsProviderType STAGING_ACME='$stagingAcme' DOMAIN='$domainName' "
|
||||
"LUSER='${rootUser.login}' ENCODED_PASSWORD='$base64Password' CF_TOKEN=$dnsApiToken DB_PASSWORD=$databasePassword "
|
||||
'API_TOKEN=$serverApiToken HOSTNAME=$hostName bash 2>&1 | tee /tmp/infect.log',
|
||||
'region': region!,
|
||||
};
|
||||
print('Decoded data: $data');
|
||||
|
||||
serverCreateResponse = await client.post(
|
||||
'/droplets',
|
||||
data: data,
|
||||
);
|
||||
dropletId = serverCreateResponse.data['droplet']['id'];
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
data: dropletId,
|
||||
success: true,
|
||||
code: serverCreateResponse.statusCode,
|
||||
message: serverCreateResponse.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> deleteServer(final int serverId) async {
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await client.delete('/droplets/$serverId');
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<bool>> isApiTokenValid(final String token) async {
|
||||
bool isValid = false;
|
||||
Response? response;
|
||||
|
@ -94,41 +188,103 @@ class DigitalOceanApi extends RestApiMap {
|
|||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<DigitalOceanVolume?>> createVolume() async {
|
||||
DigitalOceanVolume? volume;
|
||||
Response? createVolumeResponse;
|
||||
Future<GenericResult<List<DigitalOceanLocation>>>
|
||||
getAvailableLocations() async {
|
||||
final List<DigitalOceanLocation> locations = [];
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await Future.delayed(const Duration(seconds: 6));
|
||||
|
||||
createVolumeResponse = await client.post(
|
||||
'/volumes',
|
||||
data: {
|
||||
'size_gigabytes': 10,
|
||||
'name': 'volume${StringGenerators.storageName()}',
|
||||
'labels': {'labelkey': 'value'},
|
||||
'region': region,
|
||||
'filesystem_type': 'ext4',
|
||||
},
|
||||
final Response response = await client.get(
|
||||
'/regions',
|
||||
);
|
||||
volume = DigitalOceanVolume.fromJson(createVolumeResponse.data['volume']);
|
||||
|
||||
for (final region in response.data!['regions']) {
|
||||
locations.add(DigitalOceanLocation.fromJson(region));
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: null,
|
||||
data: [],
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
data: volume,
|
||||
success: true,
|
||||
code: createVolumeResponse.statusCode,
|
||||
message: createVolumeResponse.statusMessage,
|
||||
);
|
||||
return GenericResult(data: locations, success: true);
|
||||
}
|
||||
|
||||
Future<GenericResult<List<DigitalOceanServerType>>>
|
||||
getAvailableServerTypes() async {
|
||||
final List<DigitalOceanServerType> types = [];
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
final Response response = await client.get(
|
||||
'/sizes',
|
||||
);
|
||||
for (final size in response.data!['sizes']) {
|
||||
types.add(DigitalOceanServerType.fromJson(size));
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: [],
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(data: types, success: true);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> powerOn(final int serverId) async {
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await client.post(
|
||||
'/droplets/$serverId/actions',
|
||||
data: {
|
||||
'type': 'power_on',
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> restart(final int serverId) async {
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await client.post(
|
||||
'/droplets/$serverId/actions',
|
||||
data: {
|
||||
'type': 'reboot',
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<List<DigitalOceanVolume>>> getVolumes({
|
||||
|
@ -165,10 +321,24 @@ class DigitalOceanApi extends RestApiMap {
|
|||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> deleteVolume(final String uuid) async {
|
||||
Future<GenericResult<DigitalOceanVolume?>> createVolume() async {
|
||||
DigitalOceanVolume? volume;
|
||||
Response? createVolumeResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await client.delete('/volumes/$uuid');
|
||||
await Future.delayed(const Duration(seconds: 6));
|
||||
|
||||
createVolumeResponse = await client.post(
|
||||
'/volumes',
|
||||
data: {
|
||||
'size_gigabytes': 10,
|
||||
'name': 'volume${StringGenerators.storageName()}',
|
||||
'labels': {'labelkey': 'value'},
|
||||
'region': region,
|
||||
'filesystem_type': 'ext4',
|
||||
},
|
||||
);
|
||||
volume = DigitalOceanVolume.fromJson(createVolumeResponse.data['volume']);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
|
@ -181,8 +351,10 @@ class DigitalOceanApi extends RestApiMap {
|
|||
}
|
||||
|
||||
return GenericResult(
|
||||
data: null,
|
||||
data: volume,
|
||||
success: true,
|
||||
code: createVolumeResponse.statusCode,
|
||||
message: createVolumeResponse.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -262,6 +434,27 @@ class DigitalOceanApi extends RestApiMap {
|
|||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> deleteVolume(final String uuid) async {
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
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<GenericResult<bool>> resizeVolume(
|
||||
final String name,
|
||||
final DiskSize size,
|
||||
|
@ -299,125 +492,6 @@ class DigitalOceanApi extends RestApiMap {
|
|||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<int?>> createServer({
|
||||
required final String dnsApiToken,
|
||||
required final String dnsProviderType,
|
||||
required final String serverApiToken,
|
||||
required final User rootUser,
|
||||
required final String base64Password,
|
||||
required final String databasePassword,
|
||||
required final String domainName,
|
||||
required final String hostName,
|
||||
required final String serverType,
|
||||
}) async {
|
||||
final String stagingAcme = TlsOptions.stagingAcme ? 'true' : 'false';
|
||||
|
||||
int? dropletId;
|
||||
Response? serverCreateResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
final Map<String, Object> data = {
|
||||
'name': hostName,
|
||||
'size': serverType,
|
||||
'image': 'ubuntu-20-04-x64',
|
||||
'user_data': '#cloud-config\n'
|
||||
'runcmd:\n'
|
||||
'- curl https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-infect/raw/branch/providers/digital-ocean/nixos-infect | '
|
||||
"PROVIDER=$infectProviderName DNS_PROVIDER_TYPE=$dnsProviderType STAGING_ACME='$stagingAcme' DOMAIN='$domainName' "
|
||||
"LUSER='${rootUser.login}' ENCODED_PASSWORD='$base64Password' CF_TOKEN=$dnsApiToken DB_PASSWORD=$databasePassword "
|
||||
'API_TOKEN=$serverApiToken HOSTNAME=$hostName bash 2>&1 | tee /tmp/infect.log',
|
||||
'region': region!,
|
||||
};
|
||||
print('Decoded data: $data');
|
||||
|
||||
serverCreateResponse = await client.post(
|
||||
'/droplets',
|
||||
data: data,
|
||||
);
|
||||
dropletId = serverCreateResponse.data['droplet']['id'];
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
data: dropletId,
|
||||
success: true,
|
||||
code: serverCreateResponse.statusCode,
|
||||
message: serverCreateResponse.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> deleteServer(final int serverId) async {
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await client.delete('/droplets/$serverId');
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> restart(final int serverId) async {
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await client.post(
|
||||
'/droplets/$serverId/actions',
|
||||
data: {
|
||||
'type': 'reboot',
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> powerOn(final int serverId) async {
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await client.post(
|
||||
'/droplets/$serverId/actions',
|
||||
data: {
|
||||
'type': 'power_on',
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<List>> getMetricsCpu(
|
||||
final int serverId,
|
||||
final DateTime start,
|
||||
|
@ -484,78 +558,4 @@ class DigitalOceanApi extends RestApiMap {
|
|||
|
||||
return GenericResult(success: true, data: metrics);
|
||||
}
|
||||
|
||||
Future<GenericResult<List>> getServers() async {
|
||||
List servers = [];
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
final Response response = await client.get('/droplets');
|
||||
servers = response.data['droplets'];
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: servers,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: servers);
|
||||
}
|
||||
|
||||
Future<GenericResult<List<DigitalOceanLocation>>>
|
||||
getAvailableLocations() async {
|
||||
final List<DigitalOceanLocation> locations = [];
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
final Response response = await client.get(
|
||||
'/regions',
|
||||
);
|
||||
|
||||
for (final region in response.data!['regions']) {
|
||||
locations.add(DigitalOceanLocation.fromJson(region));
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: [],
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(data: locations, success: true);
|
||||
}
|
||||
|
||||
Future<GenericResult<List<DigitalOceanServerType>>>
|
||||
getAvailableServerTypes() async {
|
||||
final List<DigitalOceanServerType> types = [];
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
final Response response = await client.get(
|
||||
'/sizes',
|
||||
);
|
||||
for (final size in response.data!['sizes']) {
|
||||
types.add(DigitalOceanServerType.fromJson(size));
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: [],
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(data: types, success: true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,289 +48,29 @@ class HetznerApi extends RestApiMap {
|
|||
String get infectProviderName => 'hetzner';
|
||||
String get displayProviderName => 'Hetzner';
|
||||
|
||||
Future<GenericResult<bool>> isApiTokenValid(final String token) async {
|
||||
bool isValid = false;
|
||||
Response? response;
|
||||
String message = '';
|
||||
Future<GenericResult<List<HetznerServerInfo>>> getServers() async {
|
||||
List<HetznerServerInfo> servers = [];
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
response = await client.get(
|
||||
'/servers',
|
||||
options: Options(
|
||||
followRedirects: false,
|
||||
validateStatus: (final status) =>
|
||||
status != null && (status >= 200 || status == 401),
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
),
|
||||
);
|
||||
final Response response = await client.get('/servers');
|
||||
servers = response.data!['servers']
|
||||
.map<HetznerServerInfo>(
|
||||
(final e) => HetznerServerInfo.fromJson(e),
|
||||
)
|
||||
.toList();
|
||||
} catch (e) {
|
||||
print(e);
|
||||
isValid = false;
|
||||
message = e.toString();
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: [],
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
if (response == null) {
|
||||
return GenericResult(
|
||||
data: isValid,
|
||||
success: false,
|
||||
message: message,
|
||||
);
|
||||
}
|
||||
|
||||
if (response.statusCode == HttpStatus.ok) {
|
||||
isValid = true;
|
||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||
isValid = false;
|
||||
} else {
|
||||
throw Exception('code: ${response.statusCode}');
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
data: isValid,
|
||||
success: true,
|
||||
message: response.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<double?>> getPricePerGb() async {
|
||||
double? price;
|
||||
|
||||
final Response pricingResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
pricingResponse = await client.get('/pricing');
|
||||
|
||||
final volume = pricingResponse.data['pricing']['volume'];
|
||||
final volumePrice = volume['price_per_gb_month']['gross'];
|
||||
price = double.parse(volumePrice);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: price,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: price);
|
||||
}
|
||||
|
||||
Future<GenericResult<HetznerVolume?>> createVolume() async {
|
||||
Response? createVolumeResponse;
|
||||
HetznerVolume? volume;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
createVolumeResponse = await client.post(
|
||||
'/volumes',
|
||||
data: {
|
||||
'size': 10,
|
||||
'name': StringGenerators.storageName(),
|
||||
'labels': {'labelkey': 'value'},
|
||||
'location': region,
|
||||
'automount': false,
|
||||
'format': 'ext4'
|
||||
},
|
||||
);
|
||||
volume = HetznerVolume.fromJson(createVolumeResponse.data['volume']);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: null,
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
data: volume,
|
||||
success: true,
|
||||
code: createVolumeResponse.statusCode,
|
||||
message: createVolumeResponse.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<List<HetznerVolume>>> getVolumes({
|
||||
final String? status,
|
||||
}) async {
|
||||
final List<HetznerVolume> volumes = [];
|
||||
|
||||
Response? getVolumesResonse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
getVolumesResonse = await client.get(
|
||||
'/volumes',
|
||||
queryParameters: {
|
||||
'status': status,
|
||||
},
|
||||
);
|
||||
for (final volume in getVolumesResonse.data['volumes']) {
|
||||
volumes.add(HetznerVolume.fromJson(volume));
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: [],
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
data: volumes,
|
||||
success: true,
|
||||
code: getVolumesResonse.statusCode,
|
||||
message: getVolumesResonse.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<HetznerVolume?>> getVolume(
|
||||
final String volumeId,
|
||||
) async {
|
||||
HetznerVolume? volume;
|
||||
|
||||
final Response getVolumeResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
getVolumeResponse = await client.get('/volumes/$volumeId');
|
||||
volume = HetznerVolume.fromJson(getVolumeResponse.data['volume']);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: null,
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
data: volume,
|
||||
success: true,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<bool>> deleteVolume(final int volumeId) async {
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await client.delete('/volumes/$volumeId');
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
success: true,
|
||||
data: true,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<bool>> attachVolume(
|
||||
final HetznerVolume volume,
|
||||
final int serverId,
|
||||
) async {
|
||||
bool success = false;
|
||||
|
||||
Response? attachVolumeResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
attachVolumeResponse = await client.post(
|
||||
'/volumes/${volume.id}/actions/attach',
|
||||
data: {
|
||||
'automount': true,
|
||||
'server': serverId,
|
||||
},
|
||||
);
|
||||
success =
|
||||
attachVolumeResponse.data['action']['status'].toString() != 'error';
|
||||
} catch (e) {
|
||||
print(e);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
data: success,
|
||||
success: true,
|
||||
code: attachVolumeResponse?.statusCode,
|
||||
message: attachVolumeResponse?.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<bool>> detachVolume(final int volumeId) async {
|
||||
bool success = false;
|
||||
|
||||
final Response detachVolumeResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
detachVolumeResponse = await client.post(
|
||||
'/volumes/$volumeId/actions/detach',
|
||||
);
|
||||
success =
|
||||
detachVolumeResponse.data['action']['status'].toString() != 'error';
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: success,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<bool>> resizeVolume(
|
||||
final HetznerVolume volume,
|
||||
final DiskSize size,
|
||||
) async {
|
||||
bool success = false;
|
||||
|
||||
final Response resizeVolumeResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
resizeVolumeResponse = await client.post(
|
||||
'/volumes/${volume.id}/actions/resize',
|
||||
data: {
|
||||
'size': size.gibibyte,
|
||||
},
|
||||
);
|
||||
success =
|
||||
resizeVolumeResponse.data['action']['status'].toString() != 'error';
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: false,
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
data: success,
|
||||
success: true,
|
||||
);
|
||||
return GenericResult(data: servers, success: true);
|
||||
}
|
||||
|
||||
Future<GenericResult<HetznerServerInfo?>> createServer({
|
||||
|
@ -402,6 +142,34 @@ class HetznerApi extends RestApiMap {
|
|||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> createReverseDns({
|
||||
required final int serverId,
|
||||
required final String ip4,
|
||||
required final String dnsPtr,
|
||||
}) async {
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await client.post(
|
||||
'/servers/$serverId/actions/change_dns_ptr',
|
||||
data: {
|
||||
'ip': ip4,
|
||||
'dns_ptr': dnsPtr,
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> deleteServer({
|
||||
required final int serverId,
|
||||
}) async {
|
||||
|
@ -422,98 +190,50 @@ class HetznerApi extends RestApiMap {
|
|||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> restart(final int serverId) async {
|
||||
Future<GenericResult<bool>> isApiTokenValid(final String token) async {
|
||||
bool isValid = false;
|
||||
Response? response;
|
||||
String message = '';
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await client.post('/servers/$serverId/actions/reset');
|
||||
response = await client.get(
|
||||
'/servers',
|
||||
options: Options(
|
||||
followRedirects: false,
|
||||
validateStatus: (final status) =>
|
||||
status != null && (status >= 200 || status == 401),
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
isValid = false;
|
||||
message = e.toString();
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> powerOn(final int serverId) async {
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await client.post('/servers/$serverId/actions/poweron');
|
||||
} catch (e) {
|
||||
print(e);
|
||||
if (response == null) {
|
||||
return GenericResult(
|
||||
data: isValid,
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
message: message,
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<Map<String, dynamic>>> getMetrics(
|
||||
final int serverId,
|
||||
final DateTime start,
|
||||
final DateTime end,
|
||||
final String type,
|
||||
) async {
|
||||
Map<String, dynamic> metrics = {};
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
final Map<String, dynamic> queryParameters = {
|
||||
'start': start.toUtc().toIso8601String(),
|
||||
'end': end.toUtc().toIso8601String(),
|
||||
'type': type
|
||||
};
|
||||
final Response res = await client.get(
|
||||
'/servers/$serverId/metrics',
|
||||
queryParameters: queryParameters,
|
||||
);
|
||||
metrics = res.data['metrics'];
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: {},
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
if (response.statusCode == HttpStatus.ok) {
|
||||
isValid = true;
|
||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||
isValid = false;
|
||||
} else {
|
||||
throw Exception('code: ${response.statusCode}');
|
||||
}
|
||||
|
||||
return GenericResult(data: metrics, success: true);
|
||||
}
|
||||
|
||||
Future<GenericResult<List<HetznerServerInfo>>> getServers() async {
|
||||
List<HetznerServerInfo> servers = [];
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
final Response response = await client.get('/servers');
|
||||
servers = response.data!['servers']
|
||||
.map<HetznerServerInfo>(
|
||||
(final e) => HetznerServerInfo.fromJson(e),
|
||||
)
|
||||
.toList();
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: [],
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(data: servers, success: true);
|
||||
return GenericResult(
|
||||
data: isValid,
|
||||
success: true,
|
||||
message: response.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<List<HetznerLocation>>> getAvailableLocations() async {
|
||||
|
@ -565,20 +285,10 @@ class HetznerApi extends RestApiMap {
|
|||
return GenericResult(data: types, success: true);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> createReverseDns({
|
||||
required final int serverId,
|
||||
required final String ip4,
|
||||
required final String dnsPtr,
|
||||
}) async {
|
||||
Future<GenericResult<void>> powerOn(final int serverId) async {
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await client.post(
|
||||
'/servers/$serverId/actions/change_dns_ptr',
|
||||
data: {
|
||||
'ip': ip4,
|
||||
'dns_ptr': dnsPtr,
|
||||
},
|
||||
);
|
||||
await client.post('/servers/$serverId/actions/poweron');
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
|
@ -592,4 +302,294 @@ class HetznerApi extends RestApiMap {
|
|||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<void>> restart(final int serverId) async {
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await client.post('/servers/$serverId/actions/reset');
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: null,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<double?>> getPricePerGb() async {
|
||||
double? price;
|
||||
|
||||
final Response pricingResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
pricingResponse = await client.get('/pricing');
|
||||
|
||||
final volume = pricingResponse.data['pricing']['volume'];
|
||||
final volumePrice = volume['price_per_gb_month']['gross'];
|
||||
price = double.parse(volumePrice);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: price,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return GenericResult(success: true, data: price);
|
||||
}
|
||||
|
||||
Future<GenericResult<List<HetznerVolume>>> getVolumes({
|
||||
final String? status,
|
||||
}) async {
|
||||
final List<HetznerVolume> volumes = [];
|
||||
|
||||
Response? getVolumesResonse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
getVolumesResonse = await client.get(
|
||||
'/volumes',
|
||||
queryParameters: {
|
||||
'status': status,
|
||||
},
|
||||
);
|
||||
for (final volume in getVolumesResonse.data['volumes']) {
|
||||
volumes.add(HetznerVolume.fromJson(volume));
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: [],
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
data: volumes,
|
||||
success: true,
|
||||
code: getVolumesResonse.statusCode,
|
||||
message: getVolumesResonse.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<HetznerVolume?>> createVolume() async {
|
||||
Response? createVolumeResponse;
|
||||
HetznerVolume? volume;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
createVolumeResponse = await client.post(
|
||||
'/volumes',
|
||||
data: {
|
||||
'size': 10,
|
||||
'name': StringGenerators.storageName(),
|
||||
'labels': {'labelkey': 'value'},
|
||||
'location': region,
|
||||
'automount': false,
|
||||
'format': 'ext4'
|
||||
},
|
||||
);
|
||||
volume = HetznerVolume.fromJson(createVolumeResponse.data['volume']);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: null,
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
data: volume,
|
||||
success: true,
|
||||
code: createVolumeResponse.statusCode,
|
||||
message: createVolumeResponse.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<bool>> deleteVolume(final int volumeId) async {
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
await client.delete('/volumes/$volumeId');
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
success: true,
|
||||
data: true,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<HetznerVolume?>> getVolume(
|
||||
final String volumeId,
|
||||
) async {
|
||||
HetznerVolume? volume;
|
||||
|
||||
final Response getVolumeResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
getVolumeResponse = await client.get('/volumes/$volumeId');
|
||||
volume = HetznerVolume.fromJson(getVolumeResponse.data['volume']);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: null,
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
data: volume,
|
||||
success: true,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<bool>> detachVolume(final int volumeId) async {
|
||||
bool success = false;
|
||||
|
||||
final Response detachVolumeResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
detachVolumeResponse = await client.post(
|
||||
'/volumes/$volumeId/actions/detach',
|
||||
);
|
||||
success =
|
||||
detachVolumeResponse.data['action']['status'].toString() != 'error';
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: success,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<bool>> attachVolume(
|
||||
final HetznerVolume volume,
|
||||
final int serverId,
|
||||
) async {
|
||||
bool success = false;
|
||||
|
||||
Response? attachVolumeResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
attachVolumeResponse = await client.post(
|
||||
'/volumes/${volume.id}/actions/attach',
|
||||
data: {
|
||||
'automount': true,
|
||||
'server': serverId,
|
||||
},
|
||||
);
|
||||
success =
|
||||
attachVolumeResponse.data['action']['status'].toString() != 'error';
|
||||
} catch (e) {
|
||||
print(e);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
data: success,
|
||||
success: true,
|
||||
code: attachVolumeResponse?.statusCode,
|
||||
message: attachVolumeResponse?.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<bool>> resizeVolume(
|
||||
final HetznerVolume volume,
|
||||
final DiskSize size,
|
||||
) async {
|
||||
bool success = false;
|
||||
|
||||
final Response resizeVolumeResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
resizeVolumeResponse = await client.post(
|
||||
'/volumes/${volume.id}/actions/resize',
|
||||
data: {
|
||||
'size': size.gibibyte,
|
||||
},
|
||||
);
|
||||
success =
|
||||
resizeVolumeResponse.data['action']['status'].toString() != 'error';
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
data: false,
|
||||
success: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
return GenericResult(
|
||||
data: success,
|
||||
success: true,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<Map<String, dynamic>>> getMetrics(
|
||||
final int serverId,
|
||||
final DateTime start,
|
||||
final DateTime end,
|
||||
final String type,
|
||||
) async {
|
||||
Map<String, dynamic> metrics = {};
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
final Map<String, dynamic> queryParameters = {
|
||||
'start': start.toUtc().toIso8601String(),
|
||||
'end': end.toUtc().toIso8601String(),
|
||||
'type': type
|
||||
};
|
||||
final Response res = await client.get(
|
||||
'/servers/$serverId/metrics',
|
||||
queryParameters: queryParameters,
|
||||
);
|
||||
metrics = res.data['metrics'];
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
success: false,
|
||||
data: {},
|
||||
message: e.toString(),
|
||||
);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return GenericResult(data: metrics, success: true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ class DesecDnsProvider extends DnsProvider {
|
|||
);
|
||||
}
|
||||
|
||||
return _adapter.api().createRecords(
|
||||
return _adapter.api().createMultipleDnsRecords(
|
||||
domain: domain,
|
||||
records: bulkRecords,
|
||||
);
|
||||
|
@ -127,7 +127,7 @@ class DesecDnsProvider extends DnsProvider {
|
|||
},
|
||||
);
|
||||
|
||||
return _adapter.api().updateRecords(
|
||||
return _adapter.api().removeSimilarRecords(
|
||||
domain: domain,
|
||||
records: bulkRecords,
|
||||
);
|
||||
|
@ -179,7 +179,7 @@ class DesecDnsProvider extends DnsProvider {
|
|||
final DnsRecord record,
|
||||
final ServerDomain domain,
|
||||
) async {
|
||||
final result = await _adapter.api().createRecords(
|
||||
final result = await _adapter.api().createMultipleDnsRecords(
|
||||
domain: domain,
|
||||
records: [
|
||||
{
|
||||
|
|
|
@ -47,7 +47,7 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
|||
@override
|
||||
Future<GenericResult<List<String>>> domainList() async {
|
||||
List<String> domains = [];
|
||||
final result = await _adapter.api().domainList();
|
||||
final result = await _adapter.api().getDomains();
|
||||
if (result.data.isEmpty || !result.success) {
|
||||
return GenericResult(
|
||||
success: result.success,
|
||||
|
|
Loading…
Reference in a new issue