Align it to the moby/moby external api
Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
| ... | ... |
@@ -297,8 +297,8 @@ func (c *controller) agentInit(listenAddr, bindAddrOrInterface, advertiseAddr, d |
| 297 | 297 |
return err |
| 298 | 298 |
} |
| 299 | 299 |
|
| 300 |
- // Register the diagnose handlers |
|
| 301 |
- c.DiagnoseServer.RegisterHandler(nDB, networkdb.NetDbPaths2Func) |
|
| 300 |
+ // Register the diagnostic handlers |
|
| 301 |
+ c.DiagnosticServer.RegisterHandler(nDB, networkdb.NetDbPaths2Func) |
|
| 302 | 302 |
|
| 303 | 303 |
var cancelList []func() |
| 304 | 304 |
ch, cancel := nDB.Watch(libnetworkEPTable, "", "") |
| ... | ... |
@@ -61,7 +61,7 @@ import ( |
| 61 | 61 |
"github.com/docker/libnetwork/cluster" |
| 62 | 62 |
"github.com/docker/libnetwork/config" |
| 63 | 63 |
"github.com/docker/libnetwork/datastore" |
| 64 |
- "github.com/docker/libnetwork/diagnose" |
|
| 64 |
+ "github.com/docker/libnetwork/diagnostic" |
|
| 65 | 65 |
"github.com/docker/libnetwork/discoverapi" |
| 66 | 66 |
"github.com/docker/libnetwork/driverapi" |
| 67 | 67 |
"github.com/docker/libnetwork/drvregistry" |
| ... | ... |
@@ -136,12 +136,12 @@ type NetworkController interface {
|
| 136 | 136 |
// SetKeys configures the encryption key for gossip and overlay data path |
| 137 | 137 |
SetKeys(keys []*types.EncryptionKey) error |
| 138 | 138 |
|
| 139 |
- // StartDiagnose start the network diagnose mode |
|
| 140 |
- StartDiagnose(port int) |
|
| 141 |
- // StopDiagnose start the network diagnose mode |
|
| 142 |
- StopDiagnose() |
|
| 143 |
- // IsDiagnoseEnabled returns true if the diagnose is enabled |
|
| 144 |
- IsDiagnoseEnabled() bool |
|
| 139 |
+ // StartDiagnostic start the network diagnostic mode |
|
| 140 |
+ StartDiagnostic(port int) |
|
| 141 |
+ // StopDiagnostic start the network diagnostic mode |
|
| 142 |
+ StopDiagnostic() |
|
| 143 |
+ // IsDiagnosticEnabled returns true if the diagnostic is enabled |
|
| 144 |
+ IsDiagnosticEnabled() bool |
|
| 145 | 145 |
} |
| 146 | 146 |
|
| 147 | 147 |
// NetworkWalker is a client provided function which will be used to walk the Networks. |
| ... | ... |
@@ -176,7 +176,7 @@ type controller struct {
|
| 176 | 176 |
agentStopDone chan struct{}
|
| 177 | 177 |
keys []*types.EncryptionKey |
| 178 | 178 |
clusterConfigAvailable bool |
| 179 |
- DiagnoseServer *diagnose.Server |
|
| 179 |
+ DiagnosticServer *diagnostic.Server |
|
| 180 | 180 |
sync.Mutex |
| 181 | 181 |
} |
| 182 | 182 |
|
| ... | ... |
@@ -188,16 +188,16 @@ type initializer struct {
|
| 188 | 188 |
// New creates a new instance of network controller. |
| 189 | 189 |
func New(cfgOptions ...config.Option) (NetworkController, error) {
|
| 190 | 190 |
c := &controller{
|
| 191 |
- id: stringid.GenerateRandomID(), |
|
| 192 |
- cfg: config.ParseConfigOptions(cfgOptions...), |
|
| 193 |
- sandboxes: sandboxTable{},
|
|
| 194 |
- svcRecords: make(map[string]svcInfo), |
|
| 195 |
- serviceBindings: make(map[serviceKey]*service), |
|
| 196 |
- agentInitDone: make(chan struct{}),
|
|
| 197 |
- networkLocker: locker.New(), |
|
| 198 |
- DiagnoseServer: diagnose.New(), |
|
| 191 |
+ id: stringid.GenerateRandomID(), |
|
| 192 |
+ cfg: config.ParseConfigOptions(cfgOptions...), |
|
| 193 |
+ sandboxes: sandboxTable{},
|
|
| 194 |
+ svcRecords: make(map[string]svcInfo), |
|
| 195 |
+ serviceBindings: make(map[serviceKey]*service), |
|
| 196 |
+ agentInitDone: make(chan struct{}),
|
|
| 197 |
+ networkLocker: locker.New(), |
|
| 198 |
+ DiagnosticServer: diagnostic.New(), |
|
| 199 | 199 |
} |
| 200 |
- c.DiagnoseServer.Init() |
|
| 200 |
+ c.DiagnosticServer.Init() |
|
| 201 | 201 |
|
| 202 | 202 |
if err := c.initStores(); err != nil {
|
| 203 | 203 |
return nil, err |
| ... | ... |
@@ -1307,27 +1307,27 @@ func (c *controller) Stop() {
|
| 1307 | 1307 |
osl.GC() |
| 1308 | 1308 |
} |
| 1309 | 1309 |
|
| 1310 |
-// StartDiagnose start the network diagnose mode |
|
| 1311 |
-func (c *controller) StartDiagnose(port int) {
|
|
| 1310 |
+// StartDiagnostic start the network dias mode |
|
| 1311 |
+func (c *controller) StartDiagnostic(port int) {
|
|
| 1312 | 1312 |
c.Lock() |
| 1313 |
- if !c.DiagnoseServer.IsDebugEnable() {
|
|
| 1314 |
- c.DiagnoseServer.EnableDebug("127.0.0.1", port)
|
|
| 1313 |
+ if !c.DiagnosticServer.IsDiagnosticEnabled() {
|
|
| 1314 |
+ c.DiagnosticServer.EnableDiagnostic("127.0.0.1", port)
|
|
| 1315 | 1315 |
} |
| 1316 | 1316 |
c.Unlock() |
| 1317 | 1317 |
} |
| 1318 | 1318 |
|
| 1319 |
-// StopDiagnose start the network diagnose mode |
|
| 1320 |
-func (c *controller) StopDiagnose() {
|
|
| 1319 |
+// StopDiagnostic start the network dias mode |
|
| 1320 |
+func (c *controller) StopDiagnostic() {
|
|
| 1321 | 1321 |
c.Lock() |
| 1322 |
- if c.DiagnoseServer.IsDebugEnable() {
|
|
| 1323 |
- c.DiagnoseServer.DisableDebug() |
|
| 1322 |
+ if c.DiagnosticServer.IsDiagnosticEnabled() {
|
|
| 1323 |
+ c.DiagnosticServer.DisableDiagnostic() |
|
| 1324 | 1324 |
} |
| 1325 | 1325 |
c.Unlock() |
| 1326 | 1326 |
} |
| 1327 | 1327 |
|
| 1328 |
-// IsDiagnoseEnabled returns true if the diagnose is enabled |
|
| 1329 |
-func (c *controller) IsDiagnoseEnabled() bool {
|
|
| 1328 |
+// IsDiagnosticEnabled returns true if the dias is enabled |
|
| 1329 |
+func (c *controller) IsDiagnosticEnabled() bool {
|
|
| 1330 | 1330 |
c.Lock() |
| 1331 | 1331 |
defer c.Unlock() |
| 1332 |
- return c.DiagnoseServer.IsDebugEnable() |
|
| 1332 |
+ return c.DiagnosticServer.IsDiagnosticEnabled() |
|
| 1333 | 1333 |
} |
| 1334 | 1334 |
deleted file mode 100644 |
| ... | ... |
@@ -1,227 +0,0 @@ |
| 1 |
-package diagnose |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "context" |
|
| 5 |
- "encoding/json" |
|
| 6 |
- "fmt" |
|
| 7 |
- "net/http" |
|
| 8 |
- "sync" |
|
| 9 |
- "sync/atomic" |
|
| 10 |
- |
|
| 11 |
- stackdump "github.com/docker/docker/pkg/signal" |
|
| 12 |
- "github.com/docker/libnetwork/common" |
|
| 13 |
- "github.com/sirupsen/logrus" |
|
| 14 |
-) |
|
| 15 |
- |
|
| 16 |
-// HTTPHandlerFunc TODO |
|
| 17 |
-type HTTPHandlerFunc func(interface{}, http.ResponseWriter, *http.Request)
|
|
| 18 |
- |
|
| 19 |
-type httpHandlerCustom struct {
|
|
| 20 |
- ctx interface{}
|
|
| 21 |
- F func(interface{}, http.ResponseWriter, *http.Request)
|
|
| 22 |
-} |
|
| 23 |
- |
|
| 24 |
-// ServeHTTP TODO |
|
| 25 |
-func (h httpHandlerCustom) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
| 26 |
- h.F(h.ctx, w, r) |
|
| 27 |
-} |
|
| 28 |
- |
|
| 29 |
-var diagPaths2Func = map[string]HTTPHandlerFunc{
|
|
| 30 |
- "/": notImplemented, |
|
| 31 |
- "/help": help, |
|
| 32 |
- "/ready": ready, |
|
| 33 |
- "/stackdump": stackTrace, |
|
| 34 |
-} |
|
| 35 |
- |
|
| 36 |
-// Server when the debug is enabled exposes a |
|
| 37 |
-// This data structure is protected by the Agent mutex so does not require and additional mutex here |
|
| 38 |
-type Server struct {
|
|
| 39 |
- enable int32 |
|
| 40 |
- srv *http.Server |
|
| 41 |
- port int |
|
| 42 |
- mux *http.ServeMux |
|
| 43 |
- registeredHanders map[string]bool |
|
| 44 |
- sync.Mutex |
|
| 45 |
-} |
|
| 46 |
- |
|
| 47 |
-// New creates a new diagnose server |
|
| 48 |
-func New() *Server {
|
|
| 49 |
- return &Server{
|
|
| 50 |
- registeredHanders: make(map[string]bool), |
|
| 51 |
- } |
|
| 52 |
-} |
|
| 53 |
- |
|
| 54 |
-// Init initialize the mux for the http handling and register the base hooks |
|
| 55 |
-func (s *Server) Init() {
|
|
| 56 |
- s.mux = http.NewServeMux() |
|
| 57 |
- |
|
| 58 |
- // Register local handlers |
|
| 59 |
- s.RegisterHandler(s, diagPaths2Func) |
|
| 60 |
-} |
|
| 61 |
- |
|
| 62 |
-// RegisterHandler allows to register new handlers to the mux and to a specific path |
|
| 63 |
-func (s *Server) RegisterHandler(ctx interface{}, hdlrs map[string]HTTPHandlerFunc) {
|
|
| 64 |
- s.Lock() |
|
| 65 |
- defer s.Unlock() |
|
| 66 |
- for path, fun := range hdlrs {
|
|
| 67 |
- if _, ok := s.registeredHanders[path]; ok {
|
|
| 68 |
- continue |
|
| 69 |
- } |
|
| 70 |
- s.mux.Handle(path, httpHandlerCustom{ctx, fun})
|
|
| 71 |
- s.registeredHanders[path] = true |
|
| 72 |
- } |
|
| 73 |
-} |
|
| 74 |
- |
|
| 75 |
-// ServeHTTP this is the method called bu the ListenAndServe, and is needed to allow us to |
|
| 76 |
-// use our custom mux |
|
| 77 |
-func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
| 78 |
- s.mux.ServeHTTP(w, r) |
|
| 79 |
-} |
|
| 80 |
- |
|
| 81 |
-// EnableDebug opens a TCP socket to debug the passed network DB |
|
| 82 |
-func (s *Server) EnableDebug(ip string, port int) {
|
|
| 83 |
- s.Lock() |
|
| 84 |
- defer s.Unlock() |
|
| 85 |
- |
|
| 86 |
- s.port = port |
|
| 87 |
- |
|
| 88 |
- if s.enable == 1 {
|
|
| 89 |
- logrus.Info("The server is already up and running")
|
|
| 90 |
- return |
|
| 91 |
- } |
|
| 92 |
- |
|
| 93 |
- logrus.Infof("Starting the diagnose server listening on %d for commands", port)
|
|
| 94 |
- srv := &http.Server{Addr: fmt.Sprintf("%s:%d", ip, port), Handler: s}
|
|
| 95 |
- s.srv = srv |
|
| 96 |
- s.enable = 1 |
|
| 97 |
- go func(n *Server) {
|
|
| 98 |
- // Ingore ErrServerClosed that is returned on the Shutdown call |
|
| 99 |
- if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
|
| 100 |
- logrus.Errorf("ListenAndServe error: %s", err)
|
|
| 101 |
- atomic.SwapInt32(&n.enable, 0) |
|
| 102 |
- } |
|
| 103 |
- }(s) |
|
| 104 |
-} |
|
| 105 |
- |
|
| 106 |
-// DisableDebug stop the dubug and closes the tcp socket |
|
| 107 |
-func (s *Server) DisableDebug() {
|
|
| 108 |
- s.Lock() |
|
| 109 |
- defer s.Unlock() |
|
| 110 |
- |
|
| 111 |
- s.srv.Shutdown(context.Background()) |
|
| 112 |
- s.srv = nil |
|
| 113 |
- s.enable = 0 |
|
| 114 |
- logrus.Info("Disabling the diagnose server")
|
|
| 115 |
-} |
|
| 116 |
- |
|
| 117 |
-// IsDebugEnable returns true when the debug is enabled |
|
| 118 |
-func (s *Server) IsDebugEnable() bool {
|
|
| 119 |
- s.Lock() |
|
| 120 |
- defer s.Unlock() |
|
| 121 |
- return s.enable == 1 |
|
| 122 |
-} |
|
| 123 |
- |
|
| 124 |
-func notImplemented(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 125 |
- r.ParseForm() |
|
| 126 |
- _, json := ParseHTTPFormOptions(r) |
|
| 127 |
- rsp := WrongCommand("not implemented", fmt.Sprintf("URL path: %s no method implemented check /help\n", r.URL.Path))
|
|
| 128 |
- |
|
| 129 |
- // audit logs |
|
| 130 |
- log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 131 |
- log.Info("command not implemented done")
|
|
| 132 |
- |
|
| 133 |
- HTTPReply(w, rsp, json) |
|
| 134 |
-} |
|
| 135 |
- |
|
| 136 |
-func help(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 137 |
- r.ParseForm() |
|
| 138 |
- _, json := ParseHTTPFormOptions(r) |
|
| 139 |
- |
|
| 140 |
- // audit logs |
|
| 141 |
- log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 142 |
- log.Info("help done")
|
|
| 143 |
- |
|
| 144 |
- n, ok := ctx.(*Server) |
|
| 145 |
- var result string |
|
| 146 |
- if ok {
|
|
| 147 |
- for path := range n.registeredHanders {
|
|
| 148 |
- result += fmt.Sprintf("%s\n", path)
|
|
| 149 |
- } |
|
| 150 |
- HTTPReply(w, CommandSucceed(&StringCmd{Info: result}), json)
|
|
| 151 |
- } |
|
| 152 |
-} |
|
| 153 |
- |
|
| 154 |
-func ready(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 155 |
- r.ParseForm() |
|
| 156 |
- _, json := ParseHTTPFormOptions(r) |
|
| 157 |
- |
|
| 158 |
- // audit logs |
|
| 159 |
- log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 160 |
- log.Info("ready done")
|
|
| 161 |
- HTTPReply(w, CommandSucceed(&StringCmd{Info: "OK"}), json)
|
|
| 162 |
-} |
|
| 163 |
- |
|
| 164 |
-func stackTrace(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 165 |
- r.ParseForm() |
|
| 166 |
- _, json := ParseHTTPFormOptions(r) |
|
| 167 |
- |
|
| 168 |
- // audit logs |
|
| 169 |
- log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 170 |
- log.Info("stack trace")
|
|
| 171 |
- |
|
| 172 |
- path, err := stackdump.DumpStacks("/tmp/")
|
|
| 173 |
- if err != nil {
|
|
| 174 |
- log.WithError(err).Error("failed to write goroutines dump")
|
|
| 175 |
- HTTPReply(w, FailCommand(err), json) |
|
| 176 |
- } else {
|
|
| 177 |
- log.Info("stack trace done")
|
|
| 178 |
- HTTPReply(w, CommandSucceed(&StringCmd{Info: fmt.Sprintf("goroutine stacks written to %s", path)}), json)
|
|
| 179 |
- } |
|
| 180 |
-} |
|
| 181 |
- |
|
| 182 |
-// DebugHTTPForm helper to print the form url parameters |
|
| 183 |
-func DebugHTTPForm(r *http.Request) {
|
|
| 184 |
- for k, v := range r.Form {
|
|
| 185 |
- logrus.Debugf("Form[%q] = %q\n", k, v)
|
|
| 186 |
- } |
|
| 187 |
-} |
|
| 188 |
- |
|
| 189 |
-// JSONOutput contains details on JSON output printing |
|
| 190 |
-type JSONOutput struct {
|
|
| 191 |
- enable bool |
|
| 192 |
- prettyPrint bool |
|
| 193 |
-} |
|
| 194 |
- |
|
| 195 |
-// ParseHTTPFormOptions easily parse the JSON printing options |
|
| 196 |
-func ParseHTTPFormOptions(r *http.Request) (bool, *JSONOutput) {
|
|
| 197 |
- _, unsafe := r.Form["unsafe"] |
|
| 198 |
- v, json := r.Form["json"] |
|
| 199 |
- var pretty bool |
|
| 200 |
- if len(v) > 0 {
|
|
| 201 |
- pretty = v[0] == "pretty" |
|
| 202 |
- } |
|
| 203 |
- return unsafe, &JSONOutput{enable: json, prettyPrint: pretty}
|
|
| 204 |
-} |
|
| 205 |
- |
|
| 206 |
-// HTTPReply helper function that takes care of sending the message out |
|
| 207 |
-func HTTPReply(w http.ResponseWriter, r *HTTPResult, j *JSONOutput) (int, error) {
|
|
| 208 |
- var response []byte |
|
| 209 |
- if j.enable {
|
|
| 210 |
- w.Header().Set("Content-Type", "application/json")
|
|
| 211 |
- var err error |
|
| 212 |
- if j.prettyPrint {
|
|
| 213 |
- response, err = json.MarshalIndent(r, "", " ") |
|
| 214 |
- if err != nil {
|
|
| 215 |
- response, _ = json.MarshalIndent(FailCommand(err), "", " ") |
|
| 216 |
- } |
|
| 217 |
- } else {
|
|
| 218 |
- response, err = json.Marshal(r) |
|
| 219 |
- if err != nil {
|
|
| 220 |
- response, _ = json.Marshal(FailCommand(err)) |
|
| 221 |
- } |
|
| 222 |
- } |
|
| 223 |
- } else {
|
|
| 224 |
- response = []byte(r.String()) |
|
| 225 |
- } |
|
| 226 |
- return fmt.Fprint(w, string(response)) |
|
| 227 |
-} |
| 228 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,122 +0,0 @@ |
| 1 |
-package diagnose |
|
| 2 |
- |
|
| 3 |
-import "fmt" |
|
| 4 |
- |
|
| 5 |
-// StringInterface interface that has to be implemented by messages |
|
| 6 |
-type StringInterface interface {
|
|
| 7 |
- String() string |
|
| 8 |
-} |
|
| 9 |
- |
|
| 10 |
-// CommandSucceed creates a success message |
|
| 11 |
-func CommandSucceed(result StringInterface) *HTTPResult {
|
|
| 12 |
- return &HTTPResult{
|
|
| 13 |
- Message: "OK", |
|
| 14 |
- Details: result, |
|
| 15 |
- } |
|
| 16 |
-} |
|
| 17 |
- |
|
| 18 |
-// FailCommand creates a failure message with error |
|
| 19 |
-func FailCommand(err error) *HTTPResult {
|
|
| 20 |
- return &HTTPResult{
|
|
| 21 |
- Message: "FAIL", |
|
| 22 |
- Details: &ErrorCmd{Error: err.Error()},
|
|
| 23 |
- } |
|
| 24 |
-} |
|
| 25 |
- |
|
| 26 |
-// WrongCommand creates a wrong command response |
|
| 27 |
-func WrongCommand(message, usage string) *HTTPResult {
|
|
| 28 |
- return &HTTPResult{
|
|
| 29 |
- Message: message, |
|
| 30 |
- Details: &UsageCmd{Usage: usage},
|
|
| 31 |
- } |
|
| 32 |
-} |
|
| 33 |
- |
|
| 34 |
-// HTTPResult Diagnose Server HTTP result operation |
|
| 35 |
-type HTTPResult struct {
|
|
| 36 |
- Message string `json:"message"` |
|
| 37 |
- Details StringInterface `json:"details"` |
|
| 38 |
-} |
|
| 39 |
- |
|
| 40 |
-func (h *HTTPResult) String() string {
|
|
| 41 |
- rsp := h.Message |
|
| 42 |
- if h.Details != nil {
|
|
| 43 |
- rsp += "\n" + h.Details.String() |
|
| 44 |
- } |
|
| 45 |
- return rsp |
|
| 46 |
-} |
|
| 47 |
- |
|
| 48 |
-// UsageCmd command with usage field |
|
| 49 |
-type UsageCmd struct {
|
|
| 50 |
- Usage string `json:"usage"` |
|
| 51 |
-} |
|
| 52 |
- |
|
| 53 |
-func (u *UsageCmd) String() string {
|
|
| 54 |
- return "Usage: " + u.Usage |
|
| 55 |
-} |
|
| 56 |
- |
|
| 57 |
-// StringCmd command with info string |
|
| 58 |
-type StringCmd struct {
|
|
| 59 |
- Info string `json:"info"` |
|
| 60 |
-} |
|
| 61 |
- |
|
| 62 |
-func (s *StringCmd) String() string {
|
|
| 63 |
- return s.Info |
|
| 64 |
-} |
|
| 65 |
- |
|
| 66 |
-// ErrorCmd command with error |
|
| 67 |
-type ErrorCmd struct {
|
|
| 68 |
- Error string `json:"error"` |
|
| 69 |
-} |
|
| 70 |
- |
|
| 71 |
-func (e *ErrorCmd) String() string {
|
|
| 72 |
- return "Error: " + e.Error |
|
| 73 |
-} |
|
| 74 |
- |
|
| 75 |
-// TableObj network db table object |
|
| 76 |
-type TableObj struct {
|
|
| 77 |
- Length int `json:"size"` |
|
| 78 |
- Elements []StringInterface `json:"entries"` |
|
| 79 |
-} |
|
| 80 |
- |
|
| 81 |
-func (t *TableObj) String() string {
|
|
| 82 |
- output := fmt.Sprintf("total entries: %d\n", t.Length)
|
|
| 83 |
- for _, e := range t.Elements {
|
|
| 84 |
- output += e.String() |
|
| 85 |
- } |
|
| 86 |
- return output |
|
| 87 |
-} |
|
| 88 |
- |
|
| 89 |
-// PeerEntryObj entry in the networkdb peer table |
|
| 90 |
-type PeerEntryObj struct {
|
|
| 91 |
- Index int `json:"-"` |
|
| 92 |
- Name string `json:"-=name"` |
|
| 93 |
- IP string `json:"ip"` |
|
| 94 |
-} |
|
| 95 |
- |
|
| 96 |
-func (p *PeerEntryObj) String() string {
|
|
| 97 |
- return fmt.Sprintf("%d) %s -> %s\n", p.Index, p.Name, p.IP)
|
|
| 98 |
-} |
|
| 99 |
- |
|
| 100 |
-// TableEntryObj network db table entry object |
|
| 101 |
-type TableEntryObj struct {
|
|
| 102 |
- Index int `json:"-"` |
|
| 103 |
- Key string `json:"key"` |
|
| 104 |
- Value string `json:"value"` |
|
| 105 |
- Owner string `json:"owner"` |
|
| 106 |
-} |
|
| 107 |
- |
|
| 108 |
-func (t *TableEntryObj) String() string {
|
|
| 109 |
- return fmt.Sprintf("%d) k:`%s` -> v:`%s` owner:`%s`\n", t.Index, t.Key, t.Value, t.Owner)
|
|
| 110 |
-} |
|
| 111 |
- |
|
| 112 |
-// TableEndpointsResult fully typed message for proper unmarshaling on the client side |
|
| 113 |
-type TableEndpointsResult struct {
|
|
| 114 |
- TableObj |
|
| 115 |
- Elements []TableEntryObj `json:"entries"` |
|
| 116 |
-} |
|
| 117 |
- |
|
| 118 |
-// TablePeersResult fully typed message for proper unmarshaling on the client side |
|
| 119 |
-type TablePeersResult struct {
|
|
| 120 |
- TableObj |
|
| 121 |
- Elements []PeerEntryObj `json:"entries"` |
|
| 122 |
-} |
| 123 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,227 @@ |
| 0 |
+package diagnostic |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "context" |
|
| 4 |
+ "encoding/json" |
|
| 5 |
+ "fmt" |
|
| 6 |
+ "net/http" |
|
| 7 |
+ "sync" |
|
| 8 |
+ "sync/atomic" |
|
| 9 |
+ |
|
| 10 |
+ stackdump "github.com/docker/docker/pkg/signal" |
|
| 11 |
+ "github.com/docker/libnetwork/common" |
|
| 12 |
+ "github.com/sirupsen/logrus" |
|
| 13 |
+) |
|
| 14 |
+ |
|
| 15 |
+// HTTPHandlerFunc TODO |
|
| 16 |
+type HTTPHandlerFunc func(interface{}, http.ResponseWriter, *http.Request)
|
|
| 17 |
+ |
|
| 18 |
+type httpHandlerCustom struct {
|
|
| 19 |
+ ctx interface{}
|
|
| 20 |
+ F func(interface{}, http.ResponseWriter, *http.Request)
|
|
| 21 |
+} |
|
| 22 |
+ |
|
| 23 |
+// ServeHTTP TODO |
|
| 24 |
+func (h httpHandlerCustom) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
| 25 |
+ h.F(h.ctx, w, r) |
|
| 26 |
+} |
|
| 27 |
+ |
|
| 28 |
+var diagPaths2Func = map[string]HTTPHandlerFunc{
|
|
| 29 |
+ "/": notImplemented, |
|
| 30 |
+ "/help": help, |
|
| 31 |
+ "/ready": ready, |
|
| 32 |
+ "/stackdump": stackTrace, |
|
| 33 |
+} |
|
| 34 |
+ |
|
| 35 |
+// Server when the debug is enabled exposes a |
|
| 36 |
+// This data structure is protected by the Agent mutex so does not require and additional mutex here |
|
| 37 |
+type Server struct {
|
|
| 38 |
+ enable int32 |
|
| 39 |
+ srv *http.Server |
|
| 40 |
+ port int |
|
| 41 |
+ mux *http.ServeMux |
|
| 42 |
+ registeredHanders map[string]bool |
|
| 43 |
+ sync.Mutex |
|
| 44 |
+} |
|
| 45 |
+ |
|
| 46 |
+// New creates a new diagnostic server |
|
| 47 |
+func New() *Server {
|
|
| 48 |
+ return &Server{
|
|
| 49 |
+ registeredHanders: make(map[string]bool), |
|
| 50 |
+ } |
|
| 51 |
+} |
|
| 52 |
+ |
|
| 53 |
+// Init initialize the mux for the http handling and register the base hooks |
|
| 54 |
+func (s *Server) Init() {
|
|
| 55 |
+ s.mux = http.NewServeMux() |
|
| 56 |
+ |
|
| 57 |
+ // Register local handlers |
|
| 58 |
+ s.RegisterHandler(s, diagPaths2Func) |
|
| 59 |
+} |
|
| 60 |
+ |
|
| 61 |
+// RegisterHandler allows to register new handlers to the mux and to a specific path |
|
| 62 |
+func (s *Server) RegisterHandler(ctx interface{}, hdlrs map[string]HTTPHandlerFunc) {
|
|
| 63 |
+ s.Lock() |
|
| 64 |
+ defer s.Unlock() |
|
| 65 |
+ for path, fun := range hdlrs {
|
|
| 66 |
+ if _, ok := s.registeredHanders[path]; ok {
|
|
| 67 |
+ continue |
|
| 68 |
+ } |
|
| 69 |
+ s.mux.Handle(path, httpHandlerCustom{ctx, fun})
|
|
| 70 |
+ s.registeredHanders[path] = true |
|
| 71 |
+ } |
|
| 72 |
+} |
|
| 73 |
+ |
|
| 74 |
+// ServeHTTP this is the method called bu the ListenAndServe, and is needed to allow us to |
|
| 75 |
+// use our custom mux |
|
| 76 |
+func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
| 77 |
+ s.mux.ServeHTTP(w, r) |
|
| 78 |
+} |
|
| 79 |
+ |
|
| 80 |
+// EnableDiagnostic opens a TCP socket to debug the passed network DB |
|
| 81 |
+func (s *Server) EnableDiagnostic(ip string, port int) {
|
|
| 82 |
+ s.Lock() |
|
| 83 |
+ defer s.Unlock() |
|
| 84 |
+ |
|
| 85 |
+ s.port = port |
|
| 86 |
+ |
|
| 87 |
+ if s.enable == 1 {
|
|
| 88 |
+ logrus.Info("The server is already up and running")
|
|
| 89 |
+ return |
|
| 90 |
+ } |
|
| 91 |
+ |
|
| 92 |
+ logrus.Infof("Starting the diagnostic server listening on %d for commands", port)
|
|
| 93 |
+ srv := &http.Server{Addr: fmt.Sprintf("%s:%d", ip, port), Handler: s}
|
|
| 94 |
+ s.srv = srv |
|
| 95 |
+ s.enable = 1 |
|
| 96 |
+ go func(n *Server) {
|
|
| 97 |
+ // Ingore ErrServerClosed that is returned on the Shutdown call |
|
| 98 |
+ if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
|
| 99 |
+ logrus.Errorf("ListenAndServe error: %s", err)
|
|
| 100 |
+ atomic.SwapInt32(&n.enable, 0) |
|
| 101 |
+ } |
|
| 102 |
+ }(s) |
|
| 103 |
+} |
|
| 104 |
+ |
|
| 105 |
+// DisableDiagnostic stop the dubug and closes the tcp socket |
|
| 106 |
+func (s *Server) DisableDiagnostic() {
|
|
| 107 |
+ s.Lock() |
|
| 108 |
+ defer s.Unlock() |
|
| 109 |
+ |
|
| 110 |
+ s.srv.Shutdown(context.Background()) |
|
| 111 |
+ s.srv = nil |
|
| 112 |
+ s.enable = 0 |
|
| 113 |
+ logrus.Info("Disabling the diagnostic server")
|
|
| 114 |
+} |
|
| 115 |
+ |
|
| 116 |
+// IsDiagnosticEnabled returns true when the debug is enabled |
|
| 117 |
+func (s *Server) IsDiagnosticEnabled() bool {
|
|
| 118 |
+ s.Lock() |
|
| 119 |
+ defer s.Unlock() |
|
| 120 |
+ return s.enable == 1 |
|
| 121 |
+} |
|
| 122 |
+ |
|
| 123 |
+func notImplemented(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 124 |
+ r.ParseForm() |
|
| 125 |
+ _, json := ParseHTTPFormOptions(r) |
|
| 126 |
+ rsp := WrongCommand("not implemented", fmt.Sprintf("URL path: %s no method implemented check /help\n", r.URL.Path))
|
|
| 127 |
+ |
|
| 128 |
+ // audit logs |
|
| 129 |
+ log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 130 |
+ log.Info("command not implemented done")
|
|
| 131 |
+ |
|
| 132 |
+ HTTPReply(w, rsp, json) |
|
| 133 |
+} |
|
| 134 |
+ |
|
| 135 |
+func help(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 136 |
+ r.ParseForm() |
|
| 137 |
+ _, json := ParseHTTPFormOptions(r) |
|
| 138 |
+ |
|
| 139 |
+ // audit logs |
|
| 140 |
+ log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 141 |
+ log.Info("help done")
|
|
| 142 |
+ |
|
| 143 |
+ n, ok := ctx.(*Server) |
|
| 144 |
+ var result string |
|
| 145 |
+ if ok {
|
|
| 146 |
+ for path := range n.registeredHanders {
|
|
| 147 |
+ result += fmt.Sprintf("%s\n", path)
|
|
| 148 |
+ } |
|
| 149 |
+ HTTPReply(w, CommandSucceed(&StringCmd{Info: result}), json)
|
|
| 150 |
+ } |
|
| 151 |
+} |
|
| 152 |
+ |
|
| 153 |
+func ready(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 154 |
+ r.ParseForm() |
|
| 155 |
+ _, json := ParseHTTPFormOptions(r) |
|
| 156 |
+ |
|
| 157 |
+ // audit logs |
|
| 158 |
+ log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 159 |
+ log.Info("ready done")
|
|
| 160 |
+ HTTPReply(w, CommandSucceed(&StringCmd{Info: "OK"}), json)
|
|
| 161 |
+} |
|
| 162 |
+ |
|
| 163 |
+func stackTrace(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 164 |
+ r.ParseForm() |
|
| 165 |
+ _, json := ParseHTTPFormOptions(r) |
|
| 166 |
+ |
|
| 167 |
+ // audit logs |
|
| 168 |
+ log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 169 |
+ log.Info("stack trace")
|
|
| 170 |
+ |
|
| 171 |
+ path, err := stackdump.DumpStacks("/tmp/")
|
|
| 172 |
+ if err != nil {
|
|
| 173 |
+ log.WithError(err).Error("failed to write goroutines dump")
|
|
| 174 |
+ HTTPReply(w, FailCommand(err), json) |
|
| 175 |
+ } else {
|
|
| 176 |
+ log.Info("stack trace done")
|
|
| 177 |
+ HTTPReply(w, CommandSucceed(&StringCmd{Info: fmt.Sprintf("goroutine stacks written to %s", path)}), json)
|
|
| 178 |
+ } |
|
| 179 |
+} |
|
| 180 |
+ |
|
| 181 |
+// DebugHTTPForm helper to print the form url parameters |
|
| 182 |
+func DebugHTTPForm(r *http.Request) {
|
|
| 183 |
+ for k, v := range r.Form {
|
|
| 184 |
+ logrus.Debugf("Form[%q] = %q\n", k, v)
|
|
| 185 |
+ } |
|
| 186 |
+} |
|
| 187 |
+ |
|
| 188 |
+// JSONOutput contains details on JSON output printing |
|
| 189 |
+type JSONOutput struct {
|
|
| 190 |
+ enable bool |
|
| 191 |
+ prettyPrint bool |
|
| 192 |
+} |
|
| 193 |
+ |
|
| 194 |
+// ParseHTTPFormOptions easily parse the JSON printing options |
|
| 195 |
+func ParseHTTPFormOptions(r *http.Request) (bool, *JSONOutput) {
|
|
| 196 |
+ _, unsafe := r.Form["unsafe"] |
|
| 197 |
+ v, json := r.Form["json"] |
|
| 198 |
+ var pretty bool |
|
| 199 |
+ if len(v) > 0 {
|
|
| 200 |
+ pretty = v[0] == "pretty" |
|
| 201 |
+ } |
|
| 202 |
+ return unsafe, &JSONOutput{enable: json, prettyPrint: pretty}
|
|
| 203 |
+} |
|
| 204 |
+ |
|
| 205 |
+// HTTPReply helper function that takes care of sending the message out |
|
| 206 |
+func HTTPReply(w http.ResponseWriter, r *HTTPResult, j *JSONOutput) (int, error) {
|
|
| 207 |
+ var response []byte |
|
| 208 |
+ if j.enable {
|
|
| 209 |
+ w.Header().Set("Content-Type", "application/json")
|
|
| 210 |
+ var err error |
|
| 211 |
+ if j.prettyPrint {
|
|
| 212 |
+ response, err = json.MarshalIndent(r, "", " ") |
|
| 213 |
+ if err != nil {
|
|
| 214 |
+ response, _ = json.MarshalIndent(FailCommand(err), "", " ") |
|
| 215 |
+ } |
|
| 216 |
+ } else {
|
|
| 217 |
+ response, err = json.Marshal(r) |
|
| 218 |
+ if err != nil {
|
|
| 219 |
+ response, _ = json.Marshal(FailCommand(err)) |
|
| 220 |
+ } |
|
| 221 |
+ } |
|
| 222 |
+ } else {
|
|
| 223 |
+ response = []byte(r.String()) |
|
| 224 |
+ } |
|
| 225 |
+ return fmt.Fprint(w, string(response)) |
|
| 226 |
+} |
| 0 | 227 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,122 @@ |
| 0 |
+package diagnostic |
|
| 1 |
+ |
|
| 2 |
+import "fmt" |
|
| 3 |
+ |
|
| 4 |
+// StringInterface interface that has to be implemented by messages |
|
| 5 |
+type StringInterface interface {
|
|
| 6 |
+ String() string |
|
| 7 |
+} |
|
| 8 |
+ |
|
| 9 |
+// CommandSucceed creates a success message |
|
| 10 |
+func CommandSucceed(result StringInterface) *HTTPResult {
|
|
| 11 |
+ return &HTTPResult{
|
|
| 12 |
+ Message: "OK", |
|
| 13 |
+ Details: result, |
|
| 14 |
+ } |
|
| 15 |
+} |
|
| 16 |
+ |
|
| 17 |
+// FailCommand creates a failure message with error |
|
| 18 |
+func FailCommand(err error) *HTTPResult {
|
|
| 19 |
+ return &HTTPResult{
|
|
| 20 |
+ Message: "FAIL", |
|
| 21 |
+ Details: &ErrorCmd{Error: err.Error()},
|
|
| 22 |
+ } |
|
| 23 |
+} |
|
| 24 |
+ |
|
| 25 |
+// WrongCommand creates a wrong command response |
|
| 26 |
+func WrongCommand(message, usage string) *HTTPResult {
|
|
| 27 |
+ return &HTTPResult{
|
|
| 28 |
+ Message: message, |
|
| 29 |
+ Details: &UsageCmd{Usage: usage},
|
|
| 30 |
+ } |
|
| 31 |
+} |
|
| 32 |
+ |
|
| 33 |
+// HTTPResult Diagnostic Server HTTP result operation |
|
| 34 |
+type HTTPResult struct {
|
|
| 35 |
+ Message string `json:"message"` |
|
| 36 |
+ Details StringInterface `json:"details"` |
|
| 37 |
+} |
|
| 38 |
+ |
|
| 39 |
+func (h *HTTPResult) String() string {
|
|
| 40 |
+ rsp := h.Message |
|
| 41 |
+ if h.Details != nil {
|
|
| 42 |
+ rsp += "\n" + h.Details.String() |
|
| 43 |
+ } |
|
| 44 |
+ return rsp |
|
| 45 |
+} |
|
| 46 |
+ |
|
| 47 |
+// UsageCmd command with usage field |
|
| 48 |
+type UsageCmd struct {
|
|
| 49 |
+ Usage string `json:"usage"` |
|
| 50 |
+} |
|
| 51 |
+ |
|
| 52 |
+func (u *UsageCmd) String() string {
|
|
| 53 |
+ return "Usage: " + u.Usage |
|
| 54 |
+} |
|
| 55 |
+ |
|
| 56 |
+// StringCmd command with info string |
|
| 57 |
+type StringCmd struct {
|
|
| 58 |
+ Info string `json:"info"` |
|
| 59 |
+} |
|
| 60 |
+ |
|
| 61 |
+func (s *StringCmd) String() string {
|
|
| 62 |
+ return s.Info |
|
| 63 |
+} |
|
| 64 |
+ |
|
| 65 |
+// ErrorCmd command with error |
|
| 66 |
+type ErrorCmd struct {
|
|
| 67 |
+ Error string `json:"error"` |
|
| 68 |
+} |
|
| 69 |
+ |
|
| 70 |
+func (e *ErrorCmd) String() string {
|
|
| 71 |
+ return "Error: " + e.Error |
|
| 72 |
+} |
|
| 73 |
+ |
|
| 74 |
+// TableObj network db table object |
|
| 75 |
+type TableObj struct {
|
|
| 76 |
+ Length int `json:"size"` |
|
| 77 |
+ Elements []StringInterface `json:"entries"` |
|
| 78 |
+} |
|
| 79 |
+ |
|
| 80 |
+func (t *TableObj) String() string {
|
|
| 81 |
+ output := fmt.Sprintf("total entries: %d\n", t.Length)
|
|
| 82 |
+ for _, e := range t.Elements {
|
|
| 83 |
+ output += e.String() |
|
| 84 |
+ } |
|
| 85 |
+ return output |
|
| 86 |
+} |
|
| 87 |
+ |
|
| 88 |
+// PeerEntryObj entry in the networkdb peer table |
|
| 89 |
+type PeerEntryObj struct {
|
|
| 90 |
+ Index int `json:"-"` |
|
| 91 |
+ Name string `json:"-=name"` |
|
| 92 |
+ IP string `json:"ip"` |
|
| 93 |
+} |
|
| 94 |
+ |
|
| 95 |
+func (p *PeerEntryObj) String() string {
|
|
| 96 |
+ return fmt.Sprintf("%d) %s -> %s\n", p.Index, p.Name, p.IP)
|
|
| 97 |
+} |
|
| 98 |
+ |
|
| 99 |
+// TableEntryObj network db table entry object |
|
| 100 |
+type TableEntryObj struct {
|
|
| 101 |
+ Index int `json:"-"` |
|
| 102 |
+ Key string `json:"key"` |
|
| 103 |
+ Value string `json:"value"` |
|
| 104 |
+ Owner string `json:"owner"` |
|
| 105 |
+} |
|
| 106 |
+ |
|
| 107 |
+func (t *TableEntryObj) String() string {
|
|
| 108 |
+ return fmt.Sprintf("%d) k:`%s` -> v:`%s` owner:`%s`\n", t.Index, t.Key, t.Value, t.Owner)
|
|
| 109 |
+} |
|
| 110 |
+ |
|
| 111 |
+// TableEndpointsResult fully typed message for proper unmarshaling on the client side |
|
| 112 |
+type TableEndpointsResult struct {
|
|
| 113 |
+ TableObj |
|
| 114 |
+ Elements []TableEntryObj `json:"entries"` |
|
| 115 |
+} |
|
| 116 |
+ |
|
| 117 |
+// TablePeersResult fully typed message for proper unmarshaling on the client side |
|
| 118 |
+type TablePeersResult struct {
|
|
| 119 |
+ TableObj |
|
| 120 |
+ Elements []PeerEntryObj `json:"entries"` |
|
| 121 |
+} |
| ... | ... |
@@ -328,6 +328,9 @@ func (nDB *NetworkDB) GetEntry(tname, nid, key string) ([]byte, error) {
|
| 328 | 328 |
if err != nil {
|
| 329 | 329 |
return nil, err |
| 330 | 330 |
} |
| 331 |
+ if entry != nil && entry.deleting {
|
|
| 332 |
+ return nil, types.NotFoundErrorf("entry in table %s network id %s and key %s deleted and pending garbage collection", tname, nid, key)
|
|
| 333 |
+ } |
|
| 331 | 334 |
|
| 332 | 335 |
return entry.value, nil |
| 333 | 336 |
} |
| ... | ... |
@@ -7,6 +7,7 @@ import ( |
| 7 | 7 |
"log" |
| 8 | 8 |
"net" |
| 9 | 9 |
"os" |
| 10 |
+ "strings" |
|
| 10 | 11 |
"sync/atomic" |
| 11 | 12 |
"testing" |
| 12 | 13 |
"time" |
| ... | ... |
@@ -446,6 +447,12 @@ func TestNetworkDBCRUDMediumCluster(t *testing.T) {
|
| 446 | 446 |
dbs[i].verifyEntryExistence(t, "test_table", "network1", "test_key", "", false) |
| 447 | 447 |
} |
| 448 | 448 |
|
| 449 |
+ for i := 1; i < n; i++ {
|
|
| 450 |
+ _, err = dbs[i].GetEntry("test_table", "network1", "test_key")
|
|
| 451 |
+ assert.Error(t, err) |
|
| 452 |
+ assert.True(t, strings.Contains(err.Error(), "deleted and pending garbage collection")) |
|
| 453 |
+ } |
|
| 454 |
+ |
|
| 449 | 455 |
closeNetworkDBInstances(dbs) |
| 450 | 456 |
} |
| 451 | 457 |
|
| 452 | 458 |
deleted file mode 100644 |
| ... | ... |
@@ -1,409 +0,0 @@ |
| 1 |
-package networkdb |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "encoding/base64" |
|
| 5 |
- "fmt" |
|
| 6 |
- "net/http" |
|
| 7 |
- "strings" |
|
| 8 |
- |
|
| 9 |
- "github.com/docker/libnetwork/common" |
|
| 10 |
- "github.com/docker/libnetwork/diagnose" |
|
| 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]diagnose.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 |
-} |
|
| 32 |
- |
|
| 33 |
-func dbJoin(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 34 |
- r.ParseForm() |
|
| 35 |
- diagnose.DebugHTTPForm(r) |
|
| 36 |
- _, json := diagnose.ParseHTTPFormOptions(r) |
|
| 37 |
- |
|
| 38 |
- // audit logs |
|
| 39 |
- log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 40 |
- log.Info("join cluster")
|
|
| 41 |
- |
|
| 42 |
- if len(r.Form["members"]) < 1 {
|
|
| 43 |
- rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?members=ip1,ip2,...", r.URL.Path))
|
|
| 44 |
- log.Error("join cluster failed, wrong input")
|
|
| 45 |
- diagnose.HTTPReply(w, rsp, json) |
|
| 46 |
- return |
|
| 47 |
- } |
|
| 48 |
- |
|
| 49 |
- nDB, ok := ctx.(*NetworkDB) |
|
| 50 |
- if ok {
|
|
| 51 |
- err := nDB.Join(strings.Split(r.Form["members"][0], ",")) |
|
| 52 |
- if err != nil {
|
|
| 53 |
- rsp := diagnose.FailCommand(fmt.Errorf("%s error in the DB join %s", r.URL.Path, err))
|
|
| 54 |
- log.WithError(err).Error("join cluster failed")
|
|
| 55 |
- diagnose.HTTPReply(w, rsp, json) |
|
| 56 |
- return |
|
| 57 |
- } |
|
| 58 |
- |
|
| 59 |
- log.Info("join cluster done")
|
|
| 60 |
- diagnose.HTTPReply(w, diagnose.CommandSucceed(nil), json) |
|
| 61 |
- return |
|
| 62 |
- } |
|
| 63 |
- diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 64 |
-} |
|
| 65 |
- |
|
| 66 |
-func dbPeers(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 67 |
- r.ParseForm() |
|
| 68 |
- diagnose.DebugHTTPForm(r) |
|
| 69 |
- _, json := diagnose.ParseHTTPFormOptions(r) |
|
| 70 |
- |
|
| 71 |
- // audit logs |
|
| 72 |
- log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 73 |
- log.Info("network peers")
|
|
| 74 |
- |
|
| 75 |
- if len(r.Form["nid"]) < 1 {
|
|
| 76 |
- rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=test", r.URL.Path))
|
|
| 77 |
- log.Error("network peers failed, wrong input")
|
|
| 78 |
- diagnose.HTTPReply(w, rsp, json) |
|
| 79 |
- return |
|
| 80 |
- } |
|
| 81 |
- |
|
| 82 |
- nDB, ok := ctx.(*NetworkDB) |
|
| 83 |
- if ok {
|
|
| 84 |
- peers := nDB.Peers(r.Form["nid"][0]) |
|
| 85 |
- rsp := &diagnose.TableObj{Length: len(peers)}
|
|
| 86 |
- for i, peerInfo := range peers {
|
|
| 87 |
- rsp.Elements = append(rsp.Elements, &diagnose.PeerEntryObj{Index: i, Name: peerInfo.Name, IP: peerInfo.IP})
|
|
| 88 |
- } |
|
| 89 |
- log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("network peers done")
|
|
| 90 |
- diagnose.HTTPReply(w, diagnose.CommandSucceed(rsp), json) |
|
| 91 |
- return |
|
| 92 |
- } |
|
| 93 |
- diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 94 |
-} |
|
| 95 |
- |
|
| 96 |
-func dbClusterPeers(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 97 |
- r.ParseForm() |
|
| 98 |
- diagnose.DebugHTTPForm(r) |
|
| 99 |
- _, json := diagnose.ParseHTTPFormOptions(r) |
|
| 100 |
- |
|
| 101 |
- // audit logs |
|
| 102 |
- log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 103 |
- log.Info("cluster peers")
|
|
| 104 |
- |
|
| 105 |
- nDB, ok := ctx.(*NetworkDB) |
|
| 106 |
- if ok {
|
|
| 107 |
- peers := nDB.ClusterPeers() |
|
| 108 |
- rsp := &diagnose.TableObj{Length: len(peers)}
|
|
| 109 |
- for i, peerInfo := range peers {
|
|
| 110 |
- rsp.Elements = append(rsp.Elements, &diagnose.PeerEntryObj{Index: i, Name: peerInfo.Name, IP: peerInfo.IP})
|
|
| 111 |
- } |
|
| 112 |
- log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("cluster peers done")
|
|
| 113 |
- diagnose.HTTPReply(w, diagnose.CommandSucceed(rsp), json) |
|
| 114 |
- return |
|
| 115 |
- } |
|
| 116 |
- diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 117 |
-} |
|
| 118 |
- |
|
| 119 |
-func dbCreateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 120 |
- r.ParseForm() |
|
| 121 |
- diagnose.DebugHTTPForm(r) |
|
| 122 |
- unsafe, json := diagnose.ParseHTTPFormOptions(r) |
|
| 123 |
- |
|
| 124 |
- // audit logs |
|
| 125 |
- log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 126 |
- log.Info("create entry")
|
|
| 127 |
- |
|
| 128 |
- if len(r.Form["tname"]) < 1 || |
|
| 129 |
- len(r.Form["nid"]) < 1 || |
|
| 130 |
- len(r.Form["key"]) < 1 || |
|
| 131 |
- len(r.Form["value"]) < 1 {
|
|
| 132 |
- rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k&value=v", r.URL.Path))
|
|
| 133 |
- log.Error("create entry failed, wrong input")
|
|
| 134 |
- diagnose.HTTPReply(w, rsp, json) |
|
| 135 |
- return |
|
| 136 |
- } |
|
| 137 |
- |
|
| 138 |
- tname := r.Form["tname"][0] |
|
| 139 |
- nid := r.Form["nid"][0] |
|
| 140 |
- key := r.Form["key"][0] |
|
| 141 |
- value := r.Form["value"][0] |
|
| 142 |
- decodedValue := []byte(value) |
|
| 143 |
- if !unsafe {
|
|
| 144 |
- var err error |
|
| 145 |
- decodedValue, err = base64.StdEncoding.DecodeString(value) |
|
| 146 |
- if err != nil {
|
|
| 147 |
- log.WithError(err).Error("create entry failed")
|
|
| 148 |
- diagnose.HTTPReply(w, diagnose.FailCommand(err), json) |
|
| 149 |
- return |
|
| 150 |
- } |
|
| 151 |
- } |
|
| 152 |
- |
|
| 153 |
- nDB, ok := ctx.(*NetworkDB) |
|
| 154 |
- if ok {
|
|
| 155 |
- if err := nDB.CreateEntry(tname, nid, key, decodedValue); err != nil {
|
|
| 156 |
- rsp := diagnose.FailCommand(err) |
|
| 157 |
- diagnose.HTTPReply(w, rsp, json) |
|
| 158 |
- log.WithError(err).Error("create entry failed")
|
|
| 159 |
- return |
|
| 160 |
- } |
|
| 161 |
- log.Info("create entry done")
|
|
| 162 |
- diagnose.HTTPReply(w, diagnose.CommandSucceed(nil), json) |
|
| 163 |
- return |
|
| 164 |
- } |
|
| 165 |
- diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 166 |
-} |
|
| 167 |
- |
|
| 168 |
-func dbUpdateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 169 |
- r.ParseForm() |
|
| 170 |
- diagnose.DebugHTTPForm(r) |
|
| 171 |
- unsafe, json := diagnose.ParseHTTPFormOptions(r) |
|
| 172 |
- |
|
| 173 |
- // audit logs |
|
| 174 |
- log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 175 |
- log.Info("update entry")
|
|
| 176 |
- |
|
| 177 |
- if len(r.Form["tname"]) < 1 || |
|
| 178 |
- len(r.Form["nid"]) < 1 || |
|
| 179 |
- len(r.Form["key"]) < 1 || |
|
| 180 |
- len(r.Form["value"]) < 1 {
|
|
| 181 |
- rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k&value=v", r.URL.Path))
|
|
| 182 |
- log.Error("update entry failed, wrong input")
|
|
| 183 |
- diagnose.HTTPReply(w, rsp, json) |
|
| 184 |
- return |
|
| 185 |
- } |
|
| 186 |
- |
|
| 187 |
- tname := r.Form["tname"][0] |
|
| 188 |
- nid := r.Form["nid"][0] |
|
| 189 |
- key := r.Form["key"][0] |
|
| 190 |
- value := r.Form["value"][0] |
|
| 191 |
- decodedValue := []byte(value) |
|
| 192 |
- if !unsafe {
|
|
| 193 |
- var err error |
|
| 194 |
- decodedValue, err = base64.StdEncoding.DecodeString(value) |
|
| 195 |
- if err != nil {
|
|
| 196 |
- log.WithError(err).Error("update entry failed")
|
|
| 197 |
- diagnose.HTTPReply(w, diagnose.FailCommand(err), json) |
|
| 198 |
- return |
|
| 199 |
- } |
|
| 200 |
- } |
|
| 201 |
- |
|
| 202 |
- nDB, ok := ctx.(*NetworkDB) |
|
| 203 |
- if ok {
|
|
| 204 |
- if err := nDB.UpdateEntry(tname, nid, key, decodedValue); err != nil {
|
|
| 205 |
- log.WithError(err).Error("update entry failed")
|
|
| 206 |
- diagnose.HTTPReply(w, diagnose.FailCommand(err), json) |
|
| 207 |
- return |
|
| 208 |
- } |
|
| 209 |
- log.Info("update entry done")
|
|
| 210 |
- diagnose.HTTPReply(w, diagnose.CommandSucceed(nil), json) |
|
| 211 |
- return |
|
| 212 |
- } |
|
| 213 |
- diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 214 |
-} |
|
| 215 |
- |
|
| 216 |
-func dbDeleteEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 217 |
- r.ParseForm() |
|
| 218 |
- diagnose.DebugHTTPForm(r) |
|
| 219 |
- _, json := diagnose.ParseHTTPFormOptions(r) |
|
| 220 |
- |
|
| 221 |
- // audit logs |
|
| 222 |
- log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 223 |
- log.Info("delete entry")
|
|
| 224 |
- |
|
| 225 |
- if len(r.Form["tname"]) < 1 || |
|
| 226 |
- len(r.Form["nid"]) < 1 || |
|
| 227 |
- len(r.Form["key"]) < 1 {
|
|
| 228 |
- rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k", r.URL.Path))
|
|
| 229 |
- log.Error("delete entry failed, wrong input")
|
|
| 230 |
- diagnose.HTTPReply(w, rsp, json) |
|
| 231 |
- return |
|
| 232 |
- } |
|
| 233 |
- |
|
| 234 |
- tname := r.Form["tname"][0] |
|
| 235 |
- nid := r.Form["nid"][0] |
|
| 236 |
- key := r.Form["key"][0] |
|
| 237 |
- |
|
| 238 |
- nDB, ok := ctx.(*NetworkDB) |
|
| 239 |
- if ok {
|
|
| 240 |
- err := nDB.DeleteEntry(tname, nid, key) |
|
| 241 |
- if err != nil {
|
|
| 242 |
- log.WithError(err).Error("delete entry failed")
|
|
| 243 |
- diagnose.HTTPReply(w, diagnose.FailCommand(err), json) |
|
| 244 |
- return |
|
| 245 |
- } |
|
| 246 |
- log.Info("delete entry done")
|
|
| 247 |
- diagnose.HTTPReply(w, diagnose.CommandSucceed(nil), json) |
|
| 248 |
- return |
|
| 249 |
- } |
|
| 250 |
- diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 251 |
-} |
|
| 252 |
- |
|
| 253 |
-func dbGetEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 254 |
- r.ParseForm() |
|
| 255 |
- diagnose.DebugHTTPForm(r) |
|
| 256 |
- unsafe, json := diagnose.ParseHTTPFormOptions(r) |
|
| 257 |
- |
|
| 258 |
- // audit logs |
|
| 259 |
- log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 260 |
- log.Info("get entry")
|
|
| 261 |
- |
|
| 262 |
- if len(r.Form["tname"]) < 1 || |
|
| 263 |
- len(r.Form["nid"]) < 1 || |
|
| 264 |
- len(r.Form["key"]) < 1 {
|
|
| 265 |
- rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k", r.URL.Path))
|
|
| 266 |
- log.Error("get entry failed, wrong input")
|
|
| 267 |
- diagnose.HTTPReply(w, rsp, json) |
|
| 268 |
- return |
|
| 269 |
- } |
|
| 270 |
- |
|
| 271 |
- tname := r.Form["tname"][0] |
|
| 272 |
- nid := r.Form["nid"][0] |
|
| 273 |
- key := r.Form["key"][0] |
|
| 274 |
- |
|
| 275 |
- nDB, ok := ctx.(*NetworkDB) |
|
| 276 |
- if ok {
|
|
| 277 |
- value, err := nDB.GetEntry(tname, nid, key) |
|
| 278 |
- if err != nil {
|
|
| 279 |
- log.WithError(err).Error("get entry failed")
|
|
| 280 |
- diagnose.HTTPReply(w, diagnose.FailCommand(err), json) |
|
| 281 |
- return |
|
| 282 |
- } |
|
| 283 |
- |
|
| 284 |
- var encodedValue string |
|
| 285 |
- if unsafe {
|
|
| 286 |
- encodedValue = string(value) |
|
| 287 |
- } else {
|
|
| 288 |
- encodedValue = base64.StdEncoding.EncodeToString(value) |
|
| 289 |
- } |
|
| 290 |
- |
|
| 291 |
- rsp := &diagnose.TableEntryObj{Key: key, Value: encodedValue}
|
|
| 292 |
- log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("update entry done")
|
|
| 293 |
- diagnose.HTTPReply(w, diagnose.CommandSucceed(rsp), json) |
|
| 294 |
- return |
|
| 295 |
- } |
|
| 296 |
- diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 297 |
-} |
|
| 298 |
- |
|
| 299 |
-func dbJoinNetwork(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 300 |
- r.ParseForm() |
|
| 301 |
- diagnose.DebugHTTPForm(r) |
|
| 302 |
- _, json := diagnose.ParseHTTPFormOptions(r) |
|
| 303 |
- |
|
| 304 |
- // audit logs |
|
| 305 |
- log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 306 |
- log.Info("join network")
|
|
| 307 |
- |
|
| 308 |
- if len(r.Form["nid"]) < 1 {
|
|
| 309 |
- rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=network_id", r.URL.Path))
|
|
| 310 |
- log.Error("join network failed, wrong input")
|
|
| 311 |
- diagnose.HTTPReply(w, rsp, json) |
|
| 312 |
- return |
|
| 313 |
- } |
|
| 314 |
- |
|
| 315 |
- nid := r.Form["nid"][0] |
|
| 316 |
- |
|
| 317 |
- nDB, ok := ctx.(*NetworkDB) |
|
| 318 |
- if ok {
|
|
| 319 |
- if err := nDB.JoinNetwork(nid); err != nil {
|
|
| 320 |
- log.WithError(err).Error("join network failed")
|
|
| 321 |
- diagnose.HTTPReply(w, diagnose.FailCommand(err), json) |
|
| 322 |
- return |
|
| 323 |
- } |
|
| 324 |
- log.Info("join network done")
|
|
| 325 |
- diagnose.HTTPReply(w, diagnose.CommandSucceed(nil), json) |
|
| 326 |
- return |
|
| 327 |
- } |
|
| 328 |
- diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 329 |
-} |
|
| 330 |
- |
|
| 331 |
-func dbLeaveNetwork(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 332 |
- r.ParseForm() |
|
| 333 |
- diagnose.DebugHTTPForm(r) |
|
| 334 |
- _, json := diagnose.ParseHTTPFormOptions(r) |
|
| 335 |
- |
|
| 336 |
- // audit logs |
|
| 337 |
- log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 338 |
- log.Info("leave network")
|
|
| 339 |
- |
|
| 340 |
- if len(r.Form["nid"]) < 1 {
|
|
| 341 |
- rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=network_id", r.URL.Path))
|
|
| 342 |
- log.Error("leave network failed, wrong input")
|
|
| 343 |
- diagnose.HTTPReply(w, rsp, json) |
|
| 344 |
- return |
|
| 345 |
- } |
|
| 346 |
- |
|
| 347 |
- nid := r.Form["nid"][0] |
|
| 348 |
- |
|
| 349 |
- nDB, ok := ctx.(*NetworkDB) |
|
| 350 |
- if ok {
|
|
| 351 |
- if err := nDB.LeaveNetwork(nid); err != nil {
|
|
| 352 |
- log.WithError(err).Error("leave network failed")
|
|
| 353 |
- diagnose.HTTPReply(w, diagnose.FailCommand(err), json) |
|
| 354 |
- return |
|
| 355 |
- } |
|
| 356 |
- log.Info("leave network done")
|
|
| 357 |
- diagnose.HTTPReply(w, diagnose.CommandSucceed(nil), json) |
|
| 358 |
- return |
|
| 359 |
- } |
|
| 360 |
- diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 361 |
-} |
|
| 362 |
- |
|
| 363 |
-func dbGetTable(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 364 |
- r.ParseForm() |
|
| 365 |
- diagnose.DebugHTTPForm(r) |
|
| 366 |
- unsafe, json := diagnose.ParseHTTPFormOptions(r) |
|
| 367 |
- |
|
| 368 |
- // audit logs |
|
| 369 |
- log := logrus.WithFields(logrus.Fields{"component": "diagnose", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 370 |
- log.Info("get table")
|
|
| 371 |
- |
|
| 372 |
- if len(r.Form["tname"]) < 1 || |
|
| 373 |
- len(r.Form["nid"]) < 1 {
|
|
| 374 |
- rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id", r.URL.Path))
|
|
| 375 |
- log.Error("get table failed, wrong input")
|
|
| 376 |
- diagnose.HTTPReply(w, rsp, json) |
|
| 377 |
- return |
|
| 378 |
- } |
|
| 379 |
- |
|
| 380 |
- tname := r.Form["tname"][0] |
|
| 381 |
- nid := r.Form["nid"][0] |
|
| 382 |
- |
|
| 383 |
- nDB, ok := ctx.(*NetworkDB) |
|
| 384 |
- if ok {
|
|
| 385 |
- table := nDB.GetTableByNetwork(tname, nid) |
|
| 386 |
- rsp := &diagnose.TableObj{Length: len(table)}
|
|
| 387 |
- var i = 0 |
|
| 388 |
- for k, v := range table {
|
|
| 389 |
- var encodedValue string |
|
| 390 |
- if unsafe {
|
|
| 391 |
- encodedValue = string(v.Value) |
|
| 392 |
- } else {
|
|
| 393 |
- encodedValue = base64.StdEncoding.EncodeToString(v.Value) |
|
| 394 |
- } |
|
| 395 |
- rsp.Elements = append(rsp.Elements, |
|
| 396 |
- &diagnose.TableEntryObj{
|
|
| 397 |
- Index: i, |
|
| 398 |
- Key: k, |
|
| 399 |
- Value: encodedValue, |
|
| 400 |
- Owner: v.owner, |
|
| 401 |
- }) |
|
| 402 |
- i++ |
|
| 403 |
- } |
|
| 404 |
- log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("get table done")
|
|
| 405 |
- diagnose.HTTPReply(w, diagnose.CommandSucceed(rsp), json) |
|
| 406 |
- return |
|
| 407 |
- } |
|
| 408 |
- diagnose.HTTPReply(w, diagnose.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 409 |
-} |
| 410 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,409 @@ |
| 0 |
+package networkdb |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "encoding/base64" |
|
| 4 |
+ "fmt" |
|
| 5 |
+ "net/http" |
|
| 6 |
+ "strings" |
|
| 7 |
+ |
|
| 8 |
+ "github.com/docker/libnetwork/common" |
|
| 9 |
+ "github.com/docker/libnetwork/diagnostic" |
|
| 10 |
+ "github.com/sirupsen/logrus" |
|
| 11 |
+) |
|
| 12 |
+ |
|
| 13 |
+const ( |
|
| 14 |
+ missingParameter = "missing parameter" |
|
| 15 |
+ dbNotAvailable = "database not available" |
|
| 16 |
+) |
|
| 17 |
+ |
|
| 18 |
+// NetDbPaths2Func TODO |
|
| 19 |
+var NetDbPaths2Func = map[string]diagnostic.HTTPHandlerFunc{
|
|
| 20 |
+ "/join": dbJoin, |
|
| 21 |
+ "/networkpeers": dbPeers, |
|
| 22 |
+ "/clusterpeers": dbClusterPeers, |
|
| 23 |
+ "/joinnetwork": dbJoinNetwork, |
|
| 24 |
+ "/leavenetwork": dbLeaveNetwork, |
|
| 25 |
+ "/createentry": dbCreateEntry, |
|
| 26 |
+ "/updateentry": dbUpdateEntry, |
|
| 27 |
+ "/deleteentry": dbDeleteEntry, |
|
| 28 |
+ "/getentry": dbGetEntry, |
|
| 29 |
+ "/gettable": dbGetTable, |
|
| 30 |
+} |
|
| 31 |
+ |
|
| 32 |
+func dbJoin(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 33 |
+ r.ParseForm() |
|
| 34 |
+ diagnostic.DebugHTTPForm(r) |
|
| 35 |
+ _, json := diagnostic.ParseHTTPFormOptions(r) |
|
| 36 |
+ |
|
| 37 |
+ // audit logs |
|
| 38 |
+ log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 39 |
+ log.Info("join cluster")
|
|
| 40 |
+ |
|
| 41 |
+ if len(r.Form["members"]) < 1 {
|
|
| 42 |
+ rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?members=ip1,ip2,...", r.URL.Path))
|
|
| 43 |
+ log.Error("join cluster failed, wrong input")
|
|
| 44 |
+ diagnostic.HTTPReply(w, rsp, json) |
|
| 45 |
+ return |
|
| 46 |
+ } |
|
| 47 |
+ |
|
| 48 |
+ nDB, ok := ctx.(*NetworkDB) |
|
| 49 |
+ if ok {
|
|
| 50 |
+ err := nDB.Join(strings.Split(r.Form["members"][0], ",")) |
|
| 51 |
+ if err != nil {
|
|
| 52 |
+ rsp := diagnostic.FailCommand(fmt.Errorf("%s error in the DB join %s", r.URL.Path, err))
|
|
| 53 |
+ log.WithError(err).Error("join cluster failed")
|
|
| 54 |
+ diagnostic.HTTPReply(w, rsp, json) |
|
| 55 |
+ return |
|
| 56 |
+ } |
|
| 57 |
+ |
|
| 58 |
+ log.Info("join cluster done")
|
|
| 59 |
+ diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json) |
|
| 60 |
+ return |
|
| 61 |
+ } |
|
| 62 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 63 |
+} |
|
| 64 |
+ |
|
| 65 |
+func dbPeers(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 66 |
+ r.ParseForm() |
|
| 67 |
+ diagnostic.DebugHTTPForm(r) |
|
| 68 |
+ _, json := diagnostic.ParseHTTPFormOptions(r) |
|
| 69 |
+ |
|
| 70 |
+ // audit logs |
|
| 71 |
+ log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 72 |
+ log.Info("network peers")
|
|
| 73 |
+ |
|
| 74 |
+ if len(r.Form["nid"]) < 1 {
|
|
| 75 |
+ rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=test", r.URL.Path))
|
|
| 76 |
+ log.Error("network peers failed, wrong input")
|
|
| 77 |
+ diagnostic.HTTPReply(w, rsp, json) |
|
| 78 |
+ return |
|
| 79 |
+ } |
|
| 80 |
+ |
|
| 81 |
+ nDB, ok := ctx.(*NetworkDB) |
|
| 82 |
+ if ok {
|
|
| 83 |
+ peers := nDB.Peers(r.Form["nid"][0]) |
|
| 84 |
+ rsp := &diagnostic.TableObj{Length: len(peers)}
|
|
| 85 |
+ for i, peerInfo := range peers {
|
|
| 86 |
+ rsp.Elements = append(rsp.Elements, &diagnostic.PeerEntryObj{Index: i, Name: peerInfo.Name, IP: peerInfo.IP})
|
|
| 87 |
+ } |
|
| 88 |
+ log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("network peers done")
|
|
| 89 |
+ diagnostic.HTTPReply(w, diagnostic.CommandSucceed(rsp), json) |
|
| 90 |
+ return |
|
| 91 |
+ } |
|
| 92 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 93 |
+} |
|
| 94 |
+ |
|
| 95 |
+func dbClusterPeers(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 96 |
+ r.ParseForm() |
|
| 97 |
+ diagnostic.DebugHTTPForm(r) |
|
| 98 |
+ _, json := diagnostic.ParseHTTPFormOptions(r) |
|
| 99 |
+ |
|
| 100 |
+ // audit logs |
|
| 101 |
+ log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 102 |
+ log.Info("cluster peers")
|
|
| 103 |
+ |
|
| 104 |
+ nDB, ok := ctx.(*NetworkDB) |
|
| 105 |
+ if ok {
|
|
| 106 |
+ peers := nDB.ClusterPeers() |
|
| 107 |
+ rsp := &diagnostic.TableObj{Length: len(peers)}
|
|
| 108 |
+ for i, peerInfo := range peers {
|
|
| 109 |
+ rsp.Elements = append(rsp.Elements, &diagnostic.PeerEntryObj{Index: i, Name: peerInfo.Name, IP: peerInfo.IP})
|
|
| 110 |
+ } |
|
| 111 |
+ log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("cluster peers done")
|
|
| 112 |
+ diagnostic.HTTPReply(w, diagnostic.CommandSucceed(rsp), json) |
|
| 113 |
+ return |
|
| 114 |
+ } |
|
| 115 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 116 |
+} |
|
| 117 |
+ |
|
| 118 |
+func dbCreateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 119 |
+ r.ParseForm() |
|
| 120 |
+ diagnostic.DebugHTTPForm(r) |
|
| 121 |
+ unsafe, json := diagnostic.ParseHTTPFormOptions(r) |
|
| 122 |
+ |
|
| 123 |
+ // audit logs |
|
| 124 |
+ log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 125 |
+ log.Info("create entry")
|
|
| 126 |
+ |
|
| 127 |
+ if len(r.Form["tname"]) < 1 || |
|
| 128 |
+ len(r.Form["nid"]) < 1 || |
|
| 129 |
+ len(r.Form["key"]) < 1 || |
|
| 130 |
+ len(r.Form["value"]) < 1 {
|
|
| 131 |
+ rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k&value=v", r.URL.Path))
|
|
| 132 |
+ log.Error("create entry failed, wrong input")
|
|
| 133 |
+ diagnostic.HTTPReply(w, rsp, json) |
|
| 134 |
+ return |
|
| 135 |
+ } |
|
| 136 |
+ |
|
| 137 |
+ tname := r.Form["tname"][0] |
|
| 138 |
+ nid := r.Form["nid"][0] |
|
| 139 |
+ key := r.Form["key"][0] |
|
| 140 |
+ value := r.Form["value"][0] |
|
| 141 |
+ decodedValue := []byte(value) |
|
| 142 |
+ if !unsafe {
|
|
| 143 |
+ var err error |
|
| 144 |
+ decodedValue, err = base64.StdEncoding.DecodeString(value) |
|
| 145 |
+ if err != nil {
|
|
| 146 |
+ log.WithError(err).Error("create entry failed")
|
|
| 147 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json) |
|
| 148 |
+ return |
|
| 149 |
+ } |
|
| 150 |
+ } |
|
| 151 |
+ |
|
| 152 |
+ nDB, ok := ctx.(*NetworkDB) |
|
| 153 |
+ if ok {
|
|
| 154 |
+ if err := nDB.CreateEntry(tname, nid, key, decodedValue); err != nil {
|
|
| 155 |
+ rsp := diagnostic.FailCommand(err) |
|
| 156 |
+ diagnostic.HTTPReply(w, rsp, json) |
|
| 157 |
+ log.WithError(err).Error("create entry failed")
|
|
| 158 |
+ return |
|
| 159 |
+ } |
|
| 160 |
+ log.Info("create entry done")
|
|
| 161 |
+ diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json) |
|
| 162 |
+ return |
|
| 163 |
+ } |
|
| 164 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 165 |
+} |
|
| 166 |
+ |
|
| 167 |
+func dbUpdateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 168 |
+ r.ParseForm() |
|
| 169 |
+ diagnostic.DebugHTTPForm(r) |
|
| 170 |
+ unsafe, json := diagnostic.ParseHTTPFormOptions(r) |
|
| 171 |
+ |
|
| 172 |
+ // audit logs |
|
| 173 |
+ log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 174 |
+ log.Info("update entry")
|
|
| 175 |
+ |
|
| 176 |
+ if len(r.Form["tname"]) < 1 || |
|
| 177 |
+ len(r.Form["nid"]) < 1 || |
|
| 178 |
+ len(r.Form["key"]) < 1 || |
|
| 179 |
+ len(r.Form["value"]) < 1 {
|
|
| 180 |
+ rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k&value=v", r.URL.Path))
|
|
| 181 |
+ log.Error("update entry failed, wrong input")
|
|
| 182 |
+ diagnostic.HTTPReply(w, rsp, json) |
|
| 183 |
+ return |
|
| 184 |
+ } |
|
| 185 |
+ |
|
| 186 |
+ tname := r.Form["tname"][0] |
|
| 187 |
+ nid := r.Form["nid"][0] |
|
| 188 |
+ key := r.Form["key"][0] |
|
| 189 |
+ value := r.Form["value"][0] |
|
| 190 |
+ decodedValue := []byte(value) |
|
| 191 |
+ if !unsafe {
|
|
| 192 |
+ var err error |
|
| 193 |
+ decodedValue, err = base64.StdEncoding.DecodeString(value) |
|
| 194 |
+ if err != nil {
|
|
| 195 |
+ log.WithError(err).Error("update entry failed")
|
|
| 196 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json) |
|
| 197 |
+ return |
|
| 198 |
+ } |
|
| 199 |
+ } |
|
| 200 |
+ |
|
| 201 |
+ nDB, ok := ctx.(*NetworkDB) |
|
| 202 |
+ if ok {
|
|
| 203 |
+ if err := nDB.UpdateEntry(tname, nid, key, decodedValue); err != nil {
|
|
| 204 |
+ log.WithError(err).Error("update entry failed")
|
|
| 205 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json) |
|
| 206 |
+ return |
|
| 207 |
+ } |
|
| 208 |
+ log.Info("update entry done")
|
|
| 209 |
+ diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json) |
|
| 210 |
+ return |
|
| 211 |
+ } |
|
| 212 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 213 |
+} |
|
| 214 |
+ |
|
| 215 |
+func dbDeleteEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 216 |
+ r.ParseForm() |
|
| 217 |
+ diagnostic.DebugHTTPForm(r) |
|
| 218 |
+ _, json := diagnostic.ParseHTTPFormOptions(r) |
|
| 219 |
+ |
|
| 220 |
+ // audit logs |
|
| 221 |
+ log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 222 |
+ log.Info("delete entry")
|
|
| 223 |
+ |
|
| 224 |
+ if len(r.Form["tname"]) < 1 || |
|
| 225 |
+ len(r.Form["nid"]) < 1 || |
|
| 226 |
+ len(r.Form["key"]) < 1 {
|
|
| 227 |
+ rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k", r.URL.Path))
|
|
| 228 |
+ log.Error("delete entry failed, wrong input")
|
|
| 229 |
+ diagnostic.HTTPReply(w, rsp, json) |
|
| 230 |
+ return |
|
| 231 |
+ } |
|
| 232 |
+ |
|
| 233 |
+ tname := r.Form["tname"][0] |
|
| 234 |
+ nid := r.Form["nid"][0] |
|
| 235 |
+ key := r.Form["key"][0] |
|
| 236 |
+ |
|
| 237 |
+ nDB, ok := ctx.(*NetworkDB) |
|
| 238 |
+ if ok {
|
|
| 239 |
+ err := nDB.DeleteEntry(tname, nid, key) |
|
| 240 |
+ if err != nil {
|
|
| 241 |
+ log.WithError(err).Error("delete entry failed")
|
|
| 242 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json) |
|
| 243 |
+ return |
|
| 244 |
+ } |
|
| 245 |
+ log.Info("delete entry done")
|
|
| 246 |
+ diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json) |
|
| 247 |
+ return |
|
| 248 |
+ } |
|
| 249 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 250 |
+} |
|
| 251 |
+ |
|
| 252 |
+func dbGetEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 253 |
+ r.ParseForm() |
|
| 254 |
+ diagnostic.DebugHTTPForm(r) |
|
| 255 |
+ unsafe, json := diagnostic.ParseHTTPFormOptions(r) |
|
| 256 |
+ |
|
| 257 |
+ // audit logs |
|
| 258 |
+ log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 259 |
+ log.Info("get entry")
|
|
| 260 |
+ |
|
| 261 |
+ if len(r.Form["tname"]) < 1 || |
|
| 262 |
+ len(r.Form["nid"]) < 1 || |
|
| 263 |
+ len(r.Form["key"]) < 1 {
|
|
| 264 |
+ rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k", r.URL.Path))
|
|
| 265 |
+ log.Error("get entry failed, wrong input")
|
|
| 266 |
+ diagnostic.HTTPReply(w, rsp, json) |
|
| 267 |
+ return |
|
| 268 |
+ } |
|
| 269 |
+ |
|
| 270 |
+ tname := r.Form["tname"][0] |
|
| 271 |
+ nid := r.Form["nid"][0] |
|
| 272 |
+ key := r.Form["key"][0] |
|
| 273 |
+ |
|
| 274 |
+ nDB, ok := ctx.(*NetworkDB) |
|
| 275 |
+ if ok {
|
|
| 276 |
+ value, err := nDB.GetEntry(tname, nid, key) |
|
| 277 |
+ if err != nil {
|
|
| 278 |
+ log.WithError(err).Error("get entry failed")
|
|
| 279 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json) |
|
| 280 |
+ return |
|
| 281 |
+ } |
|
| 282 |
+ |
|
| 283 |
+ var encodedValue string |
|
| 284 |
+ if unsafe {
|
|
| 285 |
+ encodedValue = string(value) |
|
| 286 |
+ } else {
|
|
| 287 |
+ encodedValue = base64.StdEncoding.EncodeToString(value) |
|
| 288 |
+ } |
|
| 289 |
+ |
|
| 290 |
+ rsp := &diagnostic.TableEntryObj{Key: key, Value: encodedValue}
|
|
| 291 |
+ log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("get entry done")
|
|
| 292 |
+ diagnostic.HTTPReply(w, diagnostic.CommandSucceed(rsp), json) |
|
| 293 |
+ return |
|
| 294 |
+ } |
|
| 295 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 296 |
+} |
|
| 297 |
+ |
|
| 298 |
+func dbJoinNetwork(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 299 |
+ r.ParseForm() |
|
| 300 |
+ diagnostic.DebugHTTPForm(r) |
|
| 301 |
+ _, json := diagnostic.ParseHTTPFormOptions(r) |
|
| 302 |
+ |
|
| 303 |
+ // audit logs |
|
| 304 |
+ log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 305 |
+ log.Info("join network")
|
|
| 306 |
+ |
|
| 307 |
+ if len(r.Form["nid"]) < 1 {
|
|
| 308 |
+ rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=network_id", r.URL.Path))
|
|
| 309 |
+ log.Error("join network failed, wrong input")
|
|
| 310 |
+ diagnostic.HTTPReply(w, rsp, json) |
|
| 311 |
+ return |
|
| 312 |
+ } |
|
| 313 |
+ |
|
| 314 |
+ nid := r.Form["nid"][0] |
|
| 315 |
+ |
|
| 316 |
+ nDB, ok := ctx.(*NetworkDB) |
|
| 317 |
+ if ok {
|
|
| 318 |
+ if err := nDB.JoinNetwork(nid); err != nil {
|
|
| 319 |
+ log.WithError(err).Error("join network failed")
|
|
| 320 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json) |
|
| 321 |
+ return |
|
| 322 |
+ } |
|
| 323 |
+ log.Info("join network done")
|
|
| 324 |
+ diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json) |
|
| 325 |
+ return |
|
| 326 |
+ } |
|
| 327 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 328 |
+} |
|
| 329 |
+ |
|
| 330 |
+func dbLeaveNetwork(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 331 |
+ r.ParseForm() |
|
| 332 |
+ diagnostic.DebugHTTPForm(r) |
|
| 333 |
+ _, json := diagnostic.ParseHTTPFormOptions(r) |
|
| 334 |
+ |
|
| 335 |
+ // audit logs |
|
| 336 |
+ log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 337 |
+ log.Info("leave network")
|
|
| 338 |
+ |
|
| 339 |
+ if len(r.Form["nid"]) < 1 {
|
|
| 340 |
+ rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?nid=network_id", r.URL.Path))
|
|
| 341 |
+ log.Error("leave network failed, wrong input")
|
|
| 342 |
+ diagnostic.HTTPReply(w, rsp, json) |
|
| 343 |
+ return |
|
| 344 |
+ } |
|
| 345 |
+ |
|
| 346 |
+ nid := r.Form["nid"][0] |
|
| 347 |
+ |
|
| 348 |
+ nDB, ok := ctx.(*NetworkDB) |
|
| 349 |
+ if ok {
|
|
| 350 |
+ if err := nDB.LeaveNetwork(nid); err != nil {
|
|
| 351 |
+ log.WithError(err).Error("leave network failed")
|
|
| 352 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(err), json) |
|
| 353 |
+ return |
|
| 354 |
+ } |
|
| 355 |
+ log.Info("leave network done")
|
|
| 356 |
+ diagnostic.HTTPReply(w, diagnostic.CommandSucceed(nil), json) |
|
| 357 |
+ return |
|
| 358 |
+ } |
|
| 359 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 360 |
+} |
|
| 361 |
+ |
|
| 362 |
+func dbGetTable(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
|
| 363 |
+ r.ParseForm() |
|
| 364 |
+ diagnostic.DebugHTTPForm(r) |
|
| 365 |
+ unsafe, json := diagnostic.ParseHTTPFormOptions(r) |
|
| 366 |
+ |
|
| 367 |
+ // audit logs |
|
| 368 |
+ log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
|
|
| 369 |
+ log.Info("get table")
|
|
| 370 |
+ |
|
| 371 |
+ if len(r.Form["tname"]) < 1 || |
|
| 372 |
+ len(r.Form["nid"]) < 1 {
|
|
| 373 |
+ rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id", r.URL.Path))
|
|
| 374 |
+ log.Error("get table failed, wrong input")
|
|
| 375 |
+ diagnostic.HTTPReply(w, rsp, json) |
|
| 376 |
+ return |
|
| 377 |
+ } |
|
| 378 |
+ |
|
| 379 |
+ tname := r.Form["tname"][0] |
|
| 380 |
+ nid := r.Form["nid"][0] |
|
| 381 |
+ |
|
| 382 |
+ nDB, ok := ctx.(*NetworkDB) |
|
| 383 |
+ if ok {
|
|
| 384 |
+ table := nDB.GetTableByNetwork(tname, nid) |
|
| 385 |
+ rsp := &diagnostic.TableObj{Length: len(table)}
|
|
| 386 |
+ var i = 0 |
|
| 387 |
+ for k, v := range table {
|
|
| 388 |
+ var encodedValue string |
|
| 389 |
+ if unsafe {
|
|
| 390 |
+ encodedValue = string(v.Value) |
|
| 391 |
+ } else {
|
|
| 392 |
+ encodedValue = base64.StdEncoding.EncodeToString(v.Value) |
|
| 393 |
+ } |
|
| 394 |
+ rsp.Elements = append(rsp.Elements, |
|
| 395 |
+ &diagnostic.TableEntryObj{
|
|
| 396 |
+ Index: i, |
|
| 397 |
+ Key: k, |
|
| 398 |
+ Value: encodedValue, |
|
| 399 |
+ Owner: v.owner, |
|
| 400 |
+ }) |
|
| 401 |
+ i++ |
|
| 402 |
+ } |
|
| 403 |
+ log.WithField("response", fmt.Sprintf("%+v", rsp)).Info("get table done")
|
|
| 404 |
+ diagnostic.HTTPReply(w, diagnostic.CommandSucceed(rsp), json) |
|
| 405 |
+ return |
|
| 406 |
+ } |
|
| 407 |
+ diagnostic.HTTPReply(w, diagnostic.FailCommand(fmt.Errorf("%s", dbNotAvailable)), json)
|
|
| 408 |
+} |
| ... | ... |
@@ -9,17 +9,17 @@ import ( |
| 9 | 9 |
"os" |
| 10 | 10 |
"strconv" |
| 11 | 11 |
|
| 12 |
- "github.com/docker/libnetwork/diagnose" |
|
| 12 |
+ "github.com/docker/libnetwork/diagnostic" |
|
| 13 | 13 |
"github.com/docker/libnetwork/networkdb" |
| 14 | 14 |
"github.com/docker/libnetwork/test/networkDb/dummyclient" |
| 15 | 15 |
"github.com/sirupsen/logrus" |
| 16 | 16 |
) |
| 17 | 17 |
|
| 18 | 18 |
var nDB *networkdb.NetworkDB |
| 19 |
-var server *diagnose.Server |
|
| 19 |
+var server *diagnostic.Server |
|
| 20 | 20 |
var ipAddr string |
| 21 | 21 |
|
| 22 |
-var testerPaths2Func = map[string]diagnose.HTTPHandlerFunc{
|
|
| 22 |
+var testerPaths2Func = map[string]diagnostic.HTTPHandlerFunc{
|
|
| 23 | 23 |
"/myip": ipaddress, |
| 24 | 24 |
} |
| 25 | 25 |
|
| ... | ... |
@@ -49,7 +49,7 @@ func Server(args []string) {
|
| 49 | 49 |
ipAddr = ip |
| 50 | 50 |
logrus.Infof("%s uses IP %s\n", localNodeName, ipAddr)
|
| 51 | 51 |
|
| 52 |
- server = diagnose.New() |
|
| 52 |
+ server = diagnostic.New() |
|
| 53 | 53 |
server.Init() |
| 54 | 54 |
conf := networkdb.DefaultConfig() |
| 55 | 55 |
conf.Hostname = localNodeName |
| ... | ... |
@@ -65,7 +65,7 @@ func Server(args []string) {
|
| 65 | 65 |
server.RegisterHandler(nDB, networkdb.NetDbPaths2Func) |
| 66 | 66 |
server.RegisterHandler(nil, testerPaths2Func) |
| 67 | 67 |
server.RegisterHandler(nDB, dummyclient.DummyClientPaths2Func) |
| 68 |
- server.EnableDebug("", port)
|
|
| 68 |
+ server.EnableDiagnostic("", port)
|
|
| 69 | 69 |
// block here |
| 70 | 70 |
select {}
|
| 71 | 71 |
} |
| ... | ... |
@@ -6,13 +6,13 @@ import ( |
| 6 | 6 |
"net/http" |
| 7 | 7 |
|
| 8 | 8 |
events "github.com/docker/go-events" |
| 9 |
- "github.com/docker/libnetwork/diagnose" |
|
| 9 |
+ "github.com/docker/libnetwork/diagnostic" |
|
| 10 | 10 |
"github.com/docker/libnetwork/networkdb" |
| 11 | 11 |
"github.com/sirupsen/logrus" |
| 12 | 12 |
) |
| 13 | 13 |
|
| 14 | 14 |
// DummyClientPaths2Func exported paths for the client |
| 15 |
-var DummyClientPaths2Func = map[string]diagnose.HTTPHandlerFunc{
|
|
| 15 |
+var DummyClientPaths2Func = map[string]diagnostic.HTTPHandlerFunc{
|
|
| 16 | 16 |
"/watchtable": watchTable, |
| 17 | 17 |
"/watchedtableentries": watchTableEntries, |
| 18 | 18 |
} |
| ... | ... |
@@ -30,10 +30,10 @@ var clientWatchTable = map[string]tableHandler{}
|
| 30 | 30 |
|
| 31 | 31 |
func watchTable(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
| 32 | 32 |
r.ParseForm() |
| 33 |
- diagnose.DebugHTTPForm(r) |
|
| 33 |
+ diagnostic.DebugHTTPForm(r) |
|
| 34 | 34 |
if len(r.Form["tname"]) < 1 {
|
| 35 |
- rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name", r.URL.Path))
|
|
| 36 |
- diagnose.HTTPReply(w, rsp, &diagnose.JSONOutput{})
|
|
| 35 |
+ rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name", r.URL.Path))
|
|
| 36 |
+ diagnostic.HTTPReply(w, rsp, &diagnostic.JSONOutput{})
|
|
| 37 | 37 |
return |
| 38 | 38 |
} |
| 39 | 39 |
|
| ... | ... |
@@ -55,10 +55,10 @@ func watchTable(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
| 55 | 55 |
|
| 56 | 56 |
func watchTableEntries(ctx interface{}, w http.ResponseWriter, r *http.Request) {
|
| 57 | 57 |
r.ParseForm() |
| 58 |
- diagnose.DebugHTTPForm(r) |
|
| 58 |
+ diagnostic.DebugHTTPForm(r) |
|
| 59 | 59 |
if len(r.Form["tname"]) < 1 {
|
| 60 |
- rsp := diagnose.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name", r.URL.Path))
|
|
| 61 |
- diagnose.HTTPReply(w, rsp, &diagnose.JSONOutput{})
|
|
| 60 |
+ rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name", r.URL.Path))
|
|
| 61 |
+ diagnostic.HTTPReply(w, rsp, &diagnostic.JSONOutput{})
|
|
| 62 | 62 |
return |
| 63 | 63 |
} |
| 64 | 64 |
|