mirror of
https://github.com/sipeed/NanoKVM.git
synced 2026-11-10 01:49:00 -06:00
refactor: show all IP addresses in device info
This commit is contained in:
@@ -1,7 +1,14 @@
|
||||
package proto
|
||||
|
||||
type IP struct {
|
||||
Name string `json:"name"`
|
||||
Addr string `json:"addr"`
|
||||
Version string `json:"version"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type GetInfoRsp struct {
|
||||
Ip string `json:"ip"`
|
||||
IPs []IP `json:"ips"`
|
||||
Mdns string `json:"mdns"`
|
||||
Image string `json:"image"`
|
||||
Application string `json:"application"`
|
||||
|
||||
@@ -3,7 +3,6 @@ package vm
|
||||
import (
|
||||
"NanoKVM-Server/config"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
@@ -25,7 +24,7 @@ func (s *Service) GetInfo(c *gin.Context) {
|
||||
var rsp proto.Response
|
||||
|
||||
data := &proto.GetInfoRsp{
|
||||
Ip: getIp(),
|
||||
IPs: getIPs(),
|
||||
Mdns: getMdns(),
|
||||
Image: getImageVersion(),
|
||||
Application: getApplicationVersion(),
|
||||
@@ -36,20 +35,24 @@ func (s *Service) GetInfo(c *gin.Context) {
|
||||
log.Debug("get vm information success")
|
||||
}
|
||||
|
||||
func getIp() string {
|
||||
addressList, err := net.InterfaceAddrs()
|
||||
func getIPs() (ips []proto.IP) {
|
||||
interfaces, err := GetInterfaceInfos()
|
||||
if err != nil {
|
||||
return ""
|
||||
return
|
||||
}
|
||||
|
||||
for _, address := range addressList {
|
||||
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() && ipnet.IP.To4() != nil {
|
||||
ip := ipnet.IP.String()
|
||||
return ip
|
||||
for _, iface := range interfaces {
|
||||
if iface.IP.To4() != nil {
|
||||
ips = append(ips, proto.IP{
|
||||
Name: iface.Name,
|
||||
Addr: iface.IP.String(),
|
||||
Version: "IPv4",
|
||||
Type: iface.Type,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
return
|
||||
}
|
||||
|
||||
func getMdns() string {
|
||||
|
||||
107
server/service/vm/ip.go
Normal file
107
server/service/vm/ip.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
Wired = "Wired"
|
||||
Wireless = "Wireless"
|
||||
Other = "Other"
|
||||
)
|
||||
|
||||
type InterfaceInfo struct {
|
||||
Name string
|
||||
Type string
|
||||
IP net.IP
|
||||
}
|
||||
|
||||
func GetInterfaceInfos() ([]*InterfaceInfo, error) {
|
||||
var interfaceInfos []*InterfaceInfo
|
||||
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
log.Errorf("failed to get net interfaces: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, iface := range interfaces {
|
||||
info := getInterfaceInfo(iface)
|
||||
if info != nil {
|
||||
interfaceInfos = append(interfaceInfos, info)
|
||||
}
|
||||
}
|
||||
|
||||
if len(interfaceInfos) == 0 {
|
||||
return nil, fmt.Errorf("no valid IP address")
|
||||
}
|
||||
|
||||
return interfaceInfos, nil
|
||||
}
|
||||
|
||||
func getInterfaceInfo(iface net.Interface) *InterfaceInfo {
|
||||
if iface.Flags&net.FlagUp == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
interfaceType := getInterfaceType(iface)
|
||||
if interfaceType == Other {
|
||||
return nil
|
||||
}
|
||||
|
||||
interfaceIP := getInterfaceIP(iface)
|
||||
if interfaceIP == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &InterfaceInfo{
|
||||
Name: iface.Name,
|
||||
Type: interfaceType,
|
||||
IP: interfaceIP,
|
||||
}
|
||||
}
|
||||
|
||||
func getInterfaceType(iface net.Interface) string {
|
||||
if strings.HasPrefix(iface.Name, "eth") || strings.HasPrefix(iface.Name, "en") {
|
||||
return Wired
|
||||
}
|
||||
|
||||
if strings.HasPrefix(iface.Name, "wlan") || strings.HasPrefix(iface.Name, "wl") {
|
||||
return Wireless
|
||||
}
|
||||
|
||||
return Other
|
||||
}
|
||||
|
||||
func getInterfaceIP(iface net.Interface) net.IP {
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
log.Errorf("failed to get interface addresses: %s", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
var ip net.IP
|
||||
|
||||
switch v := addr.(type) {
|
||||
case *net.IPNet:
|
||||
ip = v.IP
|
||||
case *net.IPAddr:
|
||||
ip = v.IP
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
if ip == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
return ip
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,12 +1,19 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Tooltip } from 'antd';
|
||||
import { Tag, Tooltip } from 'antd';
|
||||
import { CircleHelpIcon } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import * as api from '@/api/vm.ts';
|
||||
|
||||
type IP = {
|
||||
name: string;
|
||||
addr: string;
|
||||
version: string;
|
||||
type: string;
|
||||
};
|
||||
|
||||
type Info = {
|
||||
ip: string;
|
||||
ips: IP[];
|
||||
mdns: string;
|
||||
image: string;
|
||||
application: string;
|
||||
@@ -34,11 +41,24 @@ export const Information = () => {
|
||||
<div className="pb-5 text-neutral-400">{t('settings.about.information')}</div>
|
||||
|
||||
<div className="flex w-full flex-col space-y-4">
|
||||
<div className="flex w-full items-center justify-between">
|
||||
{/* IP list */}
|
||||
<div className="flex w-full items-start justify-between">
|
||||
<span>{t('settings.about.ip')}</span>
|
||||
<span>{information ? information.ip : '-'}</span>
|
||||
{information?.ips && information.ips.length > 0 ? (
|
||||
<div className="flex flex-col space-y-1">
|
||||
{information.ips.map((ip) => (
|
||||
<div className="flex items-center space-x-1">
|
||||
<span>{ip.addr}</span>
|
||||
<Tag>{ip.type}</Tag>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<span>-</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* mDNS */}
|
||||
{!!information?.mdns && (
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<span>{t('settings.about.mdns')}</span>
|
||||
@@ -46,6 +66,7 @@ export const Information = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* image version */}
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<div className="flex items-center space-x-2">
|
||||
<span>{t('settings.about.image')}</span>
|
||||
@@ -61,6 +82,7 @@ export const Information = () => {
|
||||
<span>{information ? information.image : '-'}</span>
|
||||
</div>
|
||||
|
||||
{/* application version */}
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<div className="flex items-center space-x-2">
|
||||
<span>{t('settings.about.application')}</span>
|
||||
@@ -76,6 +98,7 @@ export const Information = () => {
|
||||
<span>{information ? information.application : '-'}</span>
|
||||
</div>
|
||||
|
||||
{/* device key */}
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<span>{t('settings.about.deviceKey')}</span>
|
||||
<span>{information ? information.deviceKey : '-'}</span>
|
||||
|
||||
Reference in New Issue
Block a user