mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-10-12 08:00:34 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53756c382d | ||
|
|
8533a71670 | ||
|
|
6b3c06a057 | ||
|
|
4fd87568cd | ||
|
|
56f8caf561 | ||
|
|
7d2f7a8d3b | ||
|
|
01a9589be9 | ||
|
|
72eb02fd39 | ||
|
|
c1332235a0 | ||
|
|
212c8634ea | ||
|
|
b966ab3e11 | ||
|
|
25c2246782 | ||
|
|
2ae1db4730 | ||
|
|
43652b2a54 | ||
|
|
574a504ec3 | ||
|
|
52a8331c78 | ||
|
|
afa9eecf35 | ||
|
|
46e13d754f | ||
|
|
0157326d61 | ||
|
|
7d08875f95 | ||
|
|
bd2a49e299 | ||
|
|
06f1d03b93 | ||
|
|
4c39955f2f | ||
|
|
56f92310f8 | ||
|
|
cb47806fd6 | ||
|
|
16ae193e9f | ||
|
|
8770939328 |
@@ -6,6 +6,7 @@
|
|||||||
<a href="https://app.codacy.com/gh/1Panel-dev/1Panel?utm_source=github.com&utm_medium=referral&utm_content=1Panel-dev/1Panel&utm_campaign=Badge_Grade_Dashboard"><img src="https://app.codacy.com/project/badge/Grade/da67574fd82b473992781d1386b937ef" alt="Codacy"></a>
|
<a href="https://app.codacy.com/gh/1Panel-dev/1Panel?utm_source=github.com&utm_medium=referral&utm_content=1Panel-dev/1Panel&utm_campaign=Badge_Grade_Dashboard"><img src="https://app.codacy.com/project/badge/Grade/da67574fd82b473992781d1386b937ef" alt="Codacy"></a>
|
||||||
<a href="https://github.com/1Panel-dev/1Panel/releases"><img src="https://img.shields.io/github/v/release/1Panel-dev/1Panel" alt="GitHub release"></a>
|
<a href="https://github.com/1Panel-dev/1Panel/releases"><img src="https://img.shields.io/github/v/release/1Panel-dev/1Panel" alt="GitHub release"></a>
|
||||||
<a href="https://github.com/1Panel-dev/1Panel"><img src="https://img.shields.io/github/stars/1Panel-dev/1Panel?color=%231890FF&style=flat-square" alt="Stars"></a>
|
<a href="https://github.com/1Panel-dev/1Panel"><img src="https://img.shields.io/github/stars/1Panel-dev/1Panel?color=%231890FF&style=flat-square" alt="Stars"></a>
|
||||||
|
<a href="https://app.fossa.com/projects/git%2Bgithub.com%2F1Panel-dev%2F1Panel?ref=badge_shield"><img src="https://app.fossa.com/api/projects/git%2Bgithub.com%2F1Panel-dev%2F1Panel.svg?type=shield" alt="FOSSA Status"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
------------------------------
|
------------------------------
|
||||||
@@ -58,6 +59,10 @@ curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_
|
|||||||
|
|
||||||
[](https://star-history.com/#1Panel-dev/1Panel&Date)
|
[](https://star-history.com/#1Panel-dev/1Panel&Date)
|
||||||
|
|
||||||
|
## FOSSA Status
|
||||||
|
|
||||||
|
[](https://app.fossa.com/projects/git%2Bgithub.com%2F1Panel-dev%2F1Panel?ref=badge_large)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Copyright (c) 2014-2023 [FIT2CLOUD 飞致云](https://fit2cloud.com/), All rights reserved.
|
Copyright (c) 2014-2023 [FIT2CLOUD 飞致云](https://fit2cloud.com/), All rights reserved.
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package v1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
|
"path"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
@@ -356,6 +358,14 @@ func (b *BaseApi) Recover(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if req.Source != "LOCAL" {
|
||||||
|
downloadPath, err := backupService.DownloadRecord(dto.DownloadRecord{Source: req.Source, FileDir: path.Dir(req.File), FileName: path.Base(req.File)})
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, fmt.Errorf("download file failed, err: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.File = downloadPath
|
||||||
|
}
|
||||||
switch req.Type {
|
switch req.Type {
|
||||||
case "mysql":
|
case "mysql":
|
||||||
if err := backupService.MysqlRecover(req); err != nil {
|
if err := backupService.MysqlRecover(req); err != nil {
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ func (b *BaseApi) OperateIPRule(c *gin.Context) {
|
|||||||
// @Param request body dto.BatchRuleOperate true "request"
|
// @Param request body dto.BatchRuleOperate true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /hosts/firewall/ip [post]
|
// @Router /hosts/firewall/batch [post]
|
||||||
func (b *BaseApi) BatchOperateRule(c *gin.Context) {
|
func (b *BaseApi) BatchOperateRule(c *gin.Context) {
|
||||||
var req dto.BatchRuleOperate
|
var req dto.BatchRuleOperate
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
@@ -188,7 +188,7 @@ func (b *BaseApi) UpdatePortRule(c *gin.Context) {
|
|||||||
// @Param request body dto.AddrRuleUpdate true "request"
|
// @Param request body dto.AddrRuleUpdate true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /hosts/firewall/update/ip [post]
|
// @Router /hosts/firewall/update/addr [post]
|
||||||
func (b *BaseApi) UpdateAddrRule(c *gin.Context) {
|
func (b *BaseApi) UpdateAddrRule(c *gin.Context) {
|
||||||
var req dto.AddrRuleUpdate
|
var req dto.AddrRuleUpdate
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ type CommonBackup struct {
|
|||||||
DetailName string `json:"detailName"`
|
DetailName string `json:"detailName"`
|
||||||
}
|
}
|
||||||
type CommonRecover struct {
|
type CommonRecover struct {
|
||||||
|
Source string `json:"source" validate:"required,oneof=OSS S3 SFTP MINIO LOCAL COS KODO"`
|
||||||
Type string `json:"type" validate:"required,oneof=app mysql redis website"`
|
Type string `json:"type" validate:"required,oneof=app mysql redis website"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
DetailName string `json:"detailName"`
|
DetailName string `json:"detailName"`
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
@@ -109,15 +110,15 @@ func (u *BackupService) DownloadRecord(info dto.DownloadRecord) (string, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("new cloud storage client failed, err: %v", err)
|
return "", fmt.Errorf("new cloud storage client failed, err: %v", err)
|
||||||
}
|
}
|
||||||
tempPath := fmt.Sprintf("%sdownload%s", constant.DataDir, info.FileDir)
|
targetPath := fmt.Sprintf("%s/download/%s/%s", constant.DataDir, info.FileDir, info.FileName)
|
||||||
if _, err := os.Stat(tempPath); err != nil && os.IsNotExist(err) {
|
if _, err := os.Stat(path.Dir(targetPath)); err != nil && os.IsNotExist(err) {
|
||||||
if err = os.MkdirAll(tempPath, os.ModePerm); err != nil {
|
if err = os.MkdirAll(path.Dir(targetPath), os.ModePerm); err != nil {
|
||||||
global.LOG.Errorf("mkdir %s failed, err: %v", tempPath, err)
|
global.LOG.Errorf("mkdir %s failed, err: %v", path.Dir(targetPath), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
targetPath := tempPath + info.FileName
|
srcPath := fmt.Sprintf("%s/%s", info.FileDir, info.FileName)
|
||||||
if _, err = os.Stat(targetPath); err != nil && os.IsNotExist(err) {
|
if exist, _ := backClient.Exist(srcPath); exist {
|
||||||
isOK, err := backClient.Download(info.FileName, targetPath)
|
isOK, err := backClient.Download(srcPath, targetPath)
|
||||||
if !isOK {
|
if !isOK {
|
||||||
return "", fmt.Errorf("cloud storage download failed, err: %v", err)
|
return "", fmt.Errorf("cloud storage download failed, err: %v", err)
|
||||||
}
|
}
|
||||||
@@ -179,7 +180,7 @@ func (u *BackupService) BatchDeleteRecord(ids []uint) error {
|
|||||||
global.LOG.Errorf("remove file %s failed, err: %v", record.FileDir+record.FileName, err)
|
global.LOG.Errorf("remove file %s failed, err: %v", record.FileDir+record.FileName, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
backupAccount, err := backupRepo.Get(commonRepo.WithByName(record.Source))
|
backupAccount, err := backupRepo.Get(commonRepo.WithByType(record.Source))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
||||||
"github.com/1Panel-dev/1Panel/backend/buserr"
|
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
@@ -99,22 +100,7 @@ func (u *MysqlService) Create(ctx context.Context, req dto.MysqlDBCreate) (*mode
|
|||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tmpPermission := req.Permission
|
if err := u.createUser(app, req); err != nil {
|
||||||
if err := excSQL(app.ContainerName, app.Password, fmt.Sprintf("create user '%s'@'%s' identified by '%s';", req.Username, tmpPermission, req.Password)); err != nil {
|
|
||||||
_ = excSQL(app.ContainerName, app.Password, fmt.Sprintf("drop database `%s`", req.Name))
|
|
||||||
if strings.Contains(err.Error(), "ERROR 1396") {
|
|
||||||
return nil, buserr.New(constant.ErrUserIsExist)
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
grantStr := fmt.Sprintf("grant all privileges on `%s`.* to '%s'@'%s'", req.Name, req.Username, tmpPermission)
|
|
||||||
if req.Name == "*" {
|
|
||||||
grantStr = fmt.Sprintf("grant all privileges on *.* to '%s'@'%s'", mysql.Username, tmpPermission)
|
|
||||||
}
|
|
||||||
if app.Version == "5.7.39" {
|
|
||||||
grantStr = fmt.Sprintf("%s identified by '%s' with grant option;", grantStr, req.Password)
|
|
||||||
}
|
|
||||||
if err := excSQL(app.ContainerName, app.Password, grantStr); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,6 +257,9 @@ func (u *MysqlService) ChangeAccess(info dto.ChangeDBInfo) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if info.Value == mysql.Permission {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
|
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -284,24 +273,30 @@ func (u *MysqlService) ChangeAccess(info dto.ChangeDBInfo) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if info.Value != mysql.Permission {
|
if info.Value != mysql.Permission {
|
||||||
if err := excuteSql(app.ContainerName, app.Password, fmt.Sprintf("drop user if exists '%s'@'%s'", mysql.Username, mysql.Permission)); err != nil {
|
var userlist []string
|
||||||
return err
|
if strings.Contains(mysql.Permission, ",") {
|
||||||
|
userlist = strings.Split(mysql.Permission, ",")
|
||||||
|
} else {
|
||||||
|
userlist = append(userlist, mysql.Permission)
|
||||||
|
}
|
||||||
|
for _, user := range userlist {
|
||||||
|
if len(user) != 0 {
|
||||||
|
if err := excuteSql(app.ContainerName, app.Password, fmt.Sprintf("drop user if exists '%s'@'%s'", mysql.Username, user)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if info.ID == 0 {
|
if info.ID == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := excuteSql(app.ContainerName, app.Password, fmt.Sprintf("create user if not exists '%s'@'%s' identified by '%s';", mysql.Username, info.Value, mysql.Password)); err != nil {
|
|
||||||
return err
|
if err := u.createUser(app, dto.MysqlDBCreate{
|
||||||
}
|
Username: mysql.Username,
|
||||||
grantStr := fmt.Sprintf("grant all privileges on `%s`.* to '%s'@'%s'", mysql.Name, mysql.Username, info.Value)
|
Name: mysql.Name,
|
||||||
if mysql.Name == "*" {
|
Permission: info.Value,
|
||||||
grantStr = fmt.Sprintf("grant all privileges on *.* to '%s'@'%s'", mysql.Username, info.Value)
|
Password: mysql.Password,
|
||||||
}
|
}); err != nil {
|
||||||
if app.Version == "5.7.39" {
|
|
||||||
grantStr = fmt.Sprintf("%s identified by '%s' with grant option;", grantStr, mysql.Password)
|
|
||||||
}
|
|
||||||
if err := excuteSql(app.ContainerName, app.Password, grantStr); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := excuteSql(app.ContainerName, app.Password, "flush privileges"); err != nil {
|
if err := excuteSql(app.ContainerName, app.Password, "flush privileges"); err != nil {
|
||||||
@@ -475,6 +470,50 @@ func (u *MysqlService) LoadStatus() (*dto.MysqlStatus, error) {
|
|||||||
return &info, nil
|
return &info, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *MysqlService) createUser(app *repo.RootInfo, req dto.MysqlDBCreate) error {
|
||||||
|
var userlist []string
|
||||||
|
if strings.Contains(req.Permission, ",") {
|
||||||
|
ips := strings.Split(req.Permission, ",")
|
||||||
|
for _, ip := range ips {
|
||||||
|
if len(ip) != 0 {
|
||||||
|
userlist = append(userlist, fmt.Sprintf("'%s'@'%s'", req.Username, ip))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
userlist = append(userlist, fmt.Sprintf("'%s'@'%s'", req.Username, req.Permission))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, user := range userlist {
|
||||||
|
if err := excSQL(app.ContainerName, app.Password, fmt.Sprintf("create user %s identified by '%s';", user, req.Password)); err != nil {
|
||||||
|
handleCreateError(req.Name, userlist, app)
|
||||||
|
if strings.Contains(err.Error(), "ERROR 1396") {
|
||||||
|
return buserr.New(constant.ErrUserIsExist)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
grantStr := fmt.Sprintf("grant all privileges on `%s`.* to %s", req.Name, user)
|
||||||
|
if req.Name == "*" {
|
||||||
|
grantStr = fmt.Sprintf("grant all privileges on *.* to %s", user)
|
||||||
|
}
|
||||||
|
if app.Version == "5.7.39" {
|
||||||
|
grantStr = fmt.Sprintf("%s identified by '%s' with grant option;", grantStr, req.Password)
|
||||||
|
}
|
||||||
|
if err := excSQL(app.ContainerName, app.Password, grantStr); err != nil {
|
||||||
|
handleCreateError(req.Name, userlist, app)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func handleCreateError(dbName string, userlist []string, app *repo.RootInfo) {
|
||||||
|
_ = excSQL(app.ContainerName, app.Password, fmt.Sprintf("drop database `%s`", dbName))
|
||||||
|
for _, user := range userlist {
|
||||||
|
if err := excSQL(app.ContainerName, app.Password, fmt.Sprintf("drop user if exists %s", user)); err != nil {
|
||||||
|
global.LOG.Errorf("drop user failed, err: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func excuteSqlForMaps(containerName, password, command string) (map[string]string, error) {
|
func excuteSqlForMaps(containerName, password, command string) (map[string]string, error) {
|
||||||
cmd := exec.Command("docker", "exec", containerName, "mysql", "-uroot", "-p"+password, "-e", command)
|
cmd := exec.Command("docker", "exec", containerName, "mysql", "-uroot", "-p"+password, "-e", command)
|
||||||
stdout, err := cmd.CombinedOutput()
|
stdout, err := cmd.CombinedOutput()
|
||||||
@@ -515,7 +554,7 @@ func excuteSql(containerName, password, command string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func excSQL(containerName, password, command string) error {
|
func excSQL(containerName, password, command string) error {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
cmd := exec.CommandContext(ctx, "docker", "exec", containerName, "mysql", "-uroot", "-p"+password, "-e", command)
|
cmd := exec.CommandContext(ctx, "docker", "exec", containerName, "mysql", "-uroot", "-p"+password, "-e", command)
|
||||||
stdout, err := cmd.CombinedOutput()
|
stdout, err := cmd.CombinedOutput()
|
||||||
|
|||||||
@@ -854,7 +854,16 @@ func (w WebsiteService) OpWebsiteLog(req request.WebsiteLogReq) (*response.Websi
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
content, err := os.ReadFile(path.Join(sitePath, "log", req.LogType))
|
filePath := path.Join(sitePath, "log", req.LogType)
|
||||||
|
fileInfo, err := os.Stat(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if fileInfo.Size() > 10<<20 {
|
||||||
|
return nil, buserr.New(constant.ErrFileToLarge)
|
||||||
|
}
|
||||||
|
fileInfo.Size()
|
||||||
|
content, err := os.ReadFile(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -903,7 +912,23 @@ func (w WebsiteService) OpWebsiteLog(req request.WebsiteLogReq) (*response.Websi
|
|||||||
func (w WebsiteService) ChangeDefaultServer(id uint) error {
|
func (w WebsiteService) ChangeDefaultServer(id uint) error {
|
||||||
defaultWebsite, _ := websiteRepo.GetFirst(websiteRepo.WithDefaultServer())
|
defaultWebsite, _ := websiteRepo.GetFirst(websiteRepo.WithDefaultServer())
|
||||||
if defaultWebsite.ID > 0 {
|
if defaultWebsite.ID > 0 {
|
||||||
if err := updateNginxConfig(constant.NginxScopeServer, []dto.NginxParam{{Name: "listen", Params: []string{"80"}}}, &defaultWebsite); err != nil {
|
params, err := getNginxParamsByKeys(constant.NginxScopeServer, []string{"listen"}, &defaultWebsite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var changeParams []dto.NginxParam
|
||||||
|
for _, param := range params {
|
||||||
|
paramLen := len(param.Params)
|
||||||
|
var newParam []string
|
||||||
|
if paramLen > 1 && param.Params[paramLen-1] == components.DefaultServer {
|
||||||
|
newParam = param.Params[:paramLen-1]
|
||||||
|
}
|
||||||
|
changeParams = append(changeParams, dto.NginxParam{
|
||||||
|
Name: param.Name,
|
||||||
|
Params: newParam,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if err := updateNginxConfig(constant.NginxScopeServer, changeParams, &defaultWebsite); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defaultWebsite.DefaultServer = false
|
defaultWebsite.DefaultServer = false
|
||||||
@@ -916,7 +941,28 @@ func (w WebsiteService) ChangeDefaultServer(id uint) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := updateNginxConfig(constant.NginxScopeServer, []dto.NginxParam{{Name: "listen", Params: []string{"80", "default_server"}}}, &website); err != nil {
|
params, err := getNginxParamsByKeys(constant.NginxScopeServer, []string{"listen"}, &website)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var changeParams []dto.NginxParam
|
||||||
|
for _, param := range params {
|
||||||
|
paramLen := len(param.Params)
|
||||||
|
bind := param.Params[0]
|
||||||
|
var newParam []string
|
||||||
|
if bind == "80" || bind == "443" || bind == "[::]:80" || bind == "[::]:443" {
|
||||||
|
if param.Params[paramLen-1] == components.DefaultServer {
|
||||||
|
newParam = param.Params
|
||||||
|
} else {
|
||||||
|
newParam = append(param.Params, components.DefaultServer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
changeParams = append(changeParams, dto.NginxParam{
|
||||||
|
Name: param.Name,
|
||||||
|
Params: newParam,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if err := updateNginxConfig(constant.NginxScopeServer, changeParams, &website); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
website.DefaultServer = true
|
website.DefaultServer = true
|
||||||
|
|||||||
@@ -371,8 +371,7 @@ func applySSL(website model.Website, websiteSSL model.WebsiteSSL, req request.We
|
|||||||
}
|
}
|
||||||
config := nginxFull.SiteConfig.Config
|
config := nginxFull.SiteConfig.Config
|
||||||
server := config.FindServers()[0]
|
server := config.FindServers()[0]
|
||||||
server.UpdateListen("443", false, "ssl")
|
server.UpdateListen("443", website.DefaultServer, "ssl")
|
||||||
server.UpdateListen("[::]:443", false, "ssl")
|
|
||||||
|
|
||||||
switch req.HttpConfig {
|
switch req.HttpConfig {
|
||||||
case constant.HTTPSOnly:
|
case constant.HTTPSOnly:
|
||||||
@@ -381,11 +380,9 @@ func applySSL(website model.Website, websiteSSL model.WebsiteSSL, req request.We
|
|||||||
server.RemoveDirective("if", []string{"($scheme"})
|
server.RemoveDirective("if", []string{"($scheme"})
|
||||||
case constant.HTTPToHTTPS:
|
case constant.HTTPToHTTPS:
|
||||||
server.UpdateListen("80", website.DefaultServer)
|
server.UpdateListen("80", website.DefaultServer)
|
||||||
server.UpdateListen("[::]:80", false)
|
|
||||||
server.AddHTTP2HTTPS()
|
server.AddHTTP2HTTPS()
|
||||||
case constant.HTTPAlso:
|
case constant.HTTPAlso:
|
||||||
server.UpdateListen("80", website.DefaultServer)
|
server.UpdateListen("80", website.DefaultServer)
|
||||||
server.UpdateListen("[::]:80", false)
|
|
||||||
server.RemoveDirective("if", []string{"($scheme"})
|
server.RemoveDirective("if", []string{"($scheme"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-18
@@ -1,22 +1,23 @@
|
|||||||
package configs
|
package configs
|
||||||
|
|
||||||
type System struct {
|
type System struct {
|
||||||
Port string `mapstructure:"port"`
|
Port string `mapstructure:"port"`
|
||||||
SSL string `mapstructure:"ssl"`
|
SSL string `mapstructure:"ssl"`
|
||||||
DbFile string `mapstructure:"db_file"`
|
DbFile string `mapstructure:"db_file"`
|
||||||
DbPath string `mapstructure:"db_path"`
|
DbPath string `mapstructure:"db_path"`
|
||||||
LogPath string `mapstructure:"log_path"`
|
LogPath string `mapstructure:"log_path"`
|
||||||
DataDir string `mapstructure:"data_dir"`
|
DataDir string `mapstructure:"data_dir"`
|
||||||
TmpDir string `mapstructure:"tmp_dir"`
|
TmpDir string `mapstructure:"tmp_dir"`
|
||||||
Cache string `mapstructure:"cache"`
|
Cache string `mapstructure:"cache"`
|
||||||
Backup string `mapstructure:"backup"`
|
Backup string `mapstructure:"backup"`
|
||||||
EncryptKey string `mapstructure:"encrypt_key"`
|
EncryptKey string `mapstructure:"encrypt_key"`
|
||||||
BaseDir string `mapstructure:"base_dir"`
|
BaseDir string `mapstructure:"base_dir"`
|
||||||
Mode string `mapstructure:"mode"`
|
Mode string `mapstructure:"mode"`
|
||||||
RepoUrl string `mapstructure:"repo_url"`
|
RepoUrl string `mapstructure:"repo_url"`
|
||||||
Version string `mapstructure:"version"`
|
Version string `mapstructure:"version"`
|
||||||
Username string `mapstructure:"username"`
|
Username string `mapstructure:"username"`
|
||||||
Password string `mapstructure:"password"`
|
Password string `mapstructure:"password"`
|
||||||
Entrance string `mapstructure:"entrance"`
|
Entrance string `mapstructure:"entrance"`
|
||||||
IsDemo bool `mapstructure:"is_demo"`
|
IsDemo bool `mapstructure:"is_demo"`
|
||||||
|
ChangeUserInfo bool `mapstructure:"change_user_info"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const (
|
|||||||
SessionName = "psession"
|
SessionName = "psession"
|
||||||
|
|
||||||
AuthMethodJWT = "jwt"
|
AuthMethodJWT = "jwt"
|
||||||
JWTHeaderName = "Authorization"
|
JWTHeaderName = "PanelAuthorization"
|
||||||
JWTBufferTime = 3600
|
JWTBufferTime = 3600
|
||||||
JWTIssuer = "1Panel"
|
JWTIssuer = "1Panel"
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ package hook
|
|||||||
import (
|
import (
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
@@ -27,6 +30,25 @@ func Init() {
|
|||||||
_ = settingRepo.Create("SystemStatus", "Free")
|
_ = settingRepo.Create("SystemStatus", "Free")
|
||||||
}
|
}
|
||||||
if err := settingRepo.Update("SystemStatus", "Free"); err != nil {
|
if err := settingRepo.Update("SystemStatus", "Free"); err != nil {
|
||||||
global.LOG.Fatalf("init service before start failed, err: %v", "Free")
|
global.LOG.Fatalf("init service before start failed, err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if global.CONF.System.ChangeUserInfo {
|
||||||
|
if err := settingRepo.Update("UserName", common.RandStrAndNum(10)); err != nil {
|
||||||
|
global.LOG.Fatalf("init username before start failed, err: %v", err)
|
||||||
|
}
|
||||||
|
pass, _ := encrypt.StringEncrypt(common.RandStrAndNum(10))
|
||||||
|
if err := settingRepo.Update("Password", pass); err != nil {
|
||||||
|
global.LOG.Fatalf("init password before start failed, err: %v", err)
|
||||||
|
}
|
||||||
|
if err := settingRepo.Update("SecurityEntrance", common.RandStrAndNum(10)); err != nil {
|
||||||
|
global.LOG.Fatalf("init entrance before start failed, err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.HasNoPasswordSudo() {
|
||||||
|
_, _ = cmd.Exec("sudo sed -i '/CHANGE_USER_INFO=true/d' /usr/local/bin/1pctl")
|
||||||
|
} else {
|
||||||
|
_, _ = cmd.Exec("sed -i '/CHANGE_USER_INFO=true/d' /usr/local/bin/1pctl")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ func Init() {
|
|||||||
global.CONF.System.Username = username
|
global.CONF.System.Username = username
|
||||||
global.CONF.System.Password = password
|
global.CONF.System.Password = password
|
||||||
global.CONF.System.Entrance = entrance
|
global.CONF.System.Entrance = entrance
|
||||||
|
global.CONF.System.ChangeUserInfo = loadChange()
|
||||||
global.Viper = v
|
global.Viper = v
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,3 +114,11 @@ func loadParams(param string) string {
|
|||||||
}
|
}
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadChange() bool {
|
||||||
|
stdout, err := cmd.Exec("grep '^CHANGE_USER_INFO=' /usr/bin/1pctl | cut -d'=' -f2")
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return stdout == "true\n"
|
||||||
|
}
|
||||||
|
|||||||
@@ -67,10 +67,11 @@ func (cos cosClient) Exist(path string) (bool, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if _, err := client.Object.IsExist(context.Background(), path); err != nil {
|
exist, err := client.Object.IsExist(context.Background(), path)
|
||||||
return true, err
|
if err != nil {
|
||||||
|
return false, err
|
||||||
}
|
}
|
||||||
return false, nil
|
return exist, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cos cosClient) Delete(path string) (bool, error) {
|
func (cos cosClient) Delete(path string) (bool, error) {
|
||||||
|
|||||||
@@ -59,9 +59,9 @@ func (kodo kodoClient) Exist(path string) (bool, error) {
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if _, err := kodo.client.Stat(bucket, path); err != nil {
|
if _, err := kodo.client.Stat(bucket, path); err != nil {
|
||||||
return true, err
|
return false, err
|
||||||
}
|
}
|
||||||
return false, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kodo kodoClient) Delete(path string) (bool, error) {
|
func (kodo kodoClient) Delete(path string) (bool, error) {
|
||||||
|
|||||||
@@ -81,9 +81,9 @@ func (minIo minIoClient) Exist(path string) (bool, error) {
|
|||||||
if _, ok := minIo.Vars["bucket"]; ok {
|
if _, ok := minIo.Vars["bucket"]; ok {
|
||||||
_, err := minIo.client.GetObject(context.Background(), minIo.Vars["bucket"].(string), path, minio.GetObjectOptions{})
|
_, err := minIo.client.GetObject(context.Background(), minIo.Vars["bucket"].(string), path, minio.GetObjectOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, err
|
return false, err
|
||||||
}
|
}
|
||||||
return false, nil
|
return true, nil
|
||||||
} else {
|
} else {
|
||||||
return false, constant.ErrInvalidParams
|
return false, constant.ErrInvalidParams
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/init/db"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/init/log"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/init/viper"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMinio(t *testing.T) {
|
|
||||||
viper.Init()
|
|
||||||
log.Init()
|
|
||||||
db.Init()
|
|
||||||
|
|
||||||
var backup model.BackupAccount
|
|
||||||
if err := global.DB.Where("id = ?", 3).First(&backup).Error; err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
varMap := make(map[string]interface{})
|
|
||||||
if err := json.Unmarshal([]byte(backup.Vars), &varMap); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
varMap["type"] = backup.Type
|
|
||||||
varMap["bucket"] = backup.Bucket
|
|
||||||
switch backup.Type {
|
|
||||||
case constant.Sftp:
|
|
||||||
varMap["password"] = backup.Credential
|
|
||||||
case constant.OSS, constant.S3, constant.MinIo:
|
|
||||||
varMap["secretKey"] = backup.Credential
|
|
||||||
}
|
|
||||||
client, _ := NewMinIoClient(varMap)
|
|
||||||
_, _ = client.ListObjects("directory/directory-test-minio/")
|
|
||||||
}
|
|
||||||
@@ -83,6 +83,16 @@ func RandStr(n int) string {
|
|||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RandStrAndNum(n int) string {
|
||||||
|
mathRand.Seed(time.Now().UnixNano())
|
||||||
|
const charset = "abcdefghijklmnopqrstuvwxyz0123456789"
|
||||||
|
b := make([]byte, 10)
|
||||||
|
for i := range b {
|
||||||
|
b[i] = charset[mathRand.Int63()%int64(len(charset))]
|
||||||
|
}
|
||||||
|
return (string(b))
|
||||||
|
}
|
||||||
|
|
||||||
func ScanPort(port int) bool {
|
func ScanPort(port int) bool {
|
||||||
ln, err := net.Listen("tcp", ":"+strconv.Itoa(port))
|
ln, err := net.Listen("tcp", ":"+strconv.Itoa(port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ func NewFileInfo(op FileOption) (*FileInfo, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileInfo) search(search string, count int) (files []FileSearchInfo, total int, err error) {
|
func (f *FileInfo) search(search string, count int) (files []FileSearchInfo, total int, err error) {
|
||||||
cmd := exec.Command("find", f.Path, "-name", search)
|
cmd := exec.Command("find", f.Path, "-name", fmt.Sprintf("*%s*", search))
|
||||||
output, err := cmd.StdoutPipe()
|
output, err := cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -65,7 +65,19 @@ func (s *Server) FindDirectives(directiveName string) []IDirective {
|
|||||||
directives = append(directives, directive.GetBlock().FindDirectives(directiveName)...)
|
directives = append(directives, directive.GetBlock().FindDirectives(directiveName)...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if directiveName == "listen" {
|
||||||
|
for _, listen := range s.Listens {
|
||||||
|
params := []string{listen.Bind}
|
||||||
|
params = append(params, listen.Parameters...)
|
||||||
|
if listen.DefaultServer != "" {
|
||||||
|
params = append(params, DefaultServer)
|
||||||
|
}
|
||||||
|
directives = append(directives, &Directive{
|
||||||
|
Name: "listen",
|
||||||
|
Parameters: params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
return directives
|
return directives
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,14 +87,12 @@ func (s *Server) UpdateDirective(key string, params []string) {
|
|||||||
}
|
}
|
||||||
if key == "listen" {
|
if key == "listen" {
|
||||||
defaultServer := false
|
defaultServer := false
|
||||||
if len(params) > 1 && params[1] == "default_server" {
|
paramLen := len(params)
|
||||||
|
if paramLen > 0 && params[paramLen-1] == "default_server" {
|
||||||
|
params = params[:paramLen-1]
|
||||||
defaultServer = true
|
defaultServer = true
|
||||||
}
|
}
|
||||||
if len(params) > 2 {
|
s.UpdateListen(params[0], defaultServer, params[1:]...)
|
||||||
s.UpdateListen(params[0], defaultServer, params[2:]...)
|
|
||||||
} else {
|
|
||||||
s.UpdateListen(params[0], defaultServer)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ func (sl *ServerListen) GetBlock() IBlock {
|
|||||||
|
|
||||||
func (sl *ServerListen) GetParameters() []string {
|
func (sl *ServerListen) GetParameters() []string {
|
||||||
params := []string{sl.Bind}
|
params := []string{sl.Bind}
|
||||||
params = append(params, sl.DefaultServer)
|
|
||||||
params = append(params, sl.Parameters...)
|
params = append(params, sl.Parameters...)
|
||||||
|
params = append(params, sl.DefaultServer)
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+45
-2
@@ -5377,7 +5377,7 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/hosts/firewall/ip": {
|
"/hosts/firewall/batch": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
@@ -5410,6 +5410,49 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/hosts/firewall/ip": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "创建防火墙 IP 规则",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Firewall"
|
||||||
|
],
|
||||||
|
"summary": "Create group",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.AddrRuleOperate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"strategy",
|
||||||
|
"address"
|
||||||
|
],
|
||||||
|
"formatEN": "create address rules [strategy][address]",
|
||||||
|
"formatZH": "添加 ip 规则 [strategy] [address]",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/hosts/firewall/operate": {
|
"/hosts/firewall/operate": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -5534,7 +5577,7 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/hosts/firewall/update/ip": {
|
"/hosts/firewall/update/addr": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5363,7 +5363,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/hosts/firewall/ip": {
|
"/hosts/firewall/batch": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
@@ -5396,6 +5396,49 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/hosts/firewall/ip": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "创建防火墙 IP 规则",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Firewall"
|
||||||
|
],
|
||||||
|
"summary": "Create group",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.AddrRuleOperate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"strategy",
|
||||||
|
"address"
|
||||||
|
],
|
||||||
|
"formatEN": "create address rules [strategy][address]",
|
||||||
|
"formatZH": "添加 ip 规则 [strategy] [address]",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/hosts/firewall/operate": {
|
"/hosts/firewall/operate": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -5520,7 +5563,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/hosts/firewall/update/ip": {
|
"/hosts/firewall/update/addr": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6461,7 +6461,7 @@ paths:
|
|||||||
summary: Load firewall base info
|
summary: Load firewall base info
|
||||||
tags:
|
tags:
|
||||||
- Firewall
|
- Firewall
|
||||||
/hosts/firewall/ip:
|
/hosts/firewall/batch:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
@@ -6481,6 +6481,34 @@ paths:
|
|||||||
summary: Create group
|
summary: Create group
|
||||||
tags:
|
tags:
|
||||||
- Firewall
|
- Firewall
|
||||||
|
/hosts/firewall/ip:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 创建防火墙 IP 规则
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/dto.AddrRuleOperate'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Create group
|
||||||
|
tags:
|
||||||
|
- Firewall
|
||||||
|
x-panel-log:
|
||||||
|
BeforeFuntions: []
|
||||||
|
bodyKeys:
|
||||||
|
- strategy
|
||||||
|
- address
|
||||||
|
formatEN: create address rules [strategy][address]
|
||||||
|
formatZH: 添加 ip 规则 [strategy] [address]
|
||||||
|
paramKeys: []
|
||||||
/hosts/firewall/operate:
|
/hosts/firewall/operate:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -6560,7 +6588,7 @@ paths:
|
|||||||
summary: Page firewall rules
|
summary: Page firewall rules
|
||||||
tags:
|
tags:
|
||||||
- Firewall
|
- Firewall
|
||||||
/hosts/firewall/update/ip:
|
/hosts/firewall/update/addr:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
listen [::]:80;
|
|
||||||
|
|
||||||
server_name ko.wp-1.com;
|
server_name ko.wp-1.com;
|
||||||
|
|
||||||
index index.php index.html index.htm default.php default.htm default.html;
|
index index.php index.html index.htm default.php default.htm default.html;
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ export namespace Backup {
|
|||||||
detailName: string;
|
detailName: string;
|
||||||
}
|
}
|
||||||
export interface Recover {
|
export interface Recover {
|
||||||
|
source: string;
|
||||||
type: string;
|
type: string;
|
||||||
name: string;
|
name: string;
|
||||||
detailName: string;
|
detailName: string;
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ const onBackup = async () => {
|
|||||||
|
|
||||||
const onRecover = async (row: Backup.RecordInfo) => {
|
const onRecover = async (row: Backup.RecordInfo) => {
|
||||||
let params = {
|
let params = {
|
||||||
|
source: row.source,
|
||||||
type: type.value,
|
type: type.value,
|
||||||
name: name.value,
|
name: name.value,
|
||||||
detailName: detailName.value,
|
detailName: detailName.value,
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ const search = async () => {
|
|||||||
|
|
||||||
const onRecover = async (row: File.File) => {
|
const onRecover = async (row: File.File) => {
|
||||||
let params = {
|
let params = {
|
||||||
|
source: 'LOCAL',
|
||||||
type: type.value,
|
type: type.value,
|
||||||
name: name.value,
|
name: name.value,
|
||||||
detailName: detailName.value,
|
detailName: detailName.value,
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ const message = {
|
|||||||
loadBackup: 'Import',
|
loadBackup: 'Import',
|
||||||
setting: 'Settings',
|
setting: 'Settings',
|
||||||
remoteAccess: 'Remote access',
|
remoteAccess: 'Remote access',
|
||||||
remoteHelper: 'One in a row, for example:\n172.16.10.111\n172.16.10.112',
|
remoteHelper: 'Multiple IP comma-delimited, example: 172.16.10.111, 172.16.10.112',
|
||||||
remoteConnHelper:
|
remoteConnHelper:
|
||||||
'Remote connection to mysql as user root may have security risks. Therefore, perform this operation with caution.',
|
'Remote connection to mysql as user root may have security risks. Therefore, perform this operation with caution.',
|
||||||
changePassword: 'Password',
|
changePassword: 'Password',
|
||||||
@@ -540,8 +540,10 @@ const message = {
|
|||||||
imageRepo: 'Image repo',
|
imageRepo: 'Image repo',
|
||||||
repoHelper: 'Does it include a mirror repository/organization/project?',
|
repoHelper: 'Does it include a mirror repository/organization/project?',
|
||||||
auth: 'Auth',
|
auth: 'Auth',
|
||||||
mirrorHelper: 'One in a row, for example:\nhttps://hub-mirror.c.163.com \nhttps://reg-mirror.qiniu.com',
|
mirrorHelper:
|
||||||
registrieHelper: 'One in a row, for example:\n172.16.10.111:8081 \n172.16.10.112:8081',
|
'If there are multiple mirrors, newlines must be displayed, for example:\nhttps://hub-mirror.c.163.com \nhttps://reg-mirror.qiniu.com',
|
||||||
|
registrieHelper:
|
||||||
|
'If multiple private repositories exist, newlines must be displayed, for example:\n172.16.10.111:8081 \n172.16.10.112:8081',
|
||||||
|
|
||||||
compose: 'Compose',
|
compose: 'Compose',
|
||||||
fromChangeHelper: 'Switching the source will clear the current edited content. Do you want to continue?',
|
fromChangeHelper: 'Switching the source will clear the current edited content. Do you want to continue?',
|
||||||
@@ -576,7 +578,8 @@ const message = {
|
|||||||
daemonJsonPathHelper: 'Ensure that the configuration path is the same as that specified in docker.service.',
|
daemonJsonPathHelper: 'Ensure that the configuration path is the same as that specified in docker.service.',
|
||||||
mirrors: 'Registry mirrors',
|
mirrors: 'Registry mirrors',
|
||||||
mirrorsHelper:
|
mirrorsHelper:
|
||||||
'Redirecting requests for a Docker image repository to a specified image accelerator can improve the download speed of the image',
|
'The acceleration URL is preferred to perform operations. If this parameter is set to empty, mirror acceleration is disabled.',
|
||||||
|
mirrorsHelper2: 'For details, see the official documents, ',
|
||||||
registries: 'Insecure registries',
|
registries: 'Insecure registries',
|
||||||
liveHelper:
|
liveHelper:
|
||||||
'Allows the running container state to be preserved in case of unexpected shutdown or crash of the Docker daemon',
|
'Allows the running container state to be preserved in case of unexpected shutdown or crash of the Docker daemon',
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ const message = {
|
|||||||
loadBackup: '导入备份',
|
loadBackup: '导入备份',
|
||||||
setting: '设置',
|
setting: '设置',
|
||||||
remoteAccess: '远程访问',
|
remoteAccess: '远程访问',
|
||||||
remoteHelper: '一行一个,例:\n172.16.10.111\n172.16.10.112',
|
remoteHelper: '多个 ip 以逗号分隔,例:172.16.10.111,172.16.10.112',
|
||||||
remoteConnHelper: 'root 帐号远程连接 mysql 有安全风险,开启需谨慎!',
|
remoteConnHelper: 'root 帐号远程连接 mysql 有安全风险,开启需谨慎!',
|
||||||
changePassword: '改密',
|
changePassword: '改密',
|
||||||
changePasswordHelper: '当前数据库已经关联应用,修改密码将同步修改应用中数据库密码,修改后重启生效。',
|
changePasswordHelper: '当前数据库已经关联应用,修改密码将同步修改应用中数据库密码,修改后重启生效。',
|
||||||
@@ -558,8 +558,9 @@ const message = {
|
|||||||
imageRepo: '镜像仓库',
|
imageRepo: '镜像仓库',
|
||||||
repoHelper: '是否包含镜像仓库/组织/项目?',
|
repoHelper: '是否包含镜像仓库/组织/项目?',
|
||||||
auth: '认证',
|
auth: '认证',
|
||||||
mirrorHelper: '一行一个,例:\nhttps://hub-mirror.c.163.com \nhttps://reg-mirror.qiniu.com',
|
mirrorHelper:
|
||||||
registrieHelper: '一行一个,例:\n172.16.10.111:8081 \n172.16.10.112:8081',
|
'当存在多个加速器时,需要换行显示,例: \nhttp://xxxxxx.m.daocloud.io \nhttps://xxxxxx.mirror.aliyuncs.com',
|
||||||
|
registrieHelper: '当存在多个私有仓库时,需要换行显示,例:\n172.16.10.111:8081 \n172.16.10.112:8081',
|
||||||
|
|
||||||
compose: '编排',
|
compose: '编排',
|
||||||
fromChangeHelper: '切换来源将清空当前已编辑内容,是否继续?',
|
fromChangeHelper: '切换来源将清空当前已编辑内容,是否继续?',
|
||||||
@@ -590,7 +591,8 @@ const message = {
|
|||||||
dockerStatus: 'Docker 服务',
|
dockerStatus: 'Docker 服务',
|
||||||
daemonJsonPathHelper: '请保证配置路径与 docker.service 中指定的配置路径保持一致。',
|
daemonJsonPathHelper: '请保证配置路径与 docker.service 中指定的配置路径保持一致。',
|
||||||
mirrors: '镜像加速',
|
mirrors: '镜像加速',
|
||||||
mirrorsHelper: '将 Docker 镜像库的请求重定向到指定的镜像加速器,从而提高镜像的下载速度',
|
mirrorsHelper: '优先使用加速 URL 执行操作,设置为空则取消镜像加速。',
|
||||||
|
mirrorsHelper2: '具体操作配置请参照官方文档,',
|
||||||
registries: '私有仓库',
|
registries: '私有仓库',
|
||||||
liveHelper: '允许在 Docker 守护进程发生意外停机或崩溃时保留正在运行的容器状态',
|
liveHelper: '允许在 Docker 守护进程发生意外停机或崩溃时保留正在运行的容器状态',
|
||||||
liveWithSwarmHelper: 'live-restore 守护进程配置与 Swarm 模式不兼容',
|
liveWithSwarmHelper: 'live-restore 守护进程配置与 Swarm 模式不兼容',
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ export function checkPort(value: string): boolean {
|
|||||||
if (Number(value) <= 0) {
|
if (Number(value) <= 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const reg = /^([0-9]|[1-9]\d{1,3}|[1-5]\d{4}|6[0-5]{2}[0-3][0-5])$/;
|
const reg = /^([1-9](\d{0,3}))$|^([1-5]\d{4})$|^(6[0-4]\d{3})$|^(65[0-4]\d{2})$|^(655[0-2]\d)$|^(6553[0-5])$/;
|
||||||
if (!reg.test(value) && value !== '') {
|
if (!reg.test(value) && value !== '') {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -9,11 +9,15 @@
|
|||||||
</template>
|
</template>
|
||||||
</Header>
|
</Header>
|
||||||
</template>
|
</template>
|
||||||
<el-descriptions border :column="1" v-if="!edit">
|
<el-row v-if="!edit">
|
||||||
<el-descriptions-item v-for="(param, key) in params" :label="getLabel(param)" :key="key">
|
<el-col :span="22" :offset="1">
|
||||||
<span>{{ param.showValue && param.showValue != '' ? param.showValue : param.value }}</span>
|
<el-descriptions border :column="1">
|
||||||
</el-descriptions-item>
|
<el-descriptions-item v-for="(param, key) in params" :label="getLabel(param)" :key="key">
|
||||||
</el-descriptions>
|
<span>{{ param.showValue && param.showValue != '' ? param.showValue : param.value }}</span>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
<el-row v-else v-loading="loading">
|
<el-row v-else v-loading="loading">
|
||||||
<el-col :span="22" :offset="1">
|
<el-col :span="22" :offset="1">
|
||||||
<el-alert :title="$t('app.updateHelper')" type="warning" :closable="false" />
|
<el-alert :title="$t('app.updateHelper')" type="warning" :closable="false" />
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ const buttons = [
|
|||||||
openOperate(row, 'start');
|
openOperate(row, 'start');
|
||||||
},
|
},
|
||||||
disabled: (row: any) => {
|
disabled: (row: any) => {
|
||||||
return row.status === 'Running';
|
return row.status === 'Running' || row.status === 'Error';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
|
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="$t('container.exportImage')" :back="handleClose" />
|
<DrawerHeader :header="$t('container.exportImage')" :back="handleClose" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
|
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="$t('container.imageTag')" :resource="form.itemName" :back="handleClose" />
|
<DrawerHeader :header="$t('container.imageTag')" :resource="form.itemName" :back="handleClose" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
|
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="$t('container.createNetwork')" :back="handleClose" />
|
<DrawerHeader :header="$t('container.createNetwork')" :back="handleClose" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -174,6 +174,9 @@ const onCheckConn = async (row: Container.RepoInfo) => {
|
|||||||
const buttons = [
|
const buttons = [
|
||||||
{
|
{
|
||||||
label: i18n.global.t('commons.button.sync'),
|
label: i18n.global.t('commons.button.sync'),
|
||||||
|
disabled: (row: Container.RepoInfo) => {
|
||||||
|
return row.downloadUrl === 'docker.io';
|
||||||
|
},
|
||||||
click: (row: Container.RepoInfo) => {
|
click: (row: Container.RepoInfo) => {
|
||||||
onCheckConn(row);
|
onCheckConn(row);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
|
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader
|
<DrawerHeader
|
||||||
:header="title + $t('container.repo')"
|
:header="title + $t('container.repo')"
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
<el-row style="margin-top: 20px" v-if="confShowType === 'base'">
|
<el-row style="margin-top: 20px" v-if="confShowType === 'base'">
|
||||||
<el-col :span="1"><br /></el-col>
|
<el-col :span="1"><br /></el-col>
|
||||||
<el-col :span="10">
|
<el-col :span="10">
|
||||||
<el-form :model="form" label-position="left" ref="formRef" label-width="120px">
|
<el-form :model="form" label-position="left" ref="formRef" label-width="150px">
|
||||||
<el-form-item :label="$t('container.mirrors')" prop="mirrors">
|
<el-form-item :label="$t('container.mirrors')" prop="mirrors">
|
||||||
<el-input
|
<el-input
|
||||||
type="textarea"
|
type="textarea"
|
||||||
@@ -53,6 +53,17 @@
|
|||||||
v-model="form.mirrors"
|
v-model="form.mirrors"
|
||||||
/>
|
/>
|
||||||
<span class="input-help">{{ $t('container.mirrorsHelper') }}</span>
|
<span class="input-help">{{ $t('container.mirrorsHelper') }}</span>
|
||||||
|
<span class="input-help">
|
||||||
|
{{ $t('container.mirrorsHelper2') }}
|
||||||
|
<el-link
|
||||||
|
style="font-size: 12px; margin-left: 5px"
|
||||||
|
icon="Position"
|
||||||
|
@click="toDoc()"
|
||||||
|
type="primary"
|
||||||
|
>
|
||||||
|
{{ $t('firewall.quickJump') }}
|
||||||
|
</el-link>
|
||||||
|
</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('container.registries')" prop="registries">
|
<el-form-item :label="$t('container.registries')" prop="registries">
|
||||||
<el-input
|
<el-input
|
||||||
@@ -219,6 +230,10 @@ const onSaveFile = async () => {
|
|||||||
confirmDialogRef.value!.acceptParams(params);
|
confirmDialogRef.value!.acceptParams(params);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toDoc = () => {
|
||||||
|
window.open('https://1panel.cn/docs/user_manual/containers/setting/', '_blank');
|
||||||
|
};
|
||||||
|
|
||||||
const onChangeIptables = () => {
|
const onChangeIptables = () => {
|
||||||
if (!form.iptables) {
|
if (!form.iptables) {
|
||||||
iptablesVisiable.value = true;
|
iptablesVisiable.value = true;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
|
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="$t('container.createVolume')" :back="handleClose" />
|
<DrawerHeader :header="$t('container.createVolume')" :back="handleClose" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer v-model="createVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
|
<el-drawer v-model="createVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="$t('database.create')" :back="handleClose" />
|
<DrawerHeader :header="$t('database.create')" :back="handleClose" />
|
||||||
</template>
|
</template>
|
||||||
@@ -37,7 +37,13 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="form.permission === 'ip'" prop="permissionIPs">
|
<el-form-item v-if="form.permission === 'ip'" prop="permissionIPs">
|
||||||
<el-input clearable v-model="form.permissionIPs" />
|
<el-input
|
||||||
|
clearable
|
||||||
|
:autosize="{ minRows: 2, maxRows: 5 }"
|
||||||
|
type="textarea"
|
||||||
|
v-model="form.permissionIPs"
|
||||||
|
/>
|
||||||
|
<span class="input-help">{{ $t('database.remoteHelper') }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('commons.table.description')" prop="description">
|
<el-form-item :label="$t('commons.table.description')" prop="description">
|
||||||
<el-input type="textarea" clearable v-model="form.description" />
|
<el-input type="textarea" clearable v-model="form.description" />
|
||||||
@@ -131,6 +137,10 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
|
|||||||
createVisiable.value = false;
|
createVisiable.value = false;
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
|
if (form.permission != '%') {
|
||||||
|
form.permissionIPs = form.permission;
|
||||||
|
form.permission = 'ip';
|
||||||
|
}
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -38,12 +38,12 @@
|
|||||||
:rules="Rules.requiredInput"
|
:rules="Rules.requiredInput"
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input
|
||||||
:placeholder="$t('database.remoteHelper')"
|
|
||||||
clearable
|
clearable
|
||||||
:autosize="{ minRows: 2, maxRows: 5 }"
|
:autosize="{ minRows: 2, maxRows: 5 }"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
v-model="changeForm.privilegeIPs"
|
v-model="changeForm.privilegeIPs"
|
||||||
/>
|
/>
|
||||||
|
<span class="input-help">{{ $t('database.remoteHelper') }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -158,7 +158,7 @@ const submitChangeInfo = async (formEl: FormInstance | undefined) => {
|
|||||||
if (changeForm.privilege !== 'ip') {
|
if (changeForm.privilege !== 'ip') {
|
||||||
param.value = changeForm.privilege;
|
param.value = changeForm.privilege;
|
||||||
} else {
|
} else {
|
||||||
param.value = changeForm.privilegeIPs.replaceAll('/n', ',');
|
param.value = changeForm.privilegeIPs;
|
||||||
}
|
}
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await updateMysqlAccess(param)
|
await updateMysqlAccess(param)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer v-model="dialogVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="40%">
|
<el-drawer v-model="dialogVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="$t('database.remoteAccess')" :back="handleClose" />
|
<DrawerHeader :header="$t('database.remoteAccess')" :back="handleClose" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -201,6 +201,7 @@ const onBackup = async () => {
|
|||||||
};
|
};
|
||||||
const onRecover = async () => {
|
const onRecover = async () => {
|
||||||
let param = {
|
let param = {
|
||||||
|
source: currentRow.value.source,
|
||||||
type: 'redis',
|
type: 'redis',
|
||||||
name: '',
|
name: '',
|
||||||
detailName: '',
|
detailName: '',
|
||||||
|
|||||||
@@ -87,8 +87,10 @@ defineExpose({
|
|||||||
.h-app-card {
|
.h-app-card {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 10px 15px;
|
padding: 10px 15px;
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
.h-app-content {
|
.h-app-content {
|
||||||
|
padding-left: 15px;
|
||||||
.h-app-title {
|
.h-app-title {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
|||||||
@@ -290,7 +290,9 @@ const freshChart = (chartName: string, Title: string, Data: number) => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
myChart.setOption(option, true);
|
nextTick(function () {
|
||||||
|
myChart.setOption(option, true);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function loadStatus(val: number) {
|
function loadStatus(val: number) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
destroy-on-close
|
destroy-on-close
|
||||||
width="70%"
|
width="70%"
|
||||||
@opened="onOpen"
|
@opened="onOpen"
|
||||||
|
:top="'5vh'"
|
||||||
>
|
>
|
||||||
<el-form :inline="true" :model="config">
|
<el-form :inline="true" :model="config">
|
||||||
<el-form-item :label="$t('file.theme')">
|
<el-form-item :label="$t('file.theme')">
|
||||||
@@ -24,8 +25,8 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="coder-editor" v-loading="loading">
|
<div v-loading="loading">
|
||||||
<div id="codeBox" style="height: 60vh"></div>
|
<div id="codeBox" style="height: 55vh"></div>
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
@@ -214,8 +215,8 @@ onBeforeUnmount(() => {
|
|||||||
defineExpose({ acceptParams });
|
defineExpose({ acceptParams });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style>
|
||||||
.coder-editor {
|
.dialog-top {
|
||||||
margin-top: 10px;
|
top: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -90,7 +90,7 @@
|
|||||||
clearable
|
clearable
|
||||||
@clear="search()"
|
@clear="search()"
|
||||||
@keydown.enter="search()"
|
@keydown.enter="search()"
|
||||||
:placeholder="req.containSub ? $t('file.searchHelper') : $t('file.search')"
|
:placeholder="$t('file.search')"
|
||||||
>
|
>
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<el-checkbox v-model="req.containSub">
|
<el-checkbox v-model="req.containSub">
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ import { MsgSuccess } from '@/utils/message';
|
|||||||
import { updatePort } from '@/api/modules/setting';
|
import { updatePort } from '@/api/modules/setting';
|
||||||
import { ElMessageBox, FormInstance } from 'element-plus';
|
import { ElMessageBox, FormInstance } from 'element-plus';
|
||||||
import { Rules } from '@/global/form-rules';
|
import { Rules } from '@/global/form-rules';
|
||||||
|
import { GlobalStore } from '@/store';
|
||||||
|
const globalStore = GlobalStore();
|
||||||
|
|
||||||
interface DialogProps {
|
interface DialogProps {
|
||||||
serverPort: number;
|
serverPort: number;
|
||||||
@@ -66,9 +68,10 @@ const onSavePort = async (formEl: FormInstance | undefined) => {
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||||
|
globalStore.isLogin = false;
|
||||||
let href = window.location.href;
|
let href = window.location.href;
|
||||||
let ip = href.split('//')[1].split(':')[0];
|
let ip = href.split('//')[1].split(':')[0];
|
||||||
window.open(`${href.split('//')[0]}//${ip}:${form.serverPort}/`, '_self');
|
window.open(`${href.split('//')[0]}//${ip}:${form.serverPort}/${globalStore.entrance}`, '_self');
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
:destroy-on-close="true"
|
:destroy-on-close="true"
|
||||||
@close="handleClose"
|
@close="handleClose"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
size="50%"
|
size="30%"
|
||||||
>
|
>
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader header="https" :back="handleClose" />
|
<DrawerHeader header="https" :back="handleClose" />
|
||||||
@@ -112,6 +112,8 @@ import { DownloadByPath } from '@/api/modules/files';
|
|||||||
import { Rules } from '@/global/form-rules';
|
import { Rules } from '@/global/form-rules';
|
||||||
import { ElMessageBox, FormInstance } from 'element-plus';
|
import { ElMessageBox, FormInstance } from 'element-plus';
|
||||||
import { Setting } from '@/api/interface/setting';
|
import { Setting } from '@/api/interface/setting';
|
||||||
|
import { GlobalStore } from '@/store';
|
||||||
|
const globalStore = GlobalStore();
|
||||||
|
|
||||||
const loading = ref();
|
const loading = ref();
|
||||||
const drawerVisiable = ref();
|
const drawerVisiable = ref();
|
||||||
@@ -207,8 +209,10 @@ const onSaveSSL = async (formEl: FormInstance | undefined) => {
|
|||||||
await updateSSL(param).then(() => {
|
await updateSSL(param).then(() => {
|
||||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||||
let href = window.location.href;
|
let href = window.location.href;
|
||||||
|
globalStore.isLogin = false;
|
||||||
let address = href.split('://')[1];
|
let address = href.split('://')[1];
|
||||||
window.open(`https://${address}/`, '_self');
|
address = address.replaceAll('settings/safe', globalStore.entrance);
|
||||||
|
window.open(`https://${address}`, '_self');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-loading="loading">
|
<div v-loading="loading">
|
||||||
<el-drawer v-model="drawerVisiable" size="50%">
|
<el-drawer v-model="drawerVisiable" size="30%">
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="$t('setting.importSnapshot')" :back="handleClose" />
|
<DrawerHeader :header="$t('setting.importSnapshot')" :back="handleClose" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ const get = () => {
|
|||||||
if (res.data.httpConfig != '') {
|
if (res.data.httpConfig != '') {
|
||||||
form.httpConfig = res.data.httpConfig;
|
form.httpConfig = res.data.httpConfig;
|
||||||
}
|
}
|
||||||
if (res.data.SSLProtocol.length > 0) {
|
if (res.data.SSLProtocol && res.data.SSLProtocol.length > 0) {
|
||||||
form.SSLProtocol = res.data.SSLProtocol;
|
form.SSLProtocol = res.data.SSLProtocol;
|
||||||
}
|
}
|
||||||
if (res.data.algorithm != '') {
|
if (res.data.algorithm != '') {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-loading="loading">
|
<div>
|
||||||
<el-form-item :label="$t('website.rewriteMode')">
|
<el-form-item :label="$t('website.rewriteMode')">
|
||||||
<el-select v-model="req.name" filterable @change="getRewriteConfig(req.name)">
|
<el-select v-model="req.name" filterable @change="getRewriteConfig(req.name)">
|
||||||
<el-option :label="$t('website.current')" :value="'current'"></el-option>
|
<el-option :label="$t('website.current')" :value="'current'"></el-option>
|
||||||
@@ -11,8 +11,9 @@
|
|||||||
></el-option>
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<Codemirror
|
||||||
<codemirror
|
ref="codeRef"
|
||||||
|
v-loading="loading"
|
||||||
:autofocus="true"
|
:autofocus="true"
|
||||||
placeholder=""
|
placeholder=""
|
||||||
:indent-with-tab="true"
|
:indent-with-tab="true"
|
||||||
@@ -37,7 +38,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onMounted, reactive, ref } from 'vue';
|
import { computed, nextTick, onMounted, reactive, ref } from 'vue';
|
||||||
import { Codemirror } from 'vue-codemirror';
|
import { Codemirror } from 'vue-codemirror';
|
||||||
import { oneDark } from '@codemirror/theme-one-dark';
|
import { oneDark } from '@codemirror/theme-one-dark';
|
||||||
import { StreamLanguage } from '@codemirror/language';
|
import { StreamLanguage } from '@codemirror/language';
|
||||||
@@ -48,8 +49,9 @@ import { MsgSuccess } from '@/utils/message';
|
|||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const content = ref('');
|
const content = ref(' ');
|
||||||
const extensions = [StreamLanguage.define(nginx), oneDark];
|
const extensions = [StreamLanguage.define(nginx), oneDark];
|
||||||
|
const codeRef = ref();
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
@@ -69,7 +71,7 @@ const req = reactive({
|
|||||||
|
|
||||||
const update = reactive({
|
const update = reactive({
|
||||||
websiteID: id.value,
|
websiteID: id.value,
|
||||||
content: '',
|
content: 'd',
|
||||||
name: '',
|
name: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -80,12 +82,24 @@ const getRewriteConfig = async (rewrite: string) => {
|
|||||||
try {
|
try {
|
||||||
const res = await GetRewriteConfig(req);
|
const res = await GetRewriteConfig(req);
|
||||||
content.value = res.data.content;
|
content.value = res.data.content;
|
||||||
|
if (res.data.content == '') {
|
||||||
|
content.value = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
setCursorPosition();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const setCursorPosition = () => {
|
||||||
|
nextTick(() => {
|
||||||
|
const codeMirrorInstance = codeRef.value?.codemirror;
|
||||||
|
codeMirrorInstance?.setCursor(0, 0);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
update.name = req.name;
|
update.name = req.name;
|
||||||
update.websiteID = id.value;
|
update.websiteID = id.value;
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ require (
|
|||||||
github.com/dgraph-io/ristretto v0.1.1 // indirect
|
github.com/dgraph-io/ristretto v0.1.1 // indirect
|
||||||
github.com/distribution/distribution/v3 v3.0.0-20230223072852-e5d5810851d1 // indirect
|
github.com/distribution/distribution/v3 v3.0.0-20230223072852-e5d5810851d1 // indirect
|
||||||
github.com/docker/buildx v0.10.4 // indirect
|
github.com/docker/buildx v0.10.4 // indirect
|
||||||
github.com/docker/distribution v2.8.1+incompatible // indirect
|
github.com/docker/distribution v2.8.2+incompatible // indirect
|
||||||
github.com/docker/docker-credential-helpers v0.7.0 // indirect
|
github.com/docker/docker-credential-helpers v0.7.0 // indirect
|
||||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
|
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
|
||||||
github.com/docker/go-metrics v0.0.1 // indirect
|
github.com/docker/go-metrics v0.0.1 // indirect
|
||||||
|
|||||||
@@ -201,6 +201,8 @@ github.com/docker/compose/v2 v2.17.2/go.mod h1:h5uld3t0RsL5h8rtkRaJtrFLJ3TJ9GOKd
|
|||||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
|
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
|
||||||
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
|
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||||
|
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/docker v23.0.3+incompatible h1:9GhVsShNWz1hO//9BNg/dpMnZW25KydO4wtVxWAIbho=
|
github.com/docker/docker v23.0.3+incompatible h1:9GhVsShNWz1hO//9BNg/dpMnZW25KydO4wtVxWAIbho=
|
||||||
github.com/docker/docker v23.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v23.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
|
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
|
||||||
|
|||||||
Reference in New Issue
Block a user