Skip to content

Commit

Permalink
fix(monitoring): show wan public ip address (#438)
Browse files Browse the repository at this point in the history
  • Loading branch information
andre8244 authored Nov 20, 2024
1 parent 434de43 commit cede102
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 22 deletions.
84 changes: 67 additions & 17 deletions src/components/standalone/monitoring/ConnectivityMonitor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,21 @@ import {
NeInlineNotification,
sortByProperty
} from '@nethesis/vue-components'
import { computed, onMounted, ref } from 'vue'
import { computed, onMounted, ref, watchEffect } from 'vue'
import { useI18n } from 'vue-i18n'
import WanEventsCard from './connectivity/WanEventsCard.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 {
getIpv4Addresses,
getIpv6Addresses,
getName,
isDeviceUp,
isIpv6Enabled,
type DeviceOrIface
} from '@/lib/standalone/network'
import { useUciNetworkConfig } from '@/composables/useUciNetworkConfig'
import InterfaceTrafficCard from './connectivity/InterfaceTrafficCard.vue'
import { useLatencyAndQualityReport } from '@/composables/useLatencyAndQualityReport'
Expand All @@ -32,8 +39,7 @@ export type Wan = {
iface: string
device: string
status?: string
ip4Addresses?: string[]
ip6Addresses?: string[]
ipAddresses?: string[]
}

export type WanEvent = {
Expand All @@ -56,6 +62,7 @@ const router = useRouter()
const wans = ref<Wan[]>([])
const mwanEvents = ref<Record<string, any[]>>({})
const mwanPolicies = ref<Policy[]>([])
const wanConnections = ref<Wan[]>([])

const {
latencyAndQualityCharts,
Expand All @@ -76,7 +83,9 @@ let error = ref({
getMwanReport: '',
getMwanReportDetails: '',
getMwanPolicies: '',
getMwanPoliciesDetails: ''
getMwanPoliciesDetails: '',
getPublicIpAddresses: '',
getPublicIpAddressesDetails: ''
})

const loadingData = computed(() => {
Expand All @@ -89,7 +98,7 @@ const loadingData = computed(() => {
)
})

const wanConnections = computed(() => {
watchEffect(async () => {
const wanData: Wan[] = []

for (const wan of wans.value) {
Expand All @@ -112,14 +121,17 @@ const wanConnections = computed(() => {
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
if (devFound) {
const publicIpAddresses = await retrievePublicIpAddresses(devFound)

wanData.push({
...wan,
status: policyMember.status,
ipAddresses: publicIpAddresses
})
statusFound = true
break
}
}
}
}
Expand All @@ -130,16 +142,17 @@ const wanConnections = computed(() => {
const devFound = allDevices.value.find((dev) => getName(dev) === wan.device)

if (devFound) {
const publicIpAddresses = await retrievePublicIpAddresses(devFound)

wanData.push({
...wan,
status: isDeviceUp(devFound, allDevices.value) ? 'online' : 'offline',
ip4Addresses: getIpv4Addresses(devFound, networkConfig.value),
ip6Addresses: getIpv6Addresses(devFound, networkConfig.value)
ipAddresses: publicIpAddresses
})
}
}
}
return wanData.sort(sortByProperty('iface'))
wanConnections.value = wanData.sort(sortByProperty('iface'))
})

onMounted(() => {
Expand All @@ -150,6 +163,27 @@ onMounted(() => {
getNetworkConfig()
})

async function retrievePublicIpAddresses(device: DeviceOrIface) {
let ipAddresses = []
let publicIpAddresses: string[] = []

if (isIpv6Enabled(device)) {
ipAddresses = getIpv6Addresses(device, networkConfig.value).concat(
getIpv4Addresses(device, networkConfig.value)
)
} else {
ipAddresses = getIpv4Addresses(device, networkConfig.value)
}
const ipAddr = ipAddresses[0].split('/')[0]
publicIpAddresses = await getPublicIpAddresses(ipAddr)

if (publicIpAddresses.length == 0 || publicIpAddresses[0] == '') {
// cannot retrieve public IP address, using interface IP address as fallback
publicIpAddresses = ipAddresses
}
return publicIpAddresses
}

async function listWans() {
loading.value.listWans = true
error.value.listWans = ''
Expand Down Expand Up @@ -197,6 +231,22 @@ async function getMwanReport() {
}
}

async function getPublicIpAddresses(privateIpAddr: string) {
error.value.getPublicIpAddresses = ''
error.value.getPublicIpAddressesDetails = ''

try {
const res = await ubusCall('ns.report', 'get-public-ip-addresses', {
ip_address: privateIpAddr
})
return res.data.public_ip_addresses
} catch (err: any) {
console.error(err)
error.value.getPublicIpAddresses = t(getAxiosErrorMessage(err))
error.value.getPublicIpAddressesDetails = err.toString()
}
}

async function getMwanPolicies() {
loading.value.getMwanPolicies = true
error.value.getMwanPolicies = ''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ function getQosRule(item: Wan) {
<NeTableHeadCell>{{ t('standalone.real_time_monitor.interface') }}</NeTableHeadCell>
<NeTableHeadCell>{{ t('standalone.real_time_monitor.device') }}</NeTableHeadCell>
<NeTableHeadCell>{{ t('common.status') }}</NeTableHeadCell>
<NeTableHeadCell>{{ t('common.ip_address') }}</NeTableHeadCell>
<NeTableHeadCell>{{ t('standalone.real_time_monitor.public_ip_address') }}</NeTableHeadCell>
<NeTableHeadCell>{{ t('standalone.qos.title_short') }}</NeTableHeadCell>
</NeTableHead>
<NeTableBody>
Expand Down Expand Up @@ -120,9 +120,9 @@ function getQosRule(item: Wan) {
}}
</div>
</NeTableCell>
<NeTableCell :data-label="t('common.ip_address')">
<span v-if="item.ip4Addresses.length || item.ip6Addresses.length">
{{ (item.ip4Addresses || []).concat(item.ip6Addresses || []).join(', ') }}
<NeTableCell :data-label="t('standalone.real_time_monitor.public_ip_address')">
<span v-if="item.ipAddresses.length">
{{ item.ipAddresses.join(', ') }}
</span>
<span v-else>-</span>
</NeTableCell>
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -1962,7 +1962,8 @@
"ping_host_latency": "Latency to {pingHost}",
"ping_host_packet_delivery_rate": "Packet delivery rate to {pingHost}",
"latency_and_packet_delivery_rate": "Latency and packet delivery rate",
"no_hosts_configured_for_monitoring": "No hosts configured for monitoring"
"no_hosts_configured_for_monitoring": "No hosts configured for monitoring",
"public_ip_address": "Public IP address"
},
"ping_latency_monitor": {
"title": "Ping latency monitor",
Expand Down
5 changes: 5 additions & 0 deletions src/lib/standalone/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -484,3 +484,8 @@ export function getVlanParent(bridgeDevice: DeviceOrIface, allDevices: DeviceOrI
const deviceFound = allDevices.find((dev) => dev.name === parentDevice)
return deviceFound
}

export function isIpv6Enabled(device: DeviceOrIface) {
const iface = getInterface(device)
return device.ipv6 === '1' || (iface.proto === 'pppoe' && device.ipv6 === 'auto')
}

0 comments on commit cede102

Please sign in to comment.