mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-11 02:15:48 +02:00
enhance: add settings for skip tls cert check
This commit is contained in:
parent
013d810678
commit
f1c0f8ddca
8 changed files with 400 additions and 394 deletions
|
@ -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: true},
|
||||
}
|
||||
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
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,43 +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/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
|
||||
|
@ -47,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: true},
|
||||
},
|
||||
}
|
||||
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
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ func IssueCert(payload *ConfigPayload, logChan chan string, errChan chan error)
|
|||
// Skip TLS check
|
||||
if config.HTTPClient != nil {
|
||||
config.HTTPClient.Transport = &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@ import (
|
|||
"github.com/0xJacky/Nginx-UI/internal/notification"
|
||||
"github.com/0xJacky/Nginx-UI/model"
|
||||
"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"
|
||||
"net/http"
|
||||
"os"
|
||||
|
@ -89,7 +90,7 @@ type SyncNotificationPayload struct {
|
|||
func deploy(env *model.Environment, c *model.Cert, payloadBytes []byte) (err error) {
|
||||
client := http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify},
|
||||
},
|
||||
}
|
||||
url, err := env.GetUrl("/api/cert_sync")
|
||||
|
|
|
@ -1,257 +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/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: true},
|
||||
},
|
||||
}
|
||||
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: true},
|
||||
},
|
||||
}
|
||||
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
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@ import (
|
|||
"crypto/tls"
|
||||
"github.com/0xJacky/Nginx-UI/internal/logger"
|
||||
"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"
|
||||
"io"
|
||||
"net/http"
|
||||
|
@ -58,7 +59,7 @@ func Proxy() gin.HandlerFunc {
|
|||
logger.Debug("Proxy request", proxyUrl.String())
|
||||
client := http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ import (
|
|||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"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"
|
||||
"math/big"
|
||||
"net/http"
|
||||
|
@ -63,7 +64,7 @@ func (u *AcmeUser) Register() error {
|
|||
// Skip TLS check
|
||||
if config.HTTPClient != nil {
|
||||
config.HTTPClient.Transport = &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: settings.ServerSettings.InsecureSkipVerify},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ type Server struct {
|
|||
CertRenewalInterval int `json:"cert_renewal_interval" binding:"min=7,max=21"`
|
||||
RecursiveNameservers []string `json:"recursive_nameservers" binding:"omitempty,dive,hostname_port"`
|
||||
SkipInstallation bool `json:"skip_installation" protected:"true"`
|
||||
InsecureSkipVerify bool `json:"insecure_skip_verify" protected:"true"`
|
||||
Name string `json:"name" binding:"omitempty,safety_text"`
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue