enhance: add settings for skip tls cert check

This commit is contained in:
Jacky 2024-07-30 15:10:02 +08:00
parent 013d810678
commit f1c0f8ddca
No known key found for this signature in database
GPG key ID: 215C21B10DF38B4D
8 changed files with 400 additions and 394 deletions

View file

@ -1,18 +1,18 @@
package openai package openai
import ( import (
"context" "context"
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"github.com/0xJacky/Nginx-UI/api" "github.com/0xJacky/Nginx-UI/api"
"github.com/0xJacky/Nginx-UI/internal/chatbot" "github.com/0xJacky/Nginx-UI/internal/chatbot"
"github.com/0xJacky/Nginx-UI/settings" "github.com/0xJacky/Nginx-UI/settings"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sashabaranov/go-openai" "github.com/sashabaranov/go-openai"
"io" "io"
"net/http" "net/http"
"net/url" "net/url"
) )
const ChatGPTInitPrompt = `You are a assistant who can help users write and optimise the configurations of Nginx, 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.` The first reply should involve the key information of the file and ask user what can you help them.`
func MakeChatCompletionRequest(c *gin.Context) { func MakeChatCompletionRequest(c *gin.Context) {
var json struct { var json struct {
Filepath string `json:"filepath"` Filepath string `json:"filepath"`
Messages []openai.ChatCompletionMessage `json:"messages"` Messages []openai.ChatCompletionMessage `json:"messages"`
} }
if !api.BindAndValid(c, &json) { if !api.BindAndValid(c, &json) {
return return
} }
messages := []openai.ChatCompletionMessage{ messages := []openai.ChatCompletionMessage{
{ {
Role: openai.ChatMessageRoleSystem, Role: openai.ChatMessageRoleSystem,
Content: ChatGPTInitPrompt, Content: ChatGPTInitPrompt,
}, },
} }
messages = append(messages, json.Messages...) messages = append(messages, json.Messages...)
if json.Filepath != "" { if json.Filepath != "" {
messages = chatbot.ChatCompletionWithContext(json.Filepath, messages) messages = chatbot.ChatCompletionWithContext(json.Filepath, messages)
} }
// SSE server // SSE server
c.Writer.Header().Set("Content-Type", "text/event-stream; charset=utf-8") c.Writer.Header().Set("Content-Type", "text/event-stream; charset=utf-8")
c.Writer.Header().Set("Cache-Control", "no-cache") c.Writer.Header().Set("Cache-Control", "no-cache")
c.Writer.Header().Set("Connection", "keep-alive") c.Writer.Header().Set("Connection", "keep-alive")
c.Writer.Header().Set("Access-Control-Allow-Origin", "*") c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
config := openai.DefaultConfig(settings.OpenAISettings.Token) config := openai.DefaultConfig(settings.OpenAISettings.Token)
if settings.OpenAISettings.Proxy != "" { if settings.OpenAISettings.Proxy != "" {
proxyUrl, err := url.Parse(settings.OpenAISettings.Proxy) proxyUrl, err := url.Parse(settings.OpenAISettings.Proxy)
if err != nil { if err != nil {
c.Stream(func(w io.Writer) bool { c.Stream(func(w io.Writer) bool {
c.SSEvent("message", gin.H{ c.SSEvent("message", gin.H{
"type": "error", "type": "error",
"content": err.Error(), "content": err.Error(),
}) })
return false return false
}) })
return return
} }
transport := &http.Transport{ transport := &http.Transport{
Proxy: http.ProxyURL(proxyUrl), Proxy: http.ProxyURL(proxyUrl),
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify},
} }
config.HTTPClient = &http.Client{ config.HTTPClient = &http.Client{
Transport: transport, Transport: transport,
} }
} }
if settings.OpenAISettings.BaseUrl != "" { if settings.OpenAISettings.BaseUrl != "" {
config.BaseURL = settings.OpenAISettings.BaseUrl config.BaseURL = settings.OpenAISettings.BaseUrl
} }
openaiClient := openai.NewClientWithConfig(config) openaiClient := openai.NewClientWithConfig(config)
ctx := context.Background() ctx := context.Background()
req := openai.ChatCompletionRequest{ req := openai.ChatCompletionRequest{
Model: settings.OpenAISettings.Model, Model: settings.OpenAISettings.Model,
Messages: messages, Messages: messages,
Stream: true, Stream: true,
} }
stream, err := openaiClient.CreateChatCompletionStream(ctx, req) stream, err := openaiClient.CreateChatCompletionStream(ctx, req)
if err != nil { if err != nil {
fmt.Printf("CompletionStream error: %v\n", err) fmt.Printf("CompletionStream error: %v\n", err)
c.Stream(func(w io.Writer) bool { c.Stream(func(w io.Writer) bool {
c.SSEvent("message", gin.H{ c.SSEvent("message", gin.H{
"type": "error", "type": "error",
"content": err.Error(), "content": err.Error(),
}) })
return false return false
}) })
return return
} }
defer stream.Close() defer stream.Close()
msgChan := make(chan string) msgChan := make(chan string)
go func() { go func() {
defer close(msgChan) defer close(msgChan)
for { for {
response, err := stream.Recv() response, err := stream.Recv()
if errors.Is(err, io.EOF) { if errors.Is(err, io.EOF) {
fmt.Println() fmt.Println()
return return
} }
if err != nil { if err != nil {
fmt.Printf("Stream error: %v\n", err) fmt.Printf("Stream error: %v\n", err)
return 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 { c.Stream(func(w io.Writer) bool {
if m, ok := <-msgChan; ok { if m, ok := <-msgChan; ok {
c.SSEvent("message", gin.H{ c.SSEvent("message", gin.H{
"type": "message", "type": "message",
"content": m, "content": m,
}) })
return true return true
} }
return false return false
}) })
} }

View file

@ -1,43 +1,44 @@
package analytic package analytic
import ( import (
"crypto/tls" "crypto/tls"
"encoding/json" "encoding/json"
"github.com/0xJacky/Nginx-UI/internal/logger" "github.com/0xJacky/Nginx-UI/internal/logger"
"github.com/0xJacky/Nginx-UI/internal/upgrader" "github.com/0xJacky/Nginx-UI/internal/upgrader"
"github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/model"
"github.com/shirou/gopsutil/v3/load" "github.com/0xJacky/Nginx-UI/settings"
"github.com/shirou/gopsutil/v3/net" "github.com/shirou/gopsutil/v3/load"
"io" "github.com/shirou/gopsutil/v3/net"
"net/http" "io"
"net/url" "net/http"
"sync" "net/url"
"time" "sync"
"time"
) )
type NodeInfo struct { type NodeInfo struct {
NodeRuntimeInfo upgrader.RuntimeInfo `json:"node_runtime_info"` NodeRuntimeInfo upgrader.RuntimeInfo `json:"node_runtime_info"`
Version string `json:"version"` Version string `json:"version"`
CPUNum int `json:"cpu_num"` CPUNum int `json:"cpu_num"`
MemoryTotal string `json:"memory_total"` MemoryTotal string `json:"memory_total"`
DiskTotal string `json:"disk_total"` DiskTotal string `json:"disk_total"`
} }
type NodeStat struct { type NodeStat struct {
AvgLoad *load.AvgStat `json:"avg_load"` AvgLoad *load.AvgStat `json:"avg_load"`
CPUPercent float64 `json:"cpu_percent"` CPUPercent float64 `json:"cpu_percent"`
MemoryPercent float64 `json:"memory_percent"` MemoryPercent float64 `json:"memory_percent"`
DiskPercent float64 `json:"disk_percent"` DiskPercent float64 `json:"disk_percent"`
Network net.IOCountersStat `json:"network"` Network net.IOCountersStat `json:"network"`
Status bool `json:"status"` Status bool `json:"status"`
ResponseAt time.Time `json:"response_at"` ResponseAt time.Time `json:"response_at"`
} }
type Node struct { type Node struct {
EnvironmentID int `json:"environment_id,omitempty"` EnvironmentID int `json:"environment_id,omitempty"`
*model.Environment *model.Environment
NodeStat NodeStat
NodeInfo NodeInfo
} }
var mutex sync.Mutex var mutex sync.Mutex
@ -47,74 +48,74 @@ type TNodeMap map[int]*Node
var NodeMap TNodeMap var NodeMap TNodeMap
func init() { func init() {
NodeMap = make(TNodeMap) NodeMap = make(TNodeMap)
} }
func GetNode(env *model.Environment) (n *Node) { func GetNode(env *model.Environment) (n *Node) {
if env == nil { if env == nil {
// this should never happen // this should never happen
logger.Error("env is nil") logger.Error("env is nil")
return return
} }
if !env.Enabled { if !env.Enabled {
return &Node{ return &Node{
Environment: env, Environment: env,
} }
} }
n, ok := NodeMap[env.ID] n, ok := NodeMap[env.ID]
if !ok { if !ok {
n = &Node{} n = &Node{}
} }
n.Environment = env n.Environment = env
return n return n
} }
func InitNode(env *model.Environment) (n *Node) { func InitNode(env *model.Environment) (n *Node) {
n = &Node{ n = &Node{
Environment: env, Environment: env,
} }
u, err := url.JoinPath(env.URL, "/api/node") u, err := url.JoinPath(env.URL, "/api/node")
if err != nil { if err != nil {
logger.Error(err) logger.Error(err)
return return
} }
client := http.Client{ client := http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify},
}, },
} }
req, err := http.NewRequest("GET", u, nil) req, err := http.NewRequest("GET", u, nil)
if err != nil { if err != nil {
logger.Error(err) logger.Error(err)
return 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 { if err != nil {
logger.Error(err) logger.Error(err)
return return
} }
defer resp.Body.Close() defer resp.Body.Close()
bytes, _ := io.ReadAll(resp.Body) bytes, _ := io.ReadAll(resp.Body)
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
logger.Error(string(bytes)) logger.Error(string(bytes))
return return
} }
err = json.Unmarshal(bytes, &n.NodeInfo) err = json.Unmarshal(bytes, &n.NodeInfo)
if err != nil { if err != nil {
logger.Error(err) logger.Error(err)
return return
} }
return return
} }

View file

@ -64,7 +64,7 @@ func IssueCert(payload *ConfigPayload, logChan chan string, errChan chan error)
// Skip TLS check // Skip TLS check
if config.HTTPClient != nil { if config.HTTPClient != nil {
config.HTTPClient.Transport = &http.Transport{ config.HTTPClient.Transport = &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify},
} }
} }

View file

@ -11,7 +11,8 @@ import (
"github.com/0xJacky/Nginx-UI/internal/notification" "github.com/0xJacky/Nginx-UI/internal/notification"
"github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/model"
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/go-acme/lego/v4/certcrypto" "github.com/0xJacky/Nginx-UI/settings"
"github.com/go-acme/lego/v4/certcrypto"
"io" "io"
"net/http" "net/http"
"os" "os"
@ -89,7 +90,7 @@ type SyncNotificationPayload struct {
func deploy(env *model.Environment, c *model.Cert, payloadBytes []byte) (err error) { func deploy(env *model.Environment, c *model.Cert, payloadBytes []byte) (err error) {
client := http.Client{ client := http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify},
}, },
} }
url, err := env.GetUrl("/api/cert_sync") url, err := env.GetUrl("/api/cert_sync")

View file

@ -1,257 +1,258 @@
package config package config
import ( import (
"bytes" "bytes"
"crypto/tls" "crypto/tls"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/helper"
"github.com/0xJacky/Nginx-UI/internal/logger" "github.com/0xJacky/Nginx-UI/internal/logger"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/0xJacky/Nginx-UI/internal/notification" "github.com/0xJacky/Nginx-UI/internal/notification"
"github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/model"
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/gin-gonic/gin" "github.com/0xJacky/Nginx-UI/settings"
"io" "github.com/gin-gonic/gin"
"net/http" "io"
"os" "net/http"
"path/filepath" "os"
"strings" "path/filepath"
"strings"
) )
type SyncConfigPayload struct { type SyncConfigPayload struct {
Name string `json:"name"` Name string `json:"name"`
Filepath string `json:"filepath"` Filepath string `json:"filepath"`
NewFilepath string `json:"new_filepath"` NewFilepath string `json:"new_filepath"`
Content string `json:"content"` Content string `json:"content"`
Overwrite bool `json:"overwrite"` Overwrite bool `json:"overwrite"`
} }
func SyncToRemoteServer(c *model.Config, newFilepath string) (err error) { func SyncToRemoteServer(c *model.Config, newFilepath string) (err error) {
if c.Filepath == "" || len(c.SyncNodeIds) == 0 { if c.Filepath == "" || len(c.SyncNodeIds) == 0 {
return return
} }
nginxConfPath := nginx.GetConfPath() nginxConfPath := nginx.GetConfPath()
if !helper.IsUnderDirectory(c.Filepath, nginxConfPath) { if !helper.IsUnderDirectory(c.Filepath, nginxConfPath) {
return fmt.Errorf("config: %s is not under the nginx conf path: %s", return fmt.Errorf("config: %s is not under the nginx conf path: %s",
c.Filepath, nginxConfPath) c.Filepath, nginxConfPath)
} }
if newFilepath != "" && !helper.IsUnderDirectory(newFilepath, nginxConfPath) { if newFilepath != "" && !helper.IsUnderDirectory(newFilepath, nginxConfPath) {
return fmt.Errorf("config: %s is not under the nginx conf path: %s", return fmt.Errorf("config: %s is not under the nginx conf path: %s",
c.Filepath, nginxConfPath) c.Filepath, nginxConfPath)
} }
currentPath := c.Filepath currentPath := c.Filepath
if newFilepath != "" { if newFilepath != "" {
currentPath = newFilepath currentPath = newFilepath
} }
configBytes, err := os.ReadFile(currentPath) configBytes, err := os.ReadFile(currentPath)
if err != nil { if err != nil {
return return
} }
payload := &SyncConfigPayload{ payload := &SyncConfigPayload{
Name: c.Name, Name: c.Name,
Filepath: c.Filepath, Filepath: c.Filepath,
NewFilepath: newFilepath, NewFilepath: newFilepath,
Content: string(configBytes), Content: string(configBytes),
Overwrite: c.SyncOverwrite, Overwrite: c.SyncOverwrite,
} }
payloadBytes, err := json.Marshal(payload) payloadBytes, err := json.Marshal(payload)
if err != nil { if err != nil {
return return
} }
q := query.Environment q := query.Environment
envs, _ := q.Where(q.ID.In(c.SyncNodeIds...)).Find() envs, _ := q.Where(q.ID.In(c.SyncNodeIds...)).Find()
for _, env := range envs { for _, env := range envs {
go func() { go func() {
err := payload.deploy(env, c, payloadBytes) err := payload.deploy(env, c, payloadBytes)
if err != nil { if err != nil {
logger.Error(err) logger.Error(err)
} }
}() }()
} }
return return
} }
func SyncRenameOnRemoteServer(origPath, newPath string, syncNodeIds []int) (err error) { func SyncRenameOnRemoteServer(origPath, newPath string, syncNodeIds []int) (err error) {
if origPath == "" || newPath == "" || len(syncNodeIds) == 0 { if origPath == "" || newPath == "" || len(syncNodeIds) == 0 {
return return
} }
nginxConfPath := nginx.GetConfPath() nginxConfPath := nginx.GetConfPath()
if !helper.IsUnderDirectory(origPath, nginxConfPath) { if !helper.IsUnderDirectory(origPath, nginxConfPath) {
return fmt.Errorf("config: %s is not under the nginx conf path: %s", return fmt.Errorf("config: %s is not under the nginx conf path: %s",
origPath, nginxConfPath) origPath, nginxConfPath)
} }
if !helper.IsUnderDirectory(newPath, nginxConfPath) { if !helper.IsUnderDirectory(newPath, nginxConfPath) {
return fmt.Errorf("config: %s is not under the nginx conf path: %s", return fmt.Errorf("config: %s is not under the nginx conf path: %s",
newPath, nginxConfPath) newPath, nginxConfPath)
} }
payload := &RenameConfigPayload{ payload := &RenameConfigPayload{
Filepath: origPath, Filepath: origPath,
NewFilepath: newPath, NewFilepath: newPath,
} }
q := query.Environment q := query.Environment
envs, _ := q.Where(q.ID.In(syncNodeIds...)).Find() envs, _ := q.Where(q.ID.In(syncNodeIds...)).Find()
for _, env := range envs { for _, env := range envs {
go func() { go func() {
err := payload.rename(env) err := payload.rename(env)
if err != nil { if err != nil {
logger.Error(err) logger.Error(err)
} }
}() }()
} }
return return
} }
type SyncNotificationPayload struct { type SyncNotificationPayload struct {
StatusCode int `json:"status_code"` StatusCode int `json:"status_code"`
ConfigName string `json:"config_name"` ConfigName string `json:"config_name"`
EnvName string `json:"env_name"` EnvName string `json:"env_name"`
RespBody string `json:"resp_body"` RespBody string `json:"resp_body"`
} }
func (p *SyncConfigPayload) deploy(env *model.Environment, c *model.Config, payloadBytes []byte) (err error) { func (p *SyncConfigPayload) deploy(env *model.Environment, c *model.Config, payloadBytes []byte) (err error) {
client := http.Client{ client := http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify},
}, },
} }
url, err := env.GetUrl("/api/config") url, err := env.GetUrl("/api/config")
if err != nil { if err != nil {
return return
} }
req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(payloadBytes)) req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(payloadBytes))
if err != nil { if err != nil {
return 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 { if err != nil {
return return
} }
defer resp.Body.Close() defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body) respBody, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return return
} }
notificationPayload := &SyncNotificationPayload{ notificationPayload := &SyncNotificationPayload{
StatusCode: resp.StatusCode, StatusCode: resp.StatusCode,
ConfigName: c.Name, ConfigName: c.Name,
EnvName: env.Name, EnvName: env.Name,
RespBody: string(respBody), RespBody: string(respBody),
} }
notificationPayloadBytes, err := json.Marshal(notificationPayload) notificationPayloadBytes, err := json.Marshal(notificationPayload)
if err != nil { if err != nil {
return return
} }
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
notification.Error("Sync Config Error", string(notificationPayloadBytes)) notification.Error("Sync Config Error", string(notificationPayloadBytes))
return return
} }
notification.Success("Sync Config Success", string(notificationPayloadBytes)) notification.Success("Sync Config Success", string(notificationPayloadBytes))
// handle rename // handle rename
if p.NewFilepath == "" || p.Filepath == p.NewFilepath { if p.NewFilepath == "" || p.Filepath == p.NewFilepath {
return return
} }
payload := &RenameConfigPayload{ payload := &RenameConfigPayload{
Filepath: p.Filepath, Filepath: p.Filepath,
NewFilepath: p.NewFilepath, NewFilepath: p.NewFilepath,
} }
err = payload.rename(env) err = payload.rename(env)
return return
} }
type RenameConfigPayload struct { type RenameConfigPayload struct {
Filepath string `json:"filepath"` Filepath string `json:"filepath"`
NewFilepath string `json:"new_filepath"` NewFilepath string `json:"new_filepath"`
} }
type SyncRenameNotificationPayload struct { type SyncRenameNotificationPayload struct {
StatusCode int `json:"status_code"` StatusCode int `json:"status_code"`
OrigPath string `json:"orig_path"` OrigPath string `json:"orig_path"`
NewPath string `json:"new_path"` NewPath string `json:"new_path"`
EnvName string `json:"env_name"` EnvName string `json:"env_name"`
RespBody string `json:"resp_body"` RespBody string `json:"resp_body"`
} }
func (p *RenameConfigPayload) rename(env *model.Environment) (err error) { func (p *RenameConfigPayload) rename(env *model.Environment) (err error) {
// handle rename // handle rename
if p.NewFilepath == "" || p.Filepath == p.NewFilepath { if p.NewFilepath == "" || p.Filepath == p.NewFilepath {
return return
} }
client := http.Client{ client := http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify},
}, },
} }
payloadBytes, err := json.Marshal(gin.H{ payloadBytes, err := json.Marshal(gin.H{
"base_path": strings.ReplaceAll(filepath.Dir(p.Filepath), nginx.GetConfPath(), ""), "base_path": strings.ReplaceAll(filepath.Dir(p.Filepath), nginx.GetConfPath(), ""),
"orig_name": filepath.Base(p.Filepath), "orig_name": filepath.Base(p.Filepath),
"new_name": filepath.Base(p.NewFilepath), "new_name": filepath.Base(p.NewFilepath),
}) })
if err != nil { if err != nil {
return return
} }
url, err := env.GetUrl("/api/config_rename") url, err := env.GetUrl("/api/config_rename")
if err != nil { if err != nil {
return return
} }
req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(payloadBytes)) req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(payloadBytes))
if err != nil { if err != nil {
return 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 { if err != nil {
return return
} }
defer resp.Body.Close() defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body) respBody, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return return
} }
notificationPayload := &SyncRenameNotificationPayload{ notificationPayload := &SyncRenameNotificationPayload{
StatusCode: resp.StatusCode, StatusCode: resp.StatusCode,
OrigPath: p.Filepath, OrigPath: p.Filepath,
NewPath: p.NewFilepath, NewPath: p.NewFilepath,
EnvName: env.Name, EnvName: env.Name,
RespBody: string(respBody), RespBody: string(respBody),
} }
notificationPayloadBytes, err := json.Marshal(notificationPayload) notificationPayloadBytes, err := json.Marshal(notificationPayload)
if err != nil { if err != nil {
return return
} }
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
notification.Error("Rename Remote Config Error", string(notificationPayloadBytes)) notification.Error("Rename Remote Config Error", string(notificationPayloadBytes))
return return
} }
notification.Success("Rename Remote Config Success", string(notificationPayloadBytes)) notification.Success("Rename Remote Config Success", string(notificationPayloadBytes))
return return
} }

View file

@ -4,7 +4,8 @@ import (
"crypto/tls" "crypto/tls"
"github.com/0xJacky/Nginx-UI/internal/logger" "github.com/0xJacky/Nginx-UI/internal/logger"
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/gin-gonic/gin" "github.com/0xJacky/Nginx-UI/settings"
"github.com/gin-gonic/gin"
"github.com/spf13/cast" "github.com/spf13/cast"
"io" "io"
"net/http" "net/http"
@ -58,7 +59,7 @@ func Proxy() gin.HandlerFunc {
logger.Debug("Proxy request", proxyUrl.String()) logger.Debug("Proxy request", proxyUrl.String())
client := http.Client{ client := http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify},
}, },
} }

View file

@ -6,7 +6,8 @@ import (
"crypto/elliptic" "crypto/elliptic"
"crypto/rand" "crypto/rand"
"crypto/tls" "crypto/tls"
"github.com/go-acme/lego/v4/lego" "github.com/0xJacky/Nginx-UI/settings"
"github.com/go-acme/lego/v4/lego"
"github.com/go-acme/lego/v4/registration" "github.com/go-acme/lego/v4/registration"
"math/big" "math/big"
"net/http" "net/http"
@ -63,7 +64,7 @@ func (u *AcmeUser) Register() error {
// Skip TLS check // Skip TLS check
if config.HTTPClient != nil { if config.HTTPClient != nil {
config.HTTPClient.Transport = &http.Transport{ config.HTTPClient.Transport = &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify},
} }
} }

View file

@ -21,6 +21,7 @@ type Server struct {
CertRenewalInterval int `json:"cert_renewal_interval" binding:"min=7,max=21"` CertRenewalInterval int `json:"cert_renewal_interval" binding:"min=7,max=21"`
RecursiveNameservers []string `json:"recursive_nameservers" binding:"omitempty,dive,hostname_port"` RecursiveNameservers []string `json:"recursive_nameservers" binding:"omitempty,dive,hostname_port"`
SkipInstallation bool `json:"skip_installation" protected:"true"` SkipInstallation bool `json:"skip_installation" protected:"true"`
InsecureSkipVerify bool `json:"insecure_skip_verify" protected:"true"`
Name string `json:"name" binding:"omitempty,safety_text"` Name string `json:"name" binding:"omitempty,safety_text"`
} }