From a66a7f3e97d4eabd58ebff740ea9e7d2f50b9c80 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal <355479+anjalshireesh@users.noreply.github.com> Date: Fri, 13 Oct 2023 04:03:31 +0530 Subject: [PATCH] Capture network device info in health report (#18213) --- CREDITS | 26 ++++++++++++++++++++++++++ cmd/admin-handlers.go | 17 ++++++++++++++++- cmd/notification.go | 25 +++++++++++++++++++++++++ cmd/peer-rest-client.go | 11 +++++++++++ cmd/peer-rest-common.go | 1 + cmd/peer-rest-server.go | 16 ++++++++++++++++ go.mod | 3 ++- go.sum | 6 ++++-- 8 files changed, 101 insertions(+), 4 deletions(-) diff --git a/CREDITS b/CREDITS index 4c8b4f8bc..e5f9f1d10 100644 --- a/CREDITS +++ b/CREDITS @@ -31077,3 +31077,29 @@ limitations under the License. ================================================================ +github.com/safchain/ethtool +https://github.com/safchain/ethtool +---------------------------------------------------------------- +MIT License + +Copyright (C) 2021-2022 Matt Layher + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +================================================================ diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index f1bb986b7..7901a8293 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -2075,7 +2075,7 @@ func fetchHealthInfo(healthCtx context.Context, objectAPI ObjectLayer, query *ur } getAndWritePartitions := func() { - if query.Get("sysdrivehw") == "true" { + if query.Get(string(madmin.HealthDataTypeSysDriveHw)) == "true" { localPartitions := madmin.GetPartitions(healthCtx, globalLocalNodeName) anonymizeAddr(&localPartitions) healthInfo.Sys.Partitions = append(healthInfo.Sys.Partitions, localPartitions) @@ -2089,6 +2089,20 @@ func fetchHealthInfo(healthCtx context.Context, objectAPI ObjectLayer, query *ur } } + getAndWriteNetInfo := func() { + if query.Get(string(madmin.HealthDataTypeSysNet)) == "true" { + localNetInfo := madmin.GetNetInfo(globalLocalNodeName, globalInternodeInterface) + healthInfo.Sys.NetInfo = append(healthInfo.Sys.NetInfo, localNetInfo) + + peerNetInfos := globalNotificationSys.GetNetInfo(healthCtx) + for _, n := range peerNetInfos { + anonymizeAddr(&n) + healthInfo.Sys.NetInfo = append(healthInfo.Sys.NetInfo, n) + } + partialWrite(healthInfo) + } + } + getAndWriteOSInfo := func() { if query.Get("sysosinfo") == "true" { localOSInfo := madmin.GetOSInfo(healthCtx, globalLocalNodeName) @@ -2310,6 +2324,7 @@ func fetchHealthInfo(healthCtx context.Context, objectAPI ObjectLayer, query *ur getAndWritePlatformInfo() getAndWriteCPUs() getAndWritePartitions() + getAndWriteNetInfo() getAndWriteOSInfo() getAndWriteMemInfo() getAndWriteProcInfo() diff --git a/cmd/notification.go b/cmd/notification.go index 87b63f006..515e5ecd4 100644 --- a/cmd/notification.go +++ b/cmd/notification.go @@ -701,6 +701,31 @@ func (sys *NotificationSys) GetCPUs(ctx context.Context) []madmin.CPUs { return reply } +// GetNetInfo - Network information +func (sys *NotificationSys) GetNetInfo(ctx context.Context) []madmin.NetInfo { + reply := make([]madmin.NetInfo, len(sys.peerClients)) + + g := errgroup.WithNErrs(len(sys.peerClients)) + for index, client := range sys.peerClients { + if client == nil { + continue + } + index := index + g.Go(func() error { + var err error + reply[index], err = sys.peerClients[index].GetNetInfo(ctx) + return err + }, index) + } + + for index, err := range g.Wait() { + if err != nil { + sys.addNodeErr(&reply[index], sys.peerClients[index], err) + } + } + return reply +} + // GetPartitions - Disk partition information func (sys *NotificationSys) GetPartitions(ctx context.Context) []madmin.Partitions { reply := make([]madmin.Partitions, len(sys.peerClients)) diff --git a/cmd/peer-rest-client.go b/cmd/peer-rest-client.go index e30c028f7..7744fb4aa 100644 --- a/cmd/peer-rest-client.go +++ b/cmd/peer-rest-client.go @@ -134,6 +134,17 @@ func (client *peerRESTClient) GetCPUs(ctx context.Context) (info madmin.CPUs, er return info, err } +// GetNetInfo - fetch network information for a remote node. +func (client *peerRESTClient) GetNetInfo(ctx context.Context) (info madmin.NetInfo, err error) { + respBody, err := client.callWithContext(ctx, peerRESTMethodNetHwInfo, nil, nil, -1) + if err != nil { + return + } + defer xhttp.DrainBody(respBody) + err = gob.NewDecoder(respBody).Decode(&info) + return info, err +} + // GetPartitions - fetch disk partition information for a remote node. func (client *peerRESTClient) GetPartitions(ctx context.Context) (info madmin.Partitions, err error) { respBody, err := client.callWithContext(ctx, peerRESTMethodDiskHwInfo, nil, nil, -1) diff --git a/cmd/peer-rest-common.go b/cmd/peer-rest-common.go index 622384f29..80fe49580 100644 --- a/cmd/peer-rest-common.go +++ b/cmd/peer-rest-common.go @@ -31,6 +31,7 @@ const ( peerRESTMethodLocalStorageInfo = "/localstorageinfo" peerRESTMethodCPUInfo = "/cpuinfo" peerRESTMethodDiskHwInfo = "/diskhwinfo" + peerRESTMethodNetHwInfo = "/nethwinfo" peerRESTMethodOsInfo = "/osinfo" peerRESTMethodMemInfo = "/meminfo" peerRESTMethodProcInfo = "/procinfo" diff --git a/cmd/peer-rest-server.go b/cmd/peer-rest-server.go index 194a9c5af..2b047374b 100644 --- a/cmd/peer-rest-server.go +++ b/cmd/peer-rest-server.go @@ -375,6 +375,21 @@ func (s *peerRESTServer) GetCPUsHandler(w http.ResponseWriter, r *http.Request) logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) } +// GetNetInfoHandler - returns network information. +func (s *peerRESTServer) GetNetInfoHandler(w http.ResponseWriter, r *http.Request) { + if !s.IsValid(w, r) { + s.writeErrorResponse(w, errors.New("Invalid request")) + return + } + + ctx, cancel := context.WithCancel(r.Context()) + defer cancel() + + info := madmin.GetNetInfo(r.Host, globalInternodeInterface) + + logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) +} + // GetPartitionsHandler - returns disk partition information. func (s *peerRESTServer) GetPartitionsHandler(w http.ResponseWriter, r *http.Request) { if !s.IsValid(w, r) { @@ -1460,6 +1475,7 @@ func registerPeerRESTHandlers(router *mux.Router) { subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodSysConfig).HandlerFunc(h(server.GetSysConfigHandler)) subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodOsInfo).HandlerFunc(h(server.GetOSInfoHandler)) subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodDiskHwInfo).HandlerFunc(h(server.GetPartitionsHandler)) + subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodNetHwInfo).HandlerFunc(h(server.GetNetInfoHandler)) subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodCPUInfo).HandlerFunc(h(server.GetCPUsHandler)) subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodGetAllBucketStats).HandlerFunc(h(server.GetAllBucketStatsHandler)) subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodDeleteBucketMetadata).HandlerFunc(h(server.DeleteBucketMetadataHandler)).Queries(restQueries(peerRESTBucket)...) diff --git a/go.mod b/go.mod index 98147f3a3..e01b9dfc7 100644 --- a/go.mod +++ b/go.mod @@ -49,7 +49,7 @@ require ( github.com/minio/dperf v0.5.0 github.com/minio/highwayhash v1.0.2 github.com/minio/kes-go v0.2.0 - github.com/minio/madmin-go/v3 v3.0.21 + github.com/minio/madmin-go/v3 v3.0.24 github.com/minio/minio-go/v7 v7.0.64-0.20230920204636-e783c9ba11b3 github.com/minio/mux v1.9.0 github.com/minio/pkg/v2 v2.0.2 @@ -210,6 +210,7 @@ require ( github.com/rivo/uniseg v0.4.4 // indirect github.com/rjeczalik/notify v0.9.3 // indirect github.com/rs/xid v1.5.0 // indirect + github.com/safchain/ethtool v0.3.0 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/tidwall/match v1.1.1 // indirect diff --git a/go.sum b/go.sum index 72a3d346e..ca1affe41 100644 --- a/go.sum +++ b/go.sum @@ -474,8 +474,8 @@ github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/minio/kes-go v0.2.0 h1:HA33arq9s3MErbsj3PAXFVfFo4U4yw7lTKQ5kWFrpCA= github.com/minio/kes-go v0.2.0/go.mod h1:VorHLaIYis9/MxAHAtXN4d8PUMNKhIxTIlvFt0hBOEo= -github.com/minio/madmin-go/v3 v3.0.21 h1:54LroTtjkn60nvDMBHmCEMGcFQ3k3Yel74RaEu9n2cY= -github.com/minio/madmin-go/v3 v3.0.21/go.mod h1:B2EgtEGrfWx+AkXv+OAcS6IHwoIJcd1p75QfDPSPd6Q= +github.com/minio/madmin-go/v3 v3.0.24 h1:FsIM3QiJGD9suobI3ei4NZxgOKg3kO7dxztZ+qW6AHs= +github.com/minio/madmin-go/v3 v3.0.24/go.mod h1:4QN2NftLSV7MdlT50dkrenOMmNVHluxTvlqJou3hte8= github.com/minio/mc v0.0.0-20230922050746-ae05d451739b h1:oZ5XAtyKMFbMbxqShGA51/YD/YaW+B2BiBQI7rN2uFc= github.com/minio/mc v0.0.0-20230922050746-ae05d451739b/go.mod h1:+4OzbgOsVsKvdmLLjN47DKKyHiLJuT05m5qF9fAQWe4= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= @@ -639,6 +639,8 @@ github.com/rs/cors v1.10.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/safchain/ethtool v0.3.0 h1:gimQJpsI6sc1yIqP/y8GYgiXn/NjgvpM0RNoWLVVmP0= +github.com/safchain/ethtool v0.3.0/go.mod h1:SA9BwrgyAqNo7M+uaL6IYbxpm5wk3L7Mm6ocLW+CJUs= github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg= github.com/secure-io/sio-go v0.3.1 h1:dNvY9awjabXTYGsTF1PiCySl9Ltofk9GA3VdWlo7rRc= github.com/secure-io/sio-go v0.3.1/go.mod h1:+xbkjDzPjwh4Axd07pRKSNriS9SCiYksWnZqdnfpQxs=