chore: Merge pull request 'refactor(rest-api): Move rest api methods according to their business logic files positions' (#235) from docs into master
continuous-integration/drone/push Build is passing Details

Reviewed-on: #235
Reviewed-by: Inex Code <inex.code@selfprivacy.org>
backups-testing
NaiJi ✨ 2023-07-16 14:00:40 +03:00
commit 0a333214d8
7 changed files with 763 additions and 763 deletions

View File

@ -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);
}
}

View File

@ -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,
);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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: [
{

View File

@ -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,