feat(website): fix issue with create load-balance failed (#8224)

This commit is contained in:
zhengkunwang
2025-03-24 09:37:31 +00:00
committed by GitHub
parent 7d81dad822
commit 6a2ab8598b
17 changed files with 116 additions and 47 deletions
+2 -1
View File
@@ -5,7 +5,6 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"os"
"path"
@@ -14,6 +13,8 @@ import (
"strconv"
"strings"
"github.com/gin-gonic/gin"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/1Panel-dev/1Panel/agent/app/dto/response"
+4 -1
View File
@@ -1845,5 +1845,8 @@ func handleOpenrestyFile(appInstall *model.AppInstall) error {
return err
}
newContent := strings.ReplaceAll(string(content), "default_server", "")
return fileOp.WriteFile(defaultConfigPath, strings.NewReader(newContent), constant.FilePerm)
if err := fileOp.WriteFile(defaultConfigPath, strings.NewReader(newContent), constant.FilePerm); err != nil {
return err
}
return createAllWebsitesWAFConfig()
}
+7 -15
View File
@@ -412,7 +412,7 @@ func (w WebsiteService) CreateWebsite(create request.WebsiteCreate) (err error)
if len(create.FtpUser) != 0 && len(create.FtpPassword) != 0 {
createFtpUser := func(t *task.Task) error {
indexDir := path.Join(nginxInstall.GetPath(), "www", "sites", website.Alias, "index")
indexDir := GetSitePath(*website, SiteIndexDir)
itemID, err := NewIFtpService().Create(dto.FtpCreate{User: create.FtpUser, Password: create.FtpPassword, Path: indexDir})
if err != nil {
createTask.Log(fmt.Sprintf("create ftp for website failed, err: %v", err))
@@ -970,7 +970,7 @@ func (w WebsiteService) OpWebsiteHTTPS(ctx context.Context, req request.WebsiteH
if err != nil {
return nil, err
}
if err = ChangeHSTSConfig(req.Hsts, nginxInstall, website); err != nil {
if err = ChangeHSTSConfig(req.Hsts, website); err != nil {
return nil, err
}
res.Enable = req.Enable
@@ -2775,11 +2775,7 @@ func (w WebsiteService) GetLoadBalances(id uint) ([]dto.NginxUpstream, error) {
if err != nil {
return nil, err
}
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
if err != nil {
return nil, err
}
includeDir := path.Join(nginxInstall.GetPath(), "www", "sites", website.Alias, "upstream")
includeDir := GetSitePath(website, SiteUpstreamDir)
fileOp := files.NewFileOp()
if !fileOp.Stat(includeDir) {
return nil, nil
@@ -2870,11 +2866,7 @@ func (w WebsiteService) CreateLoadBalance(req request.WebsiteLBCreate) error {
if err != nil {
return err
}
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
if err != nil {
return err
}
includeDir := path.Join(nginxInstall.GetPath(), "www", "sites", website.Alias, "upstream")
includeDir := GetSitePath(website, SiteUpstreamDir)
fileOp := files.NewFileOp()
if !fileOp.Stat(includeDir) {
_ = fileOp.CreateDir(includeDir, constant.DirPerm)
@@ -2949,7 +2941,7 @@ func (w WebsiteService) UpdateLoadBalance(req request.WebsiteLBUpdate) error {
if err != nil {
return err
}
includeDir := path.Join(nginxInstall.GetPath(), "www", "sites", website.Alias, "upstream")
includeDir := GetSitePath(website, SiteUpstreamDir)
fileOp := files.NewFileOp()
filePath := path.Join(includeDir, fmt.Sprintf("%s.conf", req.Name))
if !fileOp.Stat(filePath) {
@@ -3021,7 +3013,7 @@ func (w WebsiteService) DeleteLoadBalance(req request.WebsiteLBDelete) error {
if err != nil {
return err
}
includeDir := path.Join(nginxInstall.GetPath(), "www", "sites", website.Alias, "upstream")
includeDir := GetSitePath(website, SiteUpstreamDir)
fileOp := files.NewFileOp()
filePath := path.Join(includeDir, fmt.Sprintf("%s.conf", req.Name))
if !fileOp.Stat(filePath) {
@@ -3042,7 +3034,7 @@ func (w WebsiteService) UpdateLoadBalanceFile(req request.WebsiteLBUpdateFile) e
if err != nil {
return err
}
includeDir := path.Join(nginxInstall.GetPath(), "www", "sites", website.Alias, "upstream")
includeDir := GetSitePath(website, SiteUpstreamDir)
filePath := path.Join(includeDir, fmt.Sprintf("%s.conf", req.Name))
fileOp := files.NewFileOp()
oldContent, err := fileOp.GetContent(filePath)
+86 -22
View File
@@ -272,6 +272,86 @@ func configDefaultNginx(website *model.Website, domains []model.WebsiteDomain, a
return nil
}
func moveDefaultWafConfig(websiteDir string, defaultConfigContent []byte, defaultRuleDir string, fileOp files.FileOp) error {
if !fileOp.Stat(websiteDir) {
if err := fileOp.CreateDir(websiteDir, constant.DirPerm); err != nil {
return err
}
}
if err := fileOp.SaveFileWithByte(path.Join(websiteDir, "config.json"), defaultConfigContent, constant.DirPerm); err != nil {
return err
}
websiteRuleDir := path.Join(websiteDir, "rules")
if !fileOp.Stat(websiteRuleDir) {
if err := fileOp.CreateDir(websiteRuleDir, constant.DirPerm); err != nil {
return err
}
}
defaultRulesName := []string{"acl", "args", "cookie", "defaultUaBlack", "defaultUrlBlack", "fileExt", "header", "methodWhite", "cdn"}
for _, ruleName := range defaultRulesName {
srcPath := path.Join(defaultRuleDir, ruleName+".json")
if fileOp.Stat(srcPath) {
_ = fileOp.Copy(srcPath, websiteRuleDir)
}
}
return nil
}
func createAllWebsitesWAFConfig() error {
websites, _ := websiteRepo.List()
if len(websites) == 0 {
return nil
}
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
if err != nil {
return err
}
wafDataPath := path.Join(nginxInstall.GetPath(), "1pwaf", "data")
fileOp := files.NewFileOp()
if !fileOp.Stat(wafDataPath) {
return nil
}
websitesConfigPath := path.Join(wafDataPath, "conf", "sites.json")
var websitesArray []request.WafWebsite
for _, website := range websites {
wafWebsite := request.WafWebsite{
Key: website.Alias,
Domains: make([]string, 0),
Host: make([]string, 0),
}
websiteDomains, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithWebsiteId(website.ID))
for _, domain := range websiteDomains {
wafWebsite.Domains = append(wafWebsite.Domains, domain.Domain)
wafWebsite.Host = append(wafWebsite.Host, domain.Domain+":"+strconv.Itoa(domain.Port))
}
websitesArray = append(websitesArray, wafWebsite)
}
websitesContent, err := json.Marshal(websitesArray)
if err != nil {
return err
}
if err := fileOp.SaveFileWithByte(websitesConfigPath, websitesContent, constant.DirPerm); err != nil {
return err
}
var (
defaultConfigPath = path.Join(wafDataPath, "conf", "siteConfig.json")
defaultRuleDir = path.Join(wafDataPath, "rules")
sitesDir = path.Join(wafDataPath, "sites")
)
defaultConfigContent, err := fileOp.GetContent(defaultConfigPath)
if err != nil {
return err
}
for _, website := range websites {
websiteDir := path.Join(sitesDir, website.Alias)
if err := moveDefaultWafConfig(websiteDir, defaultConfigContent, defaultRuleDir, fileOp); err != nil {
return err
}
}
return nil
}
func createWafConfig(website *model.Website, domains []model.WebsiteDomain) error {
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
if err != nil {
@@ -324,35 +404,16 @@ func createWafConfig(website *model.Website, domains []model.WebsiteDomain) erro
return err
}
if !fileOp.Stat(websiteDir) {
if err = fileOp.CreateDir(websiteDir, constant.DirPerm); err != nil {
return err
}
}
defer func() {
if err != nil {
_ = fileOp.DeleteDir(websiteDir)
}
}()
if err = fileOp.SaveFileWithByte(path.Join(websiteDir, "config.json"), defaultConfigContent, constant.DirPerm); err != nil {
if err := moveDefaultWafConfig(websiteDir, defaultConfigContent, defaultRuleDir, fileOp); err != nil {
return err
}
websiteRuleDir := path.Join(websiteDir, "rules")
if !fileOp.Stat(websiteRuleDir) {
if err := fileOp.CreateDir(websiteRuleDir, constant.DirPerm); err != nil {
return err
}
}
defaultRulesName := []string{"acl", "args", "cookie", "defaultUaBlack", "defaultUrlBlack", "fileExt", "header", "methodWhite", "cdn"}
for _, ruleName := range defaultRulesName {
srcPath := path.Join(defaultRuleDir, ruleName+".json")
if fileOp.Stat(srcPath) {
_ = fileOp.Copy(srcPath, websiteRuleDir)
}
}
if err = opNginx(nginxInstall.ContainerName, constant.NginxCheck); err != nil {
return err
}
@@ -1082,8 +1143,8 @@ func UpdateSSLConfig(websiteSSL model.WebsiteSSL) error {
return nil
}
func ChangeHSTSConfig(enable bool, nginxInstall model.AppInstall, website model.Website) error {
includeDir := path.Join(nginxInstall.GetPath(), "www", "sites", website.Alias, "proxy")
func ChangeHSTSConfig(enable bool, website model.Website) error {
includeDir := GetSitePath(website, SiteProxyDir)
fileOp := files.NewFileOp()
if !fileOp.Stat(includeDir) {
return nil
@@ -1180,6 +1241,7 @@ const (
DefaultRewriteDir = "DefaultRewriteDir"
SiteRootAuthBasicPath = "SiteRootAuthBasicPath"
SitePathAuthBasicDir = "SitePathAuthBasicDir"
SiteUpstreamDir = "SiteUpstreamDir"
)
func GetSitePath(website model.Website, confType string) string {
@@ -1208,6 +1270,8 @@ func GetSitePath(website model.Website, confType string) string {
return path.Join(GteSiteDir(website.Alias), "auth_basic", "auth.pass")
case SitePathAuthBasicDir:
return path.Join(GteSiteDir(website.Alias), "path_auth")
case SiteUpstreamDir:
return path.Join(GteSiteDir(website.Alias), "upstream")
}
return ""
}
-4
View File
@@ -52,10 +52,6 @@ func Start() {
Handler: rootRouter,
}
go func() {
_ = http.ListenAndServe("0.0.0.0:6060", nil)
}()
if global.IsMaster {
_ = os.Remove("/etc/1panel/agent.sock")
_ = os.Mkdir("/etc/1panel", constant.DirPerm)
+2
View File
@@ -2401,6 +2401,8 @@ const message = {
runtimePortHelper: 'The current runtime environment has multiple ports. Please select a proxy port.',
runtimePortWarn: 'The current runtime environment has no ports, unable to proxy',
cacheWarn: 'Please turn off the cache switch in the reverse proxy first',
loadBalanceHelper:
'This section only creates load balancing rules, to use the rules please reverse proxy http(s)://<load balance name>',
},
php: {
short_open_tag: 'Short tag support',
+2
View File
@@ -2297,6 +2297,8 @@ const message = {
runtimePortHelper: '現在の実行環境には複数のポートがありますプロキシポートを選択してください',
runtimePortWarn: '現在の実行環境にはポートがありませんプロキシできません',
cacheWarn: 'まずリバースプロキシのキャッシュスイッチをオフにしてください',
loadBalanceHelper:
'This section only creates load balancing rules, to use the rules please reverse proxy http(s)://<load balance name>',
},
php: {
short_open_tag: '短いタグサポート',
+2
View File
@@ -2260,6 +2260,8 @@ const message = {
runtimePortHelper: '현재 실행 환경에 여러 포트가 있습니다. 프록시 포트를 선택하세요.',
runtimePortWarn: '현재 실행 환경에 포트가 없습니다. 프록시할 없습니다',
cacheWarn: '먼저 리버스 프록시의 캐시 스위치를 끄십시오',
loadBalanceHelper:
'여기서는 로드 밸런싱 규칙만 생성합니다. 규칙을 사용하려면 리버스 프록시 http(s)://<로드 밸런스 이름>을 사용하십시오',
},
php: {
short_open_tag: '짧은 태그 지원',
+2
View File
@@ -2353,6 +2353,8 @@ const message = {
runtimePortHelper: 'Persekitaran runtime semasa mempunyai beberapa port. Sila pilih port proksi.',
runtimePortWarn: 'Persekitaran runtime semasa tidak mempunyai port, tidak dapat proksi',
cacheWarn: 'Sila matikan suis cache dalam pembalikan proksi terlebih dahulu',
loadBalanceHelper:
'Di sini hanya mencipta peraturan keseimbangan beban, untuk menggunakan peraturan sila proksi terbalik http(s)://<nama keseimbangan beban>',
},
php: {
short_open_tag: 'Sokongan tag pendek',
+2
View File
@@ -2347,6 +2347,8 @@ const message = {
runtimePortHelper: 'O ambiente de runtime atual possui várias portas. Por favor, selecione uma porta de proxy.',
runtimePortWarn: 'O ambiente de execução atual não possui portos, não é possível proxiar',
cacheWarn: 'Por favor, desligue o interruptor de cache no proxy reverso primeiro',
loadBalanceHelper:
'Esta seção apenas cria regras de balanceamento de carga, para usar as regras, por favor, proxy reverso http(s)://<nome do balanceamento de carga>',
},
php: {
short_open_tag: 'Suporte para short tags',
+2
View File
@@ -2349,6 +2349,8 @@ const message = {
runtimePortHelper: 'O ambiente de runtime atual possui várias portas. Por favor, selecione uma porta de proxy.',
runtimePortWarn: 'В текущей среде выполнения нет портов, невозможно проксировать',
cacheWarn: 'Пожалуйста, сначала выключите кэш в обратном прокси',
loadBalanceHelper:
'Здесь создаются только правила балансировки нагрузки, чтобы использовать правила, пожалуйста, используйте обратный прокси http(s)://<имя балансировки нагрузки>',
},
php: {
short_open_tag: 'Поддержка коротких тегов',
+1
View File
@@ -2227,6 +2227,7 @@ const message = {
runtimePortHelper: '當前運行環境存在多個端口請選擇一個代理端口',
runtimePortWarn: '當前運行環境沒有端口無法代理',
cacheWarn: '請先關閉反代中的緩存開關',
loadBalanceHelper: '此處只是創建負載均衡規則使用規則請反向代理 http(s)://<負載均衡名稱>',
},
php: {
short_open_tag: '短標簽支持',
+1
View File
@@ -2217,6 +2217,7 @@ const message = {
runtimePortHelper: '当前运行环境存在多个端口请选择一个代理端口',
runtimePortWarn: '当前运行环境没有端口无法代理',
cacheWarn: '请先关闭反代中的缓存开关',
loadBalanceHelper: '此处只是创建负载均衡规则使用规则请反向代理 http://<负载均衡名称>',
},
php: {
short_open_tag: '短标签支持',
@@ -5,6 +5,7 @@
<el-button type="primary" plain @click="create()">
{{ $t('commons.button.create') }}
</el-button>
<el-text type="info" class="!ml-2" :closable="false">{{ $t('website.loadBalanceHelper') }}</el-text>
</template>
<el-table-column :label="$t('commons.table.name')" prop="name"></el-table-column>
<el-table-column :label="$t('website.algorithm')" prop="algorithm">
@@ -116,7 +116,7 @@ import { Algorithms, StatusStrategy } from '@/global/mimetype';
import { Website } from '@/api/interface/website';
const rules = ref<any>({
name: [Rules.linuxName],
name: [Rules.appName],
algorithm: [Rules.requiredSelect],
server: [Rules.requiredInput],
weight: [checkNumberRange(0, 100)],
@@ -178,6 +178,7 @@ const removeServer = (index: number) => {
const acceptParams = async (req: LoadBalanceOperate) => {
item.value.websiteID = req.websiteID;
item.value.operate = req.operate;
if (req.operate == 'edit') {
item.value.operate = 'edit';
item.value.name = req.upstream?.name || '';
@@ -85,8 +85,6 @@ const listDatabases = async () => {
break;
}
}
} else {
req.db = databases.value[0];
}
}
} catch (error) {}
-1
View File
@@ -32,7 +32,6 @@
//
"skipLibCheck": true,
"ignoreDeprecations": "5.0",
"suppressImplicitAnyIndexErrors": true
},
// "include": ["./src/views"],
"exclude": ["node_modules", "dist", "**/*.js", "*.json", "*.md"]