From 4773bb7472f022b6fd5aa172dcbb378313260ba6 Mon Sep 17 00:00:00 2001 From: Andrea Leardini Date: Tue, 12 Nov 2024 17:01:24 +0100 Subject: [PATCH] feat(monitoring): show ip addresses of wan ifaces (#433) --- .../controller/users/UsersTable.vue | 2 +- .../monitoring/ConnectivityMonitor.vue | 128 ++++++++++++--- .../connectivity/WanConnectionsCard.vue | 7 + .../CreateOrEditTunnelDrawer.vue | 1 - src/composables/useNetworkDevices.ts | 81 ++++++++++ src/composables/useUciNetworkConfig.ts | 75 +++++++++ src/i18n/en/translation.json | 3 +- src/lib/standalone/network.ts | 115 ++++++++++++- .../network/InterfacesAndDevicesView.vue | 153 +++++------------- 9 files changed, 424 insertions(+), 141 deletions(-) create mode 100644 src/composables/useNetworkDevices.ts create mode 100644 src/composables/useUciNetworkConfig.ts diff --git a/src/components/controller/users/UsersTable.vue b/src/components/controller/users/UsersTable.vue index 46e4916f0..93574fe05 100644 --- a/src/components/controller/users/UsersTable.vue +++ b/src/components/controller/users/UsersTable.vue @@ -21,7 +21,7 @@ import { type ControllerAccount } from '@/stores/controller/accounts' import { useLoginStore } from '@/stores/controller/controllerLogin' import { ref } from 'vue' import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' -import { faCheck, faCircleCheck, faCircleXmark } from '@fortawesome/free-solid-svg-icons' +import { faCircleCheck, faCircleXmark } from '@fortawesome/free-solid-svg-icons' const props = defineProps<{ users: ControllerAccount[] diff --git a/src/components/standalone/monitoring/ConnectivityMonitor.vue b/src/components/standalone/monitoring/ConnectivityMonitor.vue index 2ede431c9..e4fe0b005 100644 --- a/src/components/standalone/monitoring/ConnectivityMonitor.vue +++ b/src/components/standalone/monitoring/ConnectivityMonitor.vue @@ -19,11 +19,16 @@ import InterfaceTrafficCard from './connectivity/InterfaceTrafficCard.vue' import { isEmpty } from 'lodash-es' import type { Policy } from '@/composables/useMwan' import WanConnectionsCard from './connectivity/WanConnectionsCard.vue' +import { useNetworkDevices } from '@/composables/useNetworkDevices' +import { getIpv4Addresses, getIpv6Addresses, getName, isDeviceUp } from '@/lib/standalone/network' +import { useUciNetworkConfig } from '@/composables/useUciNetworkConfig' export type Wan = { iface: string device: string status?: string + ip4Addresses?: string[] + ip6Addresses?: string[] } export type WanEvent = { @@ -32,10 +37,20 @@ export type WanEvent = { } const { t } = useI18n() +const { allDevices, listDevices, loadingListDevices, errorListDevices, errorListDevicesDetails } = + useNetworkDevices() +const { + networkConfig, + getNetworkConfig, + loadingNetworkConfig, + errorNetworkConfig, + errorNetworkConfigDetails +} = useUciNetworkConfig() const wans = ref([]) const mwanEvents = ref>({}) const mwanPolicies = ref([]) + let loading = ref({ listWans: false, getMwanReport: false, @@ -51,43 +66,75 @@ let error = ref({ getMwanPoliciesDetails: '' }) +const loadingData = computed(() => { + return ( + loading.value.listWans || + loading.value.getMwanReport || + loading.value.getMwanPolicies || + loadingNetworkConfig.value || + loadingListDevices.value + ) +}) + const wanConnections = computed(() => { - const wanData = [] + const wanData: Wan[] = [] for (const wan of wans.value) { // get wan status from policy data let statusFound = false - for (const policy of mwanPolicies.value) { - if (statusFound) { - break - } - - for (const policyMembers of Object.values(policy.members)) { + if (mwanPolicies.value.length > 0) { + // multiwan configured + for (const policy of mwanPolicies.value) { if (statusFound) { break } - for (const policyMember of policyMembers) { - if (policyMember.interface == wan.iface) { - wanData.push({ - ...wan, - status: policyMember.status - }) - statusFound = true + for (const policyMembers of Object.values(policy.members)) { + if (statusFound) { break } + + for (const policyMember of policyMembers) { + if (policyMember.interface == wan.iface) { + const devFound = allDevices.value.find((dev) => getName(dev) === wan.device) + + wanData.push({ + ...wan, + status: policyMember.status, + ip4Addresses: devFound ? getIpv4Addresses(devFound, networkConfig.value) : [], + ip6Addresses: devFound ? getIpv6Addresses(devFound, networkConfig.value) : [] + }) + statusFound = true + break + } + } } } + } else { + // multiwan not configured + + const devFound = allDevices.value.find((dev) => getName(dev) === wan.device) + + if (devFound) { + wanData.push({ + ...wan, + status: isDeviceUp(devFound, allDevices.value) ? 'online' : 'offline', + ip4Addresses: getIpv4Addresses(devFound, networkConfig.value), + ip6Addresses: getIpv6Addresses(devFound, networkConfig.value) + }) + } } } - return wanData + return wanData.sort(sortByProperty('iface')) }) onMounted(() => { listWans() getMwanReport() getMwanPolicies() + listDevices() + getNetworkConfig() }) async function listWans() { @@ -196,25 +243,60 @@ async function getMwanPolicies() { {{ error.getMwanPoliciesDetails }} -
+ + + + + + + + +
-