mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
And generate the ServiceInfo struct from the Swagger spec. Signed-off-by: Cory Snider <csnider@mirantis.com>
456 lines
13 KiB
Go
456 lines
13 KiB
Go
package networkdb
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/containerd/log"
|
|
"github.com/moby/moby/v2/daemon/libnetwork/diagnostic"
|
|
"github.com/moby/moby/v2/daemon/libnetwork/internal/caller"
|
|
)
|
|
|
|
const (
|
|
missingParameter = "missing parameter"
|
|
dbNotAvailable = "database not available"
|
|
)
|
|
|
|
type Mux interface {
|
|
HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request))
|
|
}
|
|
|
|
func (nDB *NetworkDB) RegisterDiagnosticHandlers(m Mux) {
|
|
m.HandleFunc("/join", nDB.dbJoin)
|
|
m.HandleFunc("/networkpeers", nDB.dbPeers)
|
|
m.HandleFunc("/clusterpeers", nDB.dbClusterPeers)
|
|
m.HandleFunc("/joinnetwork", nDB.dbJoinNetwork)
|
|
m.HandleFunc("/leavenetwork", nDB.dbLeaveNetwork)
|
|
m.HandleFunc("/createentry", nDB.dbCreateEntry)
|
|
m.HandleFunc("/updateentry", nDB.dbUpdateEntry)
|
|
m.HandleFunc("/deleteentry", nDB.dbDeleteEntry)
|
|
m.HandleFunc("/getentry", nDB.dbGetEntry)
|
|
m.HandleFunc("/gettable", nDB.dbGetTable)
|
|
m.HandleFunc("/networkstats", nDB.dbNetworkStats)
|
|
}
|
|
|
|
func (nDB *NetworkDB) dbJoin(w http.ResponseWriter, r *http.Request) {
|
|
_ = r.ParseForm()
|
|
diagnostic.DebugHTTPForm(r)
|
|
_, json := diagnostic.ParseHTTPFormOptions(r)
|
|
|
|
// audit logs
|
|
logger := log.G(context.TODO()).WithFields(log.Fields{
|
|
"component": "diagnostic",
|
|
"remoteIP": r.RemoteAddr,
|
|
"method": caller.Name(0),
|
|
"url": r.URL.String(),
|
|
})
|
|
logger.Info("join cluster")
|
|
|
|
if len(r.Form["members"]) < 1 {
|
|
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?members=ip1,ip2,...", r.URL.Path))
|
|
logger.Error("join cluster failed, wrong input")
|
|
diagnostic.HTTPReply(w, rsp, json)
|
|
return
|
|
}
|
|
|
|
err := nDB.Join(strings.Split(r.Form["members"][0], ","))
|
|
if err != nil {
|
|
rsp := diagnostic.FailCommand(fmt.Errorf("%s error in the DB join %s", r.URL.Path, err))
|
|
logger.WithError(err).Error("join cluster failed")
|
|
diagnostic.HTTPReply(w, rsp, json)
|
|
return
|
|
}
|
|
|
|
logger.Info("join cluster done")
|
|
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json)
|
|
}
|
|
|
|
func (nDB *NetworkDB) dbPeers(w http.ResponseWriter, r *http.Request) {
|
|
_ = r.ParseForm()
|
|
diagnostic.DebugHTTPForm(r)
|
|
_, json := diagnostic.ParseHTTPFormOptions(r)
|
|
|
|
// audit logs
|
|
logger := log.G(context.TODO()).WithFields(log.Fields{
|
|
"component": "diagnostic",
|
|
"remoteIP": r.RemoteAddr,
|
|
"method": caller.Name(0),
|
|
"url": r.URL.String(),
|
|
})
|
|
logger.Info("network peers")
|
|
|
|
if len(r.Form["nid"]) < 1 {
|
|
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=test", r.URL.Path))
|
|
logger.Error("network peers failed, wrong input")
|
|
diagnostic.HTTPReply(w, rsp, json)
|
|
return
|
|
}
|
|
|
|
peers := nDB.Peers(r.Form["nid"][0])
|
|
rsp := &diagnostic.TableObj{Length: len(peers)}
|
|
for i, peerInfo := range peers {
|
|
if !peerInfo.IP.IsValid() {
|
|
rsp.Elements = append(rsp.Elements, &diagnostic.PeerEntryObj{Index: i, Name: "orphan-" + peerInfo.Name, IP: peerInfo.IP})
|
|
} else {
|
|
rsp.Elements = append(rsp.Elements, &diagnostic.PeerEntryObj{Index: i, Name: peerInfo.Name, IP: peerInfo.IP})
|
|
}
|
|
}
|
|
logger.WithField("response", fmt.Sprintf("%+v", rsp)).Info("network peers done")
|
|
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(rsp), json)
|
|
}
|
|
|
|
func (nDB *NetworkDB) dbClusterPeers(w http.ResponseWriter, r *http.Request) {
|
|
_ = r.ParseForm()
|
|
diagnostic.DebugHTTPForm(r)
|
|
_, json := diagnostic.ParseHTTPFormOptions(r)
|
|
|
|
// audit logs
|
|
logger := log.G(context.TODO()).WithFields(log.Fields{
|
|
"component": "diagnostic",
|
|
"remoteIP": r.RemoteAddr,
|
|
"method": caller.Name(0),
|
|
"url": r.URL.String(),
|
|
})
|
|
logger.Info("cluster peers")
|
|
|
|
peers := nDB.ClusterPeers()
|
|
rsp := &diagnostic.TableObj{Length: len(peers)}
|
|
for i, peerInfo := range peers {
|
|
rsp.Elements = append(rsp.Elements, &diagnostic.PeerEntryObj{Index: i, Name: peerInfo.Name, IP: peerInfo.IP})
|
|
}
|
|
logger.WithField("response", fmt.Sprintf("%+v", rsp)).Info("cluster peers done")
|
|
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(rsp), json)
|
|
}
|
|
|
|
func (nDB *NetworkDB) dbCreateEntry(w http.ResponseWriter, r *http.Request) {
|
|
_ = r.ParseForm()
|
|
diagnostic.DebugHTTPForm(r)
|
|
unsafe, json := diagnostic.ParseHTTPFormOptions(r)
|
|
|
|
// audit logs
|
|
logger := log.G(context.TODO()).WithFields(log.Fields{
|
|
"component": "diagnostic",
|
|
"remoteIP": r.RemoteAddr,
|
|
"method": caller.Name(0),
|
|
"url": r.URL.String(),
|
|
})
|
|
logger.Info("create entry")
|
|
|
|
if len(r.Form["tname"]) < 1 ||
|
|
len(r.Form["nid"]) < 1 ||
|
|
len(r.Form["key"]) < 1 ||
|
|
len(r.Form["value"]) < 1 {
|
|
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k&value=v", r.URL.Path))
|
|
logger.Error("create entry failed, wrong input")
|
|
diagnostic.HTTPReply(w, rsp, json)
|
|
return
|
|
}
|
|
|
|
tname := r.Form["tname"][0]
|
|
nid := r.Form["nid"][0]
|
|
key := r.Form["key"][0]
|
|
value := r.Form["value"][0]
|
|
decodedValue := []byte(value)
|
|
if !unsafe {
|
|
var err error
|
|
decodedValue, err = base64.StdEncoding.DecodeString(value)
|
|
if err != nil {
|
|
logger.WithError(err).Error("create entry failed")
|
|
diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json)
|
|
return
|
|
}
|
|
}
|
|
|
|
if err := nDB.CreateEntry(tname, nid, key, decodedValue); err != nil {
|
|
rsp := diagnostic.FailCommand(err)
|
|
diagnostic.HTTPReply(w, rsp, json)
|
|
logger.WithError(err).Error("create entry failed")
|
|
return
|
|
}
|
|
logger.Info("create entry done")
|
|
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json)
|
|
}
|
|
|
|
func (nDB *NetworkDB) dbUpdateEntry(w http.ResponseWriter, r *http.Request) {
|
|
_ = r.ParseForm()
|
|
diagnostic.DebugHTTPForm(r)
|
|
unsafe, json := diagnostic.ParseHTTPFormOptions(r)
|
|
|
|
// audit logs
|
|
logger := log.G(context.TODO()).WithFields(log.Fields{
|
|
"component": "diagnostic",
|
|
"remoteIP": r.RemoteAddr,
|
|
"method": caller.Name(0),
|
|
"url": r.URL.String(),
|
|
})
|
|
logger.Info("update entry")
|
|
|
|
if len(r.Form["tname"]) < 1 ||
|
|
len(r.Form["nid"]) < 1 ||
|
|
len(r.Form["key"]) < 1 ||
|
|
len(r.Form["value"]) < 1 {
|
|
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k&value=v", r.URL.Path))
|
|
logger.Error("update entry failed, wrong input")
|
|
diagnostic.HTTPReply(w, rsp, json)
|
|
return
|
|
}
|
|
|
|
tname := r.Form["tname"][0]
|
|
nid := r.Form["nid"][0]
|
|
key := r.Form["key"][0]
|
|
value := r.Form["value"][0]
|
|
decodedValue := []byte(value)
|
|
if !unsafe {
|
|
var err error
|
|
decodedValue, err = base64.StdEncoding.DecodeString(value)
|
|
if err != nil {
|
|
logger.WithError(err).Error("update entry failed")
|
|
diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json)
|
|
return
|
|
}
|
|
}
|
|
|
|
if err := nDB.UpdateEntry(tname, nid, key, decodedValue); err != nil {
|
|
logger.WithError(err).Error("update entry failed")
|
|
diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json)
|
|
return
|
|
}
|
|
logger.Info("update entry done")
|
|
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json)
|
|
}
|
|
|
|
func (nDB *NetworkDB) dbDeleteEntry(w http.ResponseWriter, r *http.Request) {
|
|
_ = r.ParseForm()
|
|
diagnostic.DebugHTTPForm(r)
|
|
_, json := diagnostic.ParseHTTPFormOptions(r)
|
|
|
|
// audit logs
|
|
logger := log.G(context.TODO()).WithFields(log.Fields{
|
|
"component": "diagnostic",
|
|
"remoteIP": r.RemoteAddr,
|
|
"method": caller.Name(0),
|
|
"url": r.URL.String(),
|
|
})
|
|
logger.Info("delete entry")
|
|
|
|
if len(r.Form["tname"]) < 1 ||
|
|
len(r.Form["nid"]) < 1 ||
|
|
len(r.Form["key"]) < 1 {
|
|
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k", r.URL.Path))
|
|
logger.Error("delete entry failed, wrong input")
|
|
diagnostic.HTTPReply(w, rsp, json)
|
|
return
|
|
}
|
|
|
|
tname := r.Form["tname"][0]
|
|
nid := r.Form["nid"][0]
|
|
key := r.Form["key"][0]
|
|
|
|
err := nDB.DeleteEntry(tname, nid, key)
|
|
if err != nil {
|
|
logger.WithError(err).Error("delete entry failed")
|
|
diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json)
|
|
return
|
|
}
|
|
logger.Info("delete entry done")
|
|
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json)
|
|
}
|
|
|
|
func (nDB *NetworkDB) dbGetEntry(w http.ResponseWriter, r *http.Request) {
|
|
_ = r.ParseForm()
|
|
diagnostic.DebugHTTPForm(r)
|
|
unsafe, json := diagnostic.ParseHTTPFormOptions(r)
|
|
|
|
// audit logs
|
|
logger := log.G(context.TODO()).WithFields(log.Fields{
|
|
"component": "diagnostic",
|
|
"remoteIP": r.RemoteAddr,
|
|
"method": caller.Name(0),
|
|
"url": r.URL.String(),
|
|
})
|
|
logger.Info("get entry")
|
|
|
|
if len(r.Form["tname"]) < 1 ||
|
|
len(r.Form["nid"]) < 1 ||
|
|
len(r.Form["key"]) < 1 {
|
|
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k", r.URL.Path))
|
|
logger.Error("get entry failed, wrong input")
|
|
diagnostic.HTTPReply(w, rsp, json)
|
|
return
|
|
}
|
|
|
|
tname := r.Form["tname"][0]
|
|
nid := r.Form["nid"][0]
|
|
key := r.Form["key"][0]
|
|
|
|
value, err := nDB.GetEntry(tname, nid, key)
|
|
if err != nil {
|
|
logger.WithError(err).Error("get entry failed")
|
|
diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json)
|
|
return
|
|
}
|
|
|
|
var encodedValue string
|
|
if unsafe {
|
|
encodedValue = string(value)
|
|
} else {
|
|
encodedValue = base64.StdEncoding.EncodeToString(value)
|
|
}
|
|
|
|
rsp := &diagnostic.TableEntryObj{Key: key, Value: encodedValue}
|
|
logger.WithField("response", fmt.Sprintf("%+v", rsp)).Info("get entry done")
|
|
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(rsp), json)
|
|
}
|
|
|
|
func (nDB *NetworkDB) dbJoinNetwork(w http.ResponseWriter, r *http.Request) {
|
|
_ = r.ParseForm()
|
|
diagnostic.DebugHTTPForm(r)
|
|
_, json := diagnostic.ParseHTTPFormOptions(r)
|
|
|
|
// audit logs
|
|
logger := log.G(context.TODO()).WithFields(log.Fields{
|
|
"component": "diagnostic",
|
|
"remoteIP": r.RemoteAddr,
|
|
"method": caller.Name(0),
|
|
"url": r.URL.String(),
|
|
})
|
|
logger.Info("join network")
|
|
|
|
if len(r.Form["nid"]) < 1 {
|
|
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=network_id", r.URL.Path))
|
|
logger.Error("join network failed, wrong input")
|
|
diagnostic.HTTPReply(w, rsp, json)
|
|
return
|
|
}
|
|
|
|
nid := r.Form["nid"][0]
|
|
|
|
if err := nDB.JoinNetwork(nid); err != nil {
|
|
logger.WithError(err).Error("join network failed")
|
|
diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json)
|
|
return
|
|
}
|
|
logger.Info("join network done")
|
|
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json)
|
|
}
|
|
|
|
func (nDB *NetworkDB) dbLeaveNetwork(w http.ResponseWriter, r *http.Request) {
|
|
_ = r.ParseForm()
|
|
diagnostic.DebugHTTPForm(r)
|
|
_, json := diagnostic.ParseHTTPFormOptions(r)
|
|
|
|
// audit logs
|
|
logger := log.G(context.TODO()).WithFields(log.Fields{
|
|
"component": "diagnostic",
|
|
"remoteIP": r.RemoteAddr,
|
|
"method": caller.Name(0),
|
|
"url": r.URL.String(),
|
|
})
|
|
logger.Info("leave network")
|
|
|
|
if len(r.Form["nid"]) < 1 {
|
|
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=network_id", r.URL.Path))
|
|
logger.Error("leave network failed, wrong input")
|
|
diagnostic.HTTPReply(w, rsp, json)
|
|
return
|
|
}
|
|
|
|
nid := r.Form["nid"][0]
|
|
|
|
if err := nDB.LeaveNetwork(nid); err != nil {
|
|
logger.WithError(err).Error("leave network failed")
|
|
diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json)
|
|
return
|
|
}
|
|
logger.Info("leave network done")
|
|
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json)
|
|
}
|
|
|
|
func (nDB *NetworkDB) dbGetTable(w http.ResponseWriter, r *http.Request) {
|
|
_ = r.ParseForm()
|
|
diagnostic.DebugHTTPForm(r)
|
|
unsafe, json := diagnostic.ParseHTTPFormOptions(r)
|
|
|
|
// audit logs
|
|
logger := log.G(context.TODO()).WithFields(log.Fields{
|
|
"component": "diagnostic",
|
|
"remoteIP": r.RemoteAddr,
|
|
"method": caller.Name(0),
|
|
"url": r.URL.String(),
|
|
})
|
|
logger.Info("get table")
|
|
|
|
if len(r.Form["tname"]) < 1 ||
|
|
len(r.Form["nid"]) < 1 {
|
|
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id", r.URL.Path))
|
|
logger.Error("get table failed, wrong input")
|
|
diagnostic.HTTPReply(w, rsp, json)
|
|
return
|
|
}
|
|
|
|
tname := r.Form["tname"][0]
|
|
nid := r.Form["nid"][0]
|
|
|
|
table := nDB.GetTableByNetwork(tname, nid)
|
|
rsp := &diagnostic.TableObj{Length: len(table)}
|
|
i := 0
|
|
for k, v := range table {
|
|
var encodedValue string
|
|
if unsafe {
|
|
encodedValue = string(v.Value)
|
|
} else {
|
|
encodedValue = base64.StdEncoding.EncodeToString(v.Value)
|
|
}
|
|
rsp.Elements = append(rsp.Elements,
|
|
&diagnostic.TableEntryObj{
|
|
Index: i,
|
|
Key: k,
|
|
Value: encodedValue,
|
|
Owner: v.owner,
|
|
})
|
|
i++
|
|
}
|
|
logger.WithField("response", fmt.Sprintf("%+v", rsp)).Info("get table done")
|
|
diagnostic.HTTPReply(w, diagnostic.CommandSucceed(rsp), json)
|
|
}
|
|
|
|
func (nDB *NetworkDB) dbNetworkStats(w http.ResponseWriter, r *http.Request) {
|
|
_ = r.ParseForm()
|
|
diagnostic.DebugHTTPForm(r)
|
|
_, json := diagnostic.ParseHTTPFormOptions(r)
|
|
|
|
// audit logs
|
|
logger := log.G(context.TODO()).WithFields(log.Fields{
|
|
"component": "diagnostic",
|
|
"remoteIP": r.RemoteAddr,
|
|
"method": caller.Name(0),
|
|
"url": r.URL.String(),
|
|
})
|
|
logger.Info("network stats")
|
|
|
|
if len(r.Form["nid"]) < 1 {
|
|
rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=test", r.URL.Path))
|
|
logger.Error("network stats failed, wrong input")
|
|
diagnostic.HTTPReply(w, rsp, json)
|
|
return
|
|
}
|
|
|
|
nDB.RLock()
|
|
network, ok := nDB.thisNodeNetworks[r.Form["nid"][0]]
|
|
|
|
entries := -1
|
|
qLen := -1
|
|
if ok {
|
|
entries = int(network.entriesNumber.Load())
|
|
qLen = network.tableBroadcasts.NumQueued()
|
|
}
|
|
nDB.RUnlock()
|
|
|
|
rsp := diagnostic.CommandSucceed(&diagnostic.NetworkStatsResult{Entries: entries, QueueLen: qLen})
|
|
logger.WithField("response", fmt.Sprintf("%+v", rsp)).Info("network stats done")
|
|
diagnostic.HTTPReply(w, rsp, json)
|
|
}
|