feat(ui): Display network names and optimize list loading (#1503)
This commit is contained in:
@@ -8,7 +8,8 @@ use easytier::proto::api::manage::{
|
|||||||
WebClientServiceClientFactory,
|
WebClientServiceClientFactory,
|
||||||
};
|
};
|
||||||
use easytier::rpc_service::remote_client::{
|
use easytier::rpc_service::remote_client::{
|
||||||
ListNetworkInstanceIdsJsonResp, ListNetworkProps, RemoteClientManager, Storage,
|
GetNetworkMetasResponse, ListNetworkInstanceIdsJsonResp, ListNetworkProps, RemoteClientManager,
|
||||||
|
Storage,
|
||||||
};
|
};
|
||||||
use easytier::{
|
use easytier::{
|
||||||
common::config::{ConfigLoader, FileLoggerConfig, LoggingConfigBuilder, TomlConfigLoader},
|
common::config::{ConfigLoader, FileLoggerConfig, LoggingConfigBuilder, TomlConfigLoader},
|
||||||
@@ -249,6 +250,19 @@ fn load_configs(configs: Vec<NetworkConfig>, enabled_networks: Vec<String>) -> R
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
async fn get_network_metas(
|
||||||
|
app: AppHandle,
|
||||||
|
instance_ids: Vec<uuid::Uuid>,
|
||||||
|
) -> Result<GetNetworkMetasResponse, String> {
|
||||||
|
CLIENT_MANAGER
|
||||||
|
.get()
|
||||||
|
.unwrap()
|
||||||
|
.handle_get_network_metas(app, instance_ids)
|
||||||
|
.await
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "android"))]
|
#[cfg(not(target_os = "android"))]
|
||||||
fn toggle_window_visibility<R: tauri::Runtime>(app: &tauri::AppHandle<R>) {
|
fn toggle_window_visibility<R: tauri::Runtime>(app: &tauri::AppHandle<R>) {
|
||||||
if let Some(window) = app.get_webview_window("main") {
|
if let Some(window) = app.get_webview_window("main") {
|
||||||
@@ -667,6 +681,7 @@ pub fn run() {
|
|||||||
validate_config,
|
validate_config,
|
||||||
get_config,
|
get_config,
|
||||||
load_configs,
|
load_configs,
|
||||||
|
get_network_metas,
|
||||||
])
|
])
|
||||||
.on_window_event(|_win, event| match event {
|
.on_window_event(|_win, event| match event {
|
||||||
#[cfg(not(target_os = "android"))]
|
#[cfg(not(target_os = "android"))]
|
||||||
|
|||||||
Vendored
+2
@@ -27,6 +27,7 @@ declare global {
|
|||||||
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||||
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
||||||
const getEasytierVersion: typeof import('./composables/backend')['getEasytierVersion']
|
const getEasytierVersion: typeof import('./composables/backend')['getEasytierVersion']
|
||||||
|
const getNetworkMetas: typeof import('./composables/backend')['getNetworkMetas']
|
||||||
const h: typeof import('vue')['h']
|
const h: typeof import('vue')['h']
|
||||||
const initMobileVpnService: typeof import('./composables/mobile_vpn')['initMobileVpnService']
|
const initMobileVpnService: typeof import('./composables/mobile_vpn')['initMobileVpnService']
|
||||||
const inject: typeof import('vue')['inject']
|
const inject: typeof import('vue')['inject']
|
||||||
@@ -139,6 +140,7 @@ declare module 'vue' {
|
|||||||
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
|
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
|
||||||
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
|
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
|
||||||
readonly getEasytierVersion: UnwrapRef<typeof import('./composables/backend')['getEasytierVersion']>
|
readonly getEasytierVersion: UnwrapRef<typeof import('./composables/backend')['getEasytierVersion']>
|
||||||
|
readonly getNetworkMetas: UnwrapRef<typeof import('./composables/backend')['getNetworkMetas']>
|
||||||
readonly h: UnwrapRef<typeof import('vue')['h']>
|
readonly h: UnwrapRef<typeof import('vue')['h']>
|
||||||
readonly initMobileVpnService: UnwrapRef<typeof import('./composables/mobile_vpn')['initMobileVpnService']>
|
readonly initMobileVpnService: UnwrapRef<typeof import('./composables/mobile_vpn')['initMobileVpnService']>
|
||||||
readonly inject: UnwrapRef<typeof import('vue')['inject']>
|
readonly inject: UnwrapRef<typeof import('vue')['inject']>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { invoke } from '@tauri-apps/api/core'
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
import { Api, type NetworkTypes } from 'easytier-frontend-lib'
|
import { Api, type NetworkTypes } from 'easytier-frontend-lib'
|
||||||
|
import { GetNetworkMetasResponse } from 'node_modules/easytier-frontend-lib/dist/modules/api'
|
||||||
import { getAutoLaunchStatusAsync } from '~/modules/auto_launch'
|
import { getAutoLaunchStatusAsync } from '~/modules/auto_launch'
|
||||||
|
|
||||||
type NetworkConfig = NetworkTypes.NetworkConfig
|
type NetworkConfig = NetworkTypes.NetworkConfig
|
||||||
@@ -63,3 +64,7 @@ export async function sendConfigs() {
|
|||||||
let autoStartInstIds = getAutoLaunchStatusAsync() ? JSON.parse(localStorage.getItem('autoStartInstIds') || '[]') : []
|
let autoStartInstIds = getAutoLaunchStatusAsync() ? JSON.parse(localStorage.getItem('autoStartInstIds') || '[]') : []
|
||||||
return await invoke('load_configs', { configs: networkList, enabledNetworks: autoStartInstIds })
|
return await invoke('load_configs', { configs: networkList, enabledNetworks: autoStartInstIds })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getNetworkMetas(instanceIds: string[]) {
|
||||||
|
return await invoke<GetNetworkMetasResponse>('get_network_metas', { instanceIds })
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,5 +40,8 @@ export class GUIRemoteClient implements Api.RemoteClient {
|
|||||||
return { error: e + "" };
|
return { error: e + "" };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async get_network_metas(instance_ids: string[]): Promise<Api.GetNetworkMetasResponse> {
|
||||||
|
return await backend.getNetworkMetas(instance_ids);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Button, ConfirmPopup, Divider, IftaLabel, Menu, Message, Select, Tag, useConfirm, useToast } from 'primevue';
|
import { Button, ConfirmPopup, Divider, IftaLabel, Menu, Message, Select, Tag, useConfirm, useToast, type VirtualScrollerLazyEvent } from 'primevue';
|
||||||
import { computed, onMounted, onUnmounted, Ref, ref, watch } from 'vue';
|
import { computed, onMounted, onUnmounted, Ref, ref, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import * as Api from '../modules/api';
|
import * as Api from '../modules/api';
|
||||||
@@ -37,22 +37,62 @@ const isRunning = (instanceId: string) => {
|
|||||||
return listInstanceIdResponse.value?.running_inst_ids.map(Utils.UuidToStr).includes(instanceId);
|
return listInstanceIdResponse.value?.running_inst_ids.map(Utils.UuidToStr).includes(instanceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
const instanceIdList = computed(() => {
|
const networkMetaCache = ref<Record<string, Api.NetworkMeta>>({});
|
||||||
|
const loadNetworkMetas = async (instanceIds: string[]) => {
|
||||||
|
const missingIds = instanceIds.filter(id => !networkMetaCache.value[id]);
|
||||||
|
|
||||||
|
if (missingIds.length === 0) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await props.api.get_network_metas(missingIds);
|
||||||
|
Object.assign(networkMetaCache.value, response.metas);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Failed to load network metas", e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const onLazyLoadNetworkMetas = async (event: VirtualScrollerLazyEvent) => {
|
||||||
|
const instanceIds = instanceList.value
|
||||||
|
.slice(event.first, event.last + 1)
|
||||||
|
.map(item => item.uuid);
|
||||||
|
await loadNetworkMetas(instanceIds);
|
||||||
|
};
|
||||||
|
|
||||||
|
const instanceList = ref<Array<{ uuid: string; meta?: Api.NetworkMeta }>>([]);
|
||||||
|
const updateInstanceList = () => {
|
||||||
let insts = new Set<string>();
|
let insts = new Set<string>();
|
||||||
let t = listInstanceIdResponse.value;
|
let t = listInstanceIdResponse.value;
|
||||||
if (t) {
|
if (t) {
|
||||||
t.running_inst_ids.forEach((u) => insts.add(Utils.UuidToStr(u)));
|
t.running_inst_ids.forEach((u) => insts.add(Utils.UuidToStr(u)));
|
||||||
t.disabled_inst_ids.forEach((u) => insts.add(Utils.UuidToStr(u)));
|
t.disabled_inst_ids.forEach((u) => insts.add(Utils.UuidToStr(u)));
|
||||||
}
|
}
|
||||||
let options = Array.from(insts).map((instance: string) => {
|
|
||||||
return { uuid: instance };
|
const newList = Array.from(insts).map((instance: string) => {
|
||||||
|
return {
|
||||||
|
uuid: instance,
|
||||||
|
meta: networkMetaCache.value[instance]
|
||||||
|
};
|
||||||
});
|
});
|
||||||
return options;
|
|
||||||
|
if (JSON.stringify(newList) !== JSON.stringify(instanceList.value)) {
|
||||||
|
instanceList.value = newList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
watch(listInstanceIdResponse, updateInstanceList, { deep: false });
|
||||||
|
watch(networkMetaCache, updateInstanceList, { deep: true });
|
||||||
|
watch(instanceList, async (newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
const instanceIds = new Set(newVal.map(item => item.uuid));
|
||||||
|
Object.keys(networkMetaCache.value).forEach(id => {
|
||||||
|
if (!instanceIds.has(id)) {
|
||||||
|
delete networkMetaCache.value[id];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectedInstanceId = computed({
|
const selectedInstanceId = computed({
|
||||||
get() {
|
get() {
|
||||||
return instanceIdList.value.find((instance) => instance.uuid === instanceId.value);
|
return instanceList.value.find((instance) => instance.uuid === instanceId.value);
|
||||||
},
|
},
|
||||||
set(value: any) {
|
set(value: any) {
|
||||||
console.log("set instanceId", value);
|
console.log("set instanceId", value);
|
||||||
@@ -62,6 +102,12 @@ const selectedInstanceId = computed({
|
|||||||
watch(selectedInstanceId, async (newVal, oldVal) => {
|
watch(selectedInstanceId, async (newVal, oldVal) => {
|
||||||
if (newVal?.uuid !== oldVal?.uuid && (networkIsDisabled.value || isEditingNetwork.value)) {
|
if (newVal?.uuid !== oldVal?.uuid && (networkIsDisabled.value || isEditingNetwork.value)) {
|
||||||
await loadCurrentNetworkConfig();
|
await loadCurrentNetworkConfig();
|
||||||
|
} else {
|
||||||
|
await loadCurrentNetworkInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newVal?.uuid && !networkMetaCache.value[newVal.uuid]) {
|
||||||
|
await loadNetworkMetas([newVal.uuid]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -74,6 +120,10 @@ const needShowNetworkStatus = computed(() => {
|
|||||||
// network is disabled
|
// network is disabled
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (isEditingNetwork.value) {
|
||||||
|
// editing network
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -96,7 +146,7 @@ const loadCurrentNetworkConfig = async () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret = await props.api.get_network_config(selectedInstanceId.value.uuid);
|
let ret = await props.api.get_network_config(selectedInstanceId.value!.uuid);
|
||||||
currentNetworkConfig.value = ret;
|
currentNetworkConfig.value = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,11 +194,18 @@ const confirmDeleteNetwork = (event: any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const saveAndRunNewNetwork = async () => {
|
const saveAndRunNewNetwork = async () => {
|
||||||
|
if (!currentNetworkConfig.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
await props.api.delete_network(instanceId.value!);
|
await props.api.delete_network(instanceId.value!);
|
||||||
let ret = await props.api.run_network(currentNetworkConfig.value!!);
|
let ret = await props.api.run_network(currentNetworkConfig.value);
|
||||||
console.debug("saveAndRunNewNetwork", ret);
|
console.debug("saveAndRunNewNetwork", ret);
|
||||||
selectedInstanceId.value = { uuid: currentNetworkConfig.value!.instance_id };
|
|
||||||
|
delete networkMetaCache.value[currentNetworkConfig.value.instance_id];
|
||||||
|
await loadNetworkMetas([currentNetworkConfig.value.instance_id]);
|
||||||
|
|
||||||
|
selectedInstanceId.value = { uuid: currentNetworkConfig.value.instance_id };
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
toast.add({ severity: 'error', summary: 'Error', detail: 'Failed to create network, error: ' + JSON.stringify(e.response.data), life: 2000 });
|
toast.add({ severity: 'error', summary: 'Error', detail: 'Failed to create network, error: ' + JSON.stringify(e.response.data), life: 2000 });
|
||||||
@@ -164,6 +221,10 @@ const saveNetworkConfig = async () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await props.api.save_config(currentNetworkConfig.value);
|
await props.api.save_config(currentNetworkConfig.value);
|
||||||
|
|
||||||
|
delete networkMetaCache.value[currentNetworkConfig.value.instance_id];
|
||||||
|
await loadNetworkMetas([currentNetworkConfig.value.instance_id]);
|
||||||
|
|
||||||
toast.add({ severity: 'success', summary: t("web.common.success"), detail: t("web.device_management.config_saved"), life: 2000 });
|
toast.add({ severity: 'success', summary: t("web.common.success"), detail: t("web.device_management.config_saved"), life: 2000 });
|
||||||
}
|
}
|
||||||
const newNetwork = async () => {
|
const newNetwork = async () => {
|
||||||
@@ -201,14 +262,17 @@ const loadNetworkInstanceIds = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const loadCurrentNetworkInfo = async () => {
|
const loadCurrentNetworkInfo = async () => {
|
||||||
if (!instanceId.value) {
|
if (!selectedInstanceId.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!needShowNetworkStatus.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let network_info = await props.api.get_network_info(instanceId.value);
|
let network_info = await props.api.get_network_info(selectedInstanceId.value.uuid);
|
||||||
|
|
||||||
curNetworkInfo.value = {
|
curNetworkInfo.value = {
|
||||||
instance_id: instanceId.value,
|
instance_id: selectedInstanceId.value.uuid,
|
||||||
running: network_info?.running ?? false,
|
running: network_info?.running ?? false,
|
||||||
error_msg: network_info?.error_msg ?? '',
|
error_msg: network_info?.error_msg ?? '',
|
||||||
detail: network_info,
|
detail: network_info,
|
||||||
@@ -365,13 +429,26 @@ onUnmounted(() => {
|
|||||||
<!-- 网络选择 -->
|
<!-- 网络选择 -->
|
||||||
<div class="flex-1 min-w-0">
|
<div class="flex-1 min-w-0">
|
||||||
<IftaLabel class="w-full">
|
<IftaLabel class="w-full">
|
||||||
<Select v-model="selectedInstanceId" :options="instanceIdList" optionLabel="uuid" class="w-full"
|
<Select v-model="selectedInstanceId" :options="instanceList" optionLabel="uuid" class="w-full"
|
||||||
inputId="dd-inst-id" :placeholder="t('web.device_management.select_network')"
|
inputId="dd-inst-id" :placeholder="t('web.device_management.select_network')"
|
||||||
:pt="{ root: { class: 'network-select-container' } }">
|
:pt="{ root: { class: 'network-select-container' } }" :virtualScrollerOptions="{
|
||||||
|
lazy: true,
|
||||||
|
onLazyLoad: onLazyLoadNetworkMetas,
|
||||||
|
itemSize: 60,
|
||||||
|
delay: 50
|
||||||
|
}">
|
||||||
<template #value="slotProps">
|
<template #value="slotProps">
|
||||||
<div v-if="slotProps.value" class="flex items-center content-center min-w-0">
|
<div v-if="slotProps.value" class="flex items-center content-center min-w-0">
|
||||||
<div class="mr-4 flex-col min-w-0 flex-1">
|
<div class="mr-4 flex-col min-w-0 flex-1">
|
||||||
<span class="truncate block"> {{ slotProps.value.uuid }}</span>
|
<span class="truncate block">
|
||||||
|
|
||||||
|
<span v-if="slotProps.value.meta">
|
||||||
|
{{ slotProps.value.meta.instance_name }} ({{ slotProps.value.uuid }})
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
{{ slotProps.value.uuid }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<Tag class="my-auto leading-3 shrink-0"
|
<Tag class="my-auto leading-3 shrink-0"
|
||||||
:severity="isRunning(slotProps.value.uuid) ? 'success' : 'info'"
|
:severity="isRunning(slotProps.value.uuid) ? 'success' : 'info'"
|
||||||
@@ -382,13 +459,19 @@ onUnmounted(() => {
|
|||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #option="slotProps">
|
<template #option="slotProps">
|
||||||
<div class="flex items-center content-center min-w-0">
|
<div class="flex flex-col items-start content-center max-w-full">
|
||||||
<div class="mr-4 flex-col min-w-0 flex-1">
|
<div class="flex items-center min-w-0">
|
||||||
<span class="truncate block"> {{ slotProps.option.uuid }}</span>
|
<div class="mr-4 min-w-0 flex-1">
|
||||||
|
<span class="truncate block">{{ t('network_name') }}: {{
|
||||||
|
slotProps.option.meta.instance_name }}</span>
|
||||||
|
</div>
|
||||||
|
<Tag class="my-auto leading-3 shrink-0"
|
||||||
|
:severity="isRunning(slotProps.option.uuid) ? 'success' : 'info'"
|
||||||
|
:value="t(isRunning(slotProps.option.uuid) ? 'network_running' : 'network_stopped')" />
|
||||||
|
</div>
|
||||||
|
<div class="max-w-full overflow-hidden text-ellipsis text-gray-500">
|
||||||
|
{{ slotProps.option.uuid }}
|
||||||
</div>
|
</div>
|
||||||
<Tag class="my-auto leading-3 shrink-0"
|
|
||||||
:severity="isRunning(slotProps.option.uuid) ? 'success' : 'info'"
|
|
||||||
:value="t(isRunning(slotProps.option.uuid) ? 'network_running' : 'network_stopped')" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Select>
|
</Select>
|
||||||
@@ -601,4 +684,3 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,14 @@ export interface CollectNetworkInfoResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface NetworkMeta {
|
||||||
|
instance_name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GetNetworkMetasResponse {
|
||||||
|
metas: Record<string, NetworkMeta>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface RemoteClient {
|
export interface RemoteClient {
|
||||||
validate_config(config: NetworkConfig): Promise<ValidateConfigResponse>;
|
validate_config(config: NetworkConfig): Promise<ValidateConfigResponse>;
|
||||||
run_network(config: NetworkConfig): Promise<undefined>;
|
run_network(config: NetworkConfig): Promise<undefined>;
|
||||||
@@ -37,4 +45,5 @@ export interface RemoteClient {
|
|||||||
get_network_config(inst_id: string): Promise<NetworkConfig>;
|
get_network_config(inst_id: string): Promise<NetworkConfig>;
|
||||||
generate_config(config: NetworkConfig): Promise<GenerateConfigResponse>;
|
generate_config(config: NetworkConfig): Promise<GenerateConfigResponse>;
|
||||||
parse_config(toml_config: string): Promise<ParseConfigResponse>;
|
parse_config(toml_config: string): Promise<ParseConfigResponse>;
|
||||||
|
get_network_metas(instance_ids: string[]): Promise<GetNetworkMetasResponse>;
|
||||||
}
|
}
|
||||||
@@ -243,6 +243,12 @@ class WebRemoteClient implements Api.RemoteClient {
|
|||||||
return { error: 'Unknown error: ' + error };
|
return { error: 'Unknown error: ' + error };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async get_network_metas(instance_ids: string[]): Promise<Api.GetNetworkMetasResponse> {
|
||||||
|
const response = await this.client.post<any, Api.GetNetworkMetasResponse>(`/machines/${this.machine_id}/networks/metas`, {
|
||||||
|
instance_ids: instance_ids
|
||||||
|
});
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ApiClient;
|
export default ApiClient;
|
||||||
@@ -7,7 +7,7 @@ use easytier::launcher::NetworkConfig;
|
|||||||
use easytier::proto::common::Void;
|
use easytier::proto::common::Void;
|
||||||
use easytier::proto::{api::manage::*, web::*};
|
use easytier::proto::{api::manage::*, web::*};
|
||||||
use easytier::rpc_service::remote_client::{
|
use easytier::rpc_service::remote_client::{
|
||||||
ListNetworkInstanceIdsJsonResp, RemoteClientError, RemoteClientManager,
|
GetNetworkMetasResponse, ListNetworkInstanceIdsJsonResp, RemoteClientError, RemoteClientManager,
|
||||||
};
|
};
|
||||||
use sea_orm::DbErr;
|
use sea_orm::DbErr;
|
||||||
|
|
||||||
@@ -71,6 +71,11 @@ struct UpdateNetworkStateJsonReq {
|
|||||||
disabled: bool,
|
disabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||||
|
struct GetNetworkMetasJsonReq {
|
||||||
|
instance_ids: Vec<uuid::Uuid>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||||
struct RemoveNetworkJsonReq {
|
struct RemoveNetworkJsonReq {
|
||||||
inst_ids: Vec<uuid::Uuid>,
|
inst_ids: Vec<uuid::Uuid>,
|
||||||
@@ -237,6 +242,23 @@ impl NetworkApi {
|
|||||||
.map_err(convert_error)
|
.map_err(convert_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn handle_get_network_metas(
|
||||||
|
auth_session: AuthSession,
|
||||||
|
State(client_mgr): AppState,
|
||||||
|
Path(machine_id): Path<uuid::Uuid>,
|
||||||
|
Json(payload): Json<GetNetworkMetasJsonReq>,
|
||||||
|
) -> Result<Json<GetNetworkMetasResponse>, HttpHandleError> {
|
||||||
|
Ok(Json(
|
||||||
|
client_mgr
|
||||||
|
.handle_get_network_metas(
|
||||||
|
(Self::get_user_id(&auth_session)?, machine_id),
|
||||||
|
payload.instance_ids,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(convert_error)?,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
async fn handle_save_network_config(
|
async fn handle_save_network_config(
|
||||||
auth_session: AuthSession,
|
auth_session: AuthSession,
|
||||||
State(client_mgr): AppState,
|
State(client_mgr): AppState,
|
||||||
@@ -298,5 +320,9 @@ impl NetworkApi {
|
|||||||
"/api/v1/machines/:machine-id/networks/config/:inst-id",
|
"/api/v1/machines/:machine-id/networks/config/:inst-id",
|
||||||
get(Self::handle_get_network_config).put(Self::handle_save_network_config),
|
get(Self::handle_get_network_config).put(Self::handle_save_network_config),
|
||||||
)
|
)
|
||||||
|
.route(
|
||||||
|
"/api/v1/machines/:machine-id/networks/metas",
|
||||||
|
post(Self::handle_get_network_metas),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,6 +189,28 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn handle_get_network_metas(
|
||||||
|
&self,
|
||||||
|
identify: T,
|
||||||
|
inst_ids: Vec<uuid::Uuid>,
|
||||||
|
) -> Result<GetNetworkMetasResponse, RemoteClientError<E>> {
|
||||||
|
let mut metas = std::collections::HashMap::new();
|
||||||
|
|
||||||
|
for instance_id in inst_ids {
|
||||||
|
let config = self
|
||||||
|
.handle_get_network_config(identify.clone(), instance_id)
|
||||||
|
.await?;
|
||||||
|
metas.insert(
|
||||||
|
instance_id,
|
||||||
|
NetworkMeta {
|
||||||
|
instance_name: config.network_name.unwrap_or_default(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(GetNetworkMetasResponse { metas })
|
||||||
|
}
|
||||||
|
|
||||||
async fn handle_save_network_config(
|
async fn handle_save_network_config(
|
||||||
&self,
|
&self,
|
||||||
identify: T,
|
identify: T,
|
||||||
@@ -255,6 +277,16 @@ pub struct ListNetworkInstanceIdsJsonResp {
|
|||||||
disabled_inst_ids: Vec<crate::proto::common::Uuid>,
|
disabled_inst_ids: Vec<crate::proto::common::Uuid>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub struct NetworkMeta {
|
||||||
|
instance_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub struct GetNetworkMetasResponse {
|
||||||
|
metas: std::collections::HashMap<uuid::Uuid, NetworkMeta>,
|
||||||
|
}
|
||||||
|
|
||||||
pub trait PersistentConfig<E> {
|
pub trait PersistentConfig<E> {
|
||||||
fn get_network_inst_id(&self) -> &str;
|
fn get_network_inst_id(&self) -> &str;
|
||||||
fn get_network_config(&self) -> Result<NetworkConfig, E>;
|
fn get_network_config(&self) -> Result<NetworkConfig, E>;
|
||||||
|
|||||||
Reference in New Issue
Block a user