github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/libnetwork/networkdb/networkdbdiagnostic.go (about) 1 package networkdb 2 3 import ( 4 "encoding/base64" 5 "fmt" 6 "net/http" 7 "strings" 8 9 "github.com/docker/docker/libnetwork/diagnostic" 10 "github.com/docker/docker/libnetwork/internal/caller" 11 "github.com/sirupsen/logrus" 12 ) 13 14 const ( 15 missingParameter = "missing parameter" 16 dbNotAvailable = "database not available" 17 ) 18 19 // NetDbPaths2Func TODO 20 var NetDbPaths2Func = map[string]diagnostic.HTTPHandlerFunc{ 21 "/join": dbJoin, 22 "/networkpeers": dbPeers, 23 "/clusterpeers": dbClusterPeers, 24 "/joinnetwork": dbJoinNetwork, 25 "/leavenetwork": dbLeaveNetwork, 26 "/createentry": dbCreateEntry, 27 "/updateentry": dbUpdateEntry, 28 "/deleteentry": dbDeleteEntry, 29 "/getentry": dbGetEntry, 30 "/gettable": dbGetTable, 31 "/networkstats": dbNetworkStats, 32 } 33 34 func dbJoin(ctx interface{}, w http.ResponseWriter, r *http.Request) { 35 r.ParseForm() 36 diagnostic.DebugHTTPForm(r) 37 _, json := diagnostic.ParseHTTPFormOptions(r) 38 39 // audit logs 40 log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()}) 41 log.Info("join cluster") 42 43 if len(r.Form["members"]) < 1 { 44 rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?members=ip1,ip2,...", r.URL.Path)) 45 log.Error("join cluster failed, wrong input") 46 diagnostic.HTTPReply(w, rsp, json) 47 return 48 } 49 50 nDB, ok := ctx.(*NetworkDB) 51 if ok { 52 err := nDB.Join(strings.Split(r.Form["members"][0], ",")) 53 if err != nil { 54 rsp := diagnostic.FailCommand(fmt.Errorf("%s error in the DB join %s", r.URL.Path, err)) 55 log.WithError(err).Error("join cluster failed") 56 diagnostic.HTTPReply(w, rsp, json) 57 return 58 } 59 60 log.Info("join cluster done") 61 diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json) 62 return 63 } 64 diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf(dbNotAvailable)), json) 65 } 66 67 func dbPeers(ctx interface{}, w http.ResponseWriter, r *http.Request) { 68 r.ParseForm() 69 diagnostic.DebugHTTPForm(r) 70 _, json := diagnostic.ParseHTTPFormOptions(r) 71 72 // audit logs 73 log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()}) 74 log.Info("network peers") 75 76 if len(r.Form["nid"]) < 1 { 77 rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=test", r.URL.Path)) 78 log.Error("network peers failed, wrong input") 79 diagnostic.HTTPReply(w, rsp, json) 80 return 81 } 82 83 nDB, ok := ctx.(*NetworkDB) 84 if ok { 85 peers := nDB.Peers(r.Form["nid"][0]) 86 rsp := &diagnostic.TableObj{Length: len(peers)} 87 for i, peerInfo := range peers { 88 if peerInfo.IP == "unknown" { 89 rsp.Elements = append(rsp.Elements, &diagnostic.PeerEntryObj{Index: i, Name: "orphan-" + peerInfo.Name, IP: peerInfo.IP}) 90 } else { 91 rsp.Elements = append(rsp.Elements, &diagnostic.PeerEntryObj{Index: i, Name: peerInfo.Name, IP: peerInfo.IP}) 92 } 93 } 94 log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("network peers done") 95 diagnostic.HTTPReply(w, diagnostic.CommandSucceed(rsp), json) 96 return 97 } 98 diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf(dbNotAvailable)), json) 99 } 100 101 func dbClusterPeers(ctx interface{}, w http.ResponseWriter, r *http.Request) { 102 r.ParseForm() 103 diagnostic.DebugHTTPForm(r) 104 _, json := diagnostic.ParseHTTPFormOptions(r) 105 106 // audit logs 107 log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()}) 108 log.Info("cluster peers") 109 110 nDB, ok := ctx.(*NetworkDB) 111 if ok { 112 peers := nDB.ClusterPeers() 113 rsp := &diagnostic.TableObj{Length: len(peers)} 114 for i, peerInfo := range peers { 115 rsp.Elements = append(rsp.Elements, &diagnostic.PeerEntryObj{Index: i, Name: peerInfo.Name, IP: peerInfo.IP}) 116 } 117 log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("cluster peers done") 118 diagnostic.HTTPReply(w, diagnostic.CommandSucceed(rsp), json) 119 return 120 } 121 diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf(dbNotAvailable)), json) 122 } 123 124 func dbCreateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) { 125 r.ParseForm() 126 diagnostic.DebugHTTPForm(r) 127 unsafe, json := diagnostic.ParseHTTPFormOptions(r) 128 129 // audit logs 130 log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()}) 131 log.Info("create entry") 132 133 if len(r.Form["tname"]) < 1 || 134 len(r.Form["nid"]) < 1 || 135 len(r.Form["key"]) < 1 || 136 len(r.Form["value"]) < 1 { 137 rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k&value=v", r.URL.Path)) 138 log.Error("create entry failed, wrong input") 139 diagnostic.HTTPReply(w, rsp, json) 140 return 141 } 142 143 tname := r.Form["tname"][0] 144 nid := r.Form["nid"][0] 145 key := r.Form["key"][0] 146 value := r.Form["value"][0] 147 decodedValue := []byte(value) 148 if !unsafe { 149 var err error 150 decodedValue, err = base64.StdEncoding.DecodeString(value) 151 if err != nil { 152 log.WithError(err).Error("create entry failed") 153 diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json) 154 return 155 } 156 } 157 158 nDB, ok := ctx.(*NetworkDB) 159 if ok { 160 if err := nDB.CreateEntry(tname, nid, key, decodedValue); err != nil { 161 rsp := diagnostic.FailCommand(err) 162 diagnostic.HTTPReply(w, rsp, json) 163 log.WithError(err).Error("create entry failed") 164 return 165 } 166 log.Info("create entry done") 167 diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json) 168 return 169 } 170 diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf(dbNotAvailable)), json) 171 } 172 173 func dbUpdateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) { 174 r.ParseForm() 175 diagnostic.DebugHTTPForm(r) 176 unsafe, json := diagnostic.ParseHTTPFormOptions(r) 177 178 // audit logs 179 log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()}) 180 log.Info("update entry") 181 182 if len(r.Form["tname"]) < 1 || 183 len(r.Form["nid"]) < 1 || 184 len(r.Form["key"]) < 1 || 185 len(r.Form["value"]) < 1 { 186 rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k&value=v", r.URL.Path)) 187 log.Error("update entry failed, wrong input") 188 diagnostic.HTTPReply(w, rsp, json) 189 return 190 } 191 192 tname := r.Form["tname"][0] 193 nid := r.Form["nid"][0] 194 key := r.Form["key"][0] 195 value := r.Form["value"][0] 196 decodedValue := []byte(value) 197 if !unsafe { 198 var err error 199 decodedValue, err = base64.StdEncoding.DecodeString(value) 200 if err != nil { 201 log.WithError(err).Error("update entry failed") 202 diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json) 203 return 204 } 205 } 206 207 nDB, ok := ctx.(*NetworkDB) 208 if ok { 209 if err := nDB.UpdateEntry(tname, nid, key, decodedValue); err != nil { 210 log.WithError(err).Error("update entry failed") 211 diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json) 212 return 213 } 214 log.Info("update entry done") 215 diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json) 216 return 217 } 218 diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf(dbNotAvailable)), json) 219 } 220 221 func dbDeleteEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) { 222 r.ParseForm() 223 diagnostic.DebugHTTPForm(r) 224 _, json := diagnostic.ParseHTTPFormOptions(r) 225 226 // audit logs 227 log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()}) 228 log.Info("delete entry") 229 230 if len(r.Form["tname"]) < 1 || 231 len(r.Form["nid"]) < 1 || 232 len(r.Form["key"]) < 1 { 233 rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k", r.URL.Path)) 234 log.Error("delete entry failed, wrong input") 235 diagnostic.HTTPReply(w, rsp, json) 236 return 237 } 238 239 tname := r.Form["tname"][0] 240 nid := r.Form["nid"][0] 241 key := r.Form["key"][0] 242 243 nDB, ok := ctx.(*NetworkDB) 244 if ok { 245 err := nDB.DeleteEntry(tname, nid, key) 246 if err != nil { 247 log.WithError(err).Error("delete entry failed") 248 diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json) 249 return 250 } 251 log.Info("delete entry done") 252 diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json) 253 return 254 } 255 diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf(dbNotAvailable)), json) 256 } 257 258 func dbGetEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) { 259 r.ParseForm() 260 diagnostic.DebugHTTPForm(r) 261 unsafe, json := diagnostic.ParseHTTPFormOptions(r) 262 263 // audit logs 264 log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()}) 265 log.Info("get entry") 266 267 if len(r.Form["tname"]) < 1 || 268 len(r.Form["nid"]) < 1 || 269 len(r.Form["key"]) < 1 { 270 rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k", r.URL.Path)) 271 log.Error("get entry failed, wrong input") 272 diagnostic.HTTPReply(w, rsp, json) 273 return 274 } 275 276 tname := r.Form["tname"][0] 277 nid := r.Form["nid"][0] 278 key := r.Form["key"][0] 279 280 nDB, ok := ctx.(*NetworkDB) 281 if ok { 282 value, err := nDB.GetEntry(tname, nid, key) 283 if err != nil { 284 log.WithError(err).Error("get entry failed") 285 diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json) 286 return 287 } 288 289 var encodedValue string 290 if unsafe { 291 encodedValue = string(value) 292 } else { 293 encodedValue = base64.StdEncoding.EncodeToString(value) 294 } 295 296 rsp := &diagnostic.TableEntryObj{Key: key, Value: encodedValue} 297 log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("get entry done") 298 diagnostic.HTTPReply(w, diagnostic.CommandSucceed(rsp), json) 299 return 300 } 301 diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf(dbNotAvailable)), json) 302 } 303 304 func dbJoinNetwork(ctx interface{}, w http.ResponseWriter, r *http.Request) { 305 r.ParseForm() 306 diagnostic.DebugHTTPForm(r) 307 _, json := diagnostic.ParseHTTPFormOptions(r) 308 309 // audit logs 310 log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()}) 311 log.Info("join network") 312 313 if len(r.Form["nid"]) < 1 { 314 rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=network_id", r.URL.Path)) 315 log.Error("join network failed, wrong input") 316 diagnostic.HTTPReply(w, rsp, json) 317 return 318 } 319 320 nid := r.Form["nid"][0] 321 322 nDB, ok := ctx.(*NetworkDB) 323 if ok { 324 if err := nDB.JoinNetwork(nid); err != nil { 325 log.WithError(err).Error("join network failed") 326 diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json) 327 return 328 } 329 log.Info("join network done") 330 diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json) 331 return 332 } 333 diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf(dbNotAvailable)), json) 334 } 335 336 func dbLeaveNetwork(ctx interface{}, w http.ResponseWriter, r *http.Request) { 337 r.ParseForm() 338 diagnostic.DebugHTTPForm(r) 339 _, json := diagnostic.ParseHTTPFormOptions(r) 340 341 // audit logs 342 log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()}) 343 log.Info("leave network") 344 345 if len(r.Form["nid"]) < 1 { 346 rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=network_id", r.URL.Path)) 347 log.Error("leave network failed, wrong input") 348 diagnostic.HTTPReply(w, rsp, json) 349 return 350 } 351 352 nid := r.Form["nid"][0] 353 354 nDB, ok := ctx.(*NetworkDB) 355 if ok { 356 if err := nDB.LeaveNetwork(nid); err != nil { 357 log.WithError(err).Error("leave network failed") 358 diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json) 359 return 360 } 361 log.Info("leave network done") 362 diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json) 363 return 364 } 365 diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf(dbNotAvailable)), json) 366 } 367 368 func dbGetTable(ctx interface{}, w http.ResponseWriter, r *http.Request) { 369 r.ParseForm() 370 diagnostic.DebugHTTPForm(r) 371 unsafe, json := diagnostic.ParseHTTPFormOptions(r) 372 373 // audit logs 374 log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()}) 375 log.Info("get table") 376 377 if len(r.Form["tname"]) < 1 || 378 len(r.Form["nid"]) < 1 { 379 rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id", r.URL.Path)) 380 log.Error("get table failed, wrong input") 381 diagnostic.HTTPReply(w, rsp, json) 382 return 383 } 384 385 tname := r.Form["tname"][0] 386 nid := r.Form["nid"][0] 387 388 nDB, ok := ctx.(*NetworkDB) 389 if ok { 390 table := nDB.GetTableByNetwork(tname, nid) 391 rsp := &diagnostic.TableObj{Length: len(table)} 392 var i = 0 393 for k, v := range table { 394 var encodedValue string 395 if unsafe { 396 encodedValue = string(v.Value) 397 } else { 398 encodedValue = base64.StdEncoding.EncodeToString(v.Value) 399 } 400 rsp.Elements = append(rsp.Elements, 401 &diagnostic.TableEntryObj{ 402 Index: i, 403 Key: k, 404 Value: encodedValue, 405 Owner: v.owner, 406 }) 407 i++ 408 } 409 log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("get table done") 410 diagnostic.HTTPReply(w, diagnostic.CommandSucceed(rsp), json) 411 return 412 } 413 diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf(dbNotAvailable)), json) 414 } 415 416 func dbNetworkStats(ctx interface{}, w http.ResponseWriter, r *http.Request) { 417 r.ParseForm() 418 diagnostic.DebugHTTPForm(r) 419 _, json := diagnostic.ParseHTTPFormOptions(r) 420 421 // audit logs 422 log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()}) 423 log.Info("network stats") 424 425 if len(r.Form["nid"]) < 1 { 426 rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=test", r.URL.Path)) 427 log.Error("network stats failed, wrong input") 428 diagnostic.HTTPReply(w, rsp, json) 429 return 430 } 431 432 nDB, ok := ctx.(*NetworkDB) 433 if ok { 434 nDB.RLock() 435 networks := nDB.networks[nDB.config.NodeID] 436 network, ok := networks[r.Form["nid"][0]] 437 438 entries := -1 439 qLen := -1 440 if ok { 441 entries = network.entriesNumber 442 qLen = network.tableBroadcasts.NumQueued() 443 } 444 nDB.RUnlock() 445 446 rsp := diagnostic.CommandSucceed(&diagnostic.NetworkStatsResult{Entries: entries, QueueLen: qLen}) 447 log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("network stats done") 448 diagnostic.HTTPReply(w, rsp, json) 449 return 450 } 451 diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf(dbNotAvailable)), json) 452 }