From 6c7b644f601c9d0d049d2141d934698b41d24cb9 Mon Sep 17 00:00:00 2001 From: Jacky Date: Tue, 30 Jul 2024 15:17:43 +0800 Subject: [PATCH] docs: update docs about insecure skip verify --- api/openai/openai.go | 210 ++++++++-------- docs/guide/config-server.md | 7 + docs/guide/env.md | 37 +-- docs/zh_CN/guide/config-server.md | 7 + docs/zh_CN/guide/env.md | 37 +-- docs/zh_TW/guide/config-server.md | 7 + docs/zh_TW/guide/env.md | 37 +-- internal/analytic/node.go | 164 ++++++------ internal/config/sync.go | 404 +++++++++++++++--------------- 9 files changed, 467 insertions(+), 443 deletions(-) diff --git a/api/openai/openai.go b/api/openai/openai.go index a7fbe434..672f00a0 100644 --- a/api/openai/openai.go +++ b/api/openai/openai.go @@ -1,18 +1,18 @@ package openai import ( - "context" - "crypto/tls" - "fmt" - "github.com/0xJacky/Nginx-UI/api" - "github.com/0xJacky/Nginx-UI/internal/chatbot" - "github.com/0xJacky/Nginx-UI/settings" - "github.com/gin-gonic/gin" - "github.com/pkg/errors" - "github.com/sashabaranov/go-openai" - "io" - "net/http" - "net/url" + "context" + "crypto/tls" + "fmt" + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/internal/chatbot" + "github.com/0xJacky/Nginx-UI/settings" + "github.com/gin-gonic/gin" + "github.com/pkg/errors" + "github.com/sashabaranov/go-openai" + "io" + "net/http" + "net/url" ) const ChatGPTInitPrompt = `You are a assistant who can help users write and optimise the configurations of Nginx, @@ -22,111 +22,111 @@ Later the language environment depends on the user message. The first reply should involve the key information of the file and ask user what can you help them.` func MakeChatCompletionRequest(c *gin.Context) { - var json struct { - Filepath string `json:"filepath"` - Messages []openai.ChatCompletionMessage `json:"messages"` - } + var json struct { + Filepath string `json:"filepath"` + Messages []openai.ChatCompletionMessage `json:"messages"` + } - if !api.BindAndValid(c, &json) { - return - } + if !api.BindAndValid(c, &json) { + return + } - messages := []openai.ChatCompletionMessage{ - { - Role: openai.ChatMessageRoleSystem, - Content: ChatGPTInitPrompt, - }, - } + messages := []openai.ChatCompletionMessage{ + { + Role: openai.ChatMessageRoleSystem, + Content: ChatGPTInitPrompt, + }, + } - messages = append(messages, json.Messages...) + messages = append(messages, json.Messages...) - if json.Filepath != "" { - messages = chatbot.ChatCompletionWithContext(json.Filepath, messages) - } + if json.Filepath != "" { + messages = chatbot.ChatCompletionWithContext(json.Filepath, messages) + } - // SSE server - c.Writer.Header().Set("Content-Type", "text/event-stream; charset=utf-8") - c.Writer.Header().Set("Cache-Control", "no-cache") - c.Writer.Header().Set("Connection", "keep-alive") - c.Writer.Header().Set("Access-Control-Allow-Origin", "*") + // SSE server + c.Writer.Header().Set("Content-Type", "text/event-stream; charset=utf-8") + c.Writer.Header().Set("Cache-Control", "no-cache") + c.Writer.Header().Set("Connection", "keep-alive") + c.Writer.Header().Set("Access-Control-Allow-Origin", "*") - config := openai.DefaultConfig(settings.OpenAISettings.Token) + config := openai.DefaultConfig(settings.OpenAISettings.Token) - if settings.OpenAISettings.Proxy != "" { - proxyUrl, err := url.Parse(settings.OpenAISettings.Proxy) - if err != nil { - c.Stream(func(w io.Writer) bool { - c.SSEvent("message", gin.H{ - "type": "error", - "content": err.Error(), - }) - return false - }) - return - } - transport := &http.Transport{ - Proxy: http.ProxyURL(proxyUrl), - TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify}, - } - config.HTTPClient = &http.Client{ - Transport: transport, - } - } + if settings.OpenAISettings.Proxy != "" { + proxyUrl, err := url.Parse(settings.OpenAISettings.Proxy) + if err != nil { + c.Stream(func(w io.Writer) bool { + c.SSEvent("message", gin.H{ + "type": "error", + "content": err.Error(), + }) + return false + }) + return + } + transport := &http.Transport{ + Proxy: http.ProxyURL(proxyUrl), + TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify}, + } + config.HTTPClient = &http.Client{ + Transport: transport, + } + } - if settings.OpenAISettings.BaseUrl != "" { - config.BaseURL = settings.OpenAISettings.BaseUrl - } + if settings.OpenAISettings.BaseUrl != "" { + config.BaseURL = settings.OpenAISettings.BaseUrl + } - openaiClient := openai.NewClientWithConfig(config) - ctx := context.Background() + openaiClient := openai.NewClientWithConfig(config) + ctx := context.Background() - req := openai.ChatCompletionRequest{ - Model: settings.OpenAISettings.Model, - Messages: messages, - Stream: true, - } - stream, err := openaiClient.CreateChatCompletionStream(ctx, req) - if err != nil { - fmt.Printf("CompletionStream error: %v\n", err) - c.Stream(func(w io.Writer) bool { - c.SSEvent("message", gin.H{ - "type": "error", - "content": err.Error(), - }) - return false - }) - return - } - defer stream.Close() - msgChan := make(chan string) - go func() { - defer close(msgChan) - for { - response, err := stream.Recv() - if errors.Is(err, io.EOF) { - fmt.Println() - return - } + req := openai.ChatCompletionRequest{ + Model: settings.OpenAISettings.Model, + Messages: messages, + Stream: true, + } + stream, err := openaiClient.CreateChatCompletionStream(ctx, req) + if err != nil { + fmt.Printf("CompletionStream error: %v\n", err) + c.Stream(func(w io.Writer) bool { + c.SSEvent("message", gin.H{ + "type": "error", + "content": err.Error(), + }) + return false + }) + return + } + defer stream.Close() + msgChan := make(chan string) + go func() { + defer close(msgChan) + for { + response, err := stream.Recv() + if errors.Is(err, io.EOF) { + fmt.Println() + return + } - if err != nil { - fmt.Printf("Stream error: %v\n", err) - return - } + if err != nil { + fmt.Printf("Stream error: %v\n", err) + return + } - message := fmt.Sprintf("%s", response.Choices[0].Delta.Content) + message := fmt.Sprintf("%s", response.Choices[0].Delta.Content) - msgChan <- message - } - }() + msgChan <- message + } + }() - c.Stream(func(w io.Writer) bool { - if m, ok := <-msgChan; ok { - c.SSEvent("message", gin.H{ - "type": "message", - "content": m, - }) - return true - } - return false - }) + c.Stream(func(w io.Writer) bool { + if m, ok := <-msgChan; ok { + c.SSEvent("message", gin.H{ + "type": "message", + "content": m, + }) + return true + } + return false + }) } diff --git a/docs/guide/config-server.md b/docs/guide/config-server.md index 649c7b70..0097f5e9 100644 --- a/docs/guide/config-server.md +++ b/docs/guide/config-server.md @@ -145,3 +145,10 @@ Nginx UI will not create a system initial acme user, this means you can't apply - Type: `string` Use this option to customize the name of local server to be displayed in the environment indicator. + +## InsecureSkipVerify + +- Version:`>= v2.0.0-beta.30` +- Type: `bool` + +This option is used to skip the verification of the certificate of servers when Nginx UI sends requests to them. diff --git a/docs/guide/env.md b/docs/guide/env.md index 0707b400..300928fc 100644 --- a/docs/guide/env.md +++ b/docs/guide/env.md @@ -3,24 +3,25 @@ Applicable for version v2.0.0-beta.23 and above. ## Server -| Configuration Setting | Environment Variable | -| ----------------------------- | ------------------------------------- | -| HttpPort | NGINX_UI_SERVER_HTTP_PORT | -| RunMode | NGINX_UI_SERVER_RUN_MODE | -| JwtSecret | NGINX_UI_SERVER_JWT_SECRET | -| HTTPChallengePort | NGINX_UI_SERVER_HTTP_CHALLENGE_PORT | -| StartCmd | NGINX_UI_SERVER_START_CMD | -| Database | NGINX_UI_SERVER_DATABASE | -| CADir | NGINX_UI_SERVER_CA_DIR | -| GithubProxy | NGINX_UI_SERVER_GITHUB_PROXY | -| NodeSecret | NGINX_UI_SERVER_NODE_SECRET | -| Demo | NGINX_UI_SERVER_DEMO | -| PageSize | NGINX_UI_SERVER_PAGE_SIZE | -| HttpHost | NGINX_UI_SERVER_HTTP_HOST | -| CertRenewalInterval | NGINX_UI_SERVER_CERT_RENEWAL_INTERVAL | -| RecursiveNameservers | NGINX_UI_SERVER_RECURSIVE_NAMESERVERS | -| SkipInstallation | NGINX_UI_SERVER_SKIP_INSTALLATION | -| Name | NGINX_UI_SERVER_NAME | +| Configuration Setting | Environment Variable | +|-----------------------|---------------------------------------| +| HttpPort | NGINX_UI_SERVER_HTTP_PORT | +| RunMode | NGINX_UI_SERVER_RUN_MODE | +| JwtSecret | NGINX_UI_SERVER_JWT_SECRET | +| HTTPChallengePort | NGINX_UI_SERVER_HTTP_CHALLENGE_PORT | +| StartCmd | NGINX_UI_SERVER_START_CMD | +| Database | NGINX_UI_SERVER_DATABASE | +| CADir | NGINX_UI_SERVER_CA_DIR | +| GithubProxy | NGINX_UI_SERVER_GITHUB_PROXY | +| NodeSecret | NGINX_UI_SERVER_NODE_SECRET | +| Demo | NGINX_UI_SERVER_DEMO | +| PageSize | NGINX_UI_SERVER_PAGE_SIZE | +| HttpHost | NGINX_UI_SERVER_HTTP_HOST | +| CertRenewalInterval | NGINX_UI_SERVER_CERT_RENEWAL_INTERVAL | +| RecursiveNameservers | NGINX_UI_SERVER_RECURSIVE_NAMESERVERS | +| SkipInstallation | NGINX_UI_SERVER_SKIP_INSTALLATION | +| Name | NGINX_UI_SERVER_NAME | +| InsecureSkipVerify | NGINX_UI_SERVER_INSECURE_SKIP_VERIFY | ## Nginx diff --git a/docs/zh_CN/guide/config-server.md b/docs/zh_CN/guide/config-server.md index 8825de8a..37e5327b 100644 --- a/docs/zh_CN/guide/config-server.md +++ b/docs/zh_CN/guide/config-server.md @@ -132,3 +132,10 @@ Nginx UI 将不会创建系统初始的 acme 用户,这意味着您无法在 - 类型:`string` 使用此选项自定义本地服务器的名称,以在环境指示器中显示。 + +## InsecureSkipVerify + +- 版本:`>= v2.0.0-beta.30` +- 类型: `bool` + +此选项用于配置 Nginx UI 服务器在与其他服务器建立 TLS 连接时是否跳过证书验证。 diff --git a/docs/zh_CN/guide/env.md b/docs/zh_CN/guide/env.md index 9960968d..29692e5c 100644 --- a/docs/zh_CN/guide/env.md +++ b/docs/zh_CN/guide/env.md @@ -3,24 +3,25 @@ ## Server -| Configuration Setting | Environment Variable | -| ----------------------------- | ------------------------------------- | -| HttpPort | NGINX_UI_SERVER_HTTP_PORT | -| RunMode | NGINX_UI_SERVER_RUN_MODE | -| JwtSecret | NGINX_UI_SERVER_JWT_SECRET | -| HTTPChallengePort | NGINX_UI_SERVER_HTTP_CHALLENGE_PORT | -| StartCmd | NGINX_UI_SERVER_START_CMD | -| Database | NGINX_UI_SERVER_DATABASE | -| CADir | NGINX_UI_SERVER_CA_DIR | -| GithubProxy | NGINX_UI_SERVER_GITHUB_PROXY | -| NodeSecret | NGINX_UI_SERVER_NODE_SECRET | -| Demo | NGINX_UI_SERVER_DEMO | -| PageSize | NGINX_UI_SERVER_PAGE_SIZE | -| HttpHost | NGINX_UI_SERVER_HTTP_HOST | -| CertRenewalInterval | NGINX_UI_SERVER_CERT_RENEWAL_INTERVAL | -| RecursiveNameservers | NGINX_UI_SERVER_RECURSIVE_NAMESERVERS | -| SkipInstallation | NGINX_UI_SERVER_SKIP_INSTALLATION | -| Name | NGINX_UI_SERVER_NAME | +| Configuration Setting | Environment Variable | +|-------------------------| ------------------------------------- | +| HttpPort | NGINX_UI_SERVER_HTTP_PORT | +| RunMode | NGINX_UI_SERVER_RUN_MODE | +| JwtSecret | NGINX_UI_SERVER_JWT_SECRET | +| HTTPChallengePort | NGINX_UI_SERVER_HTTP_CHALLENGE_PORT | +| StartCmd | NGINX_UI_SERVER_START_CMD | +| Database | NGINX_UI_SERVER_DATABASE | +| CADir | NGINX_UI_SERVER_CA_DIR | +| GithubProxy | NGINX_UI_SERVER_GITHUB_PROXY | +| NodeSecret | NGINX_UI_SERVER_NODE_SECRET | +| Demo | NGINX_UI_SERVER_DEMO | +| PageSize | NGINX_UI_SERVER_PAGE_SIZE | +| HttpHost | NGINX_UI_SERVER_HTTP_HOST | +| CertRenewalInterval | NGINX_UI_SERVER_CERT_RENEWAL_INTERVAL | +| RecursiveNameservers | NGINX_UI_SERVER_RECURSIVE_NAMESERVERS | +| SkipInstallation | NGINX_UI_SERVER_SKIP_INSTALLATION | +| Name | NGINX_UI_SERVER_NAME | +| InsecureSkipVerify | NGINX_UI_SERVER_INSECURE_SKIP_VERIFY | ## Nginx diff --git a/docs/zh_TW/guide/config-server.md b/docs/zh_TW/guide/config-server.md index a7608cc4..bf85b867 100644 --- a/docs/zh_TW/guide/config-server.md +++ b/docs/zh_TW/guide/config-server.md @@ -133,3 +133,10 @@ Nginx UI 將不會創建系統初始的 acme 使用者,這意味著您無法 - 類型:`string` 使用此選項自定義本地伺服器的名稱,以在環境指示器中顯示。 + +## InsecureSkipVerify + +- 版本:`>= v2.0.0-beta.30` +- 類型: `bool` + +此選項用於配置 Nginx UI 伺服器在與其他伺服器建立 TLS 連接時是否跳過證書驗證。 diff --git a/docs/zh_TW/guide/env.md b/docs/zh_TW/guide/env.md index a5ea2eed..43f8e7ed 100644 --- a/docs/zh_TW/guide/env.md +++ b/docs/zh_TW/guide/env.md @@ -3,24 +3,25 @@ ## Server -| Configuration Setting | Environment Variable | -| ----------------------------- | ------------------------------------- | -| HttpPort | NGINX_UI_SERVER_HTTP_PORT | -| RunMode | NGINX_UI_SERVER_RUN_MODE | -| JwtSecret | NGINX_UI_SERVER_JWT_SECRET | -| HTTPChallengePort | NGINX_UI_SERVER_HTTP_CHALLENGE_PORT | -| StartCmd | NGINX_UI_SERVER_START_CMD | -| Database | NGINX_UI_SERVER_DATABASE | -| CADir | NGINX_UI_SERVER_CA_DIR | -| GithubProxy | NGINX_UI_SERVER_GITHUB_PROXY | -| NodeSecret | NGINX_UI_SERVER_NODE_SECRET | -| Demo | NGINX_UI_SERVER_DEMO | -| PageSize | NGINX_UI_SERVER_PAGE_SIZE | -| HttpHost | NGINX_UI_SERVER_HTTP_HOST | -| CertRenewalInterval | NGINX_UI_SERVER_CERT_RENEWAL_INTERVAL | -| RecursiveNameservers | NGINX_UI_SERVER_RECURSIVE_NAMESERVERS | -| SkipInstallation | NGINX_UI_SERVER_SKIP_INSTALLATION | -| Name | NGINX_UI_SERVER_NAME | +| Configuration Setting | Environment Variable | +|------------------------| ------------------------------------- | +| HttpPort | NGINX_UI_SERVER_HTTP_PORT | +| RunMode | NGINX_UI_SERVER_RUN_MODE | +| JwtSecret | NGINX_UI_SERVER_JWT_SECRET | +| HTTPChallengePort | NGINX_UI_SERVER_HTTP_CHALLENGE_PORT | +| StartCmd | NGINX_UI_SERVER_START_CMD | +| Database | NGINX_UI_SERVER_DATABASE | +| CADir | NGINX_UI_SERVER_CA_DIR | +| GithubProxy | NGINX_UI_SERVER_GITHUB_PROXY | +| NodeSecret | NGINX_UI_SERVER_NODE_SECRET | +| Demo | NGINX_UI_SERVER_DEMO | +| PageSize | NGINX_UI_SERVER_PAGE_SIZE | +| HttpHost | NGINX_UI_SERVER_HTTP_HOST | +| CertRenewalInterval | NGINX_UI_SERVER_CERT_RENEWAL_INTERVAL | +| RecursiveNameservers | NGINX_UI_SERVER_RECURSIVE_NAMESERVERS | +| SkipInstallation | NGINX_UI_SERVER_SKIP_INSTALLATION | +| Name | NGINX_UI_SERVER_NAME | +| InsecureSkipVerify | NGINX_UI_SERVER_INSECURE_SKIP_VERIFY | ## Nginx diff --git a/internal/analytic/node.go b/internal/analytic/node.go index 3e14753d..368c250a 100644 --- a/internal/analytic/node.go +++ b/internal/analytic/node.go @@ -1,44 +1,44 @@ package analytic import ( - "crypto/tls" - "encoding/json" - "github.com/0xJacky/Nginx-UI/internal/logger" - "github.com/0xJacky/Nginx-UI/internal/upgrader" - "github.com/0xJacky/Nginx-UI/model" - "github.com/0xJacky/Nginx-UI/settings" - "github.com/shirou/gopsutil/v3/load" - "github.com/shirou/gopsutil/v3/net" - "io" - "net/http" - "net/url" - "sync" - "time" + "crypto/tls" + "encoding/json" + "github.com/0xJacky/Nginx-UI/internal/logger" + "github.com/0xJacky/Nginx-UI/internal/upgrader" + "github.com/0xJacky/Nginx-UI/model" + "github.com/0xJacky/Nginx-UI/settings" + "github.com/shirou/gopsutil/v3/load" + "github.com/shirou/gopsutil/v3/net" + "io" + "net/http" + "net/url" + "sync" + "time" ) type NodeInfo struct { - NodeRuntimeInfo upgrader.RuntimeInfo `json:"node_runtime_info"` - Version string `json:"version"` - CPUNum int `json:"cpu_num"` - MemoryTotal string `json:"memory_total"` - DiskTotal string `json:"disk_total"` + NodeRuntimeInfo upgrader.RuntimeInfo `json:"node_runtime_info"` + Version string `json:"version"` + CPUNum int `json:"cpu_num"` + MemoryTotal string `json:"memory_total"` + DiskTotal string `json:"disk_total"` } type NodeStat struct { - AvgLoad *load.AvgStat `json:"avg_load"` - CPUPercent float64 `json:"cpu_percent"` - MemoryPercent float64 `json:"memory_percent"` - DiskPercent float64 `json:"disk_percent"` - Network net.IOCountersStat `json:"network"` - Status bool `json:"status"` - ResponseAt time.Time `json:"response_at"` + AvgLoad *load.AvgStat `json:"avg_load"` + CPUPercent float64 `json:"cpu_percent"` + MemoryPercent float64 `json:"memory_percent"` + DiskPercent float64 `json:"disk_percent"` + Network net.IOCountersStat `json:"network"` + Status bool `json:"status"` + ResponseAt time.Time `json:"response_at"` } type Node struct { - EnvironmentID int `json:"environment_id,omitempty"` - *model.Environment - NodeStat - NodeInfo + EnvironmentID int `json:"environment_id,omitempty"` + *model.Environment + NodeStat + NodeInfo } var mutex sync.Mutex @@ -48,74 +48,74 @@ type TNodeMap map[int]*Node var NodeMap TNodeMap func init() { - NodeMap = make(TNodeMap) + NodeMap = make(TNodeMap) } func GetNode(env *model.Environment) (n *Node) { - if env == nil { - // this should never happen - logger.Error("env is nil") - return - } - if !env.Enabled { - return &Node{ - Environment: env, - } - } - n, ok := NodeMap[env.ID] - if !ok { - n = &Node{} - } - n.Environment = env - return n + if env == nil { + // this should never happen + logger.Error("env is nil") + return + } + if !env.Enabled { + return &Node{ + Environment: env, + } + } + n, ok := NodeMap[env.ID] + if !ok { + n = &Node{} + } + n.Environment = env + return n } func InitNode(env *model.Environment) (n *Node) { - n = &Node{ - Environment: env, - } + n = &Node{ + Environment: env, + } - u, err := url.JoinPath(env.URL, "/api/node") + u, err := url.JoinPath(env.URL, "/api/node") - if err != nil { - logger.Error(err) - return - } + if err != nil { + logger.Error(err) + return + } - client := http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify}, - }, - } + client := http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify}, + }, + } - req, err := http.NewRequest("GET", u, nil) - if err != nil { - logger.Error(err) - return - } + req, err := http.NewRequest("GET", u, nil) + if err != nil { + logger.Error(err) + return + } - req.Header.Set("X-Node-Secret", env.Token) + req.Header.Set("X-Node-Secret", env.Token) - resp, err := client.Do(req) + resp, err := client.Do(req) - if err != nil { - logger.Error(err) - return - } + if err != nil { + logger.Error(err) + return + } - defer resp.Body.Close() - bytes, _ := io.ReadAll(resp.Body) + defer resp.Body.Close() + bytes, _ := io.ReadAll(resp.Body) - if resp.StatusCode != http.StatusOK { - logger.Error(string(bytes)) - return - } + if resp.StatusCode != http.StatusOK { + logger.Error(string(bytes)) + return + } - err = json.Unmarshal(bytes, &n.NodeInfo) - if err != nil { - logger.Error(err) - return - } + err = json.Unmarshal(bytes, &n.NodeInfo) + if err != nil { + logger.Error(err) + return + } - return + return } diff --git a/internal/config/sync.go b/internal/config/sync.go index 70d12245..3f1fb34a 100644 --- a/internal/config/sync.go +++ b/internal/config/sync.go @@ -1,258 +1,258 @@ package config import ( - "bytes" - "crypto/tls" - "encoding/json" - "fmt" - "github.com/0xJacky/Nginx-UI/internal/helper" - "github.com/0xJacky/Nginx-UI/internal/logger" - "github.com/0xJacky/Nginx-UI/internal/nginx" - "github.com/0xJacky/Nginx-UI/internal/notification" - "github.com/0xJacky/Nginx-UI/model" - "github.com/0xJacky/Nginx-UI/query" - "github.com/0xJacky/Nginx-UI/settings" - "github.com/gin-gonic/gin" - "io" - "net/http" - "os" - "path/filepath" - "strings" + "bytes" + "crypto/tls" + "encoding/json" + "fmt" + "github.com/0xJacky/Nginx-UI/internal/helper" + "github.com/0xJacky/Nginx-UI/internal/logger" + "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/0xJacky/Nginx-UI/internal/notification" + "github.com/0xJacky/Nginx-UI/model" + "github.com/0xJacky/Nginx-UI/query" + "github.com/0xJacky/Nginx-UI/settings" + "github.com/gin-gonic/gin" + "io" + "net/http" + "os" + "path/filepath" + "strings" ) type SyncConfigPayload struct { - Name string `json:"name"` - Filepath string `json:"filepath"` - NewFilepath string `json:"new_filepath"` - Content string `json:"content"` - Overwrite bool `json:"overwrite"` + Name string `json:"name"` + Filepath string `json:"filepath"` + NewFilepath string `json:"new_filepath"` + Content string `json:"content"` + Overwrite bool `json:"overwrite"` } func SyncToRemoteServer(c *model.Config, newFilepath string) (err error) { - if c.Filepath == "" || len(c.SyncNodeIds) == 0 { - return - } + if c.Filepath == "" || len(c.SyncNodeIds) == 0 { + return + } - nginxConfPath := nginx.GetConfPath() - if !helper.IsUnderDirectory(c.Filepath, nginxConfPath) { - return fmt.Errorf("config: %s is not under the nginx conf path: %s", - c.Filepath, nginxConfPath) - } + nginxConfPath := nginx.GetConfPath() + if !helper.IsUnderDirectory(c.Filepath, nginxConfPath) { + return fmt.Errorf("config: %s is not under the nginx conf path: %s", + c.Filepath, nginxConfPath) + } - if newFilepath != "" && !helper.IsUnderDirectory(newFilepath, nginxConfPath) { - return fmt.Errorf("config: %s is not under the nginx conf path: %s", - c.Filepath, nginxConfPath) - } + if newFilepath != "" && !helper.IsUnderDirectory(newFilepath, nginxConfPath) { + return fmt.Errorf("config: %s is not under the nginx conf path: %s", + c.Filepath, nginxConfPath) + } - currentPath := c.Filepath - if newFilepath != "" { - currentPath = newFilepath - } - configBytes, err := os.ReadFile(currentPath) - if err != nil { - return - } + currentPath := c.Filepath + if newFilepath != "" { + currentPath = newFilepath + } + configBytes, err := os.ReadFile(currentPath) + if err != nil { + return + } - payload := &SyncConfigPayload{ - Name: c.Name, - Filepath: c.Filepath, - NewFilepath: newFilepath, - Content: string(configBytes), - Overwrite: c.SyncOverwrite, - } - payloadBytes, err := json.Marshal(payload) - if err != nil { - return - } + payload := &SyncConfigPayload{ + Name: c.Name, + Filepath: c.Filepath, + NewFilepath: newFilepath, + Content: string(configBytes), + Overwrite: c.SyncOverwrite, + } + payloadBytes, err := json.Marshal(payload) + if err != nil { + return + } - q := query.Environment - envs, _ := q.Where(q.ID.In(c.SyncNodeIds...)).Find() - for _, env := range envs { - go func() { - err := payload.deploy(env, c, payloadBytes) - if err != nil { - logger.Error(err) - } - }() - } + q := query.Environment + envs, _ := q.Where(q.ID.In(c.SyncNodeIds...)).Find() + for _, env := range envs { + go func() { + err := payload.deploy(env, c, payloadBytes) + if err != nil { + logger.Error(err) + } + }() + } - return + return } func SyncRenameOnRemoteServer(origPath, newPath string, syncNodeIds []int) (err error) { - if origPath == "" || newPath == "" || len(syncNodeIds) == 0 { - return - } + if origPath == "" || newPath == "" || len(syncNodeIds) == 0 { + return + } - nginxConfPath := nginx.GetConfPath() - if !helper.IsUnderDirectory(origPath, nginxConfPath) { - return fmt.Errorf("config: %s is not under the nginx conf path: %s", - origPath, nginxConfPath) - } + nginxConfPath := nginx.GetConfPath() + if !helper.IsUnderDirectory(origPath, nginxConfPath) { + return fmt.Errorf("config: %s is not under the nginx conf path: %s", + origPath, nginxConfPath) + } - if !helper.IsUnderDirectory(newPath, nginxConfPath) { - return fmt.Errorf("config: %s is not under the nginx conf path: %s", - newPath, nginxConfPath) - } + if !helper.IsUnderDirectory(newPath, nginxConfPath) { + return fmt.Errorf("config: %s is not under the nginx conf path: %s", + newPath, nginxConfPath) + } - payload := &RenameConfigPayload{ - Filepath: origPath, - NewFilepath: newPath, - } + payload := &RenameConfigPayload{ + Filepath: origPath, + NewFilepath: newPath, + } - q := query.Environment - envs, _ := q.Where(q.ID.In(syncNodeIds...)).Find() - for _, env := range envs { - go func() { - err := payload.rename(env) - if err != nil { - logger.Error(err) - } - }() - } + q := query.Environment + envs, _ := q.Where(q.ID.In(syncNodeIds...)).Find() + for _, env := range envs { + go func() { + err := payload.rename(env) + if err != nil { + logger.Error(err) + } + }() + } - return + return } type SyncNotificationPayload struct { - StatusCode int `json:"status_code"` - ConfigName string `json:"config_name"` - EnvName string `json:"env_name"` - RespBody string `json:"resp_body"` + StatusCode int `json:"status_code"` + ConfigName string `json:"config_name"` + EnvName string `json:"env_name"` + RespBody string `json:"resp_body"` } func (p *SyncConfigPayload) deploy(env *model.Environment, c *model.Config, payloadBytes []byte) (err error) { - client := http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify}, - }, - } - url, err := env.GetUrl("/api/config") - if err != nil { - return - } - req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(payloadBytes)) - if err != nil { - return - } - req.Header.Set("X-Node-Secret", env.Token) - resp, err := client.Do(req) - if err != nil { - return - } - defer resp.Body.Close() + client := http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify}, + }, + } + url, err := env.GetUrl("/api/config") + if err != nil { + return + } + req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(payloadBytes)) + if err != nil { + return + } + req.Header.Set("X-Node-Secret", env.Token) + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() - respBody, err := io.ReadAll(resp.Body) - if err != nil { - return - } + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return + } - notificationPayload := &SyncNotificationPayload{ - StatusCode: resp.StatusCode, - ConfigName: c.Name, - EnvName: env.Name, - RespBody: string(respBody), - } + notificationPayload := &SyncNotificationPayload{ + StatusCode: resp.StatusCode, + ConfigName: c.Name, + EnvName: env.Name, + RespBody: string(respBody), + } - notificationPayloadBytes, err := json.Marshal(notificationPayload) - if err != nil { - return - } + notificationPayloadBytes, err := json.Marshal(notificationPayload) + if err != nil { + return + } - if resp.StatusCode != http.StatusOK { - notification.Error("Sync Config Error", string(notificationPayloadBytes)) - return - } + if resp.StatusCode != http.StatusOK { + notification.Error("Sync Config Error", string(notificationPayloadBytes)) + return + } - notification.Success("Sync Config Success", string(notificationPayloadBytes)) + notification.Success("Sync Config Success", string(notificationPayloadBytes)) - // handle rename - if p.NewFilepath == "" || p.Filepath == p.NewFilepath { - return - } + // handle rename + if p.NewFilepath == "" || p.Filepath == p.NewFilepath { + return + } - payload := &RenameConfigPayload{ - Filepath: p.Filepath, - NewFilepath: p.NewFilepath, - } + payload := &RenameConfigPayload{ + Filepath: p.Filepath, + NewFilepath: p.NewFilepath, + } - err = payload.rename(env) + err = payload.rename(env) - return + return } type RenameConfigPayload struct { - Filepath string `json:"filepath"` - NewFilepath string `json:"new_filepath"` + Filepath string `json:"filepath"` + NewFilepath string `json:"new_filepath"` } type SyncRenameNotificationPayload struct { - StatusCode int `json:"status_code"` - OrigPath string `json:"orig_path"` - NewPath string `json:"new_path"` - EnvName string `json:"env_name"` - RespBody string `json:"resp_body"` + StatusCode int `json:"status_code"` + OrigPath string `json:"orig_path"` + NewPath string `json:"new_path"` + EnvName string `json:"env_name"` + RespBody string `json:"resp_body"` } func (p *RenameConfigPayload) rename(env *model.Environment) (err error) { - // handle rename - if p.NewFilepath == "" || p.Filepath == p.NewFilepath { - return - } + // handle rename + if p.NewFilepath == "" || p.Filepath == p.NewFilepath { + return + } - client := http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify}, - }, - } + client := http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify}, + }, + } - payloadBytes, err := json.Marshal(gin.H{ - "base_path": strings.ReplaceAll(filepath.Dir(p.Filepath), nginx.GetConfPath(), ""), - "orig_name": filepath.Base(p.Filepath), - "new_name": filepath.Base(p.NewFilepath), - }) - if err != nil { - return - } - url, err := env.GetUrl("/api/config_rename") - if err != nil { - return - } - req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(payloadBytes)) - if err != nil { - return - } - req.Header.Set("X-Node-Secret", env.Token) - resp, err := client.Do(req) - if err != nil { - return - } - defer resp.Body.Close() + payloadBytes, err := json.Marshal(gin.H{ + "base_path": strings.ReplaceAll(filepath.Dir(p.Filepath), nginx.GetConfPath(), ""), + "orig_name": filepath.Base(p.Filepath), + "new_name": filepath.Base(p.NewFilepath), + }) + if err != nil { + return + } + url, err := env.GetUrl("/api/config_rename") + if err != nil { + return + } + req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(payloadBytes)) + if err != nil { + return + } + req.Header.Set("X-Node-Secret", env.Token) + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() - respBody, err := io.ReadAll(resp.Body) - if err != nil { - return - } + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return + } - notificationPayload := &SyncRenameNotificationPayload{ - StatusCode: resp.StatusCode, - OrigPath: p.Filepath, - NewPath: p.NewFilepath, - EnvName: env.Name, - RespBody: string(respBody), - } + notificationPayload := &SyncRenameNotificationPayload{ + StatusCode: resp.StatusCode, + OrigPath: p.Filepath, + NewPath: p.NewFilepath, + EnvName: env.Name, + RespBody: string(respBody), + } - notificationPayloadBytes, err := json.Marshal(notificationPayload) - if err != nil { - return - } + notificationPayloadBytes, err := json.Marshal(notificationPayload) + if err != nil { + return + } - if resp.StatusCode != http.StatusOK { - notification.Error("Rename Remote Config Error", string(notificationPayloadBytes)) - return - } + if resp.StatusCode != http.StatusOK { + notification.Error("Rename Remote Config Error", string(notificationPayloadBytes)) + return + } - notification.Success("Rename Remote Config Success", string(notificationPayloadBytes)) + notification.Success("Rename Remote Config Success", string(notificationPayloadBytes)) - return + return }