From d879b8208b3047ff5391985b0fc3874f37bf7786 Mon Sep 17 00:00:00 2001 From: fatedier Date: Thu, 31 Jan 2019 18:35:44 +0800 Subject: [PATCH] frpc: add api PUT api/config --- client/admin.go | 1 + client/admin_api.go | 100 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 88 insertions(+), 13 deletions(-) diff --git a/client/admin.go b/client/admin.go index f3ed248f..f163b446 100644 --- a/client/admin.go +++ b/client/admin.go @@ -42,6 +42,7 @@ func (svr *Service) RunAdminServer(addr string, port int) (err error) { router.HandleFunc("/api/reload", svr.apiReload).Methods("GET") router.HandleFunc("/api/status", svr.apiStatus).Methods("GET") router.HandleFunc("/api/config", svr.apiGetConfig).Methods("GET") + router.HandleFunc("/api/config", svr.apiPutConfig).Methods("PUT") address := fmt.Sprintf("%s:%d", addr, port) server := &http.Server{ diff --git a/client/admin_api.go b/client/admin_api.go index 1d06cdcf..5b6e7380 100644 --- a/client/admin_api.go +++ b/client/admin_api.go @@ -17,6 +17,7 @@ package client import ( "encoding/json" "fmt" + "io/ioutil" "net/http" "sort" "strings" @@ -32,7 +33,7 @@ type GeneralResponse struct { Msg string `json:"msg"` } -// api/reload +// GET api/reload type ReloadResp struct { GeneralResponse } @@ -42,19 +43,19 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) { buf []byte res ReloadResp ) + + log.Info("Http request: [/api/reload]") defer func() { log.Info("Http response [/api/reload]: code [%d]", res.Code) buf, _ = json.Marshal(&res) w.Write(buf) }() - log.Info("Http request: [/api/reload]") - content, err := config.GetRenderedConfFromFile(g.GlbClientCfg.CfgFile) if err != nil { res.Code = 1 res.Msg = err.Error() - log.Error("reload frpc config file error: %v", err) + log.Warn("reload frpc config file error: %v", err) return } @@ -62,7 +63,7 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) { if err != nil { res.Code = 2 res.Msg = err.Error() - log.Error("reload frpc common section error: %v", err) + log.Warn("reload frpc common section error: %v", err) return } @@ -70,7 +71,7 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) { if err != nil { res.Code = 3 res.Msg = err.Error() - log.Error("reload frpc proxy config error: %v", err) + log.Warn("reload frpc proxy config error: %v", err) return } @@ -78,7 +79,7 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) { if err != nil { res.Code = 4 res.Msg = err.Error() - log.Error("reload frpc proxy config error: %v", err) + log.Warn("reload frpc proxy config error: %v", err) return } log.Info("success reload conf") @@ -163,7 +164,7 @@ func NewProxyStatusResp(status *proxy.ProxyStatus) ProxyStatusResp { return psr } -// api/status +// GET api/status func (svr *Service) apiStatus(w http.ResponseWriter, r *http.Request) { var ( buf []byte @@ -175,14 +176,14 @@ func (svr *Service) apiStatus(w http.ResponseWriter, r *http.Request) { res.Https = make([]ProxyStatusResp, 0) res.Stcp = make([]ProxyStatusResp, 0) res.Xtcp = make([]ProxyStatusResp, 0) + + log.Info("Http request: [/api/status]") defer func() { log.Info("Http response [/api/status]") buf, _ = json.Marshal(&res) w.Write(buf) }() - log.Info("Http request: [/api/status]") - ps := svr.ctl.pm.GetAllProxyStatus() for _, status := range ps { switch status.Type { @@ -209,12 +210,14 @@ func (svr *Service) apiStatus(w http.ResponseWriter, r *http.Request) { return } -// api/config +// GET api/config func (svr *Service) apiGetConfig(w http.ResponseWriter, r *http.Request) { var ( buf []byte res GeneralResponse ) + + log.Info("Http get request: [/api/config]") defer func() { log.Info("Http get response [/api/config]") if len(buf) > 0 { @@ -224,12 +227,12 @@ func (svr *Service) apiGetConfig(w http.ResponseWriter, r *http.Request) { w.Write(buf) } }() - log.Info("Http get request: [/api/config]") if g.GlbClientCfg.CfgFile == "" { w.WriteHeader(400) res.Code = 1 res.Msg = "frpc don't configure a config file path" + log.Warn("%s", res.Msg) return } @@ -238,7 +241,7 @@ func (svr *Service) apiGetConfig(w http.ResponseWriter, r *http.Request) { w.WriteHeader(400) res.Code = 2 res.Msg = err.Error() - log.Error("load frpc config file error: %v", err) + log.Warn("load frpc config file error: %v", err) return } @@ -253,3 +256,74 @@ func (svr *Service) apiGetConfig(w http.ResponseWriter, r *http.Request) { } buf = []byte(strings.Join(newRows, "\n")) } + +// PUT api/config +func (svr *Service) apiPutConfig(w http.ResponseWriter, r *http.Request) { + var ( + buf []byte + res GeneralResponse + ) + + log.Info("Http put request: [/api/config]") + defer func() { + log.Info("Http put response: [/api/config]") + buf, _ = json.Marshal(&res) + w.Write(buf) + }() + + // get new config content + body, err := ioutil.ReadAll(r.Body) + if err != nil { + res.Code = 1 + res.Msg = fmt.Sprintf("read request body error: %v", err) + log.Warn("%s", res.Msg) + return + } + + // get token from origin content + token := "" + b, err := ioutil.ReadFile(g.GlbClientCfg.CfgFile) + if err != nil { + res.Code = 2 + res.Msg = err.Error() + log.Warn("load frpc config file error: %v", err) + return + } + content := string(b) + + for _, row := range strings.Split(content, "\n") { + row = strings.TrimSpace(row) + if strings.HasPrefix(row, "token") { + token = row + break + } + } + + tmpRows := make([]string, 0) + for _, row := range strings.Split(string(body), "\n") { + row = strings.TrimSpace(row) + if strings.HasPrefix(row, "token") { + continue + } + tmpRows = append(tmpRows, row) + } + + newRows := make([]string, 0) + if token != "" { + for _, row := range tmpRows { + newRows = append(newRows, row) + if strings.HasPrefix(row, "[common]") { + newRows = append(newRows, token) + } + } + } + content = strings.Join(newRows, "\n") + + err = ioutil.WriteFile(g.GlbClientCfg.CfgFile, []byte(content), 0644) + if err != nil { + res.Code = 3 + res.Msg = fmt.Sprintf("write content to frpc config file error: %v", err) + log.Warn("%s", res.Msg) + return + } +}