diff --git a/.gitignore b/.gitignore index 0f69b089..84856c99 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ # Folders _obj _test +.DS_Store # Architecture specific extensions/prefixes *.[568vq] diff --git a/pkg/metrics/mem/server.go b/pkg/metrics/mem/server.go index d92546c4..cf1b7932 100644 --- a/pkg/metrics/mem/server.go +++ b/pkg/metrics/mem/server.go @@ -260,6 +260,17 @@ func (m *serverMetrics) GetProxiesByTypeAndName(proxyType string, proxyName stri return } +func (m *serverMetrics) RemoveProxyByTypeAndName(proxyType string, proxyName string) bool { + m.mu.Lock() + defer m.mu.Unlock() + sType, ok := m.info.ProxyStatistics[proxyName] + if ok && sType.ProxyType == proxyType { + delete(m.info.ProxyStatistics, proxyName) + return true + } + return false +} + func (m *serverMetrics) GetProxyTraffic(name string) (res *ProxyTrafficInfo) { m.mu.Lock() defer m.mu.Unlock() diff --git a/pkg/metrics/mem/types.go b/pkg/metrics/mem/types.go index a6f276ce..21a86a31 100644 --- a/pkg/metrics/mem/types.go +++ b/pkg/metrics/mem/types.go @@ -78,6 +78,7 @@ type Collector interface { GetServer() *ServerStats GetProxiesByType(proxyType string) []*ProxyStats GetProxiesByTypeAndName(proxyType string, proxyName string) *ProxyStats + RemoveProxyByTypeAndName(proxyType string, proxyName string) bool GetProxyTraffic(name string) *ProxyTrafficInfo ClearOfflineProxies() (int, int) } diff --git a/server/dashboard_api.go b/server/dashboard_api.go index f34da4ef..db7459a1 100644 --- a/server/dashboard_api.go +++ b/server/dashboard_api.go @@ -17,6 +17,7 @@ package server import ( "cmp" "encoding/json" + "fmt" "net/http" "slices" @@ -52,6 +53,7 @@ func (svr *Service) registerRouteHandlers(helper *httppkg.RouterRegisterHelper) subRouter.HandleFunc("/api/serverinfo", svr.apiServerInfo).Methods("GET") subRouter.HandleFunc("/api/proxy/{type}", svr.apiProxyByType).Methods("GET") subRouter.HandleFunc("/api/proxy/{type}/{name}", svr.apiProxyByTypeAndName).Methods("GET") + subRouter.HandleFunc("/api/proxy/{type}/{name}", svr.apiProxyDeleteByTypeAndName).Methods("DELETE") subRouter.HandleFunc("/api/traffic/{name}", svr.apiProxyTraffic).Methods("GET") subRouter.HandleFunc("/api/proxies", svr.deleteProxies).Methods("DELETE") @@ -308,6 +310,42 @@ func (svr *Service) apiProxyByTypeAndName(w http.ResponseWriter, r *http.Request res.Msg = string(buf) } +// /api/proxy/:type/:name DELETE +func (svr *Service) apiProxyDeleteByTypeAndName(w http.ResponseWriter, r *http.Request) { + res := GeneralResponse{Code: 200} + params := mux.Vars(r) + proxyType := params["type"] + name := params["name"] + + defer func() { + log.Infof("Http response [%s]: code [%d]", r.URL.Path, res.Code) + w.WriteHeader(res.Code) + if len(res.Msg) > 0 { + _, _ = w.Write([]byte(res.Msg)) + } + }() + log.Infof("Http request: [%s]", r.URL.Path) + + var proxyStatsResp GetProxyStatsResp + proxyStatsResp, res.Code, res.Msg = svr.getProxyStatsByTypeAndName(proxyType, name) + if res.Code != 200 { + return + } + log.Debugf("proxy to be deleted: %v", proxyStatsResp) + if proxyStatsResp.Status != "offline" { + res.Code = 400 + res.Msg = "proxy is online, can not be deleted" + return + } + ok := mem.StatsCollector.RemoveProxyByTypeAndName(proxyType, name) + if !ok { + res.Code = 400 + res.Msg = "proxy cannot not be deleted,name mismatch with type " + return + } + res.Msg = fmt.Sprintf("proxy %q is deleted successfully", name) +} + func (svr *Service) getProxyStatsByTypeAndName(proxyType string, proxyName string) (proxyInfo GetProxyStatsResp, code int, msg string) { proxyInfo.Name = proxyName ps := mem.StatsCollector.GetProxiesByTypeAndName(proxyType, proxyName)