feat(region): Implement endpoints for listing available provider regions

routes-refactor
NaiJi ✨ 2022-10-13 23:13:56 +00:00
parent 2f59954641
commit e032bd8a78
8 changed files with 220 additions and 21 deletions

View File

@ -11,6 +11,7 @@ import 'package:selfprivacy/logic/models/hive/server_details.dart';
import 'package:selfprivacy/logic/models/hive/user.dart';
import 'package:selfprivacy/logic/models/price.dart';
import 'package:selfprivacy/logic/models/server_basic_info.dart';
import 'package:selfprivacy/logic/models/server_provider_location.dart';
import 'package:selfprivacy/utils/password_generator.dart';
class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
@ -538,6 +539,69 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
return servers;
}
String? getEmojiFlag(final String query) {
String? emoji;
switch (query.toLowerCase().substring(0, 2)) {
case 'fra':
emoji = '🇩🇪';
break;
case 'ams':
emoji = '🇳🇱';
break;
case 'sgp':
emoji = '🇸🇬';
break;
case 'lon':
emoji = '🇬🇧';
break;
case 'tor':
emoji = '🇨🇦';
break;
case 'blr':
emoji = '🇮🇳';
break;
case 'nyc':
case 'sfo':
emoji = '🇺🇸';
break;
}
return emoji;
}
@override
Future<List<ServerProviderLocation>> getAvailableLocations() async {
List<ServerProviderLocation> locations = [];
final Dio client = await getClient();
try {
final Response response = await client.post(
'/locations',
);
locations = response.data!['locations'].map<ServerProviderLocation>(
(final location) => ServerProviderLocation(
title: location['slug'],
description: location['name'],
flag: getEmojiFlag(location['slug']),
),
);
} catch (e) {
print(e);
} finally {
close(client);
}
return locations;
}
@override
Future<void> createReverseDns({
required final ServerHostingDetails serverDetails,

View File

@ -11,10 +11,15 @@ import 'package:selfprivacy/logic/models/hive/server_details.dart';
import 'package:selfprivacy/logic/models/hive/user.dart';
import 'package:selfprivacy/logic/models/price.dart';
import 'package:selfprivacy/logic/models/server_basic_info.dart';
import 'package:selfprivacy/logic/models/server_provider_location.dart';
import 'package:selfprivacy/utils/password_generator.dart';
class HetznerApi extends ServerProviderApi with VolumeProviderApi {
HetznerApi({required this.region, this.hasLogger = false, this.isWithToken = true,});
HetznerApi({
required this.region,
this.hasLogger = false,
this.isWithToken = true,
});
@override
bool hasLogger;
@override
@ -536,6 +541,52 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
return servers;
}
String? getEmojiFlag(final String query) {
String? emoji;
switch (query.toLowerCase()) {
case 'de':
emoji = '🇩🇪';
break;
case 'fi':
emoji = '🇫🇮';
break;
case 'us':
emoji = '🇺🇸';
break;
}
return emoji;
}
@override
Future<List<ServerProviderLocation>> getAvailableLocations() async {
List<ServerProviderLocation> locations = [];
final Dio client = await getClient();
try {
final Response response = await client.post(
'/locations',
);
locations = response.data!['locations'].map<ServerProviderLocation>(
(final location) => ServerProviderLocation(
title: location['city'],
description: location['description'],
flag: getEmojiFlag(location['country']),
),
);
} catch (e) {
print(e);
} finally {
close(client);
}
return locations;
}
@override
Future<void> createReverseDns({
required final ServerHostingDetails serverDetails,

View File

@ -3,9 +3,11 @@ import 'package:selfprivacy/logic/models/hive/server_details.dart';
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
import 'package:selfprivacy/logic/models/hive/user.dart';
import 'package:selfprivacy/logic/models/server_basic_info.dart';
import 'package:selfprivacy/logic/models/server_provider_location.dart';
abstract class ServerProviderApi extends ApiMap {
Future<List<ServerBasicInfo>> getServers();
Future<List<ServerProviderLocation>> getAvailableLocations();
Future<ServerHostingDetails> restart();
Future<ServerHostingDetails> powerOn();

View File

@ -26,7 +26,10 @@ class HetznerMetricsRepository {
break;
}
final HetznerApi api = HetznerApi(hasLogger: false, region: 'fra1',);
final HetznerApi api = HetznerApi(
hasLogger: false,
region: 'fra1',
);
final List<Map<String, dynamic>> results = await Future.wait([
api.getMetrics(start, end, 'cpu'),

View File

@ -34,8 +34,13 @@ class ApiProviderVolumeCubit
}
}
Future<Price?> getPricePerGb() async =>
providerApi!.getVolumeProvider(settings: const ServerProviderApiSettings(region: 'fra1',),).getPricePerGb();
Future<Price?> getPricePerGb() async => providerApi!
.getVolumeProvider(
settings: const ServerProviderApiSettings(
region: 'fra1',
),
)
.getPricePerGb();
Future<void> refresh() async {
emit(const ApiProviderVolumeState([], LoadingStatus.refreshing, false));
@ -47,8 +52,13 @@ class ApiProviderVolumeCubit
return emit(const ApiProviderVolumeState([], LoadingStatus.error, false));
}
final List<ServerVolume> volumes =
await providerApi!.getVolumeProvider(settings: const ServerProviderApiSettings(region: 'fra1',),).getVolumes();
final List<ServerVolume> volumes = await providerApi!
.getVolumeProvider(
settings: const ServerProviderApiSettings(
region: 'fra1',
),
)
.getVolumes();
if (volumes.isEmpty) {
return emit(const ApiProviderVolumeState([], LoadingStatus.error, false));
@ -60,14 +70,22 @@ class ApiProviderVolumeCubit
Future<void> attachVolume(final DiskVolume volume) async {
final ServerHostingDetails server = getIt<ApiConfigModel>().serverDetails!;
await providerApi!
.getVolumeProvider(settings: const ServerProviderApiSettings(region: 'fra1',),)
.getVolumeProvider(
settings: const ServerProviderApiSettings(
region: 'fra1',
),
)
.attachVolume(volume.providerVolume!.id.toString(), server.id);
refresh();
}
Future<void> detachVolume(final DiskVolume volume) async {
await providerApi!
.getVolumeProvider(settings: const ServerProviderApiSettings(region: 'fra1',),)
.getVolumeProvider(
settings: const ServerProviderApiSettings(
region: 'fra1',
),
)
.detachVolume(volume.providerVolume!.id.toString());
refresh();
}
@ -81,7 +99,13 @@ class ApiProviderVolumeCubit
'Starting resize',
);
emit(state.copyWith(isResizing: true));
final bool resized = await providerApi!.getVolumeProvider(settings: const ServerProviderApiSettings(region: 'fra1',),).resizeVolume(
final bool resized = await providerApi!
.getVolumeProvider(
settings: const ServerProviderApiSettings(
region: 'fra1',
),
)
.resizeVolume(
volume.providerVolume!.id.toString(),
newSizeGb,
);
@ -117,8 +141,13 @@ class ApiProviderVolumeCubit
}
Future<void> createVolume() async {
final ServerVolume? volume =
await providerApi!.getVolumeProvider(settings: const ServerProviderApiSettings(region: 'fra1',),).createVolume();
final ServerVolume? volume = await providerApi!
.getVolumeProvider(
settings: const ServerProviderApiSettings(
region: 'fra1',
),
)
.createVolume();
final diskVolume = DiskVolume(providerVolume: volume);
await attachVolume(diskVolume);
@ -131,7 +160,11 @@ class ApiProviderVolumeCubit
Future<void> deleteVolume(final DiskVolume volume) async {
await providerApi!
.getVolumeProvider(settings: const ServerProviderApiSettings(region: 'fra1',),)
.getVolumeProvider(
settings: const ServerProviderApiSettings(
region: 'fra1',
),
)
.deleteVolume(volume.providerVolume!.id.toString());
refresh();
}

View File

@ -63,7 +63,11 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
RegExp getServerProviderApiTokenValidation() =>
repository.serverProviderApiFactory!
.getServerProvider(settings: const ServerProviderApiSettings(region: 'fra1',),)
.getServerProvider(
settings: const ServerProviderApiSettings(
region: 'fra1',
),
)
.getApiTokenValidation();
RegExp getDnsProviderApiTokenValidation() => repository.dnsProviderApiFactory!
@ -75,7 +79,8 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
) async =>
repository.serverProviderApiFactory!
.getServerProvider(
settings: const ServerProviderApiSettings(region: 'fra1', isWithToken: false),
settings: const ServerProviderApiSettings(
region: 'fra1', isWithToken: false),
)
.isApiTokenValid(providerToken);

View File

@ -153,7 +153,11 @@ class ServerInstallationRepository {
) async {
ServerHostingDetails serverDetails;
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(settings: const ServerProviderApiSettings(region: 'fra1',),);
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(
settings: const ServerProviderApiSettings(
region: 'fra1',
),
);
serverDetails = await api.powerOn();
return serverDetails;
@ -229,7 +233,11 @@ class ServerInstallationRepository {
required final Future<void> Function(ServerHostingDetails serverDetails)
onSuccess,
}) async {
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(settings: const ServerProviderApiSettings(region: 'fra1',),);
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(
settings: const ServerProviderApiSettings(
region: 'fra1',
),
);
try {
final ServerHostingDetails? serverDetails = await api.createServer(
dnsApiToken: cloudFlareKey,
@ -334,7 +342,11 @@ class ServerInstallationRepository {
final DnsProviderApi dnsProviderApi =
dnsProviderApiFactory!.getDnsProvider();
final ServerProviderApi serverApi =
serverProviderApiFactory!.getServerProvider(settings: const ServerProviderApiSettings(region: 'fra1',),);
serverProviderApiFactory!.getServerProvider(
settings: const ServerProviderApiSettings(
region: 'fra1',
),
);
await dnsProviderApi.removeSimilarRecords(
ip4: serverDetails.ip4,
@ -406,12 +418,20 @@ class ServerInstallationRepository {
}
Future<ServerHostingDetails> restart() async {
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(settings: const ServerProviderApiSettings(region: 'fra1',),);
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(
settings: const ServerProviderApiSettings(
region: 'fra1',
),
);
return api.restart();
}
Future<ServerHostingDetails> powerOn() async {
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(settings: const ServerProviderApiSettings(region: 'fra1',),);
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(
settings: const ServerProviderApiSettings(
region: 'fra1',
),
);
return api.powerOn();
}
@ -654,7 +674,11 @@ class ServerInstallationRepository {
}
Future<List<ServerBasicInfo>> getServersOnProviderAccount() async {
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(settings: const ServerProviderApiSettings(region: 'fra1',),);
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(
settings: const ServerProviderApiSettings(
region: 'fra1',
),
);
return api.getServers();
}
@ -732,7 +756,11 @@ class ServerInstallationRepository {
}
Future<void> deleteServer(final ServerDomain serverDomain) async {
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(settings: const ServerProviderApiSettings(region: 'fra1',),);
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(
settings: const ServerProviderApiSettings(
region: 'fra1',
),
);
final DnsProviderApi dnsProviderApi =
dnsProviderApiFactory!.getDnsProvider();

View File

@ -0,0 +1,13 @@
class ServerProviderLocation {
ServerProviderLocation({
required this.title,
this.description,
this.flag,
});
final String title;
final String? description;
/// as emoji
final String? flag;
}