Compare commits

..
6 Commits
273 changed files with 3592 additions and 9694 deletions
+4 -1
View File
@@ -44,7 +44,10 @@ curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_
- [在线文档](https://1panel.cn/docs/)
- [教学视频](https://space.bilibili.com/510493147/channel/collectiondetail?sid=1199760)
- [社区论坛](https://bbs.fit2cloud.com/c/1p/7)
- [如何加入微信交流群?](https://bbs.fit2cloud.com/t/topic/2147)
**加入微信交流群**
<img src="https://1panel.cn/img/wechat-group.jpg" width="156" height="156"/>
## 安全说明
+5 -8
View File
@@ -19,7 +19,8 @@ import (
// @Router /apps/search [post]
func (b *BaseApi) SearchApp(c *gin.Context) {
var req request.AppSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
list, err := appService.PageApp(req)
@@ -44,13 +45,8 @@ func (b *BaseApi) SyncApp(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
if !res.CanUpdate {
if res.IsSyncing {
helper.SuccessWithMsg(c, i18n.GetMsgByKey("AppStoreIsSyncing"))
} else {
helper.SuccessWithMsg(c, i18n.GetMsgByKey("AppStoreIsUpToDate"))
}
helper.SuccessWithMsg(c, i18n.GetMsgByKey("AppStoreIsUpToDate"))
return
}
go func() {
@@ -158,7 +154,8 @@ func (b *BaseApi) GetIgnoredApp(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[{"input_column":"name","input_value":"name","isList":false,"db":"app_installs","output_column":"app_id","output_value":"appId"},{"info":"appId","isList":false,"db":"apps","output_column":"key","output_value":"appKey"}],"formatZH":"安装应用 [appKey]-[name]","formatEN":"Install app [appKey]-[name]"}
func (b *BaseApi) InstallApp(c *gin.Context) {
var req request.AppInstallCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
tx, ctx := helper.GetTxAndContext()
+32 -17
View File
@@ -1,6 +1,8 @@
package v1
import (
"reflect"
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
@@ -20,17 +22,11 @@ import (
// @Router /apps/installed/search [post]
func (b *BaseApi) SearchAppInstalled(c *gin.Context) {
var req request.AppInstalledSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if req.All {
list, err := appInstallService.SearchForWebsite(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, list)
} else {
if !reflect.DeepEqual(req.PageInfo, dto.PageInfo{}) {
total, list, err := appInstallService.Page(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -40,6 +36,13 @@ func (b *BaseApi) SearchAppInstalled(c *gin.Context) {
Items: list,
Total: total,
})
} else {
list, err := appInstallService.SearchForWebsite(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, list)
}
}
@@ -69,7 +72,8 @@ func (b *BaseApi) ListAppInstalled(c *gin.Context) {
// @Router /apps/installed/check [post]
func (b *BaseApi) CheckAppInstalled(c *gin.Context) {
var req request.AppInstalledInfo
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
@@ -94,7 +98,8 @@ func (b *BaseApi) CheckAppInstalled(c *gin.Context) {
// @Router /apps/installed/loadport [post]
func (b *BaseApi) LoadPort(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
port, err := appInstallService.LoadPort(req)
@@ -115,7 +120,8 @@ func (b *BaseApi) LoadPort(c *gin.Context) {
// @Router /apps/installed/conninfo/:key [get]
func (b *BaseApi) LoadConnInfo(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
conn, err := appInstallService.LoadConnInfo(req)
@@ -175,7 +181,8 @@ func (b *BaseApi) SyncInstalled(c *gin.Context) {
// @x-panel-log {"bodyKeys":["installId","operate"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"installId","isList":false,"db":"app_installs","output_column":"app_id","output_value":"appId"},{"input_column":"id","input_value":"installId","isList":false,"db":"app_installs","output_column":"name","output_value":"appName"},{"input_column":"id","input_value":"appId","isList":false,"db":"apps","output_column":"key","output_value":"appKey"}],"formatZH":"[operate] 应用 [appKey][appName]","formatEN":"[operate] App [appKey][appName]"}
func (b *BaseApi) OperateInstalled(c *gin.Context) {
var req request.AppInstalledOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := appInstallService.Operate(req); err != nil {
@@ -236,7 +243,12 @@ func (b *BaseApi) GetUpdateVersions(c *gin.Context) {
// @x-panel-log {"bodyKeys":["key","name","port"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"应用端口修改 [key]-[name] => [port]","formatEN":"Application port update [key]-[name] => [port]"}
func (b *BaseApi) ChangeAppPort(c *gin.Context) {
var req request.PortUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := appInstallService.ChangeAppPort(req); err != nil {
@@ -256,7 +268,8 @@ func (b *BaseApi) ChangeAppPort(c *gin.Context) {
// @Router /apps/installed/conf [post]
func (b *BaseApi) GetDefaultConfig(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
content, err := appInstallService.GetDefaultConfigByKey(req.Type, req.Name)
@@ -301,7 +314,8 @@ func (b *BaseApi) GetParams(c *gin.Context) {
// @x-panel-log {"bodyKeys":["installId"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"应用参数修改 [installId]","formatEN":"Application param update [installId]"}
func (b *BaseApi) UpdateInstalled(c *gin.Context) {
var req request.AppInstalledUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := appInstallService.Update(req); err != nil {
@@ -322,7 +336,8 @@ func (b *BaseApi) UpdateInstalled(c *gin.Context) {
// @x-panel-log {"bodyKeys":["installId"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"忽略应用 [installId] 版本升级","formatEN":"Application param update [installId]"}
func (b *BaseApi) IgnoreUpgrade(c *gin.Context) {
var req request.AppInstalledIgnoreUpgrade
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := appInstallService.IgnoreUpgrade(req); err != nil {
+8 -4
View File
@@ -25,10 +25,10 @@ type BaseApi struct{}
// @Router /auth/login [post]
func (b *BaseApi) Login(c *gin.Context) {
var req dto.Login
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if req.AuthMethod != "jwt" && !req.IgnoreCaptcha {
if err := captcha.VerifyCode(req.CaptchaID, req.Captcha); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -60,10 +60,14 @@ func (b *BaseApi) Login(c *gin.Context) {
// @Header 200 {string} EntranceCode "安全入口"
func (b *BaseApi) MFALogin(c *gin.Context) {
var req dto.MFALogin
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
entranceItem := c.Request.Header.Get("EntranceCode")
var entrance []byte
if len(entranceItem) != 0 {
+63 -13
View File
@@ -8,6 +8,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
@@ -22,7 +23,12 @@ import (
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建备份账号 [type]","formatEN":"create backup account [type]"}
func (b *BaseApi) CreateBackup(c *gin.Context) {
var req dto.BackupOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if len(req.Credential) != 0 {
@@ -59,7 +65,12 @@ func (b *BaseApi) CreateBackup(c *gin.Context) {
// @Router /settings/backup/search [post]
func (b *BaseApi) ListBuckets(c *gin.Context) {
var req dto.ForBuckets
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if len(req.Credential) != 0 {
@@ -114,7 +125,12 @@ func (b *BaseApi) LoadOneDriveInfo(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":true,"db":"backup_accounts","output_column":"type","output_value":"types"}],"formatZH":"删除备份账号 [types]","formatEN":"delete backup account [types]"}
func (b *BaseApi) DeleteBackup(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -135,7 +151,8 @@ func (b *BaseApi) DeleteBackup(c *gin.Context) {
// @Router /settings/backup/record/search [post]
func (b *BaseApi) SearchBackupRecords(c *gin.Context) {
var req dto.RecordSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -162,7 +179,12 @@ func (b *BaseApi) SearchBackupRecords(c *gin.Context) {
// @x-panel-log {"bodyKeys":["source","fileName"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"下载备份记录 [source][fileName]","formatEN":"download backup records [source][fileName]"}
func (b *BaseApi) DownloadRecord(c *gin.Context) {
var req dto.DownloadRecord
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -185,7 +207,12 @@ func (b *BaseApi) DownloadRecord(c *gin.Context) {
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"backup_records","output_column":"file_name","output_value":"files"}],"formatZH":"删除备份记录 [files]","formatEN":"delete backup records [files]"}
func (b *BaseApi) DeleteBackupRecord(c *gin.Context) {
var req dto.BatchDeleteReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -207,10 +234,14 @@ func (b *BaseApi) DeleteBackupRecord(c *gin.Context) {
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新备份账号 [types]","formatEN":"update backup account [types]"}
func (b *BaseApi) UpdateBackup(c *gin.Context) {
var req dto.BackupOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if len(req.Credential) != 0 {
credential, err := base64.StdEncoding.DecodeString(req.Credential)
if err != nil {
@@ -261,10 +292,14 @@ func (b *BaseApi) ListBackup(c *gin.Context) {
// @Router /settings/backup/search/files [post]
func (b *BaseApi) LoadFilesFromBackup(c *gin.Context) {
var req dto.BackupSearchFile
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
data, err := backupService.ListFiles(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -285,7 +320,12 @@ func (b *BaseApi) LoadFilesFromBackup(c *gin.Context) {
// @x-panel-log {"bodyKeys":["type","name","detailName"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"备份 [type] 数据 [name][detailName]","formatEN":"backup [type] data [name][detailName]"}
func (b *BaseApi) Backup(c *gin.Context) {
var req dto.CommonBackup
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -325,7 +365,12 @@ func (b *BaseApi) Backup(c *gin.Context) {
// @x-panel-log {"bodyKeys":["type","name","detailName","file"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"从 [file] 恢复 [type] 数据 [name][detailName]","formatEN":"recover [type] data [name][detailName] from [file]"}
func (b *BaseApi) Recover(c *gin.Context) {
var req dto.CommonRecover
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -373,7 +418,12 @@ func (b *BaseApi) Recover(c *gin.Context) {
// @x-panel-log {"bodyKeys":["type","name","detailName","file"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"从 [file] 恢复 [type] 数据 [name][detailName]","formatEN":"recover [type] data [name][detailName] from [file]"}
func (b *BaseApi) RecoverByUpload(c *gin.Context) {
var req dto.CommonRecover
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
+22 -24
View File
@@ -4,6 +4,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
@@ -18,10 +19,14 @@ import (
// @x-panel-log {"bodyKeys":["name","command"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建快捷命令 [name][command]","formatEN":"create quick command [name][command]"}
func (b *BaseApi) CreateCommand(c *gin.Context) {
var req dto.CommandOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := commandService.Create(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -38,8 +43,9 @@ func (b *BaseApi) CreateCommand(c *gin.Context) {
// @Security ApiKeyAuth
// @Router /hosts/command/search [post]
func (b *BaseApi) SearchCommand(c *gin.Context) {
var req dto.SearchCommandWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
var req dto.SearchWithPage
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -55,23 +61,6 @@ func (b *BaseApi) SearchCommand(c *gin.Context) {
})
}
// @Tags Command
// @Summary Tree commands
// @Description 获取快速命令树
// @Accept json
// @Success 200 {Array} dto.CommandTree
// @Security ApiKeyAuth
// @Router /hosts/command/tree [get]
func (b *BaseApi) SearchCommandTree(c *gin.Context) {
list, err := commandService.SearchForTree()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Command
// @Summary List commands
// @Description 获取快速命令列表
@@ -99,7 +88,12 @@ func (b *BaseApi) ListCommand(c *gin.Context) {
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"commands","output_column":"name","output_value":"names"}],"formatZH":"删除快捷命令 [names]","formatEN":"delete quick command [names]"}
func (b *BaseApi) DeleteCommand(c *gin.Context) {
var req dto.BatchDeleteReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -121,13 +115,17 @@ func (b *BaseApi) DeleteCommand(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新快捷命令 [name]","formatEN":"update quick command [name]"}
func (b *BaseApi) UpdateCommand(c *gin.Context) {
var req dto.CommandOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
upMap := make(map[string]interface{})
upMap["name"] = req.Name
upMap["group_id"] = req.GroupID
upMap["command"] = req.Command
if err := commandService.Update(req.ID, upMap); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
+21 -5
View File
@@ -4,6 +4,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
@@ -18,10 +19,14 @@ import (
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 compose 模版 [name]","formatEN":"create compose template [name]"}
func (b *BaseApi) CreateComposeTemplate(c *gin.Context) {
var req dto.ComposeTemplateCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := composeTemplateService.Create(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -40,7 +45,8 @@ func (b *BaseApi) CreateComposeTemplate(c *gin.Context) {
// @Router /containers/template/search [post]
func (b *BaseApi) SearchComposeTemplate(c *gin.Context) {
var req dto.SearchWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -84,7 +90,12 @@ func (b *BaseApi) ListComposeTemplate(c *gin.Context) {
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"compose_templates","output_column":"name","output_value":"names"}],"formatZH":"删除 compose 模版 [names]","formatEN":"delete compose template [names]"}
func (b *BaseApi) DeleteComposeTemplate(c *gin.Context) {
var req dto.BatchDeleteReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -106,7 +117,12 @@ func (b *BaseApi) DeleteComposeTemplate(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"compose_templates","output_column":"name","output_value":"name"}],"formatZH":"更新 compose 模版 [name]","formatEN":"update compose template information [name]"}
func (b *BaseApi) UpdateComposeTemplate(c *gin.Context) {
var req dto.ComposeTemplateUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
+127 -56
View File
@@ -20,7 +20,12 @@ import (
// @Router /containers/search [post]
func (b *BaseApi) SearchContainer(c *gin.Context) {
var req dto.PageContainer
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -62,7 +67,12 @@ func (b *BaseApi) ListContainer(c *gin.Context) {
// @Router /containers/compose/search [post]
func (b *BaseApi) SearchCompose(c *gin.Context) {
var req dto.SearchWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -88,7 +98,12 @@ func (b *BaseApi) SearchCompose(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"检测 compose [name] 格式","formatEN":"check compose [name]"}
func (b *BaseApi) TestCompose(c *gin.Context) {
var req dto.ComposeCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -111,7 +126,12 @@ func (b *BaseApi) TestCompose(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 compose [name]","formatEN":"create compose [name]"}
func (b *BaseApi) CreateCompose(c *gin.Context) {
var req dto.ComposeCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -134,7 +154,12 @@ func (b *BaseApi) CreateCompose(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name","operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"compose [operation] [name]","formatEN":"compose [operation] [name]"}
func (b *BaseApi) OperatorCompose(c *gin.Context) {
var req dto.ComposeOperation
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -156,10 +181,14 @@ func (b *BaseApi) OperatorCompose(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name","image"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新容器 [name][image]","formatEN":"update container [name][image]"}
func (b *BaseApi) ContainerUpdate(c *gin.Context) {
var req dto.ContainerOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := containerService.ContainerUpdate(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -177,10 +206,14 @@ func (b *BaseApi) ContainerUpdate(c *gin.Context) {
// @Router /containers/info [post]
func (b *BaseApi) ContainerInfo(c *gin.Context) {
var req dto.OperationWithName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
data, err := containerService.ContainerInfo(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -209,12 +242,12 @@ func (b *BaseApi) LoadResourceLimit(c *gin.Context) {
// @Security ApiKeyAuth
// @Router /containers/list/stats [get]
func (b *BaseApi) ContainerListStats(c *gin.Context) {
data, err := containerService.ContainerListStats()
datas, err := containerService.ContainerListStats()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, data)
helper.SuccessWithData(c, datas)
}
// @Tags Container
@@ -228,10 +261,14 @@ func (b *BaseApi) ContainerListStats(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name","image"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建容器 [name][image]","formatEN":"create container [name][image]"}
func (b *BaseApi) ContainerCreate(c *gin.Context) {
var req dto.ContainerOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := containerService.ContainerCreate(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -250,10 +287,14 @@ func (b *BaseApi) ContainerCreate(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name","image"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新容器镜像 [name][image]","formatEN":"upgrade container image [name][image]"}
func (b *BaseApi) ContainerUpgrade(c *gin.Context) {
var req dto.ContainerUpgrade
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := containerService.ContainerUpgrade(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -272,10 +313,14 @@ func (b *BaseApi) ContainerUpgrade(c *gin.Context) {
// @x-panel-log {"bodyKeys":["pruneType"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清理容器 [pruneType]","formatEN":"clean container [pruneType]"}
func (b *BaseApi) ContainerPrune(c *gin.Context) {
var req dto.ContainerPrune
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
report, err := containerService.Prune(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -295,10 +340,14 @@ func (b *BaseApi) ContainerPrune(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清理容器 [name] 日志","formatEN":"clean container [name] logs"}
func (b *BaseApi) CleanContainerLog(c *gin.Context) {
var req dto.OperationWithName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := containerService.ContainerLogClean(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -316,36 +365,14 @@ func (b *BaseApi) CleanContainerLog(c *gin.Context) {
// @Router /containers/load/log [post]
func (b *BaseApi) LoadContainerLog(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
content := containerService.LoadContainerLogs(req)
helper.SuccessWithData(c, content)
}
// @Tags Container
// @Summary Rename Container
// @Description 容器重命名
// @Accept json
// @Param request body dto.ContainerRename true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /containers/rename [post]
// @x-panel-log {"bodyKeys":["name","newName"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"容器重命名 [name] => [newName]","formatEN":"rename container [name] => [newName]"}
func (b *BaseApi) ContainerRename(c *gin.Context) {
var req dto.ContainerRename
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.ContainerRename(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Container
// @Summary Operate Container
// @Description 容器操作
@@ -354,13 +381,17 @@ func (b *BaseApi) ContainerRename(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /containers/operate [post]
// @x-panel-log {"bodyKeys":["names","operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"容器 [names] 执行 [operation]","formatEN":"container [operation] [names]"}
// @x-panel-log {"bodyKeys":["name","operation","newName"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"容器 [name] 执行 [operation] [newName]","formatEN":"container [operation] [name] [newName]"}
func (b *BaseApi) ContainerOperation(c *gin.Context) {
var req dto.ContainerOperation
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := containerService.ContainerOperation(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -400,7 +431,12 @@ func (b *BaseApi) ContainerStats(c *gin.Context) {
// @Router /containers/inspect [post]
func (b *BaseApi) Inspect(c *gin.Context) {
var req dto.InspectReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -434,7 +470,7 @@ func (b *BaseApi) ContainerLogs(c *gin.Context) {
follow := c.Query("follow") == "true"
tail := c.Query("tail")
if err := containerService.ContainerLogs(wsConn, "container", container, since, tail, follow); err != nil {
if err := containerService.ContainerLogs(wsConn, container, since, tail, follow); err != nil {
_ = wsConn.WriteMessage(1, []byte(err.Error()))
return
}
@@ -451,7 +487,12 @@ func (b *BaseApi) ContainerLogs(c *gin.Context) {
// @Router /containers/network/search [post]
func (b *BaseApi) SearchNetwork(c *gin.Context) {
var req dto.SearchWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -494,7 +535,12 @@ func (b *BaseApi) ListNetwork(c *gin.Context) {
// @x-panel-log {"bodyKeys":["names"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除容器网络 [names]","formatEN":"delete container network [names]"}
func (b *BaseApi) DeleteNetwork(c *gin.Context) {
var req dto.BatchDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -516,7 +562,12 @@ func (b *BaseApi) DeleteNetwork(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建容器网络 name","formatEN":"create container network [name]"}
func (b *BaseApi) CreateNetwork(c *gin.Context) {
var req dto.NetworkCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -538,7 +589,12 @@ func (b *BaseApi) CreateNetwork(c *gin.Context) {
// @Router /containers/volume/search [post]
func (b *BaseApi) SearchVolume(c *gin.Context) {
var req dto.SearchWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -581,7 +637,12 @@ func (b *BaseApi) ListVolume(c *gin.Context) {
// @x-panel-log {"bodyKeys":["names"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除容器存储卷 [names]","formatEN":"delete container volume [names]"}
func (b *BaseApi) DeleteVolume(c *gin.Context) {
var req dto.BatchDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -603,7 +664,12 @@ func (b *BaseApi) DeleteVolume(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建容器存储卷 [name]","formatEN":"create container volume [name]"}
func (b *BaseApi) CreateVolume(c *gin.Context) {
var req dto.VolumeCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -625,7 +691,12 @@ func (b *BaseApi) CreateVolume(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 compose [name]","formatEN":"update compose information [name]"}
func (b *BaseApi) ComposeUpdate(c *gin.Context) {
var req dto.ComposeUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -658,7 +729,7 @@ func (b *BaseApi) ComposeLogs(c *gin.Context) {
follow := c.Query("follow") == "true"
tail := c.Query("tail")
if err := containerService.ContainerLogs(wsConn, "compose", compose, since, tail, follow); err != nil {
if err := containerService.ComposeLogs(wsConn, compose, since, tail, follow); err != nil {
_ = wsConn.WriteMessage(1, []byte(err.Error()))
return
}
+45 -12
View File
@@ -6,6 +6,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/common"
"github.com/gin-gonic/gin"
)
@@ -21,10 +22,14 @@ import (
// @x-panel-log {"bodyKeys":["type","name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建计划任务 [type][name]","formatEN":"create cronjob [type][name]"}
func (b *BaseApi) CreateCronjob(c *gin.Context) {
var req dto.CronjobCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := cronjobService.Create(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -42,7 +47,8 @@ func (b *BaseApi) CreateCronjob(c *gin.Context) {
// @Router /cronjobs/search [post]
func (b *BaseApi) SearchCronjob(c *gin.Context) {
var req dto.SearchWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -68,10 +74,10 @@ func (b *BaseApi) SearchCronjob(c *gin.Context) {
// @Router /cronjobs/search/records [post]
func (b *BaseApi) SearchJobRecords(c *gin.Context) {
var req dto.SearchRecord
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
loc, _ := time.LoadLocation(common.LoadTimeZone())
req.StartTime = req.StartTime.In(loc)
req.EndTime = req.EndTime.In(loc)
@@ -98,7 +104,8 @@ func (b *BaseApi) SearchJobRecords(c *gin.Context) {
// @Router /cronjob/record/log [post]
func (b *BaseApi) LoadRecordLog(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
content, err := cronjobService.LoadRecordLog(req)
@@ -120,7 +127,8 @@ func (b *BaseApi) LoadRecordLog(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"cronjobs","output_column":"name","output_value":"name"}],"formatZH":"清空计划任务记录 [name]","formatEN":"clean cronjob [name] records"}
func (b *BaseApi) CleanRecord(c *gin.Context) {
var req dto.CronjobClean
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -143,7 +151,12 @@ func (b *BaseApi) CleanRecord(c *gin.Context) {
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"cronjobs","output_column":"name","output_value":"names"}],"formatZH":"删除计划任务 [names]","formatEN":"delete cronjob [names]"}
func (b *BaseApi) DeleteCronjob(c *gin.Context) {
var req dto.CronjobBatchDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -165,7 +178,12 @@ func (b *BaseApi) DeleteCronjob(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"cronjobs","output_column":"name","output_value":"name"}],"formatZH":"更新计划任务 [name]","formatEN":"update cronjob [name]"}
func (b *BaseApi) UpdateCronjob(c *gin.Context) {
var req dto.CronjobUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -187,7 +205,12 @@ func (b *BaseApi) UpdateCronjob(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id","status"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"cronjobs","output_column":"name","output_value":"name"}],"formatZH":"修改计划任务 [name] 状态为 [status]","formatEN":"change the status of cronjob [name] to [status]."}
func (b *BaseApi) UpdateCronjobStatus(c *gin.Context) {
var req dto.CronjobUpdateStatus
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -209,7 +232,12 @@ func (b *BaseApi) UpdateCronjobStatus(c *gin.Context) {
// @x-panel-log {"bodyKeys":["recordID"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"recordID","isList":false,"db":"job_records","output_column":"file","output_value":"file"}],"formatZH":"下载计划任务记录 [file]","formatEN":"download the cronjob record [file]"}
func (b *BaseApi) TargetDownload(c *gin.Context) {
var req dto.CronjobDownload
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -233,7 +261,12 @@ func (b *BaseApi) TargetDownload(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"cronjobs","output_column":"name","output_value":"name"}],"formatZH":"手动执行计划任务 [name]","formatEN":"manually execute the cronjob [name]"}
func (b *BaseApi) HandleOnce(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
-22
View File
@@ -56,28 +56,6 @@ func (b *BaseApi) LoadDashboardCurrentInfo(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error netOption in path"))
return
}
data := dashboardService.LoadCurrentInfo(ioOption, netOption)
helper.SuccessWithData(c, data)
}
// @Tags Dashboard
// @Summary System restart
// @Description 重启服务器/面板
// @Accept json
// @Param operation path string true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /dashboard/system/restart/:operation [post]
func (b *BaseApi) SystemRestart(c *gin.Context) {
operation, ok := c.Params.Get("operation")
if !ok {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error operation in path"))
return
}
if err := dashboardService.Restart(operation); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
+33 -8
View File
@@ -4,6 +4,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
@@ -18,10 +19,14 @@ import (
// @x-panel-log {"bodyKeys":["name", "type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建远程数据库 [name][type]","formatEN":"create database [name][type]"}
func (b *BaseApi) CreateDatabase(c *gin.Context) {
var req dto.DatabaseCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := databaseService.Create(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -40,10 +45,14 @@ func (b *BaseApi) CreateDatabase(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name", "type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"检测远程数据库 [name][type] 连接性","formatEN":"check if database [name][type] is connectable"}
func (b *BaseApi) CheckDatabase(c *gin.Context) {
var req dto.DatabaseCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
helper.SuccessWithData(c, databaseService.CheckDatabase(req))
}
@@ -57,7 +66,8 @@ func (b *BaseApi) CheckDatabase(c *gin.Context) {
// @Router /databases/db/search [post]
func (b *BaseApi) SearchDatabase(c *gin.Context) {
var req dto.DatabaseSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -125,7 +135,12 @@ func (b *BaseApi) GetDatabase(c *gin.Context) {
// @Router /db/remote/del/check [post]
func (b *BaseApi) DeleteCheckDatabase(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -148,7 +163,12 @@ func (b *BaseApi) DeleteCheckDatabase(c *gin.Context) {
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"databases","output_column":"name","output_value":"names"}],"formatZH":"删除远程数据库 [names]","formatEN":"delete database [names]"}
func (b *BaseApi) DeleteDatabase(c *gin.Context) {
var req dto.DatabaseDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -170,7 +190,12 @@ func (b *BaseApi) DeleteDatabase(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新远程数据库 [name]","formatEN":"update database [name]"}
func (b *BaseApi) UpdateDatabase(c *gin.Context) {
var req dto.DatabaseUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
+63 -25
View File
@@ -7,6 +7,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
@@ -21,10 +22,14 @@ import (
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 mysql 数据库 [name]","formatEN":"create mysql database [name]"}
func (b *BaseApi) CreateMysql(c *gin.Context) {
var req dto.MysqlDBCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if len(req.Password) != 0 {
password, err := base64.StdEncoding.DecodeString(req.Password)
if err != nil {
@@ -52,10 +57,14 @@ func (b *BaseApi) CreateMysql(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mysqls","output_column":"name","output_value":"name"}],"formatZH":"mysql 数据库 [name] 描述信息修改 [description]","formatEN":"The description of the mysql database [name] is modified => [description]"}
func (b *BaseApi) UpdateMysqlDescription(c *gin.Context) {
var req dto.UpdateDescription
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := mysqlService.UpdateDescription(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -74,10 +83,14 @@ func (b *BaseApi) UpdateMysqlDescription(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mysqls","output_column":"name","output_value":"name"}],"formatZH":"更新数据库 [name] 密码","formatEN":"Update database [name] password"}
func (b *BaseApi) ChangeMysqlPassword(c *gin.Context) {
var req dto.ChangeDBInfo
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if len(req.Value) != 0 {
value, err := base64.StdEncoding.DecodeString(req.Value)
if err != nil {
@@ -105,10 +118,14 @@ func (b *BaseApi) ChangeMysqlPassword(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mysqls","output_column":"name","output_value":"name"}],"formatZH":"更新数据库 [name] 访问权限","formatEN":"Update database [name] access"}
func (b *BaseApi) ChangeMysqlAccess(c *gin.Context) {
var req dto.ChangeDBInfo
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := mysqlService.ChangeAccess(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -127,7 +144,8 @@ func (b *BaseApi) ChangeMysqlAccess(c *gin.Context) {
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"调整 mysql 数据库性能参数","formatEN":"adjust mysql database performance parameters"}
func (b *BaseApi) UpdateMysqlVariables(c *gin.Context) {
var req dto.MysqlVariablesUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -149,7 +167,12 @@ func (b *BaseApi) UpdateMysqlVariables(c *gin.Context) {
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 mysql 数据库配置信息","formatEN":"update the mysql database configuration information"}
func (b *BaseApi) UpdateMysqlConfByFile(c *gin.Context) {
var req dto.MysqlConfUpdateByFile
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -171,7 +194,8 @@ func (b *BaseApi) UpdateMysqlConfByFile(c *gin.Context) {
// @Router /databases/search [post]
func (b *BaseApi) SearchMysql(c *gin.Context) {
var req dto.MysqlDBSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -214,10 +238,14 @@ func (b *BaseApi) ListDBName(c *gin.Context) {
// @Router /databases/load [post]
func (b *BaseApi) LoadDBFromRemote(c *gin.Context) {
var req dto.MysqlLoadDB
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := mysqlService.LoadFromRemote(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -236,7 +264,12 @@ func (b *BaseApi) LoadDBFromRemote(c *gin.Context) {
// @Router /databases/del/check [post]
func (b *BaseApi) DeleteCheckMysql(c *gin.Context) {
var req dto.MysqlDBDeleteCheck
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -259,7 +292,12 @@ func (b *BaseApi) DeleteCheckMysql(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mysqls","output_column":"name","output_value":"name"}],"formatZH":"删除 mysql 数据库 [name]","formatEN":"delete mysql database [name]"}
func (b *BaseApi) DeleteMysql(c *gin.Context) {
var req dto.MysqlDBDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -283,10 +321,10 @@ func (b *BaseApi) DeleteMysql(c *gin.Context) {
// @Router /databases/baseinfo [post]
func (b *BaseApi) LoadBaseinfo(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
data, err := mysqlService.LoadBaseInfo(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -306,10 +344,10 @@ func (b *BaseApi) LoadBaseinfo(c *gin.Context) {
// @Router /databases/load/file [post]
func (b *BaseApi) LoadDatabaseFile(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
content, err := mysqlService.LoadDatabaseFile(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -328,10 +366,10 @@ func (b *BaseApi) LoadDatabaseFile(c *gin.Context) {
// @Router /databases/remote [post]
func (b *BaseApi) LoadRemoteAccess(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
isRemote, err := mysqlService.LoadRemoteAccess(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -351,10 +389,10 @@ func (b *BaseApi) LoadRemoteAccess(c *gin.Context) {
// @Router /databases/status [post]
func (b *BaseApi) LoadStatus(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
data, err := mysqlService.LoadStatus(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -374,10 +412,10 @@ func (b *BaseApi) LoadStatus(c *gin.Context) {
// @Router /databases/variables [post]
func (b *BaseApi) LoadVariables(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
data, err := mysqlService.LoadVariables(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
+23 -9
View File
@@ -9,6 +9,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/compose"
"github.com/gin-gonic/gin"
)
@@ -72,10 +73,14 @@ func (b *BaseApi) LoadPersistenceConf(c *gin.Context) {
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 redis 数据库配置信息","formatEN":"update the redis database configuration information"}
func (b *BaseApi) UpdateRedisConf(c *gin.Context) {
var req dto.RedisConfUpdate
if err := helper.CheckBind(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := redisService.UpdateConf(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -94,10 +99,14 @@ func (b *BaseApi) UpdateRedisConf(c *gin.Context) {
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改 redis 数据库密码","formatEN":"change the password of the redis database"}
func (b *BaseApi) ChangeRedisPassword(c *gin.Context) {
var req dto.ChangeRedisPass
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if len(req.Value) != 0 {
value, err := base64.StdEncoding.DecodeString(req.Value)
if err != nil {
@@ -125,10 +134,14 @@ func (b *BaseApi) ChangeRedisPassword(c *gin.Context) {
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"redis 数据库持久化配置更新","formatEN":"redis database persistence configuration update"}
func (b *BaseApi) UpdateRedisPersistenceConf(c *gin.Context) {
var req dto.RedisConfPersistenceUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := redisService.UpdatePersistenceConf(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -146,7 +159,8 @@ func (b *BaseApi) UpdateRedisPersistenceConf(c *gin.Context) {
// @Router /databases/redis/backup/search [post]
func (b *BaseApi) RedisBackupList(c *gin.Context) {
var req dto.PageInfo
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -173,10 +187,10 @@ func (b *BaseApi) RedisBackupList(c *gin.Context) {
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 redis 数据库配置信息","formatEN":"update the redis database configuration information"}
func (b *BaseApi) UpdateRedisConfByFile(c *gin.Context) {
var req dto.RedisConfUpdateByFile
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
redisInfo, err := redisService.LoadConf()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
+17 -4
View File
@@ -6,6 +6,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
@@ -64,7 +65,8 @@ func (b *BaseApi) LoadDaemonJson(c *gin.Context) {
// @x-panel-log {"bodyKeys":["key", "value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 docker daemon.json 配置 [key]=>[value]","formatEN":"Updated the docker daemon.json configuration [key]=>[value]"}
func (b *BaseApi) UpdateDaemonJson(c *gin.Context) {
var req dto.SettingUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -87,7 +89,8 @@ func (b *BaseApi) UpdateDaemonJson(c *gin.Context) {
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 docker daemon.json 日志配置","formatEN":"Updated the docker daemon.json log option"}
func (b *BaseApi) UpdateLogOption(c *gin.Context) {
var req dto.LogOption
if err := helper.CheckBind(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -110,7 +113,12 @@ func (b *BaseApi) UpdateLogOption(c *gin.Context) {
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 docker daemon.json 配置","formatEN":"Updated the docker daemon.json configuration"}
func (b *BaseApi) UpdateDaemonJsonByFile(c *gin.Context) {
var req dto.DaemonJsonUpdateByFile
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -133,7 +141,12 @@ func (b *BaseApi) UpdateDaemonJsonByFile(c *gin.Context) {
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"docker 服务 [operation]","formatEN":"[operation] docker service"}
func (b *BaseApi) OperateDocker(c *gin.Context) {
var req dto.DockerOperation
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
-3
View File
@@ -53,7 +53,4 @@ var (
processService = service.NewIProcessService()
hostToolService = service.NewIHostToolService()
recycleBinService = service.NewIRecycleBinService()
favoriteService = service.NewIFavoriteService()
)
-76
View File
@@ -1,76 +0,0 @@
package v1
import (
"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/request"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/gin-gonic/gin"
)
// @Tags File
// @Summary List favorites
// @Description 获取收藏列表
// @Accept json
// @Param request body dto.PageInfo true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /files/favorite/search [post]
func (b *BaseApi) SearchFavorite(c *gin.Context) {
var req dto.PageInfo
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := favoriteService.Page(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Total: total,
Items: list,
})
}
// @Tags File
// @Summary Create favorite
// @Description 创建收藏
// @Accept json
// @Param request body request.FavoriteCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /files/favorite [post]
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"收藏文件/文件夹 [path]","formatEN":"收藏文件/文件夹 [path]"}
func (b *BaseApi) CreateFavorite(c *gin.Context) {
var req request.FavoriteCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
favorite, err := favoriteService.Create(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, favorite)
}
// @Tags File
// @Summary Delete favorite
// @Description 删除收藏
// @Accept json
// @Param request body request.FavoriteDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /files/favorite/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"favorites","output_column":"path","output_value":"path"}],"formatZH":"删除收藏 [path]","formatEN":"delete avorite [path]"}
func (b *BaseApi) DeleteFavorite(c *gin.Context) {
var req request.FavoriteDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := favoriteService.Delete(req.ID); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithOutData(c)
}
+55 -71
View File
@@ -35,7 +35,8 @@ import (
// @Router /files/search [post]
func (b *BaseApi) ListFiles(c *gin.Context) {
var req request.FileOption
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
files, err := fileService.GetFileList(req)
@@ -56,7 +57,12 @@ func (b *BaseApi) ListFiles(c *gin.Context) {
// @Router /files/upload/search [post]
func (b *BaseApi) SearchUploadWithPage(c *gin.Context) {
var req request.SearchUploadWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
total, files, err := fileService.SearchUploadWithPage(req)
@@ -80,7 +86,8 @@ func (b *BaseApi) SearchUploadWithPage(c *gin.Context) {
// @Router /files/tree [post]
func (b *BaseApi) GetFileTree(c *gin.Context) {
var req request.FileOption
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
tree, err := fileService.GetFileTree(req)
@@ -102,7 +109,8 @@ func (b *BaseApi) GetFileTree(c *gin.Context) {
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建文件/文件夹 [path]","formatEN":"Create dir or file [path]"}
func (b *BaseApi) CreateFile(c *gin.Context) {
var req request.FileCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
err := fileService.Create(req)
@@ -124,7 +132,8 @@ func (b *BaseApi) CreateFile(c *gin.Context) {
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除文件/文件夹 [path]","formatEN":"Delete dir or file [path]"}
func (b *BaseApi) DeleteFile(c *gin.Context) {
var req request.FileDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
err := fileService.Delete(req)
@@ -146,7 +155,8 @@ func (b *BaseApi) DeleteFile(c *gin.Context) {
// @x-panel-log {"bodyKeys":["paths"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"批量删除文件/文件夹 [paths]","formatEN":"Batch delete dir or file [paths]"}
func (b *BaseApi) BatchDeleteFile(c *gin.Context) {
var req request.FileBatchDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
err := fileService.BatchDelete(req)
@@ -168,7 +178,8 @@ func (b *BaseApi) BatchDeleteFile(c *gin.Context) {
// @x-panel-log {"bodyKeys":["path","mode"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改权限 [paths] => [mode]","formatEN":"Change mode [paths] => [mode]"}
func (b *BaseApi) ChangeFileMode(c *gin.Context) {
var req request.FileCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
err := fileService.ChangeMode(req)
@@ -190,7 +201,8 @@ func (b *BaseApi) ChangeFileMode(c *gin.Context) {
// @x-panel-log {"bodyKeys":["path","user","group"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改用户/组 [paths] => [user]/[group]","formatEN":"Change owner [paths] => [user]/[group]"}
func (b *BaseApi) ChangeFileOwner(c *gin.Context) {
var req request.FileRoleUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := fileService.ChangeOwner(req); err != nil {
@@ -211,7 +223,8 @@ func (b *BaseApi) ChangeFileOwner(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"压缩文件 [name]","formatEN":"Compress file [name]"}
func (b *BaseApi) CompressFile(c *gin.Context) {
var req request.FileCompress
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
err := fileService.Compress(req)
@@ -233,7 +246,8 @@ func (b *BaseApi) CompressFile(c *gin.Context) {
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"解压 [path]","formatEN":"Decompress file [path]"}
func (b *BaseApi) DeCompressFile(c *gin.Context) {
var req request.FileDeCompress
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
err := fileService.DeCompress(req)
@@ -248,14 +262,15 @@ func (b *BaseApi) DeCompressFile(c *gin.Context) {
// @Summary Load file content
// @Description 获取文件内容
// @Accept json
// @Param request body request.FileContentReq true "request"
// @Param request body request.FileOption true "request"
// @Success 200 {object} response.FileInfo
// @Security ApiKeyAuth
// @Router /files/content [post]
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"获取文件内容 [path]","formatEN":"Load file content [path]"}
func (b *BaseApi) GetContent(c *gin.Context) {
var req request.FileContentReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
var req request.FileOption
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
info, err := fileService.GetContent(req)
@@ -277,7 +292,8 @@ func (b *BaseApi) GetContent(c *gin.Context) {
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新文件内容 [path]","formatEN":"Update file content [path]"}
func (b *BaseApi) SaveContent(c *gin.Context) {
var req request.FileEdit
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := fileService.SaveContent(req); err != nil {
@@ -340,16 +356,24 @@ func (b *BaseApi) UploadFiles(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /files/check [post]
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"检测文件 [path] 是否存在","formatEN":"Check whether file [path] exists"}
func (b *BaseApi) CheckFile(c *gin.Context) {
var req request.FilePathCheck
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if _, err := os.Stat(req.Path); err != nil {
helper.SuccessWithData(c, false)
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
helper.SuccessWithData(c, true)
if _, err := os.Stat(req.Path); err != nil && os.IsNotExist(err) {
helper.SuccessWithData(c, true)
return
}
helper.SuccessWithData(c, false)
}
// @Tags File
@@ -363,7 +387,8 @@ func (b *BaseApi) CheckFile(c *gin.Context) {
// @x-panel-log {"bodyKeys":["oldName","newName"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"重命名 [oldName] => [newName]","formatEN":"Rename [oldName] => [newName]"}
func (b *BaseApi) ChangeFileName(c *gin.Context) {
var req request.FileRename
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := fileService.ChangeName(req); err != nil {
@@ -384,7 +409,8 @@ func (b *BaseApi) ChangeFileName(c *gin.Context) {
// @x-panel-log {"bodyKeys":["url","path","name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"下载 url => [path]/[name]","formatEN":"Download url => [path]/[name]"}
func (b *BaseApi) WgetFile(c *gin.Context) {
var req request.FileWget
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
key, err := fileService.Wget(req)
@@ -408,7 +434,8 @@ func (b *BaseApi) WgetFile(c *gin.Context) {
// @x-panel-log {"bodyKeys":["oldPaths","newPath"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"移动文件 [oldPaths] => [newPath]","formatEN":"Move [oldPaths] => [newPath]"}
func (b *BaseApi) MoveFile(c *gin.Context) {
var req request.FileMove
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := fileService.MvFile(req); err != nil {
@@ -450,7 +477,8 @@ func (b *BaseApi) Download(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"下载文件 [name]","formatEN":"Download file [name]"}
func (b *BaseApi) DownloadChunkFiles(c *gin.Context) {
var req request.FileChunkDownload
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
fileOp := files.NewFileOp()
@@ -527,7 +555,8 @@ func (b *BaseApi) DownloadChunkFiles(c *gin.Context) {
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"获取文件夹大小 [path]","formatEN":"Load file size [path]"}
func (b *BaseApi) Size(c *gin.Context) {
var req request.DirSizeReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
res, err := fileService.DirSize(req)
@@ -539,13 +568,12 @@ func (b *BaseApi) Size(c *gin.Context) {
}
func mergeChunks(fileName string, fileDir string, dstDir string, chunkCount int) error {
op := files.NewFileOp()
dstDir = strings.TrimSpace(dstDir)
if _, err := os.Stat(dstDir); err != nil && os.IsNotExist(err) {
if err = op.CreateDir(dstDir, os.ModePerm); err != nil {
if _, err := os.Stat(path.Dir(dstDir)); err != nil && os.IsNotExist(err) {
if err = os.MkdirAll(path.Dir(dstDir), os.ModePerm); err != nil {
return err
}
}
targetFile, err := os.Create(filepath.Join(dstDir, fileName))
if err != nil {
return err
@@ -682,47 +710,3 @@ func (b *BaseApi) Keys(c *gin.Context) {
res.Keys = keys
helper.SuccessWithData(c, res)
}
// @Tags File
// @Summary Read file by Line
// @Description 按行读取文件
// @Param request body request.FileReadByLineReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /files/read [post]
func (b *BaseApi) ReadFileByLine(c *gin.Context) {
var req request.FileReadByLineReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
lines, end, err := files.ReadFileByLine(req.Path, req.Page, req.PageSize)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
}
res := response.FileLineContent{
End: end,
}
res.Path = req.Path
res.Content = strings.Join(lines, "\n")
helper.SuccessWithData(c, res)
}
// @Tags File
// @Summary Batch change file mode and owner
// @Description 批量修改文件权限和用户/组
// @Accept json
// @Param request body request.FileRoleReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /files/batch/role [post]
// @x-panel-log {"bodyKeys":["paths","mode","user","group"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"批量修改文件权限和用户/组 [paths] => [mode]/[user]/[group]","formatEN":"Batch change file mode and owner [paths] => [mode]/[user]/[group]"}
func (b *BaseApi) BatchChangeModeAndOwner(c *gin.Context) {
var req request.FileRoleReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := fileService.BatchChangeModeAndOwner(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
}
helper.SuccessWithOutData(c)
}
+50 -15
View File
@@ -4,6 +4,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
@@ -27,13 +28,18 @@ func (b *BaseApi) LoadFirewallBaseInfo(c *gin.Context) {
// @Summary Page firewall rules
// @Description 获取防火墙规则列表分页
// @Accept json
// @Param request body dto.RuleSearch true "request"
// @Param request body dto.SearchWithPage true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Router /hosts/firewall/search [post]
func (b *BaseApi) SearchFirewallRule(c *gin.Context) {
var req dto.RuleSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -60,7 +66,12 @@ func (b *BaseApi) SearchFirewallRule(c *gin.Context) {
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] 防火墙","formatEN":"[operation] firewall"}
func (b *BaseApi) OperateFirewall(c *gin.Context) {
var req dto.FirewallOperation
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -83,10 +94,14 @@ func (b *BaseApi) OperateFirewall(c *gin.Context) {
// @x-panel-log {"bodyKeys":["port","strategy"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"添加端口规则 [strategy] [port]","formatEN":"create port rules [strategy][port]"}
func (b *BaseApi) OperatePortRule(c *gin.Context) {
var req dto.PortRuleOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := firewallService.OperatePortRule(req, true); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -105,10 +120,14 @@ func (b *BaseApi) OperatePortRule(c *gin.Context) {
// @x-panel-log {"bodyKeys":["strategy","address"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"添加 ip 规则 [strategy] [address]","formatEN":"create address rules [strategy][address]"}
func (b *BaseApi) OperateIPRule(c *gin.Context) {
var req dto.AddrRuleOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := firewallService.OperateAddressRule(req, true); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -126,10 +145,14 @@ func (b *BaseApi) OperateIPRule(c *gin.Context) {
// @Router /hosts/firewall/batch [post]
func (b *BaseApi) BatchOperateRule(c *gin.Context) {
var req dto.BatchRuleOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := firewallService.BatchOperateRule(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -147,10 +170,14 @@ func (b *BaseApi) BatchOperateRule(c *gin.Context) {
// @Router /hosts/firewall/update/description [post]
func (b *BaseApi) UpdateFirewallDescription(c *gin.Context) {
var req dto.UpdateFirewallDescription
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := firewallService.UpdateDescription(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -168,10 +195,14 @@ func (b *BaseApi) UpdateFirewallDescription(c *gin.Context) {
// @Router /hosts/firewall/update/port [post]
func (b *BaseApi) UpdatePortRule(c *gin.Context) {
var req dto.PortRuleUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := firewallService.UpdatePortRule(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -189,10 +220,14 @@ func (b *BaseApi) UpdatePortRule(c *gin.Context) {
// @Router /hosts/firewall/update/addr [post]
func (b *BaseApi) UpdateAddrRule(c *gin.Context) {
var req dto.AddrRuleUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := firewallService.UpdateAddrRule(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
+25 -6
View File
@@ -4,6 +4,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
@@ -18,10 +19,14 @@ import (
// @x-panel-log {"bodyKeys":["name","type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建组 [name][type]","formatEN":"create group [name][type]"}
func (b *BaseApi) CreateGroup(c *gin.Context) {
var req dto.GroupCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := groupService.Create(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -40,7 +45,12 @@ func (b *BaseApi) CreateGroup(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"groups","output_column":"name","output_value":"name"},{"input_column":"id","input_value":"id","isList":false,"db":"groups","output_column":"type","output_value":"type"}],"formatZH":"删除组 [type][name]","formatEN":"delete group [type][name]"}
func (b *BaseApi) DeleteGroup(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -62,10 +72,14 @@ func (b *BaseApi) DeleteGroup(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name","type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新组 [name][type]","formatEN":"update group [name][type]"}
func (b *BaseApi) UpdateGroup(c *gin.Context) {
var req dto.GroupUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := groupService.Update(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -83,7 +97,12 @@ func (b *BaseApi) UpdateGroup(c *gin.Context) {
// @Router /groups/search [post]
func (b *BaseApi) ListGroup(c *gin.Context) {
var req dto.GroupSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
+1 -9
View File
@@ -115,7 +115,7 @@ func GetTxAndContext() (tx *gorm.DB, ctx context.Context) {
}
func CheckBindAndValidate(req interface{}, c *gin.Context) error {
if err := c.ShouldBindJSON(req); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return err
}
@@ -125,11 +125,3 @@ func CheckBindAndValidate(req interface{}, c *gin.Context) error {
}
return nil
}
func CheckBind(req interface{}, c *gin.Context) error {
if err := c.ShouldBindJSON(&req); err != nil {
ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return err
}
return nil
}
+35 -8
View File
@@ -4,6 +4,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
"github.com/gin-gonic/gin"
)
@@ -19,7 +20,12 @@ import (
// @x-panel-log {"bodyKeys":["name","addr"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建主机 [name][addr]","formatEN":"create host [name][addr]"}
func (b *BaseApi) CreateHost(c *gin.Context) {
var req dto.HostOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -41,7 +47,12 @@ func (b *BaseApi) CreateHost(c *gin.Context) {
// @Router /hosts/test/byinfo [post]
func (b *BaseApi) TestByInfo(c *gin.Context) {
var req dto.HostConnTest
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -78,7 +89,8 @@ func (b *BaseApi) TestByID(c *gin.Context) {
// @Router /hosts/tree [post]
func (b *BaseApi) HostTree(c *gin.Context) {
var req dto.SearchForTree
if err := helper.CheckBind(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -101,7 +113,8 @@ func (b *BaseApi) HostTree(c *gin.Context) {
// @Router /hosts/search [post]
func (b *BaseApi) SearchHost(c *gin.Context) {
var req dto.SearchHostWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -128,7 +141,12 @@ func (b *BaseApi) SearchHost(c *gin.Context) {
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"hosts","output_column":"addr","output_value":"addrs"}],"formatZH":"删除主机 [addrs]","formatEN":"delete host [addrs]"}
func (b *BaseApi) DeleteHost(c *gin.Context) {
var req dto.BatchDeleteReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -150,10 +168,14 @@ func (b *BaseApi) DeleteHost(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name","addr"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新主机信息 [name][addr]","formatEN":"update host [name][addr]"}
func (b *BaseApi) UpdateHost(c *gin.Context) {
var req dto.HostOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
var err error
if len(req.Password) != 0 && req.AuthMode == "password" {
req.Password, err = hostService.EncryptHost(req.Password)
@@ -216,7 +238,12 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id","group"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"hosts","output_column":"addr","output_value":"addr"}],"formatZH":"切换主机[addr]分组 => [group]","formatEN":"change host [addr] group => [group]"}
func (b *BaseApi) UpdateHostGroup(c *gin.Context) {
var req dto.ChangeHostGroup
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
+40 -7
View File
@@ -4,6 +4,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
@@ -17,7 +18,12 @@ import (
// @Router /host/tool [post]
func (b *BaseApi) GetToolStatus(c *gin.Context) {
var req request.HostToolReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -40,7 +46,12 @@ func (b *BaseApi) GetToolStatus(c *gin.Context) {
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 [type] 配置","formatEN":"create [type] config"}
func (b *BaseApi) InitToolConfig(c *gin.Context) {
var req request.HostToolCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -62,9 +73,15 @@ func (b *BaseApi) InitToolConfig(c *gin.Context) {
// @x-panel-log {"bodyKeys":["operate","type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] [type] ","formatEN":"[operate] [type]"}
func (b *BaseApi) OperateTool(c *gin.Context) {
var req request.HostToolReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
err := hostToolService.OperateTool(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -84,7 +101,12 @@ func (b *BaseApi) OperateTool(c *gin.Context) {
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] 主机工具配置文件 ","formatEN":"[operate] tool config"}
func (b *BaseApi) OperateToolConfig(c *gin.Context) {
var req request.HostToolConfig
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -106,7 +128,12 @@ func (b *BaseApi) OperateToolConfig(c *gin.Context) {
// @Router /host/tool/log [post]
func (b *BaseApi) GetToolLog(c *gin.Context) {
var req request.HostToolLogReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -129,7 +156,12 @@ func (b *BaseApi) GetToolLog(c *gin.Context) {
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] 守护进程 ","formatEN":"[operate] process"}
func (b *BaseApi) OperateProcess(c *gin.Context) {
var req request.SupervisorProcessConfig
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -168,7 +200,8 @@ func (b *BaseApi) GetProcess(c *gin.Context) {
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] Supervisor 进程文件 ","formatEN":"[operate] Supervisor Process Config file"}
func (b *BaseApi) GetProcessFile(c *gin.Context) {
var req request.SupervisorProcessFileReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
content, err := hostToolService.OperateSupervisorProcessFile(req)
+49 -8
View File
@@ -4,6 +4,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
@@ -18,7 +19,12 @@ import (
// @Router /containers/image/search [post]
func (b *BaseApi) SearchImage(c *gin.Context) {
var req dto.SearchWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -61,7 +67,12 @@ func (b *BaseApi) ListImage(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"构建镜像 [name]","formatEN":"build image [name]"}
func (b *BaseApi) ImageBuild(c *gin.Context) {
var req dto.ImageBuild
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -85,7 +96,12 @@ func (b *BaseApi) ImageBuild(c *gin.Context) {
// @x-panel-log {"bodyKeys":["repoID","imageName"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"repoID","isList":false,"db":"image_repos","output_column":"name","output_value":"reponame"}],"formatZH":"镜像拉取 [reponame][imageName]","formatEN":"image pull [reponame][imageName]"}
func (b *BaseApi) ImagePull(c *gin.Context) {
var req dto.ImagePull
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -109,7 +125,12 @@ func (b *BaseApi) ImagePull(c *gin.Context) {
// @x-panel-log {"bodyKeys":["repoID","tagName","name"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"repoID","isList":false,"db":"image_repos","output_column":"name","output_value":"reponame"}],"formatZH":"[tagName] 推送到 [reponame][name]","formatEN":"push [tagName] to [reponame][name]"}
func (b *BaseApi) ImagePush(c *gin.Context) {
var req dto.ImagePush
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -133,7 +154,12 @@ func (b *BaseApi) ImagePush(c *gin.Context) {
// @x-panel-log {"bodyKeys":["names"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"移除镜像 [names]","formatEN":"remove image [names]"}
func (b *BaseApi) ImageRemove(c *gin.Context) {
var req dto.BatchDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -156,7 +182,12 @@ func (b *BaseApi) ImageRemove(c *gin.Context) {
// @x-panel-log {"bodyKeys":["tagName","path","name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"保留 [tagName] 为 [path]/[name]","formatEN":"save [tagName] as [path]/[name]"}
func (b *BaseApi) ImageSave(c *gin.Context) {
var req dto.ImageSave
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -179,7 +210,12 @@ func (b *BaseApi) ImageSave(c *gin.Context) {
// @x-panel-log {"bodyKeys":["repoID","targetName"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"repoID","isList":false,"db":"image_repos","output_column":"name","output_value":"reponame"}],"formatZH":"tag 镜像 [reponame][targetName]","formatEN":"tag image [reponame][targetName]"}
func (b *BaseApi) ImageTag(c *gin.Context) {
var req dto.ImageTag
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -202,7 +238,12 @@ func (b *BaseApi) ImageTag(c *gin.Context) {
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"从 [path] 加载镜像","formatEN":"load image from [path]"}
func (b *BaseApi) ImageLoad(c *gin.Context) {
var req dto.ImageLoad
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
+31 -7
View File
@@ -4,6 +4,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
@@ -18,7 +19,12 @@ import (
// @Router /containers/repo/search [post]
func (b *BaseApi) SearchRepo(c *gin.Context) {
var req dto.SearchWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -62,10 +68,14 @@ func (b *BaseApi) ListRepo(c *gin.Context) {
// @Router /containers/repo/status [get]
func (b *BaseApi) CheckRepoStatus(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := imageRepoService.Login(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -85,10 +95,14 @@ func (b *BaseApi) CheckRepoStatus(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建镜像仓库 [name]","formatEN":"create image repo [name]"}
func (b *BaseApi) CreateRepo(c *gin.Context) {
var req dto.ImageRepoCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := imageRepoService.Create(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -108,7 +122,12 @@ func (b *BaseApi) CreateRepo(c *gin.Context) {
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"image_repos","output_column":"name","output_value":"names"}],"formatZH":"删除镜像仓库 [names]","formatEN":"delete image repo [names]"}
func (b *BaseApi) DeleteRepo(c *gin.Context) {
var req dto.ImageRepoDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -131,7 +150,12 @@ func (b *BaseApi) DeleteRepo(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"image_repos","output_column":"name","output_value":"name"}],"formatZH":"更新镜像仓库 [name]","formatEN":"update image repo information [name]"}
func (b *BaseApi) UpdateRepo(c *gin.Context) {
var req dto.ImageRepoUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
+13 -5
View File
@@ -4,6 +4,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
@@ -17,7 +18,8 @@ import (
// @Router /logs/login [post]
func (b *BaseApi) GetLoginLogs(c *gin.Context) {
var req dto.SearchLgLogWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -43,7 +45,8 @@ func (b *BaseApi) GetLoginLogs(c *gin.Context) {
// @Router /logs/operation [post]
func (b *BaseApi) GetOperationLogs(c *gin.Context) {
var req dto.SearchOpLogWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -70,7 +73,12 @@ func (b *BaseApi) GetOperationLogs(c *gin.Context) {
// @x-panel-log {"bodyKeys":["logType"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清空 [logType] 日志信息","formatEN":"Clean the [logType] log information"}
func (b *BaseApi) CleanLogs(c *gin.Context) {
var req dto.CleanLog
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -106,10 +114,10 @@ func (b *BaseApi) GetSystemFiles(c *gin.Context) {
// @Router /logs/system [post]
func (b *BaseApi) GetSystemLogs(c *gin.Context) {
var req dto.OperationWithName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
data, err := logService.LoadSystemLog(req.Name)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
+6 -2
View File
@@ -17,10 +17,14 @@ import (
func (b *BaseApi) LoadMonitor(c *gin.Context) {
var req dto.MonitorSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
loc, _ := time.LoadLocation(common.LoadTimeZone())
req.StartTime = req.StartTime.In(loc)
req.EndTime = req.EndTime.In(loc)
+6 -3
View File
@@ -32,7 +32,8 @@ func (b *BaseApi) GetNginx(c *gin.Context) {
// @Router /openResty/scope [post]
func (b *BaseApi) GetNginxConfigByScope(c *gin.Context) {
var req request.NginxScopeReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -55,7 +56,8 @@ func (b *BaseApi) GetNginxConfigByScope(c *gin.Context) {
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新 nginx 配置 [domain]","formatEN":"Update nginx conf [domain]"}
func (b *BaseApi) UpdateNginxConfigByScope(c *gin.Context) {
var req request.NginxConfigUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := nginxService.UpdateConfigByScope(req); err != nil {
@@ -91,7 +93,8 @@ func (b *BaseApi) GetNginxStatus(c *gin.Context) {
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 nginx 配置","formatEN":"Update nginx conf"}
func (b *BaseApi) UpdateNginxFile(c *gin.Context) {
var req request.NginxConfigFileUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
+2 -1
View File
@@ -28,7 +28,8 @@ func (b *BaseApi) ProcessWs(c *gin.Context) {
// @x-panel-log {"bodyKeys":["PID"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"结束进程 [PID]","formatEN":"结束进程 [PID]"}
func (b *BaseApi) StopProcess(c *gin.Context) {
var req request.ProcessReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := processService.StopProcess(req); err != nil {
-70
View File
@@ -1,70 +0,0 @@
package v1
import (
"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/request"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/gin-gonic/gin"
)
// @Tags File
// @Summary List RecycleBin files
// @Description 获取回收站文件列表
// @Accept json
// @Param request body dto.PageInfo true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /files/recycle/search [post]
func (b *BaseApi) SearchRecycleBinFile(c *gin.Context) {
var req dto.PageInfo
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := recycleBinService.Page(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags File
// @Summary Reduce RecycleBin files
// @Description 还原回收站文件
// @Accept json
// @Param request body request.RecycleBinReduce true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /files/recycle/reduce [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"还原回收站文件 [name]","formatEN":"Reduce RecycleBin file [name]"}
func (b *BaseApi) ReduceRecycleBinFile(c *gin.Context) {
var req request.RecycleBinReduce
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := recycleBinService.Reduce(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithOutData(c)
}
// @Tags File
// @Summary Clear RecycleBin files
// @Description 清空回收站文件
// @Accept json
// @Success 200
// @Security ApiKeyAuth
// @Router /files/recycle/clear [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清空回收站","formatEN":"清空回收站"}
func (b *BaseApi) ClearRecycleBinFile(c *gin.Context) {
if err := recycleBinService.Clear(); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithOutData(c)
}
+38 -50
View File
@@ -49,7 +49,12 @@ func (b *BaseApi) GetSystemAvailable(c *gin.Context) {
// @x-panel-log {"bodyKeys":["key","value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统配置 [key] => [value]","formatEN":"update system setting [key] => [value]"}
func (b *BaseApi) UpdateSetting(c *gin.Context) {
var req dto.SettingUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -71,7 +76,12 @@ func (b *BaseApi) UpdateSetting(c *gin.Context) {
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统密码","formatEN":"update system password"}
func (b *BaseApi) UpdatePassword(c *gin.Context) {
var req dto.PasswordUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -93,7 +103,12 @@ func (b *BaseApi) UpdatePassword(c *gin.Context) {
// @x-panel-log {"bodyKeys":["ssl"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统 ssl => [ssl]","formatEN":"update system ssl => [ssl]"}
func (b *BaseApi) UpdateSSL(c *gin.Context) {
var req dto.SSLUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -135,44 +150,6 @@ func (b *BaseApi) DownloadSSL(c *gin.Context) {
c.File(pathItem)
}
// @Tags System Setting
// @Summary Load system address
// @Description 获取系统地址信息
// @Accept json
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/interface [get]
func (b *BaseApi) LoadInterfaceAddr(c *gin.Context) {
data, err := settingService.LoadInterfaceAddr()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags System Setting
// @Summary Update system bind info
// @Description 更新系统监听信息
// @Accept json
// @Param request body dto.BindInfo true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/bind/update [post]
// @x-panel-log {"bodyKeys":["ipv6", "bindAddress"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统监听信息 => ipv6: [ipv6], 监听 IP: [bindAddress]","formatEN":"update system bind info => ipv6: [ipv6], 监听 IP: [bindAddress]"}
func (b *BaseApi) UpdateBindInfo(c *gin.Context) {
var req dto.BindInfo
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := settingService.UpdateBindInfo(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags System Setting
// @Summary Update system port
// @Description 更新系统端口
@@ -184,7 +161,12 @@ func (b *BaseApi) UpdateBindInfo(c *gin.Context) {
// @x-panel-log {"bodyKeys":["serverPort"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统端口 => [serverPort]","formatEN":"update system port => [serverPort]"}
func (b *BaseApi) UpdatePort(c *gin.Context) {
var req dto.PortUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -206,7 +188,12 @@ func (b *BaseApi) UpdatePort(c *gin.Context) {
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"重置过期密码","formatEN":"reset an expired Password"}
func (b *BaseApi) HandlePasswordExpired(c *gin.Context) {
var req dto.PasswordUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -243,10 +230,10 @@ func (b *BaseApi) LoadTimeZone(c *gin.Context) {
// @x-panel-log {"bodyKeys":["ntpSite"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"系统时间同步[ntpSite]","formatEN":"sync system time [ntpSite]"}
func (b *BaseApi) SyncTime(c *gin.Context) {
var req dto.SyncTime
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := settingService.SyncTime(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -310,10 +297,10 @@ func (b *BaseApi) ScanSystem(c *gin.Context) {
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清理系统垃圾文件","formatEN":"Clean system junk files"}
func (b *BaseApi) SystemClean(c *gin.Context) {
var req []dto.Clean
if err := helper.CheckBind(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
settingService.SystemClean(req)
helper.SuccessWithData(c, nil)
@@ -329,7 +316,8 @@ func (b *BaseApi) SystemClean(c *gin.Context) {
// @Router /settings/mfa [post]
func (b *BaseApi) LoadMFA(c *gin.Context) {
var req dto.MfaRequest
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -353,10 +341,10 @@ func (b *BaseApi) LoadMFA(c *gin.Context) {
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"mfa 绑定","formatEN":"bind mfa"}
func (b *BaseApi) MFABind(c *gin.Context) {
var req dto.MfaCredential
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
success := mfa.ValidCode(req.Code, req.Interval, req.Secret)
if !success {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, errors.New("code is not valid"))
+45 -13
View File
@@ -4,6 +4,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
@@ -18,10 +19,14 @@ import (
// @x-panel-log {"bodyKeys":["from", "description"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建系统快照 [description] 到 [from]","formatEN":"Create system backup [description] to [from]"}
func (b *BaseApi) CreateSnapshot(c *gin.Context) {
var req dto.SnapshotCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := snapshotService.SnapshotCreate(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -40,10 +45,14 @@ func (b *BaseApi) CreateSnapshot(c *gin.Context) {
// @x-panel-log {"bodyKeys":["from", "names"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"从 [from] 同步系统快照 [names]","formatEN":"Sync system snapshots [names] from [from]"}
func (b *BaseApi) ImportSnapshot(c *gin.Context) {
var req dto.SnapshotImport
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := snapshotService.SnapshotImport(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -61,10 +70,14 @@ func (b *BaseApi) ImportSnapshot(c *gin.Context) {
// @Router /settings/snapshot/status [post]
func (b *BaseApi) LoadSnapShotStatus(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
data, err := snapshotService.LoadSnapShotStatus(req.ID)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -84,10 +97,14 @@ func (b *BaseApi) LoadSnapShotStatus(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"snapshots","output_column":"name","output_value":"name"}],"formatZH":"快照 [name] 描述信息修改 [description]","formatEN":"The description of the snapshot [name] is modified => [description]"}
func (b *BaseApi) UpdateSnapDescription(c *gin.Context) {
var req dto.UpdateDescription
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := snapshotService.UpdateDescription(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -105,10 +122,10 @@ func (b *BaseApi) UpdateSnapDescription(c *gin.Context) {
// @Router /settings/snapshot/search [post]
func (b *BaseApi) SearchSnapshot(c *gin.Context) {
var req dto.SearchWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
total, accounts, err := snapshotService.SearchWithPage(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -131,7 +148,12 @@ func (b *BaseApi) SearchSnapshot(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"snapshots","output_column":"name","output_value":"name"}],"formatZH":"从系统快照 [name] 恢复","formatEN":"Recover from system backup [name]"}
func (b *BaseApi) RecoverSnapshot(c *gin.Context) {
var req dto.SnapshotRecover
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -153,7 +175,12 @@ func (b *BaseApi) RecoverSnapshot(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"snapshots","output_column":"name","output_value":"name"}],"formatZH":"从系统快照 [name] 回滚","formatEN":"Rollback from system backup [name]"}
func (b *BaseApi) RollbackSnapshot(c *gin.Context) {
var req dto.SnapshotRecover
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -175,7 +202,12 @@ func (b *BaseApi) RollbackSnapshot(c *gin.Context) {
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"snapshots","output_column":"name","output_value":"name"}],"formatZH":"删除系统快照 [name]","formatEN":"Delete system backup [name]"}
func (b *BaseApi) DeleteSnapshot(c *gin.Context) {
var req dto.BatchDeleteReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
+46 -10
View File
@@ -4,6 +4,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
@@ -32,7 +33,12 @@ func (b *BaseApi) GetSSHInfo(c *gin.Context) {
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] SSH ","formatEN":"[operation] SSH"}
func (b *BaseApi) OperateSSH(c *gin.Context) {
var req dto.Operate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -47,18 +53,23 @@ func (b *BaseApi) OperateSSH(c *gin.Context) {
// @Summary Update host SSH setting
// @Description 更新 SSH 配置
// @Accept json
// @Param request body dto.SSHUpdate true "request"
// @Param request body dto.SettingUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /host/ssh/update [post]
// @x-panel-log {"bodyKeys":["key","value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改 SSH 配置 [key] => [value]","formatEN":"update SSH setting [key] => [value]"}
func (b *BaseApi) UpdateSSH(c *gin.Context) {
var req dto.SSHUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
var req dto.SettingUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := sshService.Update(req); err != nil {
if err := sshService.Update(req.Key, req.Value); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
@@ -76,7 +87,12 @@ func (b *BaseApi) UpdateSSH(c *gin.Context) {
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改 SSH 配置文件","formatEN":"update SSH conf"}
func (b *BaseApi) UpdateSSHByfile(c *gin.Context) {
var req dto.SSHConf
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -98,7 +114,12 @@ func (b *BaseApi) UpdateSSHByfile(c *gin.Context) {
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"生成 SSH 密钥 ","formatEN":"generate SSH secret"}
func (b *BaseApi) GenerateSSH(c *gin.Context) {
var req dto.GenerateSSH
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -119,7 +140,12 @@ func (b *BaseApi) GenerateSSH(c *gin.Context) {
// @Router /host/ssh/secret [post]
func (b *BaseApi) LoadSSHSecret(c *gin.Context) {
var req dto.GenerateLoad
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -141,7 +167,12 @@ func (b *BaseApi) LoadSSHSecret(c *gin.Context) {
// @Router /host/ssh/log/analysis [post]
func (b *BaseApi) AnalysisLog(c *gin.Context) {
var req dto.SearchForAnalysis
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
@@ -163,7 +194,12 @@ func (b *BaseApi) AnalysisLog(c *gin.Context) {
// @Router /host/ssh/log [post]
func (b *BaseApi) LoadSSHLogs(c *gin.Context) {
var req dto.SearchSSHLog
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
+4 -4
View File
@@ -32,10 +32,10 @@ func (b *BaseApi) GetUpgradeInfo(c *gin.Context) {
// @Router /settings/upgrade [get]
func (b *BaseApi) GetNotesByVersion(c *gin.Context) {
var req dto.Upgrade
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
notes, err := upgradeService.LoadNotes(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -55,10 +55,10 @@ func (b *BaseApi) GetNotesByVersion(c *gin.Context) {
// @x-panel-log {"bodyKeys":["version"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新系统 => [version]","formatEN":"upgrade service => [version]"}
func (b *BaseApi) Upgrade(c *gin.Context) {
var req dto.Upgrade
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := upgradeService.Upgrade(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
+136 -33
View File
@@ -18,7 +18,8 @@ import (
// @Router /websites/search [post]
func (b *BaseApi) PageWebsite(c *gin.Context) {
var req request.WebsiteSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
total, websites, err := websiteService.PageWebsite(req)
@@ -73,9 +74,11 @@ func (b *BaseApi) GetWebsiteOptions(c *gin.Context) {
// @x-panel-log {"bodyKeys":["primaryDomain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建网站 [primaryDomain]","formatEN":"Create website [primaryDomain]"}
func (b *BaseApi) CreateWebsite(c *gin.Context) {
var req request.WebsiteCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
err := websiteService.CreateWebsite(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -95,7 +98,8 @@ func (b *BaseApi) CreateWebsite(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"[operate] 网站 [domain]","formatEN":"[operate] website [domain]"}
func (b *BaseApi) OpWebsite(c *gin.Context) {
var req request.WebsiteOp
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
err := websiteService.OpWebsite(req)
@@ -117,9 +121,11 @@ func (b *BaseApi) OpWebsite(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"删除网站 [domain]","formatEN":"Delete website [domain]"}
func (b *BaseApi) DeleteWebsite(c *gin.Context) {
var req request.WebsiteDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
err := websiteService.DeleteWebsite(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -139,7 +145,8 @@ func (b *BaseApi) DeleteWebsite(c *gin.Context) {
// @x-panel-log {"bodyKeys":["primaryDomain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新网站 [primaryDomain]","formatEN":"Update website [primaryDomain]"}
func (b *BaseApi) UpdateWebsite(c *gin.Context) {
var req request.WebsiteUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateWebsite(req); err != nil {
@@ -195,6 +202,74 @@ func (b *BaseApi) GetWebsiteNginx(c *gin.Context) {
helper.SuccessWithData(c, fileInfo)
}
// @Tags Website Domain
// @Summary Search website domains by websiteId
// @Description 通过网站 id 查询域名
// @Accept json
// @Param websiteId path integer true "request"
// @Success 200 {array} model.WebsiteDomain
// @Security ApiKeyAuth
// @Router /websites/domains/:websiteId [get]
func (b *BaseApi) GetWebDomains(c *gin.Context) {
websiteId, err := helper.GetIntParamByKey(c, "websiteId")
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
return
}
list, err := websiteService.GetWebsiteDomain(websiteId)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Website Domain
// @Summary Delete website domain
// @Description 删除网站域名
// @Accept json
// @Param request body request.WebsiteDomainDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/domains/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_domains","output_column":"domain","output_value":"domain"}],"formatZH":"删除域名 [domain]","formatEN":"Delete domain [domain]"}
func (b *BaseApi) DeleteWebDomain(c *gin.Context) {
var req request.WebsiteDomainDelete
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.DeleteWebsiteDomain(req.ID); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Website Domain
// @Summary Create website domain
// @Description 创建网站域名
// @Accept json
// @Param request body request.WebsiteDomainCreate true "request"
// @Success 200 {object} model.WebsiteDomain
// @Security ApiKeyAuth
// @Router /websites/domains [post]
// @x-panel-log {"bodyKeys":["domain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建域名 [domain]","formatEN":"Create domain [domain]"}
func (b *BaseApi) CreateWebDomain(c *gin.Context) {
var req request.WebsiteDomainCreate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
domain, err := websiteService.CreateWebsiteDomain(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, domain)
}
// @Tags Website Nginx
// @Summary Load nginx conf
// @Description 获取 nginx 配置
@@ -205,7 +280,8 @@ func (b *BaseApi) GetWebsiteNginx(c *gin.Context) {
// @Router /websites/config [post]
func (b *BaseApi) GetNginxConfig(c *gin.Context) {
var req request.NginxScopeReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
config, err := websiteService.GetNginxConfigByScope(req)
@@ -227,7 +303,8 @@ func (b *BaseApi) GetNginxConfig(c *gin.Context) {
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"nginx 配置修改 [domain]","formatEN":"Nginx conf update [domain]"}
func (b *BaseApi) UpdateNginxConfig(c *gin.Context) {
var req request.NginxConfigUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateNginxConfigByScope(req); err != nil {
@@ -270,7 +347,8 @@ func (b *BaseApi) GetHTTPSConfig(c *gin.Context) {
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新网站 [domain] https 配置","formatEN":"Update website https [domain] conf"}
func (b *BaseApi) UpdateHTTPSConfig(c *gin.Context) {
var req request.WebsiteHTTPSOp
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
tx, ctx := helper.GetTxAndContext()
@@ -294,7 +372,8 @@ func (b *BaseApi) UpdateHTTPSConfig(c *gin.Context) {
// @Router /websites/check [post]
func (b *BaseApi) CreateWebsiteCheck(c *gin.Context) {
var req request.WebsiteInstallCheckReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
data, err := websiteService.PreInstallCheck(req)
@@ -315,7 +394,8 @@ func (b *BaseApi) CreateWebsiteCheck(c *gin.Context) {
// @Router /websites/waf/config [post]
func (b *BaseApi) GetWebsiteWafConfig(c *gin.Context) {
var req request.WebsiteWafReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
data, err := websiteService.GetWafConfig(req)
@@ -337,7 +417,8 @@ func (b *BaseApi) GetWebsiteWafConfig(c *gin.Context) {
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"WAF 配置修改 [domain]","formatEN":"WAF conf update [domain]"}
func (b *BaseApi) UpdateWebsiteWafConfig(c *gin.Context) {
var req request.WebsiteWafUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateWafConfig(req); err != nil {
@@ -358,7 +439,8 @@ func (b *BaseApi) UpdateWebsiteWafConfig(c *gin.Context) {
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"WAF 配置文件修改 [domain]","formatEN":"WAF conf file update [domain]"}
func (b *BaseApi) UpdateWebsiteWafFile(c *gin.Context) {
var req request.WebsiteWafFileUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateWafFile(req); err != nil {
@@ -379,7 +461,8 @@ func (b *BaseApi) UpdateWebsiteWafFile(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"[domain] Nginx 配置修改","formatEN":"[domain] Nginx conf update"}
func (b *BaseApi) UpdateWebsiteNginxConfig(c *gin.Context) {
var req request.WebsiteNginxUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateNginxConfigFile(req); err != nil {
@@ -400,7 +483,8 @@ func (b *BaseApi) UpdateWebsiteNginxConfig(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"[domain][operate] 日志","formatEN":"[domain][operate] logs"}
func (b *BaseApi) OpWebsiteLog(c *gin.Context) {
var req request.WebsiteLogReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
res, err := websiteService.OpWebsiteLog(req)
@@ -422,7 +506,8 @@ func (b *BaseApi) OpWebsiteLog(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"修改默认 server => [domain]","formatEN":"Change default server => [domain]"}
func (b *BaseApi) ChangeDefaultServer(c *gin.Context) {
var req request.WebsiteDefaultUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.ChangeDefaultServer(req.ID); err != nil {
@@ -465,7 +550,8 @@ func (b *BaseApi) GetWebsitePHPConfig(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"[domain] PHP 配置修改","formatEN":"[domain] PHP conf update"}
func (b *BaseApi) UpdateWebsitePHPConfig(c *gin.Context) {
var req request.WebsitePHPConfigUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdatePHPConfig(req); err != nil {
@@ -486,7 +572,8 @@ func (b *BaseApi) UpdateWebsitePHPConfig(c *gin.Context) {
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"php 配置修改 [domain]","formatEN":"Nginx conf update [domain]"}
func (b *BaseApi) UpdatePHPFile(c *gin.Context) {
var req request.WebsitePHPFileUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdatePHPConfigFile(req); err != nil {
@@ -507,7 +594,8 @@ func (b *BaseApi) UpdatePHPFile(c *gin.Context) {
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"php 版本变更 [domain]","formatEN":"php version update [domain]"}
func (b *BaseApi) ChangePHPVersion(c *gin.Context) {
var req request.WebsitePHPVersionReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.ChangePHPVersion(req); err != nil {
@@ -527,7 +615,8 @@ func (b *BaseApi) ChangePHPVersion(c *gin.Context) {
// @Router /websites/rewrite [post]
func (b *BaseApi) GetRewriteConfig(c *gin.Context) {
var req request.NginxRewriteReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
res, err := websiteService.GetRewriteConfig(req)
@@ -549,7 +638,8 @@ func (b *BaseApi) GetRewriteConfig(c *gin.Context) {
// @x-panel-log {"bodyKeys":["websiteID"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteID","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"伪静态配置修改 [domain]","formatEN":"Nginx conf rewrite update [domain]"}
func (b *BaseApi) UpdateRewriteConfig(c *gin.Context) {
var req request.NginxRewriteUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateRewriteConfig(req); err != nil {
@@ -570,7 +660,8 @@ func (b *BaseApi) UpdateRewriteConfig(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新网站 [domain] 目录","formatEN":"Update domain [domain] dir"}
func (b *BaseApi) UpdateSiteDir(c *gin.Context) {
var req request.WebsiteUpdateDir
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateSiteDir(req); err != nil {
@@ -591,7 +682,8 @@ func (b *BaseApi) UpdateSiteDir(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新网站 [domain] 目录权限","formatEN":"Update domain [domain] dir permission"}
func (b *BaseApi) UpdateSiteDirPermission(c *gin.Context) {
var req request.WebsiteUpdateDirPermission
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateSitePermission(req); err != nil {
@@ -611,7 +703,8 @@ func (b *BaseApi) UpdateSiteDirPermission(c *gin.Context) {
// @Router /websites/proxies [post]
func (b *BaseApi) GetProxyConfig(c *gin.Context) {
var req request.WebsiteProxyReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
res, err := websiteService.GetProxies(req.ID)
@@ -633,7 +726,8 @@ func (b *BaseApi) GetProxyConfig(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"修改网站 [domain] 反向代理配置 ","formatEN":"Update domain [domain] proxy config"}
func (b *BaseApi) UpdateProxyConfig(c *gin.Context) {
var req request.WebsiteProxyConfig
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
err := websiteService.OperateProxy(req)
@@ -655,7 +749,8 @@ func (b *BaseApi) UpdateProxyConfig(c *gin.Context) {
// @x-panel-log {"bodyKeys":["websiteID"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteID","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新反向代理文件 [domain]","formatEN":"Nginx conf proxy file update [domain]"}
func (b *BaseApi) UpdateProxyConfigFile(c *gin.Context) {
var req request.NginxProxyUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateProxyFile(req); err != nil {
@@ -675,7 +770,8 @@ func (b *BaseApi) UpdateProxyConfigFile(c *gin.Context) {
// @Router /websites/auths [post]
func (b *BaseApi) GetAuthConfig(c *gin.Context) {
var req request.NginxAuthReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
res, err := websiteService.GetAuthBasics(req)
@@ -696,7 +792,8 @@ func (b *BaseApi) GetAuthConfig(c *gin.Context) {
// @Router /websites/auths/update [post]
func (b *BaseApi) UpdateAuthConfig(c *gin.Context) {
var req request.NginxAuthUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateAuthBasic(req); err != nil {
@@ -716,7 +813,8 @@ func (b *BaseApi) UpdateAuthConfig(c *gin.Context) {
// @Router /websites/leech [post]
func (b *BaseApi) GetAntiLeech(c *gin.Context) {
var req request.NginxCommonReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
res, err := websiteService.GetAntiLeech(req.WebsiteID)
@@ -737,7 +835,8 @@ func (b *BaseApi) GetAntiLeech(c *gin.Context) {
// @Router /websites/leech/update [post]
func (b *BaseApi) UpdateAntiLeech(c *gin.Context) {
var req request.NginxAntiLeechUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateAntiLeech(req); err != nil {
@@ -758,7 +857,8 @@ func (b *BaseApi) UpdateAntiLeech(c *gin.Context) {
// @x-panel-log {"bodyKeys":["websiteID"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteID","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"修改网站 [domain] 重定向理配置 ","formatEN":"Update domain [domain] redirect config"}
func (b *BaseApi) UpdateRedirectConfig(c *gin.Context) {
var req request.NginxRedirectReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
err := websiteService.OperateRedirect(req)
@@ -779,7 +879,8 @@ func (b *BaseApi) UpdateRedirectConfig(c *gin.Context) {
// @Router /websites/redirect [post]
func (b *BaseApi) GetRedirectConfig(c *gin.Context) {
var req request.WebsiteRedirectReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
res, err := websiteService.GetRedirect(req.WebsiteID)
@@ -801,7 +902,8 @@ func (b *BaseApi) GetRedirectConfig(c *gin.Context) {
// @x-panel-log {"bodyKeys":["websiteID"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteID","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新重定向文件 [domain]","formatEN":"Nginx conf redirect file update [domain]"}
func (b *BaseApi) UpdateRedirectConfigFile(c *gin.Context) {
var req request.NginxRedirectUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateRedirectFile(req); err != nil {
@@ -821,7 +923,8 @@ func (b *BaseApi) UpdateRedirectConfigFile(c *gin.Context) {
// @Router /websites/dir [post]
func (b *BaseApi) GetDirConfig(c *gin.Context) {
var req request.WebsiteCommonReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
res, err := websiteService.LoadWebsiteDirConfig(req)
+6 -3
View File
@@ -18,7 +18,8 @@ import (
// @Router /websites/acme/search [post]
func (b *BaseApi) PageWebsiteAcmeAccount(c *gin.Context) {
var req dto.PageInfo
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
total, accounts, err := websiteAcmeAccountService.Page(req)
@@ -43,7 +44,8 @@ func (b *BaseApi) PageWebsiteAcmeAccount(c *gin.Context) {
// @x-panel-log {"bodyKeys":["email"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建网站 acme [email]","formatEN":"Create website acme [email]"}
func (b *BaseApi) CreateWebsiteAcmeAccount(c *gin.Context) {
var req request.WebsiteAcmeAccountCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
res, err := websiteAcmeAccountService.Create(req)
@@ -65,7 +67,8 @@ func (b *BaseApi) CreateWebsiteAcmeAccount(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_acme_accounts","output_column":"email","output_value":"email"}],"formatZH":"删除网站 acme [email]","formatEN":"Delete website acme [email]"}
func (b *BaseApi) DeleteWebsiteAcmeAccount(c *gin.Context) {
var req request.WebsiteResourceReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteAcmeAccountService.Delete(req.ID); err != nil {
+9 -4
View File
@@ -18,7 +18,8 @@ import (
// @Router /websites/dns/search [post]
func (b *BaseApi) PageWebsiteDnsAccount(c *gin.Context) {
var req dto.PageInfo
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
total, accounts, err := websiteDnsAccountService.Page(req)
@@ -43,7 +44,8 @@ func (b *BaseApi) PageWebsiteDnsAccount(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建网站 dns [name]","formatEN":"Create website dns [name]"}
func (b *BaseApi) CreateWebsiteDnsAccount(c *gin.Context) {
var req request.WebsiteDnsAccountCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if _, err := websiteDnsAccountService.Create(req); err != nil {
@@ -64,7 +66,8 @@ func (b *BaseApi) CreateWebsiteDnsAccount(c *gin.Context) {
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新网站 dns [name]","formatEN":"Update website dns [name]"}
func (b *BaseApi) UpdateWebsiteDnsAccount(c *gin.Context) {
var req request.WebsiteDnsAccountUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if _, err := websiteDnsAccountService.Update(req); err != nil {
@@ -85,9 +88,11 @@ func (b *BaseApi) UpdateWebsiteDnsAccount(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_dns_accounts","output_column":"name","output_value":"name"}],"formatZH":"删除网站 dns [name]","formatEN":"Delete website dns [name]"}
func (b *BaseApi) DeleteWebsiteDnsAccount(c *gin.Context) {
var req request.WebsiteResourceReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteDnsAccountService.Delete(req.ID); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
-73
View File
@@ -1,73 +0,0 @@
package v1
import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/gin-gonic/gin"
)
// @Tags Website Domain
// @Summary Delete website domain
// @Description 删除网站域名
// @Accept json
// @Param request body request.WebsiteDomainDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/domains/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_domains","output_column":"domain","output_value":"domain"}],"formatZH":"删除域名 [domain]","formatEN":"Delete domain [domain]"}
func (b *BaseApi) DeleteWebDomain(c *gin.Context) {
var req request.WebsiteDomainDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := websiteService.DeleteWebsiteDomain(req.ID); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Website Domain
// @Summary Create website domain
// @Description 创建网站域名
// @Accept json
// @Param request body request.WebsiteDomainCreate true "request"
// @Success 200 {object} model.WebsiteDomain
// @Security ApiKeyAuth
// @Router /websites/domains [post]
// @x-panel-log {"bodyKeys":["domain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建域名 [domain]","formatEN":"Create domain [domain]"}
func (b *BaseApi) CreateWebDomain(c *gin.Context) {
var req request.WebsiteDomainCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
domain, err := websiteService.CreateWebsiteDomain(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, domain)
}
// @Tags Website Domain
// @Summary Search website domains by websiteId
// @Description 通过网站 id 查询域名
// @Accept json
// @Param websiteId path integer true "request"
// @Success 200 {array} model.WebsiteDomain
// @Security ApiKeyAuth
// @Router /websites/domains/:websiteId [get]
func (b *BaseApi) GetWebDomains(c *gin.Context) {
websiteId, err := helper.GetIntParamByKey(c, "websiteId")
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
return
}
list, err := websiteService.GetWebsiteDomain(websiteId)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, list)
}
+12 -27
View File
@@ -20,7 +20,8 @@ import (
// @Router /websites/ssl/search [post]
func (b *BaseApi) PageWebsiteSSL(c *gin.Context) {
var req request.WebsiteSSLSearch
if err := helper.CheckBind(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if !reflect.DeepEqual(req.PageInfo, dto.PageInfo{}) {
@@ -54,7 +55,8 @@ func (b *BaseApi) PageWebsiteSSL(c *gin.Context) {
// @x-panel-log {"bodyKeys":["primaryDomain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建网站 ssl [primaryDomain]","formatEN":"Create website ssl [primaryDomain]"}
func (b *BaseApi) CreateWebsiteSSL(c *gin.Context) {
var req request.WebsiteSSLCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
res, err := websiteSSLService.Create(req)
@@ -76,7 +78,8 @@ func (b *BaseApi) CreateWebsiteSSL(c *gin.Context) {
// @x-panel-log {"bodyKeys":["SSLId"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"SSLId","isList":false,"db":"website_ssls","output_column":"primary_domain","output_value":"domain"}],"formatZH":"重置 ssl [domain]","formatEN":"Renew ssl [domain]"}
func (b *BaseApi) RenewWebsiteSSL(c *gin.Context) {
var req request.WebsiteSSLRenew
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteSSLService.Renew(req.SSLID); err != nil {
@@ -96,7 +99,8 @@ func (b *BaseApi) RenewWebsiteSSL(c *gin.Context) {
// @Router /websites/ssl/resolve [post]
func (b *BaseApi) GetDNSResolve(c *gin.Context) {
var req request.WebsiteDNSReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
res, err := websiteSSLService.GetDNSResolve(req)
@@ -118,7 +122,8 @@ func (b *BaseApi) GetDNSResolve(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_ssls","output_column":"primary_domain","output_value":"domain"}],"formatZH":"删除 ssl [domain]","formatEN":"Delete ssl [domain]"}
func (b *BaseApi) DeleteWebsiteSSL(c *gin.Context) {
var req request.WebsiteResourceReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteSSLService.Delete(req.ID); err != nil {
@@ -183,7 +188,8 @@ func (b *BaseApi) GetWebsiteSSLById(c *gin.Context) {
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_ssls","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新证书设置 [domain]","formatEN":"Update ssl config [domain]"}
func (b *BaseApi) UpdateWebsiteSSL(c *gin.Context) {
var req request.WebsiteSSLUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteSSLService.Update(req); err != nil {
@@ -192,24 +198,3 @@ func (b *BaseApi) UpdateWebsiteSSL(c *gin.Context) {
}
helper.SuccessWithData(c, nil)
}
// @Tags Website SSL
// @Summary Upload ssl
// @Description 上传 ssl
// @Accept json
// @Param request body request.WebsiteSSLUpload true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/ssl/upload [post]
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"上传 ssl [type]","formatEN":"Upload ssl [type]"}
func (b *BaseApi) UploadWebsiteSSL(c *gin.Context) {
var req request.WebsiteSSLUpload
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := websiteSSLService.Upload(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
+12 -12
View File
@@ -12,29 +12,29 @@ type UserLoginInfo struct {
}
type MfaRequest struct {
Title string `json:"title" validate:"required"`
Interval int `json:"interval" validate:"required"`
Title string `json:"title"`
Interval int `json:"interval"`
}
type MfaCredential struct {
Secret string `json:"secret" validate:"required"`
Code string `json:"code" validate:"required"`
Interval string `json:"interval" validate:"required"`
Secret string `json:"secret"`
Code string `json:"code"`
Interval string `json:"interval"`
}
type Login struct {
Name string `json:"name" validate:"required"`
Password string `json:"password" validate:"required"`
Name string `json:"name"`
Password string `json:"password"`
IgnoreCaptcha bool `json:"ignoreCaptcha"`
Captcha string `json:"captcha"`
CaptchaID string `json:"captchaID"`
AuthMethod string `json:"authMethod" validate:"required,oneof=jwt session"`
Language string `json:"language" validate:"required,oneof=zh en tw"`
AuthMethod string `json:"authMethod"`
Language string `json:"language"`
}
type MFALogin struct {
Name string `json:"name" validate:"required"`
Password string `json:"password" validate:"required"`
Code string `json:"code" validate:"required"`
Name string `json:"name"`
Password string `json:"password"`
Code string `json:"code"`
AuthMethod string `json:"authMethod"`
}
+1 -1
View File
@@ -41,7 +41,7 @@ type CommonRecover struct {
type RecordSearch struct {
PageInfo
Type string `json:"type" validate:"required"`
Name string `json:"name"`
Name string `json:"name" validate:"required"`
DetailName string `json:"detailName"`
}
+6 -22
View File
@@ -1,29 +1,13 @@
package dto
type SearchCommandWithPage struct {
SearchWithPage
GroupID uint `json:"groupID"`
Info string `json:"info"`
}
type CommandOperate struct {
ID uint `json:"id"`
GroupID uint `json:"groupID"`
GroupBelong string `json:"groupBelong"`
Name string `json:"name" validate:"required"`
Command string `json:"command" validate:"required"`
ID uint `json:"id"`
Name string `json:"name" validate:"required"`
Command string `json:"command" validate:"required"`
}
type CommandInfo struct {
ID uint `json:"id"`
GroupID uint `json:"groupID"`
Name string `json:"name"`
Command string `json:"command"`
GroupBelong string `json:"groupBelong"`
}
type CommandTree struct {
ID uint `json:"id"`
Label string `json:"label"`
Children []CommandInfo `json:"children"`
ID uint `json:"id"`
Name string `json:"name"`
Command string `json:"command"`
}
+1 -1
View File
@@ -42,6 +42,6 @@ type DeleteByName struct {
}
type OperationWithNameAndType struct {
Name string `json:"name"`
Name string `json:"name" validate:"required"`
Type string `json:"type" validate:"required"`
}
+11 -16
View File
@@ -5,15 +5,14 @@ import "time"
type PageContainer struct {
PageInfo
Name string `json:"name"`
State string `json:"state" validate:"required,oneof=all created running paused restarting removing exited dead"`
OrderBy string `json:"orderBy"`
Order string `json:"order"`
Filters string `json:"filters"`
}
type InspectReq struct {
ID string `json:"id" validate:"required"`
Type string `json:"type" validate:"required"`
ID string `json:"id"`
Type string `json:"type"`
}
type ContainerInfo struct {
@@ -40,8 +39,8 @@ type ResourceLimit struct {
type ContainerOperate struct {
ContainerID string `json:"containerID"`
ForcePull bool `json:"forcePull"`
Name string `json:"name" validate:"required"`
Image string `json:"image" validate:"required"`
Name string `json:"name"`
Image string `json:"image"`
Network string `json:"network"`
PublishAllPorts bool `json:"publishAllPorts"`
ExposedPorts []PortHelper `json:"exposedPorts"`
@@ -104,13 +103,9 @@ type PortHelper struct {
}
type ContainerOperation struct {
Names []string `json:"names" validate:"required"`
Operation string `json:"operation" validate:"required,oneof=start stop restart kill pause unpause remove"`
}
type ContainerRename struct {
Name string `json:"name" validate:"required"`
NewName string `json:"newName" validate:"required"`
Name string `json:"name" validate:"required"`
Operation string `json:"operation" validate:"required,oneof=start stop restart kill pause unpause rename remove"`
NewName string `json:"newName"`
}
type ContainerPrune struct {
@@ -135,8 +130,8 @@ type Network struct {
Attachable bool `json:"attachable"`
}
type NetworkCreate struct {
Name string `json:"name" validate:"required"`
Driver string `json:"driver" validate:"required"`
Name string `json:"name"`
Driver string `json:"driver"`
Options []string `json:"options"`
Subnet string `json:"subnet"`
Gateway string `json:"gateway"`
@@ -152,8 +147,8 @@ type Volume struct {
CreatedAt time.Time `json:"createdAt"`
}
type VolumeCreate struct {
Name string `json:"name" validate:"required"`
Driver string `json:"driver" validate:"required"`
Name string `json:"name"`
Driver string `json:"driver"`
Options []string `json:"options"`
Labels []string `json:"labels"`
}
+1 -1
View File
@@ -65,7 +65,7 @@ type CronjobClean struct {
type CronjobBatchDelete struct {
CleanData bool `json:"cleanData"`
IDs []uint `json:"ids" validate:"required"`
IDs []uint `json:"ids"`
}
type CronjobInfo struct {
+1 -1
View File
@@ -170,7 +170,7 @@ type RedisConfPersistenceUpdate struct {
Save string `json:"save"`
}
type RedisConfUpdateByFile struct {
File string `json:"file" validate:"required"`
File string `json:"file"`
RestartNow bool `json:"restartNow"`
}
-2
View File
@@ -31,7 +31,6 @@ type AppContainerConfig struct {
AllowPort bool `json:"allowPort"`
EditCompose bool `json:"editCompose"`
DockerCompose string `json:"dockerCompose"`
HostMode bool `json:"hostMode"`
}
type AppInstalledSearch struct {
@@ -41,7 +40,6 @@ type AppInstalledSearch struct {
Tags []string `json:"tags"`
Update bool `json:"update"`
Unused bool `json:"unused"`
All bool `json:"all"`
}
type AppInstalledInfo struct {
-9
View File
@@ -1,9 +0,0 @@
package request
type FavoriteCreate struct {
Path string `json:"path" validate:"required"`
}
type FavoriteDelete struct {
ID uint `json:"id" validate:"required"`
}
+4 -30
View File
@@ -9,10 +9,6 @@ type FileOption struct {
files.FileOption
}
type FileContentReq struct {
Path string `json:"path" validate:"required"`
}
type SearchUploadWithPage struct {
dto.PageInfo
Path string `json:"path" validate:"required"`
@@ -29,18 +25,9 @@ type FileCreate struct {
Sub bool `json:"sub"`
}
type FileRoleReq struct {
Paths []string `json:"paths" validate:"required"`
Mode int64 `json:"mode" validate:"required"`
User string `json:"user" validate:"required"`
Group string `json:"group" validate:"required"`
Sub bool `json:"sub"`
}
type FileDelete struct {
Path string `json:"path" validate:"required"`
IsDir bool `json:"isDir"`
ForceDelete bool `json:"forceDelete"`
Path string `json:"path" validate:"required"`
IsDir bool `json:"isDir"`
}
type FileBatchDelete struct {
@@ -86,15 +73,13 @@ type FileMove struct {
Type string `json:"type" validate:"required"`
OldPaths []string `json:"oldPaths" validate:"required"`
NewPath string `json:"newPath" validate:"required"`
Name string `json:"name"`
Cover bool `json:"cover"`
}
type FileDownload struct {
Paths []string `json:"paths" validate:"required"`
Type string `json:"type" validate:"required"`
Name string `json:"name" validate:"required"`
Compress bool `json:"compress"`
Compress bool `json:"compress" validate:"required"`
}
type FileChunkDownload struct {
@@ -114,16 +99,5 @@ type FileRoleUpdate struct {
Path string `json:"path" validate:"required"`
User string `json:"user" validate:"required"`
Group string `json:"group" validate:"required"`
Sub bool `json:"sub"`
}
type FileReadByLineReq struct {
Path string `json:"path" validate:"required"`
Page int `json:"page" validate:"required"`
PageSize int `json:"pageSize" validate:"required"`
}
type FileExistReq struct {
Name string `json:"name" validate:"required"`
Dir string `json:"dir" validate:"required"`
Sub bool `json:"sub" validate:"required"`
}
+8 -8
View File
@@ -4,7 +4,7 @@ import "github.com/1Panel-dev/1Panel/backend/app/dto"
type NginxConfigFileUpdate struct {
Content string `json:"content" validate:"required"`
Backup bool `json:"backup"`
Backup bool `json:"backup" validate:"required"`
}
type NginxScopeReq struct {
@@ -14,8 +14,8 @@ type NginxScopeReq struct {
type NginxConfigUpdate struct {
Scope dto.NginxKey `json:"scope"`
Operate string `json:"operate" validate:"required,oneof=add update delete"`
WebsiteID uint `json:"websiteId"`
Operate string `json:"operate" validate:"required;oneof=add update delete"`
WebsiteID uint `json:"websiteId" validate:"required"`
Params interface{} `json:"params"`
}
@@ -39,8 +39,8 @@ type NginxProxyUpdate struct {
type NginxAuthUpdate struct {
WebsiteID uint `json:"websiteID" validate:"required"`
Operate string `json:"operate" validate:"required"`
Username string `json:"username"`
Password string `json:"password"`
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
Remark string `json:"remark"`
}
@@ -56,7 +56,7 @@ type NginxAntiLeechUpdate struct {
WebsiteID uint `json:"websiteID" validate:"required"`
Extends string `json:"extends" validate:"required"`
Return string `json:"return" validate:"required"`
Enable bool `json:"enable" `
Enable bool `json:"enable" validate:"required"`
ServerNames []string `json:"serverNames"`
Cache bool `json:"cache"`
CacheTime int `json:"cacheTime"`
@@ -70,8 +70,8 @@ type NginxRedirectReq struct {
Name string `json:"name" validate:"required"`
WebsiteID uint `json:"websiteID" validate:"required"`
Domains []string `json:"domains"`
KeepPath bool `json:"keepPath"`
Enable bool `json:"enable"`
KeepPath bool `json:"keepPath" validate:"required"`
Enable bool `json:"enable" validate:"required"`
Type string `json:"type" validate:"required"`
Redirect string `json:"redirect" validate:"required"`
Path string `json:"path"`
-11
View File
@@ -1,11 +0,0 @@
package request
type RecycleBinCreate struct {
SourcePath string `json:"sourcePath" validate:"required"`
}
type RecycleBinReduce struct {
From string `json:"from" validate:"required"`
RName string `json:"rName" validate:"required"`
Name string `json:"name"`
}
+3 -9
View File
@@ -23,15 +23,9 @@ type RuntimeCreate struct {
}
type NodeConfig struct {
Install bool `json:"install"`
Clean bool `json:"clean"`
Port int `json:"port"`
ExposedPorts []ExposedPort `json:"exposedPorts"`
}
type ExposedPort struct {
HostPort int `json:"hostPort"`
ContainerPort int `json:"containerPort"`
Install bool `json:"install"`
Clean bool `json:"clean"`
Port int `json:"port"`
}
type RuntimeDelete struct {
+13 -12
View File
@@ -45,7 +45,7 @@ type NewAppInstall struct {
}
type WebsiteInstallCheckReq struct {
InstallIds []uint `json:"InstallIds"`
InstallIds []uint `json:"InstallIds" validate:"required"`
}
type WebsiteUpdate struct {
@@ -78,13 +78,13 @@ type WebsiteWafReq struct {
type WebsiteRedirectUpdate struct {
WebsiteID uint `json:"websiteId" validate:"required"`
Key string `json:"key" validate:"required"`
Enable bool `json:"enable"`
Enable bool `json:"enable" validate:"required"`
}
type WebsiteWafUpdate struct {
WebsiteID uint `json:"websiteId" validate:"required"`
Key string `json:"key" validate:"required"`
Enable bool `json:"enable"`
Enable bool `json:"enable" validate:"required"`
}
type WebsiteRecover struct {
@@ -111,8 +111,9 @@ type WebsiteGroupUpdate struct {
}
type WebsiteDomainCreate struct {
WebsiteID uint `json:"websiteID" validate:"required"`
Domains string `json:"domains" validate:"required"`
WebsiteID uint `json:"websiteId" validate:"required"`
Port int `json:"port" validate:"required"`
Domain string `json:"domain" validate:"required"`
}
type WebsiteDomainDelete struct {
@@ -121,7 +122,7 @@ type WebsiteDomainDelete struct {
type WebsiteHTTPSOp struct {
WebsiteID uint `json:"websiteId" validate:"required"`
Enable bool `json:"enable"`
Enable bool `json:"enable" validate:"required"`
WebsiteSSLID uint `json:"websiteSSLId"`
Type string `json:"type" validate:"oneof=existed auto manual"`
PrivateKey string `json:"privateKey"`
@@ -148,7 +149,7 @@ type WebsiteLogReq struct {
}
type WebsiteDefaultUpdate struct {
ID uint `json:"id"`
ID uint `json:"id" validate:"required"`
}
type WebsitePHPConfigUpdate struct {
@@ -168,7 +169,7 @@ type WebsitePHPFileUpdate struct {
type WebsitePHPVersionReq struct {
WebsiteID uint `json:"websiteID" validate:"required"`
RuntimeID uint `json:"runtimeID" validate:"required"`
RetainConfig bool `json:"retainConfig" `
RetainConfig bool `json:"retainConfig" validate:"required"`
}
type WebsiteUpdateDir struct {
@@ -185,10 +186,10 @@ type WebsiteUpdateDirPermission struct {
type WebsiteProxyConfig struct {
ID uint `json:"id" validate:"required"`
Operate string `json:"operate" validate:"required"`
Enable bool `json:"enable" `
Cache bool `json:"cache" `
CacheTime int `json:"cacheTime" `
CacheUnit string `json:"cacheUnit"`
Enable bool `json:"enable" validate:"required"`
Cache bool `json:"cache" validate:"required"`
CacheTime int `json:"cacheTime" validate:"required"`
CacheUnit string `json:"cacheUnit" validate:"required"`
Name string `json:"name" validate:"required"`
Modifier string `json:"modifier" validate:"required"`
Match string `json:"match" validate:"required"`
+2 -10
View File
@@ -13,7 +13,7 @@ type WebsiteSSLCreate struct {
Provider string `json:"provider" validate:"required"`
AcmeAccountID uint `json:"acmeAccountId" validate:"required"`
DnsAccountID uint `json:"dnsAccountId"`
AutoRenew bool `json:"autoRenew"`
AutoRenew bool `json:"autoRenew" validate:"required"`
}
type WebsiteDNSReq struct {
@@ -48,13 +48,5 @@ type WebsiteResourceReq struct {
type WebsiteSSLUpdate struct {
ID uint `json:"id" validate:"required"`
AutoRenew bool `json:"autoRenew"`
}
type WebsiteSSLUpload struct {
PrivateKey string `json:"privateKey"`
Certificate string `json:"certificate"`
PrivateKeyPath string `json:"privateKeyPath"`
CertificatePath string `json:"certificatePath"`
Type string `json:"type" validate:"required,oneof=paste local"`
AutoRenew bool `json:"autoRenew" validate:"required"`
}
+3 -5
View File
@@ -15,7 +15,6 @@ type AppRes struct {
type AppUpdateRes struct {
CanUpdate bool `json:"canUpdate"`
IsSyncing bool `json:"isSyncing"`
AppStoreLastModified int `json:"appStoreLastModified"`
AppList *dto.AppList `json:"appList"`
}
@@ -48,10 +47,9 @@ type AppInstalledCheck struct {
type AppDetailDTO struct {
model.AppDetail
Enable bool `json:"enable"`
Params interface{} `json:"params"`
Image string `json:"image"`
HostMode bool `json:"hostMode"`
Enable bool `json:"enable"`
Params interface{} `json:"params"`
Image string `json:"image"`
}
type IgnoredApp struct {
-7
View File
@@ -1,7 +0,0 @@
package response
import "github.com/1Panel-dev/1Panel/backend/app/model"
type FavoriteDTO struct {
model.Favorite
}
-10
View File
@@ -32,13 +32,3 @@ type FileProcessKeys struct {
type FileWgetRes struct {
Key string `json:"key"`
}
type FileLineContent struct {
Content string `json:"content"`
End bool `json:"end"`
Path string `json:"path"`
}
type FileExist struct {
Exist bool `json:"exist"`
}
-14
View File
@@ -1,14 +0,0 @@
package response
import "time"
type RecycleBinDTO struct {
Name string `json:"name"`
Size int `json:"size"`
Type string `json:"type"`
DeleteTime time.Time `json:"deleteTime"`
RName string `json:"rName"`
SourcePath string `json:"sourcePath"`
IsDir bool `json:"isDir"`
From string `json:"from"`
}
+17 -19
View File
@@ -1,30 +1,28 @@
package response
import (
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
"github.com/1Panel-dev/1Panel/backend/app/model"
"time"
)
type RuntimeDTO struct {
ID uint `json:"id"`
Name string `json:"name"`
Resource string `json:"resource"`
AppDetailID uint `json:"appDetailID"`
AppID uint `json:"appID"`
Source string `json:"source"`
Status string `json:"status"`
Type string `json:"type"`
Image string `json:"image"`
Params map[string]interface{} `json:"params"`
Message string `json:"message"`
Version string `json:"version"`
CreatedAt time.Time `json:"createdAt"`
CodeDir string `json:"codeDir"`
AppParams []AppParam `json:"appParams"`
Port int `json:"port"`
Path string `json:"path"`
ExposedPorts []request.ExposedPort `json:"exposedPorts"`
ID uint `json:"id"`
Name string `json:"name"`
Resource string `json:"resource"`
AppDetailID uint `json:"appDetailID"`
AppID uint `json:"appID"`
Source string `json:"source"`
Status string `json:"status"`
Type string `json:"type"`
Image string `json:"image"`
Params map[string]interface{} `json:"params"`
Message string `json:"message"`
Version string `json:"version"`
CreatedAt time.Time `json:"createdAt"`
CodeDir string `json:"codeDir"`
AppParams []AppParam `json:"appParams"`
Port int `json:"port"`
Path string `json:"path"`
}
type PackageScripts struct {
+2 -10
View File
@@ -14,8 +14,6 @@ type SettingInfo struct {
NtpSite string `json:"ntpSite"`
Port string `json:"port"`
Ipv6 string `json:"ipv6"`
BindAddress string `json:"bindAddress"`
PanelName string `json:"panelName"`
Theme string `json:"theme"`
Language string `json:"language"`
@@ -48,7 +46,6 @@ type SettingInfo struct {
AppStoreVersion string `json:"appStoreVersion"`
AppStoreLastModified string `json:"appStoreLastModified"`
AppStoreSyncStatus string `json:"appStoreSyncStatus"`
}
type SettingUpdate struct {
@@ -136,16 +133,11 @@ type UpgradeInfo struct {
}
type SyncTime struct {
NtpSite string `json:"ntpSite" validate:"required"`
}
type BindInfo struct {
Ipv6 string `json:"ipv6" validate:"required,oneof=enable disable"`
BindAddress string `json:"bindAddress" validate:"required"`
NtpSite string `json:"ntpSite"`
}
type Upgrade struct {
Version string `json:"version" validate:"required"`
Version string `json:"version"`
}
type CleanData struct {
-7
View File
@@ -2,14 +2,7 @@ package dto
import "time"
type SSHUpdate struct {
Key string `json:"key" validate:"required"`
OldValue string `json:"oldValue"`
NewValue string `json:"newValue"`
}
type SSHInfo struct {
AutoStart bool `json:"autoStart"`
Status string `json:"status"`
Message string `json:"message"`
Port string `json:"port"`
+4 -4
View File
@@ -27,18 +27,18 @@ type AppInstall struct {
}
func (i *AppInstall) GetPath() string {
return path.Join(i.GetAppPath(), i.Name)
return path.Join(i.getAppPath(), i.Name)
}
func (i *AppInstall) GetComposePath() string {
return path.Join(i.GetAppPath(), i.Name, "docker-compose.yml")
return path.Join(i.getAppPath(), i.Name, "docker-compose.yml")
}
func (i *AppInstall) GetEnvPath() string {
return path.Join(i.GetAppPath(), i.Name, ".env")
return path.Join(i.getAppPath(), i.Name, ".env")
}
func (i *AppInstall) GetAppPath() string {
func (i *AppInstall) getAppPath() string {
if i.App.Resource == constant.AppResourceLocal {
return path.Join(constant.LocalAppInstallDir, strings.TrimPrefix(i.App.Key, constant.AppResourceLocal))
} else {
-1
View File
@@ -3,6 +3,5 @@ package model
type Command struct {
BaseModel
Name string `gorm:"type:varchar(64);unique;not null" json:"name"`
GroupID uint `gorm:"type:decimal" json:"groupID"`
Command string `gorm:"type:varchar(256);not null" json:"command"`
}
-10
View File
@@ -1,10 +0,0 @@
package model
type Favorite struct {
BaseModel
Name string `gorm:"type:varchar(256);not null;" json:"name" `
Path string `gorm:"type:varchar(256);not null;unique" json:"path"`
Type string `gorm:"type:varchar(64);" json:"type"`
IsDir bool `json:"isDir"`
IsTxt bool `json:"isTxt"`
}
-66
View File
@@ -1,66 +0,0 @@
package repo
import (
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/global"
"gorm.io/gorm"
)
type FavoriteRepo struct{}
type IFavoriteRepo interface {
Page(page, size int, opts ...DBOption) (int64, []model.Favorite, error)
Create(group *model.Favorite) error
Delete(opts ...DBOption) error
GetFirst(opts ...DBOption) (model.Favorite, error)
All() ([]model.Favorite, error)
WithByPath(path string) DBOption
}
func NewIFavoriteRepo() IFavoriteRepo {
return &FavoriteRepo{}
}
func (f *FavoriteRepo) WithByPath(path string) DBOption {
return func(db *gorm.DB) *gorm.DB {
return db.Where("path = ?", path)
}
}
func (f *FavoriteRepo) Page(page, size int, opts ...DBOption) (int64, []model.Favorite, error) {
var (
favorites []model.Favorite
count int64
)
count = int64(0)
db := getDb(opts...).Model(&model.Favorite{})
db = db.Count(&count)
err := db.Limit(size).Offset(size * (page - 1)).Find(&favorites).Error
return count, favorites, err
}
func (f *FavoriteRepo) Create(favorite *model.Favorite) error {
return global.DB.Create(favorite).Error
}
func (f *FavoriteRepo) GetFirst(opts ...DBOption) (model.Favorite, error) {
var favorite model.Favorite
db := getDb(opts...).Model(&model.Favorite{})
if err := db.First(&favorite).Error; err != nil {
return favorite, err
}
return favorite, nil
}
func (f *FavoriteRepo) Delete(opts ...DBOption) error {
db := getDb(opts...).Model(&model.Favorite{})
return db.Delete(&model.Favorite{}).Error
}
func (f *FavoriteRepo) All() ([]model.Favorite, error) {
var favorites []model.Favorite
if err := getDb().Find(&favorites).Error; err != nil {
return nil, err
}
return favorites, nil
}
+3 -3
View File
@@ -15,7 +15,7 @@ type IGroupRepo interface {
Update(id uint, vars map[string]interface{}) error
Delete(opts ...DBOption) error
CancelDefault(groupType string) error
WithByHostDefault() DBOption
WithByIsDefault(isDefault bool) DBOption
}
func NewIGroupRepo() IGroupRepo {
@@ -50,9 +50,9 @@ func (u *GroupRepo) Update(id uint, vars map[string]interface{}) error {
return global.DB.Model(&model.Group{}).Where("id = ?", id).Updates(vars).Error
}
func (u *GroupRepo) WithByHostDefault() DBOption {
func (u *GroupRepo) WithByIsDefault(isDefault bool) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("is_default = ? AND type = ?", 1, "host")
return g.Where("is_default = ?", isDefault)
}
}
+20 -63
View File
@@ -222,27 +222,6 @@ func (a AppService) GetAppDetail(appID uint, version, appType string) (response.
appDetailDTO.Params = paramMap
}
if appDetailDTO.DockerCompose == "" {
filename := path.Base(appDetailDTO.DownloadUrl)
dockerComposeUrl := fmt.Sprintf("%s%s", strings.TrimSuffix(appDetailDTO.DownloadUrl, filename), "docker-compose.yml")
composeRes, err := http.Get(dockerComposeUrl)
if err != nil {
return appDetailDTO, buserr.WithDetail("ErrGetCompose", err.Error(), err)
}
bodyContent, err := io.ReadAll(composeRes.Body)
if err != nil {
return appDetailDTO, buserr.WithDetail("ErrGetCompose", err.Error(), err)
}
if composeRes.StatusCode > 200 {
return appDetailDTO, buserr.WithDetail("ErrGetCompose", string(bodyContent), err)
}
detail.DockerCompose = string(bodyContent)
_ = appDetailRepo.Update(context.Background(), detail)
appDetailDTO.DockerCompose = string(bodyContent)
}
appDetailDTO.HostMode = isHostModel(appDetailDTO.DockerCompose)
app, err := appRepo.GetFirst(commonRepo.WithByID(detail.AppId))
if err != nil {
return appDetailDTO, err
@@ -264,7 +243,6 @@ func (a AppService) GetAppDetailByID(id uint) (*response.AppDetailDTO, error) {
return nil, err
}
res.Params = paramMap
res.HostMode = isHostModel(appDetail.DockerCompose)
return res, nil
}
@@ -715,11 +693,6 @@ func (a AppService) GetAppUpdate() (*response.AppUpdateRes, error) {
if err != nil {
return nil, err
}
if setting.AppStoreSyncStatus == constant.Syncing {
res.IsSyncing = true
return res, nil
}
appStoreLastModified, _ := strconv.Atoi(setting.AppStoreLastModified)
res.AppStoreLastModified = appStoreLastModified
if setting.AppStoreLastModified == "" || lastModified != appStoreLastModified {
@@ -746,7 +719,7 @@ func getAppFromRepo(downloadPath string) error {
if err := fileOp.DownloadFile(downloadUrl, packagePath); err != nil {
return err
}
if err := fileOp.Decompress(packagePath, constant.ResourceDir, files.SdkZip); err != nil {
if err := fileOp.Decompress(packagePath, constant.ResourceDir, files.Zip); err != nil {
return err
}
defer func() {
@@ -771,12 +744,6 @@ func getAppList() (*dto.AppList, error) {
return list, nil
}
var InitTypes = map[string]struct{}{
"runtime": {},
"php": {},
"node": {},
}
func (a AppService) SyncAppListFromRemote() (err error) {
global.LOG.Infof("Starting synchronization with App Store...")
updateRes, err := a.GetAppUpdate()
@@ -784,14 +751,9 @@ func (a AppService) SyncAppListFromRemote() (err error) {
return err
}
if !updateRes.CanUpdate {
if updateRes.IsSyncing {
global.LOG.Infof("AppStore is Syncing!")
return
}
global.LOG.Infof("The App Store is at the latest version")
return
}
list := &dto.AppList{}
if updateRes.AppList == nil {
list, err = getAppList()
@@ -801,8 +763,16 @@ func (a AppService) SyncAppListFromRemote() (err error) {
} else {
list = updateRes.AppList
}
settingService := NewISettingService()
_ = settingService.Update("AppStoreSyncStatus", constant.Syncing)
if err = NewISettingService().Update("AppStoreLastModified", strconv.Itoa(list.LastModified)); err != nil {
return err
}
defer func() {
if err != nil {
_ = NewISettingService().Update("AppStoreLastModified", strconv.Itoa(updateRes.AppStoreLastModified))
}
}()
var (
tags []*model.Tag
@@ -826,8 +796,6 @@ func (a AppService) SyncAppListFromRemote() (err error) {
baseRemoteUrl := fmt.Sprintf("%s/%s/1panel", global.CONF.System.AppRepo, global.CONF.System.Mode)
appsMap := getApps(oldApps, list.Apps)
global.LOG.Infof("Starting synchronization of application details...")
for _, l := range list.Apps {
app := appsMap[l.AppProperty.Key]
iconRes, err := http.Get(l.Icon)
@@ -854,21 +822,16 @@ func (a AppService) SyncAppListFromRemote() (err error) {
version := v.Name
detail := detailsMap[version]
versionUrl := fmt.Sprintf("%s/%s/%s", baseRemoteUrl, app.Key, version)
if _, ok := InitTypes[app.Type]; ok {
dockerComposeUrl := fmt.Sprintf("%s/%s", versionUrl, "docker-compose.yml")
composeRes, err := http.Get(dockerComposeUrl)
if err != nil {
return err
}
bodyContent, err := io.ReadAll(composeRes.Body)
if err != nil {
return err
}
detail.DockerCompose = string(bodyContent)
} else {
detail.DockerCompose = ""
dockerComposeUrl := fmt.Sprintf("%s/%s", versionUrl, "docker-compose.yml")
composeRes, err := http.Get(dockerComposeUrl)
if err != nil {
return err
}
bodyContent, err := io.ReadAll(composeRes.Body)
if err != nil {
return err
}
detail.DockerCompose = string(bodyContent)
paramByte, _ := json.Marshal(v.AppForm)
detail.Params = string(paramByte)
@@ -886,8 +849,6 @@ func (a AppService) SyncAppListFromRemote() (err error) {
appsMap[l.AppProperty.Key] = app
}
global.LOG.Infof("Synchronization of application details Success")
var (
addAppArray []model.App
updateAppArray []model.App
@@ -1012,10 +973,6 @@ func (a AppService) SyncAppListFromRemote() (err error) {
}
}
tx.Commit()
_ = settingService.Update("AppStoreSyncStatus", constant.SyncSuccess)
_ = settingService.Update("AppStoreLastModified", strconv.Itoa(list.LastModified))
global.LOG.Infof("Synchronization with the App Store was successful!")
return
}
+1 -2
View File
@@ -518,7 +518,7 @@ func (a *AppInstallService) ChangeAppPort(req request.PortUpdate) error {
return nil
}
if err := updateInstallInfoInDB(req.Key, req.Name, "port", true, strconv.FormatInt(req.Port, 10)); err != nil {
if err := updateInstallInfoInDB(req.Key, "", "port", true, strconv.FormatInt(req.Port, 10)); err != nil {
return nil
}
@@ -675,7 +675,6 @@ func (a *AppInstallService) GetParams(id uint) (*response.AppConfig, error) {
config.ContainerName = install.ContainerName
}
res.AppContainerConfig = config
res.HostMode = isHostModel(install.DockerCompose)
return &res, nil
}
+1 -27
View File
@@ -419,16 +419,6 @@ func upgradeInstall(installId uint, detailId uint, backup bool) error {
_, _ = scriptCmd.CombinedOutput()
}
if detail.DockerCompose == "" {
composeDetail, err := fileOp.GetContent(path.Join(detailDir, "docker-compose.yml"))
if err != nil {
upErr = err
return
}
detail.DockerCompose = string(composeDetail)
_ = appDetailRepo.Update(context.Background(), detail)
}
composeMap := make(map[string]interface{})
if upErr = yaml.Unmarshal([]byte(detail.DockerCompose), &composeMap); upErr != nil {
return
@@ -659,7 +649,7 @@ func downloadApp(app model.App, appDetail model.AppDetail, appInstall *model.App
global.LOG.Errorf("download app[%s] error %v", app.Name, err)
return
}
if err = fileOp.Decompress(filePath, appResourceDir, files.SdkTarGz); err != nil {
if err = fileOp.Decompress(filePath, appResourceDir, files.TarGz); err != nil {
global.LOG.Errorf("decompress app[%s] error %v", app.Name, err)
return
}
@@ -1206,19 +1196,3 @@ func getAppCommonConfig(envs map[string]interface{}) request.AppContainerConfig
return config
}
func isHostModel(dockerCompose string) bool {
composeMap := make(map[string]interface{})
_ = yaml.Unmarshal([]byte(dockerCompose), &composeMap)
services, serviceValid := composeMap["services"].(map[string]interface{})
if !serviceValid {
return false
}
for _, service := range services {
serviceValue := service.(map[string]interface{})
if value, ok := serviceValue["network_mode"]; ok && value == "host" {
return true
}
}
return false
}
+4 -50
View File
@@ -1,7 +1,6 @@
package service
import (
"bufio"
"context"
"encoding/base64"
"encoding/json"
@@ -151,26 +150,20 @@ func (u *BackupService) DownloadRecord(info dto.DownloadRecord) (string, error)
return targetPath, nil
}
func (u *BackupService) Create(req dto.BackupOperate) error {
backup, _ := backupRepo.Get(commonRepo.WithByType(req.Type))
func (u *BackupService) Create(backupDto dto.BackupOperate) error {
backup, _ := backupRepo.Get(commonRepo.WithByType(backupDto.Type))
if backup.ID != 0 {
return constant.ErrRecordExist
}
if err := copier.Copy(&backup, &req); err != nil {
if err := copier.Copy(&backup, &backupDto); err != nil {
return errors.WithMessage(constant.ErrStructTransform, err.Error())
}
if req.Type == constant.OneDrive {
if backupDto.Type == constant.OneDrive {
if err := u.loadAccessToken(&backup); err != nil {
return err
}
}
if req.Type != "LOCAL" {
isOk, err := u.checkBackupConn(&backup)
if err != nil || !isOk {
return buserr.WithMap("ErrBackupCheck", map[string]interface{}{"err": err.Error()}, err)
}
}
if err := backupRepo.Create(&backup); err != nil {
return err
}
@@ -249,15 +242,10 @@ func (u *BackupService) Update(req dto.BackupOperate) error {
}
upMap := make(map[string]interface{})
upMap["bucket"] = req.Bucket
upMap["access_key"] = req.AccessKey
upMap["credential"] = req.Credential
upMap["backup_path"] = req.BackupPath
upMap["vars"] = req.Vars
backup.Bucket = req.Bucket
backup.Vars = req.Vars
backup.Credential = req.Credential
backup.AccessKey = req.AccessKey
backup.BackupPath = req.BackupPath
if req.Type == constant.OneDrive {
if err := u.loadAccessToken(&backup); err != nil {
@@ -266,13 +254,6 @@ func (u *BackupService) Update(req dto.BackupOperate) error {
upMap["credential"] = backup.Credential
upMap["vars"] = backup.Vars
}
if backup.Type != "LOCAL" {
isOk, err := u.checkBackupConn(&backup)
if err != nil || !isOk {
return buserr.WithMap("ErrBackupCheck", map[string]interface{}{"err": err.Error()}, err)
}
}
if err := backupRepo.Update(req.ID, upMap); err != nil {
return err
}
@@ -460,30 +441,3 @@ func copyDir(src, dst string) error {
return nil
}
func (u *BackupService) checkBackupConn(backup *model.BackupAccount) (bool, error) {
client, err := u.NewClient(backup)
if err != nil {
return false, err
}
fileItem := path.Join(global.CONF.System.TmpDir, "test", "1panel")
if _, err := os.Stat(path.Dir(fileItem)); err != nil && os.IsNotExist(err) {
if err = os.MkdirAll(path.Dir(fileItem), os.ModePerm); err != nil {
return false, err
}
}
file, err := os.OpenFile(fileItem, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
return false, err
}
defer file.Close()
write := bufio.NewWriter(file)
_, _ = write.WriteString(string("1Panel 备份账号测试文件。\n"))
_, _ = write.WriteString(string("1Panel 備份賬號測試文件。\n"))
_, _ = write.WriteString(string("1Panel Backs up account test files.\n"))
_, _ = write.WriteString(string("1Panelアカウントのテストファイルをバックアップします。\n"))
write.Flush()
targetPath := strings.TrimPrefix(path.Join(backup.BackupPath, "test/1panel"), "/")
return client.Upload(fileItem, targetPath)
}
+1 -1
View File
@@ -225,7 +225,7 @@ func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback
_ = fileOp.Rename(appDir, backPath)
_ = fileOp.CreateDir(appDir, 0755)
if err := handleUnTar(tmpPath+"/app.tar.gz", install.GetAppPath()); err != nil {
if err := handleUnTar(tmpPath+"/app.tar.gz", fmt.Sprintf("%s/%s", constant.AppInstallDir, install.App.Key)); err != nil {
global.LOG.Errorf("handle recover from app.tar.gz failed, err: %v", err)
_ = fileOp.DeleteDir(appDir)
_ = fileOp.Rename(backPath, appDir)
+3 -40
View File
@@ -11,8 +11,7 @@ type CommandService struct{}
type ICommandService interface {
List() ([]dto.CommandInfo, error)
SearchForTree() ([]dto.CommandTree, error)
SearchWithPage(search dto.SearchCommandWithPage) (int64, interface{}, error)
SearchWithPage(search dto.SearchWithPage) (int64, interface{}, error)
Create(commandDto dto.CommandOperate) error
Update(id uint, upMap map[string]interface{}) error
Delete(ids []uint) error
@@ -38,50 +37,14 @@ func (u *CommandService) List() ([]dto.CommandInfo, error) {
return dtoCommands, err
}
func (u *CommandService) SearchForTree() ([]dto.CommandTree, error) {
cmdList, err := commandRepo.GetList()
if err != nil {
return nil, err
}
groups, err := groupRepo.GetList(commonRepo.WithByType("command"))
if err != nil {
return nil, err
}
var lists []dto.CommandTree
for _, group := range groups {
var data dto.CommandTree
data.ID = group.ID + 10000
data.Label = group.Name
for _, cmd := range cmdList {
if cmd.GroupID == group.ID {
data.Children = append(data.Children, dto.CommandInfo{ID: cmd.ID, Name: cmd.Name, Command: cmd.Command})
}
}
if len(data.Children) != 0 {
lists = append(lists, data)
}
}
return lists, err
}
func (u *CommandService) SearchWithPage(search dto.SearchCommandWithPage) (int64, interface{}, error) {
total, commands, err := commandRepo.Page(search.Page, search.PageSize, commonRepo.WithLikeName(search.Info), commonRepo.WithByGroupID(search.GroupID))
if err != nil {
return 0, nil, err
}
groups, _ := groupRepo.GetList(commonRepo.WithByType("command"))
func (u *CommandService) SearchWithPage(search dto.SearchWithPage) (int64, interface{}, error) {
total, commands, err := commandRepo.Page(search.Page, search.PageSize, commonRepo.WithLikeName(search.Info))
var dtoCommands []dto.CommandInfo
for _, command := range commands {
var item dto.CommandInfo
if err := copier.Copy(&item, &command); err != nil {
return 0, nil, errors.WithMessage(constant.ErrStructTransform, err.Error())
}
for _, group := range groups {
if command.GroupID == group.ID {
item.GroupBelong = group.Name
item.GroupID = group.ID
}
}
dtoCommands = append(dtoCommands, item)
}
return total, dtoCommands, err
+45 -107
View File
@@ -13,7 +13,6 @@ import (
"strconv"
"strings"
"sync"
"syscall"
"time"
"github.com/1Panel-dev/1Panel/backend/app/dto"
@@ -53,10 +52,9 @@ type IContainerService interface {
ContainerInfo(req dto.OperationWithName) (*dto.ContainerOperate, error)
ContainerListStats() ([]dto.ContainerListStats, error)
LoadResourceLimit() (*dto.ResourceLimit, error)
ContainerRename(req dto.ContainerRename) error
ContainerLogClean(req dto.OperationWithName) error
ContainerOperation(req dto.ContainerOperation) error
ContainerLogs(wsConn *websocket.Conn, containerType, container, since, tail string, follow bool) error
ContainerLogs(wsConn *websocket.Conn, container, since, tail string, follow bool) error
ContainerStats(id string) (*dto.ContainerStats, error)
Inspect(req dto.InspectReq) (string, error)
DeleteNetwork(req dto.BatchDelete) error
@@ -68,6 +66,7 @@ type IContainerService interface {
Prune(req dto.ContainerPrune) (dto.ContainerPruneReport, error)
LoadContainerLogs(req dto.OperationWithNameAndType) string
ComposeLogs(wsConn *websocket.Conn, composePath, since, tail string, follow bool) error
}
func NewIContainerService() IContainerService {
@@ -103,17 +102,6 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
}
}
}
if req.State != "all" {
length, count := len(list), 0
for count < length {
if list[count].State != req.State {
list = append(list[:count], list[(count+1):]...)
length--
} else {
count++
}
}
}
switch req.OrderBy {
case "name":
sort.Slice(list, func(i, j int) bool {
@@ -328,6 +316,11 @@ func (u *ContainerService) ContainerCreate(req dto.ContainerOperate) error {
return buserr.New(constant.ErrContainerName)
}
config, hostConf, networkConf, err := loadConfigInfo(true, req, nil)
if err != nil {
return err
}
global.LOG.Infof("new container info %s has been made, now start to create", req.Name)
if !checkImageExist(client, req.Image) || req.ForcePull {
if err := pullImages(ctx, client, req.Image); err != nil {
if !req.ForcePull {
@@ -336,21 +329,6 @@ func (u *ContainerService) ContainerCreate(req dto.ContainerOperate) error {
global.LOG.Errorf("force pull image %s failed, err: %v", req.Image, err)
}
}
imageInfo, _, err := client.ImageInspectWithRaw(ctx, req.Image)
if err != nil {
return err
}
if len(req.Entrypoint) == 0 {
req.Entrypoint = imageInfo.Config.Entrypoint
}
if len(req.Cmd) == 0 {
req.Cmd = imageInfo.Config.Cmd
}
config, hostConf, networkConf, err := loadConfigInfo(true, req, nil)
if err != nil {
return err
}
global.LOG.Infof("new container info %s has been made, now start to create", req.Name)
container, err := client.ContainerCreate(ctx, config, hostConf, networkConf, &v1.Platform{}, req.Name)
if err != nil {
_ = client.ContainerRemove(ctx, req.Name, types.ContainerRemoveOptions{RemoveVolumes: true, Force: true})
@@ -515,20 +493,6 @@ func (u *ContainerService) ContainerUpgrade(req dto.ContainerUpgrade) error {
return nil
}
func (u *ContainerService) ContainerRename(req dto.ContainerRename) error {
ctx := context.Background()
client, err := docker.NewDockerClient()
if err != nil {
return err
}
newContainer, _ := client.ContainerInspect(ctx, req.NewName)
if newContainer.ContainerJSONBase != nil {
return buserr.New(constant.ErrContainerName)
}
return client.ContainerRename(ctx, req.Name, req.NewName)
}
func (u *ContainerService) ContainerOperation(req dto.ContainerOperation) error {
var err error
ctx := context.Background()
@@ -536,24 +500,28 @@ func (u *ContainerService) ContainerOperation(req dto.ContainerOperation) error
if err != nil {
return err
}
for _, item := range req.Names {
global.LOG.Infof("start container %s operation %s", item, req.Operation)
switch req.Operation {
case constant.ContainerOpStart:
err = client.ContainerStart(ctx, item, types.ContainerStartOptions{})
case constant.ContainerOpStop:
err = client.ContainerStop(ctx, item, container.StopOptions{})
case constant.ContainerOpRestart:
err = client.ContainerRestart(ctx, item, container.StopOptions{})
case constant.ContainerOpKill:
err = client.ContainerKill(ctx, item, "SIGKILL")
case constant.ContainerOpPause:
err = client.ContainerPause(ctx, item)
case constant.ContainerOpUnpause:
err = client.ContainerUnpause(ctx, item)
case constant.ContainerOpRemove:
err = client.ContainerRemove(ctx, item, types.ContainerRemoveOptions{RemoveVolumes: true, Force: true})
global.LOG.Infof("start container %s operation %s", req.Name, req.Operation)
switch req.Operation {
case constant.ContainerOpStart:
err = client.ContainerStart(ctx, req.Name, types.ContainerStartOptions{})
case constant.ContainerOpStop:
err = client.ContainerStop(ctx, req.Name, container.StopOptions{})
case constant.ContainerOpRestart:
err = client.ContainerRestart(ctx, req.Name, container.StopOptions{})
case constant.ContainerOpKill:
err = client.ContainerKill(ctx, req.Name, "SIGKILL")
case constant.ContainerOpPause:
err = client.ContainerPause(ctx, req.Name)
case constant.ContainerOpUnpause:
err = client.ContainerUnpause(ctx, req.Name)
case constant.ContainerOpRename:
newContainer, _ := client.ContainerInspect(ctx, req.NewName)
if newContainer.ContainerJSONBase != nil {
return buserr.New(constant.ErrContainerName)
}
err = client.ContainerRename(ctx, req.Name, req.NewName)
case constant.ContainerOpRemove:
err = client.ContainerRemove(ctx, req.Name, types.ContainerRemoveOptions{RemoveVolumes: true, Force: true})
}
return err
}
@@ -592,15 +560,11 @@ func (u *ContainerService) ContainerLogClean(req dto.OperationWithName) error {
return nil
}
func (u *ContainerService) ContainerLogs(wsConn *websocket.Conn, containerType, container, since, tail string, follow bool) error {
defer func() { wsConn.Close() }()
func (u *ContainerService) ContainerLogs(wsConn *websocket.Conn, container, since, tail string, follow bool) error {
if cmd.CheckIllegal(container, since, tail) {
return buserr.New(constant.ErrCmdIllegal)
}
command := fmt.Sprintf("docker logs %s", container)
if containerType == "compose" {
command = fmt.Sprintf("docker-compose -f %s logs", container)
}
if tail != "0" {
command += " --tail " + tail
}
@@ -612,14 +576,6 @@ func (u *ContainerService) ContainerLogs(wsConn *websocket.Conn, containerType,
}
command += " 2>&1"
cmd := exec.Command("bash", "-c", command)
if !follow {
stdout, _ := cmd.CombinedOutput()
if err := wsConn.WriteMessage(websocket.TextMessage, stdout); err != nil {
global.LOG.Errorf("send message with log to ws failed, err: %v", err)
}
return nil
}
stdout, err := cmd.StdoutPipe()
if err != nil {
return err
@@ -627,40 +583,23 @@ func (u *ContainerService) ContainerLogs(wsConn *websocket.Conn, containerType,
if err := cmd.Start(); err != nil {
return err
}
defer func() {
_ = cmd.Process.Signal(syscall.SIGTERM)
_ = cmd.Wait()
}()
var exitCh chan struct{}
if follow {
go func() {
_, wsData, _ := wsConn.ReadMessage()
if string(wsData) == "close conn" {
exitCh <- struct{}{}
}
}()
}
buffer := make([]byte, 1024)
for {
select {
case <-exitCh:
return nil
default:
n, err := stdout.Read(buffer)
if err != nil {
if err == io.EOF {
return err
}
global.LOG.Errorf("read bytes from log failed, err: %v", err)
continue
}
if err = wsConn.WriteMessage(websocket.TextMessage, buffer[:n]); err != nil {
global.LOG.Errorf("send message with log to ws failed, err: %v", err)
return err
n, err := stdout.Read(buffer)
if err != nil {
if err == io.EOF {
break
}
global.LOG.Errorf("read bytes from container log failed, err: %v", err)
continue
}
if err = wsConn.WriteMessage(websocket.TextMessage, buffer[:n]); err != nil {
global.LOG.Errorf("send message with container log to ws failed, err: %v", err)
break
}
}
return nil
}
func (u *ContainerService) ContainerStats(id string) (*dto.ContainerStats, error) {
@@ -1048,29 +987,28 @@ func simplifyPort(ports []types.Port) []string {
if start.PublicPort != 0 {
itemPortStr = fmt.Sprintf("%s:%v->%v/%s", start.IP, start.PublicPort, start.PrivatePort, start.Type)
}
datas = append(datas, strings.TrimPrefix(itemPortStr, ":"))
datas = append(datas, itemPortStr)
} else {
itemPortStr := fmt.Sprintf("%s:%v-%v/%s", start.IP, start.PrivatePort, ports[i-1].PrivatePort, start.Type)
if start.PublicPort != 0 {
itemPortStr = fmt.Sprintf("%s:%v-%v->%v-%v/%s", start.IP, start.PublicPort, ports[i-1].PublicPort, start.PrivatePort, ports[i-1].PrivatePort, start.Type)
}
datas = append(datas, strings.TrimPrefix(itemPortStr, ":"))
datas = append(datas, itemPortStr)
}
start = ports[i]
}
if i == len(ports)-1 {
} else if i == len(ports)-1 {
if ports[i].PrivatePort == start.PrivatePort {
itemPortStr := fmt.Sprintf("%s:%v/%s", start.IP, start.PrivatePort, start.Type)
if start.PublicPort != 0 {
itemPortStr = fmt.Sprintf("%s:%v->%v/%s", start.IP, start.PublicPort, start.PrivatePort, start.Type)
}
datas = append(datas, strings.TrimPrefix(itemPortStr, ":"))
datas = append(datas, itemPortStr)
} else {
itemPortStr := fmt.Sprintf("%s:%v-%v/%s", start.IP, start.PrivatePort, ports[i].PrivatePort, start.Type)
if start.PublicPort != 0 {
itemPortStr = fmt.Sprintf("%s:%v-%v->%v-%v/%s", start.IP, start.PublicPort, ports[i].PublicPort, start.PrivatePort, ports[i].PrivatePort, start.Type)
}
datas = append(datas, strings.TrimPrefix(itemPortStr, ":"))
datas = append(datas, itemPortStr)
}
}
}
+43
View File
@@ -4,6 +4,7 @@ import (
"bufio"
"errors"
"fmt"
"github.com/gorilla/websocket"
"io"
"os"
"os/exec"
@@ -261,3 +262,45 @@ func (u *ContainerService) loadPath(req *dto.ComposeCreate) error {
}
return nil
}
func (u *ContainerService) ComposeLogs(wsConn *websocket.Conn, composePath, since, tail string, follow bool) error {
if cmd.CheckIllegal(composePath, since, tail) {
return buserr.New(constant.ErrCmdIllegal)
}
command := fmt.Sprintf("docker-compose -f %s logs", composePath)
if tail != "0" {
command += " --tail " + tail
}
if since != "all" {
command += " --since " + since
}
if follow {
command += " -f"
}
command += " 2>&1"
cmd := exec.Command("bash", "-c", command)
stdout, err := cmd.StdoutPipe()
if err != nil {
return err
}
if err := cmd.Start(); err != nil {
return err
}
buffer := make([]byte, 1024)
for {
n, err := stdout.Read(buffer)
if err != nil {
if err == io.EOF {
break
}
global.LOG.Errorf("read bytes from compose log failed, err: %v", err)
continue
}
if err = wsConn.WriteMessage(websocket.TextMessage, buffer[:n]); err != nil {
global.LOG.Errorf("send message with compose log to ws failed, err: %v", err)
break
}
}
return nil
}
+5 -5
View File
@@ -19,7 +19,7 @@ func (u *ContainerService) PageVolume(req dto.SearchWithPage) (int64, interface{
if err != nil {
return 0, nil, err
}
list, err := client.VolumeList(context.TODO(), volume.ListOptions{})
list, err := client.VolumeList(context.TODO(), filters.NewArgs())
if err != nil {
return 0, nil, err
}
@@ -76,7 +76,7 @@ func (u *ContainerService) ListVolume() ([]dto.Options, error) {
if err != nil {
return nil, err
}
list, err := client.VolumeList(context.TODO(), volume.ListOptions{})
list, err := client.VolumeList(context.TODO(), filters.NewArgs())
if err != nil {
return nil, err
}
@@ -111,9 +111,9 @@ func (u *ContainerService) CreateVolume(req dto.VolumeCreate) error {
if err != nil {
return err
}
arg := filters.NewArgs()
arg.Add("name", req.Name)
vos, _ := client.VolumeList(context.TODO(), volume.ListOptions{Filters: arg})
var array []filters.KeyValuePair
array = append(array, filters.Arg("name", req.Name))
vos, _ := client.VolumeList(context.TODO(), filters.NewArgs(array...))
if len(vos.Volumes) != 0 {
for _, v := range vos.Volumes {
if v.Name == req.Name {
+2 -2
View File
@@ -46,7 +46,7 @@ func (u *CronjobService) SearchWithPage(search dto.SearchWithPage) (int64, inter
if err := copier.Copy(&item, &cronjob); err != nil {
return 0, nil, errors.WithMessage(constant.ErrStructTransform, err.Error())
}
if hasBackup(item.Type) {
if item.Type == "app" || item.Type == "website" || item.Type == "database" || item.Type == "directory" || item.Type == "snapshot" {
backup, _ := backupRepo.Get(commonRepo.WithByID(uint(item.TargetDirID)))
if len(backup.Type) != 0 {
item.TargetDir = backup.Type
@@ -103,7 +103,7 @@ func (u *CronjobService) CleanRecord(req dto.CronjobClean) error {
if err != nil {
return err
}
if req.CleanData && hasBackup(cronjob.Type) {
if req.CleanData && (cronjob.Type == "app" || cronjob.Type == "database" || cronjob.Type == "website" || cronjob.Type == "directory" || cronjob.Type == "snapshot") {
cronjob.RetainCopies = 0
backup, err := backupRepo.Get(commonRepo.WithByID(uint(cronjob.TargetDirID)))
if err != nil {
-123
View File
@@ -64,13 +64,6 @@ func (u *CronjobService) HandleJob(cronjob *model.Cronjob) {
if err != nil {
global.LOG.Errorf("cut website log file failed, err: %v", err)
}
case "clean":
messageItem := ""
messageItem, err = u.handleSystemClean()
message = []byte(messageItem)
u.HandleRmExpired("LOCAL", "", "", cronjob, nil)
case "log":
record.File, err = u.handleSystemLog(*cronjob, record.StartTime)
}
if err != nil {
@@ -221,7 +214,6 @@ func handleTar(sourceDir, targetDir, name, exclusionRules string) error {
excludes := strings.Split(exclusionRules, ",")
excludeRules := ""
excludes = append(excludes, "*.sock")
for _, exclude := range excludes {
if len(exclude) == 0 {
continue
@@ -592,118 +584,3 @@ func (u *CronjobService) handleSnapshot(cronjob *model.Cronjob, startTime time.T
u.HandleRmExpired(backup.Type, backup.BackupPath, "", cronjob, client)
return message, path, nil
}
func (u *CronjobService) handleSystemClean() (string, error) {
return NewISettingService().SystemCleanForCronjob()
}
func (u *CronjobService) handleSystemLog(cronjob model.Cronjob, startTime time.Time) (string, error) {
backup, err := backupRepo.Get(commonRepo.WithByID(uint(cronjob.TargetDirID)))
if err != nil {
return "", err
}
pathItem := path.Join(global.CONF.System.BaseDir, "1panel/tmp/log", startTime.Format("20060102150405"))
websites, err := websiteRepo.List()
if err != nil {
return "", err
}
if len(websites) != 0 {
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
if err != nil {
return "", err
}
webItem := path.Join(nginxInstall.GetPath(), "www/sites")
for _, website := range websites {
dirItem := path.Join(pathItem, "website", website.Alias)
if _, err := os.Stat(dirItem); err != nil && os.IsNotExist(err) {
if err = os.MkdirAll(dirItem, os.ModePerm); err != nil {
return "", err
}
}
itemDir := path.Join(webItem, website.Alias, "log")
logFiles, _ := os.ReadDir(itemDir)
if len(logFiles) != 0 {
for i := 0; i < len(logFiles); i++ {
if !logFiles[i].IsDir() {
_ = cpBinary([]string{path.Join(itemDir, logFiles[i].Name())}, dirItem)
}
}
}
itemDir2 := path.Join(global.CONF.System.Backup, "log/website", website.Alias)
logFiles2, _ := os.ReadDir(itemDir2)
if len(logFiles2) != 0 {
for i := 0; i < len(logFiles2); i++ {
if !logFiles2[i].IsDir() {
_ = cpBinary([]string{path.Join(itemDir2, logFiles2[i].Name())}, dirItem)
}
}
}
}
global.LOG.Debug("backup website log successful!")
}
systemLogDir := path.Join(global.CONF.System.BaseDir, "1panel/log")
systemDir := path.Join(pathItem, "system")
if _, err := os.Stat(systemDir); err != nil && os.IsNotExist(err) {
if err = os.MkdirAll(systemDir, os.ModePerm); err != nil {
return "", err
}
}
systemLogFiles, _ := os.ReadDir(systemLogDir)
if len(systemLogFiles) != 0 {
for i := 0; i < len(systemLogFiles); i++ {
if !systemLogFiles[i].IsDir() {
_ = cpBinary([]string{path.Join(systemLogDir, systemLogFiles[i].Name())}, systemDir)
}
}
}
global.LOG.Debug("backup system log successful!")
loginLogFiles, _ := os.ReadDir("/var/log")
loginDir := path.Join(pathItem, "login")
if _, err := os.Stat(loginDir); err != nil && os.IsNotExist(err) {
if err = os.MkdirAll(loginDir, os.ModePerm); err != nil {
return "", err
}
}
if len(loginLogFiles) != 0 {
for i := 0; i < len(loginLogFiles); i++ {
if !loginLogFiles[i].IsDir() && (strings.HasPrefix(loginLogFiles[i].Name(), "secure") || strings.HasPrefix(loginLogFiles[i].Name(), "auth.log")) {
_ = cpBinary([]string{path.Join("/var/log", loginLogFiles[i].Name())}, loginDir)
}
}
}
global.LOG.Debug("backup ssh log successful!")
fileName := fmt.Sprintf("system_log_%s.tar.gz", startTime.Format("20060102150405"))
targetDir := path.Dir(pathItem)
if err := handleTar(pathItem, targetDir, fileName, ""); err != nil {
return "", err
}
defer func() {
os.RemoveAll(pathItem)
os.RemoveAll(path.Join(targetDir, fileName))
}()
client, err := NewIBackupService().NewClient(&backup)
if err != nil {
return "", err
}
targetPath := "log/" + fileName
if len(backup.BackupPath) != 0 {
targetPath = strings.TrimPrefix(backup.BackupPath, "/") + "/log/" + fileName
}
if _, err = client.Upload(path.Join(targetDir, fileName), targetPath); err != nil {
return "", err
}
u.HandleRmExpired(backup.Type, backup.BackupPath, "", &cronjob, client)
return targetPath, nil
}
func hasBackup(cronjobType string) bool {
return cronjobType == "app" || cronjobType == "database" || cronjobType == "website" || cronjobType == "directory" || cronjobType == "snapshot" || cronjobType == "log"
}
+18 -70
View File
@@ -2,14 +2,10 @@ package service
import (
"encoding/json"
"fmt"
"sort"
"strings"
"sync"
"time"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/disk"
@@ -24,31 +20,11 @@ type DashboardService struct{}
type IDashboardService interface {
LoadBaseInfo(ioOption string, netOption string) (*dto.DashboardBase, error)
LoadCurrentInfo(ioOption string, netOption string) *dto.DashboardCurrent
Restart(operation string) error
}
func NewIDashboardService() IDashboardService {
return &DashboardService{}
}
func (u *DashboardService) Restart(operation string) error {
if operation != "1panel" && operation != "system" {
return fmt.Errorf("handle restart operation %s failed, err: nonsupport such operation", operation)
}
itemCmd := fmt.Sprintf("%s 1pctl restart", cmd.SudoHandleCmd())
if operation == "system" {
itemCmd = fmt.Sprintf("%s reboot", cmd.SudoHandleCmd())
}
go func() {
stdout, err := cmd.Exec(itemCmd)
if err != nil {
global.LOG.Errorf("handle %s failed, err: %v", itemCmd, stdout)
}
}()
return nil
}
func (u *DashboardService) LoadBaseInfo(ioOption string, netOption string) (*dto.DashboardBase, error) {
var baseInfo dto.DashboardBase
hostInfo, err := host.Info()
@@ -175,7 +151,7 @@ type diskInfo struct {
func loadDiskInfo() []dto.DiskInfo {
var datas []dto.DiskInfo
stdout, err := cmd.ExecWithTimeOut("df -hT -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev", 2*time.Second)
stdout, err := cmd.Exec("df -hT -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev")
if err != nil {
return datas
}
@@ -209,52 +185,24 @@ func loadDiskInfo() []dto.DiskInfo {
mounts = append(mounts, diskInfo{Type: fields[1], Device: fields[0], Mount: fields[6]})
}
var (
wg sync.WaitGroup
mu sync.Mutex
)
wg.Add(len(mounts))
for i := 0; i < len(mounts); i++ {
go func(timeoutCh <-chan time.Time, mount diskInfo) {
defer wg.Done()
var itemData dto.DiskInfo
itemData.Path = mount.Mount
itemData.Type = mount.Type
itemData.Device = mount.Device
select {
case <-timeoutCh:
mu.Lock()
datas = append(datas, itemData)
mu.Unlock()
global.LOG.Errorf("load disk info from %s failed, err: timeout", mount.Mount)
default:
state, err := disk.Usage(mount.Mount)
if err != nil {
mu.Lock()
datas = append(datas, itemData)
mu.Unlock()
global.LOG.Errorf("load disk info from %s failed, err: %v", mount.Mount, err)
return
}
itemData.Total = state.Total
itemData.Free = state.Free
itemData.Used = state.Used
itemData.UsedPercent = state.UsedPercent
itemData.InodesTotal = state.InodesTotal
itemData.InodesUsed = state.InodesUsed
itemData.InodesFree = state.InodesFree
itemData.InodesUsedPercent = state.InodesUsedPercent
mu.Lock()
datas = append(datas, itemData)
mu.Unlock()
}
}(time.After(5*time.Second), mounts[i])
state, err := disk.Usage(mounts[i].Mount)
if err != nil {
continue
}
var itemData dto.DiskInfo
itemData.Path = mounts[i].Mount
itemData.Type = mounts[i].Type
itemData.Device = mounts[i].Device
itemData.Total = state.Total
itemData.Free = state.Free
itemData.Used = state.Used
itemData.UsedPercent = state.UsedPercent
itemData.InodesTotal = state.InodesTotal
itemData.InodesUsed = state.InodesUsed
itemData.InodesFree = state.InodesFree
itemData.InodesUsedPercent = state.InodesUsedPercent
datas = append(datas, itemData)
}
wg.Wait()
sort.Slice(datas, func(i, j int) bool {
return datas[i].Path < datas[j].Path
})
return datas
}
-2
View File
@@ -37,6 +37,4 @@ var (
snapshotRepo = repo.NewISnapshotRepo()
runtimeRepo = repo.NewIRunTimeRepo()
favoriteRepo = repo.NewIFavoriteRepo()
)
-83
View File
@@ -1,83 +0,0 @@
package service
import (
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
"github.com/1Panel-dev/1Panel/backend/app/dto/response"
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/buserr"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/utils/files"
"github.com/spf13/afero"
)
type FavoriteService struct {
}
type IFavoriteService interface {
Page(req dto.PageInfo) (int64, []response.FavoriteDTO, error)
Create(req request.FavoriteCreate) (*model.Favorite, error)
Delete(id uint) error
}
func NewIFavoriteService() IFavoriteService {
return &FavoriteService{}
}
func (f *FavoriteService) Page(req dto.PageInfo) (int64, []response.FavoriteDTO, error) {
total, favorites, err := favoriteRepo.Page(req.Page, req.PageSize)
if err != nil {
return 0, nil, err
}
var dtoFavorites []response.FavoriteDTO
for _, favorite := range favorites {
dtoFavorites = append(dtoFavorites, response.FavoriteDTO{
Favorite: favorite,
})
}
return total, dtoFavorites, nil
}
func (f *FavoriteService) Create(req request.FavoriteCreate) (*model.Favorite, error) {
exist, _ := favoriteRepo.GetFirst(favoriteRepo.WithByPath(req.Path))
if exist.ID > 0 {
return nil, buserr.New(constant.ErrFavoriteExist)
}
op := files.NewFileOp()
if !op.Stat(req.Path) {
return nil, buserr.New(constant.ErrLinkPathNotFound)
}
openFile, err := op.OpenFile(req.Path)
if err != nil {
return nil, err
}
fileInfo, err := openFile.Stat()
if err != nil {
return nil, err
}
favorite := &model.Favorite{
Name: fileInfo.Name(),
IsDir: fileInfo.IsDir(),
Path: req.Path,
}
if fileInfo.Size() <= 10*1024*1024 {
afs := &afero.Afero{Fs: op.Fs}
cByte, err := afs.ReadFile(req.Path)
if err == nil {
if len(cByte) > 0 && !files.DetectBinary(cByte) {
favorite.IsTxt = true
}
}
}
if err := favoriteRepo.Create(favorite); err != nil {
return nil, err
}
return favorite, nil
}
func (f *FavoriteService) Delete(id uint) error {
if err := favoriteRepo.Delete(commonRepo.WithByID(id)); err != nil {
return err
}
return nil
}
+15 -38
View File
@@ -29,9 +29,10 @@ type IFileService interface {
Create(op request.FileCreate) error
Delete(op request.FileDelete) error
BatchDelete(op request.FileBatchDelete) error
ChangeMode(op request.FileCreate) error
Compress(c request.FileCompress) error
DeCompress(c request.FileDeCompress) error
GetContent(op request.FileContentReq) (response.FileInfo, error)
GetContent(op request.FileOption) (response.FileInfo, error)
SaveContent(edit request.FileEdit) error
FileDownload(d request.FileDownload) (string, error)
DirSize(req request.DirSizeReq) (response.DirSizeRes, error)
@@ -39,8 +40,6 @@ type IFileService interface {
Wget(w request.FileWget) (string, error)
MvFile(m request.FileMove) error
ChangeOwner(req request.FileRoleUpdate) error
ChangeMode(op request.FileCreate) error
BatchChangeModeAndOwner(op request.FileRoleReq) error
}
func NewIFileService() IFileService {
@@ -134,17 +133,11 @@ func (f *FileService) Create(op request.FileCreate) error {
func (f *FileService) Delete(op request.FileDelete) error {
fo := files.NewFileOp()
if op.ForceDelete {
if op.IsDir {
return fo.DeleteDir(op.Path)
} else {
return fo.DeleteFile(op.Path)
}
if op.IsDir {
return fo.DeleteDir(op.Path)
} else {
return fo.DeleteFile(op.Path)
}
if err := NewIRecycleBinService().Create(request.RecycleBinCreate{SourcePath: op.Path}); err != nil {
return err
}
return favoriteRepo.Delete(favoriteRepo.WithByPath(op.Path))
}
func (f *FileService) BatchDelete(op request.FileBatchDelete) error {
@@ -167,24 +160,11 @@ func (f *FileService) BatchDelete(op request.FileBatchDelete) error {
func (f *FileService) ChangeMode(op request.FileCreate) error {
fo := files.NewFileOp()
return fo.ChmodR(op.Path, op.Mode, op.Sub)
}
func (f *FileService) BatchChangeModeAndOwner(op request.FileRoleReq) error {
fo := files.NewFileOp()
for _, path := range op.Paths {
if !fo.Stat(path) {
return buserr.New(constant.ErrPathNotFound)
}
if err := fo.ChownR(path, op.User, op.Group, op.Sub); err != nil {
return err
}
if err := fo.ChmodR(path, op.Mode, op.Sub); err != nil {
return err
}
if op.Sub {
return fo.ChmodR(op.Path, op.Mode)
} else {
return fo.Chmod(op.Path, fs.FileMode(op.Mode))
}
return nil
}
func (f *FileService) ChangeOwner(req request.FileRoleUpdate) error {
@@ -205,11 +185,8 @@ func (f *FileService) DeCompress(c request.FileDeCompress) error {
return fo.Decompress(c.Path, c.Dst, files.CompressType(c.Type))
}
func (f *FileService) GetContent(op request.FileContentReq) (response.FileInfo, error) {
info, err := files.NewFileInfo(files.FileOption{
Path: op.Path,
Expand: true,
})
func (f *FileService) GetContent(op request.FileOption) (response.FileInfo, error) {
info, err := files.NewFileInfo(op.FileOption)
if err != nil {
return response.FileInfo{}, err
}
@@ -246,17 +223,17 @@ func (f *FileService) MvFile(m request.FileMove) error {
return buserr.New(constant.ErrPathNotFound)
}
for _, path := range m.OldPaths {
if path == m.NewPath || strings.Contains(m.NewPath, filepath.Clean(path)+"/") {
if path == m.NewPath || strings.Contains(m.NewPath, path) {
return buserr.New(constant.ErrMovePathFailed)
}
}
if m.Type == "cut" {
return fo.Cut(m.OldPaths, m.NewPath, m.Name, m.Cover)
return fo.Cut(m.OldPaths, m.NewPath)
}
var errs []error
if m.Type == "copy" {
for _, src := range m.OldPaths {
if err := fo.CopyAndReName(src, m.NewPath, m.Name, m.Cover); err != nil {
if err := fo.Copy(src, m.NewPath); err != nil {
errs = append(errs, err)
global.LOG.Errorf("copy file [%s] to [%s] failed, err: %s", src, m.NewPath, err.Error())
}
+16 -31
View File
@@ -223,11 +223,11 @@ func (u *FirewallService) OperatePortRule(req dto.PortRuleOperate, reload bool)
req.Port = strings.ReplaceAll(req.Port, "-", ":")
req.Protocol = proto
if err := u.operatePort(client, req); err != nil {
return err
global.LOG.Errorf("%s port %s/%s failed (strategy: %s, address: %s), err: %v", req.Operation, req.Port, req.Protocol, req.Strategy, req.Address, err)
}
req.Port = strings.ReplaceAll(req.Port, ":", "-")
if err := u.addPortRecord(req); err != nil {
return err
global.LOG.Errorf("add record %s/%s failed (strategy: %s, address: %s), err: %v", req.Port, req.Protocol, req.Strategy, req.Address, err)
}
}
}
@@ -242,13 +242,13 @@ func (u *FirewallService) OperatePortRule(req dto.PortRuleOperate, reload bool)
}
req.Address = addr
if err := u.operatePort(client, req); err != nil {
return err
global.LOG.Errorf("%s port %s/%s failed (strategy: %s, address: %s), err: %v", req.Operation, req.Port, req.Protocol, req.Strategy, req.Address, err)
}
if len(req.Protocol) == 0 {
req.Protocol = "tcp/udp"
}
if err := u.addPortRecord(req); err != nil {
return err
global.LOG.Errorf("add record %s/%s failed (strategy: %s, address: %s), err: %v", req.Port, req.Protocol, req.Strategy, req.Address, err)
}
}
return nil
@@ -261,11 +261,9 @@ func (u *FirewallService) OperatePortRule(req dto.PortRuleOperate, reload bool)
req.Protocol = proto
req.Address = addr
if err := u.operatePort(client, req); err != nil {
return err
}
if err := u.addPortRecord(req); err != nil {
return err
global.LOG.Errorf("%s port %s/%s failed (strategy: %s, address: %s), err: %v", req.Operation, req.Port, req.Protocol, req.Strategy, req.Address, err)
}
_ = u.addPortRecord(req)
}
} else {
ports := strings.Split(itemPorts, ",")
@@ -278,11 +276,9 @@ func (u *FirewallService) OperatePortRule(req dto.PortRuleOperate, reload bool)
req.Port = port
req.Protocol = proto
if err := u.operatePort(client, req); err != nil {
return err
}
if err := u.addPortRecord(req); err != nil {
return err
global.LOG.Errorf("%s port %s/%s failed (strategy: %s, address: %s), err: %v", req.Operation, req.Port, req.Protocol, req.Strategy, req.Address, err)
}
_ = u.addPortRecord(req)
}
}
}
@@ -312,12 +308,10 @@ func (u *FirewallService) OperateAddressRule(req dto.AddrRuleOperate, reload boo
}
fireInfo.Address = addressList[i]
if err := client.RichRules(fireInfo, req.Operation); err != nil {
return err
global.LOG.Errorf("%s address %s failed (strategy: %s), err: %v", req.Operation, addressList[i], req.Strategy, err)
}
req.Address = addressList[i]
if err := u.addAddressRecord(req); err != nil {
return err
}
_ = u.addAddressRecord(req)
}
if reload {
return client.Reload()
@@ -538,10 +532,8 @@ func (u *FirewallService) addPortsBeforeStart(client firewall.FirewallClient) er
}
apps := u.loadPortByApp()
for _, app := range apps {
if len(app.HttpPort) != 0 && app.HttpPort != "0" {
if err := client.Port(fireClient.FireInfo{Port: app.HttpPort, Protocol: "tcp", Strategy: "accept"}, "add"); err != nil {
return err
}
if err := client.Port(fireClient.FireInfo{Port: app.HttpPort, Protocol: "tcp", Strategy: "accept"}, "add"); err != nil {
return err
}
}
@@ -553,33 +545,26 @@ func (u *FirewallService) addPortRecord(req dto.PortRuleOperate) error {
return hostRepo.DeleteFirewallRecord("port", req.Port, req.Protocol, req.Address, req.Strategy)
}
if err := hostRepo.SaveFirewallRecord(&model.Firewall{
return hostRepo.SaveFirewallRecord(&model.Firewall{
Type: "port",
Port: req.Port,
Protocol: req.Protocol,
Address: req.Address,
Strategy: req.Strategy,
Description: req.Description,
}); err != nil {
return fmt.Errorf("add record %s/%s failed (strategy: %s, address: %s), err: %v", req.Port, req.Protocol, req.Strategy, req.Address, err)
}
return nil
})
}
func (u *FirewallService) addAddressRecord(req dto.AddrRuleOperate) error {
if req.Operation == "remove" {
return hostRepo.DeleteFirewallRecord("address", "", "", req.Address, req.Strategy)
}
if err := hostRepo.SaveFirewallRecord(&model.Firewall{
return hostRepo.SaveFirewallRecord(&model.Firewall{
Type: "address",
Address: req.Address,
Strategy: req.Strategy,
Description: req.Description,
}); err != nil {
return fmt.Errorf("add record failed (strategy: %s, address: %s), err: %v", req.Strategy, req.Address, err)
}
return nil
})
}
func listIpRules(strategy string) ([]string, error) {
-5
View File
@@ -62,11 +62,6 @@ func (u *GroupService) Delete(id uint) error {
if len(websites) > 0 {
return buserr.New(constant.ErrGroupIsUsed)
}
case "command":
commands, _ := commandRepo.GetList(commonRepo.WithByGroupID(id))
if len(commands) > 0 {
return buserr.New(constant.ErrGroupIsUsed)
}
case "host":
hosts, _ := hostRepo.GetList(commonRepo.WithByGroupID(id))
if len(hosts) > 0 {
+1 -1
View File
@@ -249,7 +249,7 @@ func (u *HostService) Create(req dto.HostOperate) (*dto.HostInfo, error) {
return nil, errors.WithMessage(constant.ErrStructTransform, err.Error())
}
if req.GroupID == 0 {
group, err := groupRepo.Get(groupRepo.WithByHostDefault())
group, err := groupRepo.Get(groupRepo.WithByIsDefault(true))
if err != nil {
return nil, errors.New("get default group failed")
}
+2 -3
View File
@@ -19,7 +19,6 @@ import (
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/docker"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/pkg/archive"
)
@@ -240,7 +239,7 @@ func (u *ImageService) ImagePull(req dto.ImagePull) (string, error) {
}
options := types.ImagePullOptions{}
if repo.Auth {
authConfig := registry.AuthConfig{
authConfig := types.AuthConfig{
Username: repo.Username,
Password: repo.Password,
}
@@ -337,7 +336,7 @@ func (u *ImageService) ImagePush(req dto.ImagePush) (string, error) {
}
options := types.ImagePushOptions{}
if repo.Auth {
authConfig := registry.AuthConfig{
authConfig := types.AuthConfig{
Username: repo.Username,
Password: repo.Password,
}
+1 -1
View File
@@ -217,12 +217,12 @@ func (u *ImageRepoService) handleRegistries(newHost, delHost, handle string) err
case "create":
registries = common.RemoveRepeatElement(append(registries, newHost))
case "update":
registries = common.RemoveRepeatElement(append(registries, newHost))
for i, regi := range registries {
if regi == delHost {
registries = append(registries[:i], registries[i+1:]...)
}
}
registries = common.RemoveRepeatElement(append(registries, newHost))
case "delete":
for i, regi := range registries {
if regi == delHost {
+2 -5
View File
@@ -196,11 +196,8 @@ func opNginx(containerName, operate string) error {
if operate == constant.NginxCheck {
nginxCmd = fmt.Sprintf("docker exec -i %s %s", containerName, "nginx -t")
}
if out, err := cmd.ExecWithTimeOut(nginxCmd, 20*time.Second); err != nil {
if out != "" {
return errors.New(out)
}
return err
if out, err := cmd.ExecWithTimeOut(nginxCmd, 2*time.Second); err != nil {
return errors.New(out)
}
return nil
}
-208
View File
@@ -1,208 +0,0 @@
package service
import (
"fmt"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
"github.com/1Panel-dev/1Panel/backend/app/dto/response"
"github.com/1Panel-dev/1Panel/backend/buserr"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/utils/files"
"github.com/shirou/gopsutil/v3/disk"
"os"
"path"
"regexp"
"strconv"
"strings"
"time"
)
type RecycleBinService struct {
}
type IRecycleBinService interface {
Page(search dto.PageInfo) (int64, []response.RecycleBinDTO, error)
Create(create request.RecycleBinCreate) error
Reduce(reduce request.RecycleBinReduce) error
Clear() error
}
func NewIRecycleBinService() IRecycleBinService {
return &RecycleBinService{}
}
func (r RecycleBinService) Page(search dto.PageInfo) (int64, []response.RecycleBinDTO, error) {
var (
result []response.RecycleBinDTO
)
partitions, err := disk.Partitions(false)
if err != nil {
return 0, nil, err
}
op := files.NewFileOp()
for _, p := range partitions {
dir := path.Join(p.Mountpoint, ".1panel_clash")
if !op.Stat(dir) {
continue
}
clashFiles, err := os.ReadDir(dir)
if err != nil {
return 0, nil, err
}
for _, file := range clashFiles {
if strings.HasPrefix(file.Name(), "_1p_") {
recycleDTO, err := getRecycleBinDTOFromName(file.Name())
recycleDTO.IsDir = file.IsDir()
recycleDTO.From = dir
if err == nil {
result = append(result, *recycleDTO)
}
}
}
}
startIndex := (search.Page - 1) * search.PageSize
endIndex := startIndex + search.PageSize
if startIndex > len(result) {
return int64(len(result)), result, nil
}
if endIndex > len(result) {
endIndex = len(result)
}
return int64(len(result)), result[startIndex:endIndex], nil
}
func (r RecycleBinService) Create(create request.RecycleBinCreate) error {
op := files.NewFileOp()
if !op.Stat(create.SourcePath) {
return buserr.New(constant.ErrLinkPathNotFound)
}
clashDir, err := getClashDir(create.SourcePath)
if err != nil {
return err
}
paths := strings.Split(create.SourcePath, "/")
rNamePre := strings.Join(paths, "_1p_")
deleteTime := time.Now()
openFile, err := op.OpenFile(create.SourcePath)
if err != nil {
return err
}
fileInfo, err := openFile.Stat()
if err != nil {
return err
}
size := 0
if fileInfo.IsDir() {
sizeF, err := op.GetDirSize(create.SourcePath)
if err != nil {
return err
}
size = int(sizeF)
} else {
size = int(fileInfo.Size())
}
rName := fmt.Sprintf("_1p_%s%s_p_%d_%d", "file", rNamePre, size, deleteTime.Unix())
return op.Rename(create.SourcePath, path.Join(clashDir, rName))
}
func (r RecycleBinService) Reduce(reduce request.RecycleBinReduce) error {
filePath := path.Join(reduce.From, reduce.RName)
op := files.NewFileOp()
if !op.Stat(filePath) {
return buserr.New(constant.ErrLinkPathNotFound)
}
recycleBinDTO, err := getRecycleBinDTOFromName(reduce.RName)
if err != nil {
return err
}
if !op.Stat(path.Dir(recycleBinDTO.SourcePath)) {
return buserr.New("ErrSourcePathNotFound")
}
if op.Stat(recycleBinDTO.SourcePath) {
if err = op.RmRf(recycleBinDTO.SourcePath); err != nil {
return err
}
}
return op.Rename(filePath, recycleBinDTO.SourcePath)
}
func (r RecycleBinService) Clear() error {
partitions, err := disk.Partitions(false)
if err != nil {
return err
}
op := files.NewFileOp()
for _, p := range partitions {
dir := path.Join(p.Mountpoint, ".1panel_clash")
if !op.Stat(dir) {
continue
}
newDir := path.Join(p.Mountpoint, "1panel_clash")
if err := op.Rename(dir, newDir); err != nil {
return err
}
go func() {
_ = op.DeleteDir(newDir)
}()
}
return nil
}
func getClashDir(realPath string) (string, error) {
trimmedPath := strings.Trim(realPath, "/")
parts := strings.Split(trimmedPath, "/")
dir := ""
if len(parts) > 0 {
dir = parts[0]
partitions, err := disk.Partitions(false)
if err != nil {
return "", err
}
for _, p := range partitions {
if p.Mountpoint == dir {
if err = createClashDir(path.Join(p.Mountpoint, ".1panel_clash")); err != nil {
return "", err
}
return dir, nil
}
}
}
return constant.RecycleBinDir, createClashDir(constant.RecycleBinDir)
}
func createClashDir(clashDir string) error {
op := files.NewFileOp()
if !op.Stat(clashDir) {
if err := op.CreateDir(clashDir, 0755); err != nil {
return err
}
}
return nil
}
func getRecycleBinDTOFromName(filename string) (*response.RecycleBinDTO, error) {
r := regexp.MustCompile(`_1p_file_1p_(.+)_p_(\d+)_(\d+)`)
matches := r.FindStringSubmatch(filename)
if len(matches) != 4 {
return nil, fmt.Errorf("invalid filename format")
}
sourcePath := "/" + strings.ReplaceAll(matches[1], "_1p_", "/")
size, err := strconv.ParseInt(matches[2], 10, 64)
if err != nil {
return nil, err
}
deleteTime, err := strconv.ParseInt(matches[3], 10, 64)
if err != nil {
return nil, err
}
return &response.RecycleBinDTO{
Name: path.Base(sourcePath),
Size: int(size),
Type: "file",
DeleteTime: time.Unix(deleteTime, 0),
SourcePath: sourcePath,
RName: filename,
}, nil
}
+3 -69
View File
@@ -3,7 +3,6 @@ package service
import (
"context"
"encoding/json"
"fmt"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
"github.com/1Panel-dev/1Panel/backend/app/dto/response"
@@ -21,7 +20,6 @@ import (
"github.com/subosito/gotenv"
"os"
"path"
"regexp"
"strconv"
"strings"
"time"
@@ -40,7 +38,6 @@ type IRuntimeService interface {
OperateRuntime(req request.RuntimeOperate) error
GetNodeModules(req request.NodeModuleReq) ([]response.NodeModule, error)
OperateNodeModules(req request.NodeModuleOperateReq) error
SyncForRestart() error
}
func NewRuntimeService() IRuntimeService {
@@ -87,11 +84,6 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (err error) {
if err = checkPortExist(create.Port); err != nil {
return err
}
for _, export := range create.ExposedPorts {
if err = checkPortExist(export.HostPort); err != nil {
return err
}
}
if containerName, ok := create.Params["CONTAINER_NAME"]; ok {
if err := checkContainerName(containerName.(string)); err != nil {
return err
@@ -294,26 +286,7 @@ func (r *RuntimeService) Get(id uint) (*response.RuntimeDTO, error) {
}
res.Params[k] = port
default:
if strings.Contains(k, "CONTAINER_PORT") || strings.Contains(k, "HOST_PORT") {
if strings.Contains(k, "CONTAINER_PORT") {
r := regexp.MustCompile(`_(\d+)$`)
matches := r.FindStringSubmatch(k)
containerPort, err := strconv.Atoi(v)
if err != nil {
return nil, err
}
hostPort, err := strconv.Atoi(envs[fmt.Sprintf("HOST_PORT_%s", matches[1])])
if err != nil {
return nil, err
}
res.ExposedPorts = append(res.ExposedPorts, request.ExposedPort{
ContainerPort: containerPort,
HostPort: hostPort,
})
}
} else {
res.Params[k] = v
}
res.Params[k] = v
}
}
if v, ok := envs["CONTAINER_PACKAGE_URL"]; ok {
@@ -347,11 +320,6 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
}
runtime.Port = req.Port
}
for _, export := range req.ExposedPorts {
if err = checkPortExist(export.HostPort); err != nil {
return err
}
}
if containerName, ok := req.Params["CONTAINER_NAME"]; ok {
envs, err := gotenv.Unmarshal(runtime.Env)
if err != nil {
@@ -364,24 +332,6 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
}
}
}
appDetail, err := appDetailRepo.GetFirst(commonRepo.WithByID(runtime.AppDetailID))
if err != nil {
return err
}
app, err := appRepo.GetFirst(commonRepo.WithByID(appDetail.AppId))
if err != nil {
return err
}
fileOp := files.NewFileOp()
appVersionDir := path.Join(constant.AppResourceDir, app.Resource, app.Key, appDetail.Version)
if !fileOp.Stat(appVersionDir) || appDetail.Update {
if err := downloadApp(app, appDetail, nil); err != nil {
return err
}
_ = fileOp.Rename(path.Join(runtime.GetPath(), "run.sh"), path.Join(runtime.GetPath(), "run.sh.bak"))
_ = fileOp.CopyFile(path.Join(appVersionDir, "run.sh"), runtime.GetPath())
}
}
projectDir := path.Join(constant.RuntimeDir, runtime.Type, runtime.Name)
@@ -393,9 +343,8 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
CodeDir: req.CodeDir,
Version: req.Version,
NodeConfig: request.NodeConfig{
Port: req.Port,
Install: true,
ExposedPorts: req.ExposedPorts,
Port: req.Port,
Install: true,
},
}
composeContent, envContent, _, err := handleParams(create, projectDir)
@@ -566,18 +515,3 @@ func (r *RuntimeService) OperateNodeModules(req request.NodeModuleOperateReq) er
cmd += " " + req.Module
return cmd2.ExecContainerScript(containerName, cmd, 5*time.Minute)
}
func (r *RuntimeService) SyncForRestart() error {
runtimes, err := runtimeRepo.List()
if err != nil {
return err
}
for _, runtime := range runtimes {
if runtime.Status == constant.RuntimeBuildIng || runtime.Status == constant.RuntimeReCreating || runtime.Status == constant.RuntimeStarting || runtime.Status == constant.RuntimeCreating {
runtime.Status = constant.SystemRestart
runtime.Message = "System restart causing interrupt"
_ = runtimeRepo.Save(&runtime)
}
}
return nil
}
-59
View File
@@ -12,7 +12,6 @@ import (
"github.com/1Panel-dev/1Panel/backend/utils/files"
"github.com/pkg/errors"
"github.com/subosito/gotenv"
"gopkg.in/yaml.v3"
"io"
"net/http"
"os"
@@ -322,11 +321,6 @@ func handleParams(create request.RuntimeCreate, projectDir string) (composeConte
create.Params["RUN_INSTALL"] = "0"
}
create.Params["CONTAINER_PACKAGE_URL"] = create.Source
composeContent, err = handleNodeCompose(env, composeContent, create, projectDir)
if err != nil {
return
}
}
newMap := make(map[string]string)
@@ -334,7 +328,6 @@ func handleParams(create request.RuntimeCreate, projectDir string) (composeConte
for k, v := range newMap {
env[k] = v
}
envStr, err := gotenv.Marshal(env)
if err != nil {
return
@@ -346,58 +339,6 @@ func handleParams(create request.RuntimeCreate, projectDir string) (composeConte
return
}
func handleNodeCompose(env gotenv.Env, composeContent []byte, create request.RuntimeCreate, projectDir string) (composeByte []byte, err error) {
existMap := make(map[string]interface{})
composeMap := make(map[string]interface{})
if err = yaml.Unmarshal(composeContent, &composeMap); err != nil {
return
}
services, serviceValid := composeMap["services"].(map[string]interface{})
if !serviceValid {
err = buserr.New(constant.ErrFileParse)
return
}
serviceName := ""
serviceValue := make(map[string]interface{})
for name, service := range services {
serviceName = name
serviceValue = service.(map[string]interface{})
_, ok := serviceValue["ports"].([]interface{})
if ok {
var ports []interface{}
ports = append(ports, "${HOST_IP}:${PANEL_APP_PORT_HTTP}:${NODE_APP_PORT}")
for i, port := range create.ExposedPorts {
containerPortStr := fmt.Sprintf("CONTAINER_PORT_%d", i)
hostPortStr := fmt.Sprintf("HOST_PORT_%d", i)
existMap[containerPortStr] = struct{}{}
existMap[hostPortStr] = struct{}{}
ports = append(ports, fmt.Sprintf("${HOST_IP}:${%s}:${%s}", hostPortStr, containerPortStr))
create.Params[containerPortStr] = port.ContainerPort
create.Params[hostPortStr] = port.HostPort
}
serviceValue["ports"] = ports
}
break
}
for k := range env {
if strings.Contains(k, "CONTAINER_PORT_") || strings.Contains(k, "HOST_PORT_") {
if _, ok := existMap[k]; !ok {
delete(env, k)
}
}
}
services[serviceName] = serviceValue
composeMap["services"] = services
composeByte, err = yaml.Marshal(composeMap)
if err != nil {
return
}
fileOp := files.NewFileOp()
_ = fileOp.SaveFile(path.Join(projectDir, "docker-compose.yml"), string(composeByte), 0644)
return
}
func checkContainerName(name string) error {
dockerCli, err := docker.NewClient()
if err != nil {
-39
View File
@@ -6,7 +6,6 @@ import (
"encoding/json"
"encoding/pem"
"fmt"
"net"
"os"
"path"
"strconv"
@@ -31,12 +30,10 @@ type SettingService struct{}
type ISettingService interface {
GetSettingInfo() (*dto.SettingInfo, error)
LoadInterfaceAddr() ([]string, error)
LoadTimeZone() ([]string, error)
Update(key, value string) error
UpdatePassword(c *gin.Context, old, new string) error
UpdatePort(port uint) error
UpdateBindInfo(req dto.BindInfo) error
UpdateSSL(c *gin.Context, req dto.SSLUpdate) error
LoadFromCert() (*dto.SSLInfo, error)
HandlePasswordExpired(c *gin.Context, old, new string) error
@@ -44,7 +41,6 @@ type ISettingService interface {
SystemScan() dto.CleanData
SystemClean(req []dto.Clean)
SystemCleanForCronjob() (string, error)
}
func NewISettingService() ISettingService {
@@ -163,41 +159,6 @@ func (u *SettingService) SyncTime(req dto.SyncTime) error {
return nil
}
func (u *SettingService) LoadInterfaceAddr() ([]string, error) {
addrMap := make(map[string]struct{})
addrs, err := net.InterfaceAddrs()
if err != nil {
return nil, err
}
for _, addr := range addrs {
ipNet, ok := addr.(*net.IPNet)
if ok && ipNet.IP.To16() != nil {
addrMap[ipNet.IP.String()] = struct{}{}
}
}
var data []string
for key := range addrMap {
data = append(data, key)
}
return data, nil
}
func (u *SettingService) UpdateBindInfo(req dto.BindInfo) error {
if err := settingRepo.Update("Ipv6", req.Ipv6); err != nil {
return err
}
if err := settingRepo.Update("BindAddress", req.BindAddress); err != nil {
return err
}
go func() {
_, err := cmd.Exec("systemctl restart 1panel.service")
if err != nil {
global.LOG.Errorf("restart system with new bind info failed, err: %v", err)
}
}()
return nil
}
func (u *SettingService) UpdatePort(port uint) error {
if common.ScanPort(int(port)) {
return buserr.WithDetail(constant.ErrPortInUsed, port, nil)
+63 -172
View File
@@ -11,28 +11,10 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
"github.com/1Panel-dev/1Panel/backend/utils/common"
fileUtils "github.com/1Panel-dev/1Panel/backend/utils/files"
"github.com/google/uuid"
)
const (
upgradePath = "1panel/tmp/upgrade"
snapshotTmpPath = "1panel/tmp/system"
rollbackPath = "1panel/tmp"
cachePath = "1panel/cache"
oldOriginalPath = "original"
oldAppBackupPath = "1panel/resource/apps_bak"
oldDownloadPath = "1panel/tmp/download"
oldUpgradePath = "1panel/tmp"
tmpUploadPath = "1panel/tmp/upload"
uploadPath = "1panel/uploads"
downloadPath = "1panel/download"
logPath = "1panel/log"
dockerLogPath = "1panel/tmp/docker_logs"
taskPath = "1panel/task"
)
func (u *SettingService) SystemScan() dto.CleanData {
var (
SystemClean dto.CleanData
@@ -52,7 +34,7 @@ func (u *SettingService) SystemScan() dto.CleanData {
Children: loadTreeWithDir(true, "1panel_original", originalPath, fileOp),
})
upgradePath := path.Join(global.CONF.System.BaseDir, upgradePath)
upgradePath := path.Join(global.CONF.System.BaseDir, "1panel/tmp/upgrade")
upgradeSize, _ := fileOp.GetDirSize(upgradePath)
treeData = append(treeData, dto.CleanTree{
ID: uuid.NewString(),
@@ -94,7 +76,7 @@ func (u *SettingService) SystemScan() dto.CleanData {
Children: rollBackTree,
})
cachePath := path.Join(global.CONF.System.BaseDir, cachePath)
cachePath := path.Join(global.CONF.System.BaseDir, "1panel/cache")
cacheSize, _ := fileOp.GetDirSize(cachePath)
treeData = append(treeData, dto.CleanTree{
ID: uuid.NewString(),
@@ -143,94 +125,94 @@ func (u *SettingService) SystemClean(req []dto.Clean) {
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel_original", item.Name))
case "upgrade":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, upgradePath, item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp/upgrade", item.Name))
case "snapshot":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, snapshotTmpPath, item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp/system", item.Name))
dropFileOrDir(path.Join(global.CONF.System.Backup, "system", item.Name))
case "snapshot_tmp":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, snapshotTmpPath, item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp/system", item.Name))
case "snapshot_local":
dropFileOrDir(path.Join(global.CONF.System.Backup, "system", item.Name))
case "rollback":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, rollbackPath, "app"))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, rollbackPath, "database"))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, rollbackPath, "website"))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp/app"))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp/database"))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp/website"))
case "rollback_app":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, rollbackPath, "app", item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp/app", item.Name))
case "rollback_database":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, rollbackPath, "database", item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp/database", item.Name))
case "rollback_website":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, rollbackPath, "website", item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp/website", item.Name))
case "cache":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, cachePath, item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/cache", item.Name))
restart = true
case "unused":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, oldOriginalPath))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, oldAppBackupPath))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, oldDownloadPath))
files, _ := os.ReadDir(path.Join(global.CONF.System.BaseDir, oldUpgradePath))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "original"))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/resource/apps_bak"))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp/download"))
files, _ := os.ReadDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp"))
if len(files) == 0 {
continue
}
for _, file := range files {
if strings.HasPrefix(file.Name(), "upgrade_") {
dropFileOrDir(path.Join(global.CONF.System.BaseDir, oldUpgradePath, file.Name()))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp", file.Name()))
}
}
case "old_original":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, oldOriginalPath, item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "original", item.Name))
case "old_apps_bak":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, oldAppBackupPath, item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/resource/apps_bak", item.Name))
case "old_download":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, oldDownloadPath, item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp/download", item.Name))
case "old_upgrade":
if len(item.Name) == 0 {
files, _ := os.ReadDir(path.Join(global.CONF.System.BaseDir, oldUpgradePath))
files, _ := os.ReadDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp"))
if len(files) == 0 {
continue
}
for _, file := range files {
if strings.HasPrefix(file.Name(), "upgrade_") {
dropFileOrDir(path.Join(global.CONF.System.BaseDir, oldUpgradePath, file.Name()))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp", file.Name()))
}
}
} else {
dropFileOrDir(path.Join(global.CONF.System.BaseDir, oldUpgradePath, item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp", item.Name))
}
case "upload":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, uploadPath, item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/uploads", item.Name))
if len(item.Name) == 0 {
dropFileOrDir(path.Join(global.CONF.System.BaseDir, tmpUploadPath))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp/upload"))
}
case "upload_tmp":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, tmpUploadPath, item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp/upload", item.Name))
case "upload_app":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, uploadPath, "app", item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/uploads/app", item.Name))
case "upload_database":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, uploadPath, "database", item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/uploads/database", item.Name))
case "upload_website":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, uploadPath, "website", item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/uploads/website", item.Name))
case "upload_directory":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, uploadPath, "directory", item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/uploads/directory", item.Name))
case "download":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, downloadPath, item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/download", item.Name))
case "download_app":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, downloadPath, "app", item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/download/app", item.Name))
case "download_database":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, downloadPath, "database", item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/download/database", item.Name))
case "download_website":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, downloadPath, "website", item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/download/website", item.Name))
case "download_directory":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, downloadPath, "directory", item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/download/directory", item.Name))
case "system_log":
if len(item.Name) == 0 {
files, _ := os.ReadDir(path.Join(global.CONF.System.BaseDir, logPath))
files, _ := os.ReadDir(path.Join(global.CONF.System.BaseDir, "1panel/log"))
if len(files) == 0 {
continue
}
@@ -238,16 +220,16 @@ func (u *SettingService) SystemClean(req []dto.Clean) {
if file.Name() == "1Panel.log" {
continue
}
dropFileOrDir(path.Join(global.CONF.System.BaseDir, logPath, file.Name()))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/log", file.Name()))
}
} else {
dropFileOrDir(path.Join(global.CONF.System.BaseDir, logPath, item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/log", item.Name))
}
case "docker_log":
dropFileOrDir(path.Join(global.CONF.System.BaseDir, dockerLogPath, item.Name))
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/tmp/docker_logs", item.Name))
case "task_log":
pathItem := path.Join(global.CONF.System.BaseDir, taskPath, item.Name)
dropFileOrDir(path.Join(global.CONF.System.BaseDir, taskPath, item.Name))
pathItem := path.Join(global.CONF.System.BaseDir, "1panel/task", item.Name)
dropFileOrDir(path.Join(global.CONF.System.BaseDir, "1panel/task", item.Name))
if len(item.Name) == 0 {
files, _ := os.ReadDir(pathItem)
if len(files) == 0 {
@@ -276,70 +258,9 @@ func (u *SettingService) SystemClean(req []dto.Clean) {
}
}
func (u *SettingService) SystemCleanForCronjob() (string, error) {
logs := ""
size := int64(0)
fileCount := 0
dropFileOrDirWithLog(path.Join(global.CONF.System.BaseDir, "1panel_original"), &logs, &size, &fileCount)
upgradePath := path.Join(global.CONF.System.BaseDir, upgradePath)
upgradeFiles, _ := os.ReadDir(upgradePath)
if len(upgradeFiles) != 0 {
sort.Slice(upgradeFiles, func(i, j int) bool {
return upgradeFiles[i].Name() > upgradeFiles[j].Name()
})
for i := 0; i < len(upgradeFiles); i++ {
if i != 0 {
dropFileOrDirWithLog(path.Join(upgradePath, upgradeFiles[i].Name()), &logs, &size, &fileCount)
}
}
}
dropFileOrDirWithLog(path.Join(global.CONF.System.BaseDir, snapshotTmpPath), &logs, &size, &fileCount)
dropFileOrDirWithLog(path.Join(global.CONF.System.Backup, "system"), &logs, &size, &fileCount)
dropFileOrDirWithLog(path.Join(global.CONF.System.BaseDir, rollbackPath, "app"), &logs, &size, &fileCount)
dropFileOrDirWithLog(path.Join(global.CONF.System.BaseDir, rollbackPath, "website"), &logs, &size, &fileCount)
dropFileOrDirWithLog(path.Join(global.CONF.System.BaseDir, rollbackPath, "database"), &logs, &size, &fileCount)
dropFileOrDirWithLog(path.Join(global.CONF.System.BaseDir, oldOriginalPath), &logs, &size, &fileCount)
dropFileOrDirWithLog(path.Join(global.CONF.System.BaseDir, oldAppBackupPath), &logs, &size, &fileCount)
dropFileOrDirWithLog(path.Join(global.CONF.System.BaseDir, oldDownloadPath), &logs, &size, &fileCount)
oldUpgradePath := path.Join(global.CONF.System.BaseDir, oldUpgradePath)
oldUpgradeFiles, _ := os.ReadDir(oldUpgradePath)
if len(oldUpgradeFiles) != 0 {
for i := 0; i < len(oldUpgradeFiles); i++ {
dropFileOrDirWithLog(path.Join(oldUpgradePath, oldUpgradeFiles[i].Name()), &logs, &size, &fileCount)
}
}
dropFileOrDirWithLog(path.Join(global.CONF.System.BaseDir, tmpUploadPath), &logs, &size, &fileCount)
dropFileOrDirWithLog(path.Join(global.CONF.System.BaseDir, uploadPath), &logs, &size, &fileCount)
dropFileOrDirWithLog(path.Join(global.CONF.System.BaseDir, downloadPath), &logs, &size, &fileCount)
logPath := path.Join(global.CONF.System.BaseDir, logPath)
logFiles, _ := os.ReadDir(logPath)
if len(logFiles) != 0 {
for i := 0; i < len(logFiles); i++ {
if logFiles[i].Name() != "1Panel.log" {
dropFileOrDirWithLog(path.Join(logPath, logFiles[i].Name()), &logs, &size, &fileCount)
}
}
}
timeNow := time.Now().Format("2006-01-02 15:04:05")
dropFileOrDirWithLog(path.Join(global.CONF.System.BaseDir, dockerLogPath), &logs, &size, &fileCount)
logs += fmt.Sprintf("\n%s: total clean: %s, total count: %d", timeNow, common.LoadSizeUnit2F(float64(size)), fileCount)
_ = settingRepo.Update("LastCleanTime", timeNow)
_ = settingRepo.Update("LastCleanSize", fmt.Sprintf("%v", size))
_ = settingRepo.Update("LastCleanData", fmt.Sprintf("%v", fileCount))
return logs, nil
}
func loadSnapshotTree(fileOp fileUtils.FileOp) []dto.CleanTree {
var treeData []dto.CleanTree
path1 := path.Join(global.CONF.System.BaseDir, snapshotTmpPath)
path1 := path.Join(global.CONF.System.BaseDir, "1panel/tmp/system")
list1 := loadTreeWithAllFile(true, path1, "snapshot_tmp", path1, fileOp)
if len(list1) != 0 {
size, _ := fileOp.GetDirSize(path1)
@@ -357,17 +278,17 @@ func loadSnapshotTree(fileOp fileUtils.FileOp) []dto.CleanTree {
func loadRollBackTree(fileOp fileUtils.FileOp) []dto.CleanTree {
var treeData []dto.CleanTree
path1 := path.Join(global.CONF.System.BaseDir, rollbackPath, "app")
path1 := path.Join(global.CONF.System.BaseDir, "1panel/tmp/app")
list1 := loadTreeWithAllFile(true, path1, "rollback_app", path1, fileOp)
size1, _ := fileOp.GetDirSize(path1)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "rollback_app", Size: uint64(size1), Children: list1, Type: "rollback_app", IsRecommend: true})
path2 := path.Join(global.CONF.System.BaseDir, rollbackPath, "website")
path2 := path.Join(global.CONF.System.BaseDir, "1panel/tmp/website")
list2 := loadTreeWithAllFile(true, path2, "rollback_website", path2, fileOp)
size2, _ := fileOp.GetDirSize(path2)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "rollback_website", Size: uint64(size2), Children: list2, Type: "rollback_website", IsRecommend: true})
path3 := path.Join(global.CONF.System.BaseDir, rollbackPath, "database")
path3 := path.Join(global.CONF.System.BaseDir, "1panel/tmp/database")
list3 := loadTreeWithAllFile(true, path3, "rollback_database", path3, fileOp)
size3, _ := fileOp.GetDirSize(path3)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "rollback_database", Size: uint64(size3), Children: list3, Type: "rollback_database", IsRecommend: true})
@@ -377,28 +298,28 @@ func loadRollBackTree(fileOp fileUtils.FileOp) []dto.CleanTree {
func loadUnusedFile(fileOp fileUtils.FileOp) []dto.CleanTree {
var treeData []dto.CleanTree
path1 := path.Join(global.CONF.System.BaseDir, oldOriginalPath)
path1 := path.Join(global.CONF.System.BaseDir, "original")
list1 := loadTreeWithAllFile(true, path1, "old_original", path1, fileOp)
if len(list1) != 0 {
size, _ := fileOp.GetDirSize(path1)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "old_original", Size: uint64(size), Children: list1, Type: "old_original"})
}
path2 := path.Join(global.CONF.System.BaseDir, oldAppBackupPath)
path2 := path.Join(global.CONF.System.BaseDir, "1panel/resource/apps_bak")
list2 := loadTreeWithAllFile(true, path2, "old_apps_bak", path2, fileOp)
if len(list2) != 0 {
size, _ := fileOp.GetDirSize(path2)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "old_apps_bak", Size: uint64(size), Children: list2, Type: "old_apps_bak"})
}
path3 := path.Join(global.CONF.System.BaseDir, oldDownloadPath)
path3 := path.Join(global.CONF.System.BaseDir, "1panel/tmp/download")
list3 := loadTreeWithAllFile(true, path3, "old_download", path3, fileOp)
if len(list3) != 0 {
size, _ := fileOp.GetDirSize(path3)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "old_download", Size: uint64(size), Children: list3, Type: "old_download"})
}
path4 := path.Join(global.CONF.System.BaseDir, oldUpgradePath)
path4 := path.Join(global.CONF.System.BaseDir, "1panel/tmp")
list4 := loadTreeWithDir(true, "old_upgrade", path4, fileOp)
itemSize := uint64(0)
for _, item := range list4 {
@@ -413,32 +334,32 @@ func loadUnusedFile(fileOp fileUtils.FileOp) []dto.CleanTree {
func loadUploadTree(fileOp fileUtils.FileOp) []dto.CleanTree {
var treeData []dto.CleanTree
path0 := path.Join(global.CONF.System.BaseDir, tmpUploadPath)
path0 := path.Join(global.CONF.System.BaseDir, "1panel/tmp/upload")
list0 := loadTreeWithAllFile(true, path0, "upload_tmp", path0, fileOp)
size0, _ := fileOp.GetDirSize(path0)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "upload_tmp", Size: uint64(size0), Children: list0, Type: "upload_tmp", IsRecommend: true})
path1 := path.Join(global.CONF.System.BaseDir, uploadPath, "app")
path1 := path.Join(global.CONF.System.BaseDir, "1panel/uploads/app")
list1 := loadTreeWithAllFile(true, path1, "upload_app", path1, fileOp)
size1, _ := fileOp.GetDirSize(path1)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "upload_app", Size: uint64(size1), Children: list1, Type: "upload_app", IsRecommend: true})
path2 := path.Join(global.CONF.System.BaseDir, uploadPath, "website")
path2 := path.Join(global.CONF.System.BaseDir, "1panel/uploads/website")
list2 := loadTreeWithAllFile(true, path2, "upload_website", path2, fileOp)
size2, _ := fileOp.GetDirSize(path2)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "upload_website", Size: uint64(size2), Children: list2, Type: "upload_website", IsRecommend: true})
path3 := path.Join(global.CONF.System.BaseDir, uploadPath, "database")
path3 := path.Join(global.CONF.System.BaseDir, "1panel/uploads/database")
list3 := loadTreeWithAllFile(true, path3, "upload_database", path3, fileOp)
size3, _ := fileOp.GetDirSize(path3)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "upload_database", Size: uint64(size3), Children: list3, Type: "upload_database", IsRecommend: true})
path4 := path.Join(global.CONF.System.BaseDir, uploadPath, "directory")
path4 := path.Join(global.CONF.System.BaseDir, "1panel/uploads/directory")
list4 := loadTreeWithAllFile(true, path4, "upload_directory", path4, fileOp)
size4, _ := fileOp.GetDirSize(path4)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "upload_directory", Size: uint64(size4), Children: list4, Type: "upload_directory", IsRecommend: true})
path5 := path.Join(global.CONF.System.BaseDir, uploadPath)
path5 := path.Join(global.CONF.System.BaseDir, "1panel/uploads")
uploadTreeData := loadTreeWithAllFile(true, path5, "upload", path5, fileOp)
treeData = append(treeData, uploadTreeData...)
@@ -447,27 +368,27 @@ func loadUploadTree(fileOp fileUtils.FileOp) []dto.CleanTree {
func loadDownloadTree(fileOp fileUtils.FileOp) []dto.CleanTree {
var treeData []dto.CleanTree
path1 := path.Join(global.CONF.System.BaseDir, downloadPath, "app")
path1 := path.Join(global.CONF.System.BaseDir, "1panel/download/app")
list1 := loadTreeWithAllFile(true, path1, "download_app", path1, fileOp)
size1, _ := fileOp.GetDirSize(path1)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "download_app", Size: uint64(size1), Children: list1, Type: "download_app", IsRecommend: true})
path2 := path.Join(global.CONF.System.BaseDir, downloadPath, "website")
path2 := path.Join(global.CONF.System.BaseDir, "1panel/download/website")
list2 := loadTreeWithAllFile(true, path2, "download_website", path2, fileOp)
size2, _ := fileOp.GetDirSize(path2)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "download_website", Size: uint64(size2), Children: list2, Type: "download_website", IsRecommend: true})
path3 := path.Join(global.CONF.System.BaseDir, downloadPath, "database")
path3 := path.Join(global.CONF.System.BaseDir, "1panel/download/database")
list3 := loadTreeWithAllFile(true, path3, "download_database", path3, fileOp)
size3, _ := fileOp.GetDirSize(path3)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "download_database", Size: uint64(size3), Children: list3, Type: "download_database", IsRecommend: true})
path4 := path.Join(global.CONF.System.BaseDir, downloadPath, "directory")
path4 := path.Join(global.CONF.System.BaseDir, "1panel/download/directory")
list4 := loadTreeWithAllFile(true, path4, "download_directory", path4, fileOp)
size4, _ := fileOp.GetDirSize(path4)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "download_directory", Size: uint64(size4), Children: list4, Type: "download_directory", IsRecommend: true})
path5 := path.Join(global.CONF.System.BaseDir, downloadPath)
path5 := path.Join(global.CONF.System.BaseDir, "1panel/download")
uploadTreeData := loadTreeWithAllFile(true, path5, "download", path5, fileOp)
treeData = append(treeData, uploadTreeData...)
@@ -476,7 +397,7 @@ func loadDownloadTree(fileOp fileUtils.FileOp) []dto.CleanTree {
func loadLogTree(fileOp fileUtils.FileOp) []dto.CleanTree {
var treeData []dto.CleanTree
path1 := path.Join(global.CONF.System.BaseDir, logPath)
path1 := path.Join(global.CONF.System.BaseDir, "1panel/log")
list1 := loadTreeWithAllFile(true, path1, "system_log", path1, fileOp)
size := uint64(0)
for _, file := range list1 {
@@ -484,12 +405,12 @@ func loadLogTree(fileOp fileUtils.FileOp) []dto.CleanTree {
}
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "system_log", Size: uint64(size), Children: list1, Type: "system_log", IsRecommend: true})
path2 := path.Join(global.CONF.System.BaseDir, dockerLogPath)
path2 := path.Join(global.CONF.System.BaseDir, "1panel/tmp/docker_logs")
list2 := loadTreeWithAllFile(true, path2, "docker_log", path2, fileOp)
size2, _ := fileOp.GetDirSize(path2)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "docker_log", Size: uint64(size2), Children: list2, Type: "docker_log", IsRecommend: true})
path3 := path.Join(global.CONF.System.BaseDir, taskPath)
path3 := path.Join(global.CONF.System.BaseDir, "1panel/task")
list3 := loadTreeWithAllFile(false, path3, "task_log", path3, fileOp)
size3, _ := fileOp.GetDirSize(path3)
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "task_log", Size: uint64(size3), Children: list3, Type: "task_log"})
@@ -585,33 +506,3 @@ func dropFileOrDir(itemPath string) {
global.LOG.Errorf("drop file %s failed, err %v", itemPath, err)
}
}
func dropFileOrDirWithLog(itemPath string, log *string, size *int64, count *int) {
itemSize := int64(0)
itemCount := 0
scanFile(itemPath, &itemSize, &itemCount)
*size += itemSize
*count += itemCount
if err := os.RemoveAll(itemPath); err != nil {
global.LOG.Errorf("drop file %s failed, err %v", itemPath, err)
*log += fmt.Sprintf("- drop file %s failed, err: %v \n\n", itemPath, err)
return
}
*log += fmt.Sprintf("+ drop file %s successful!, size: %s, count: %d \n\n", itemPath, common.LoadSizeUnit2F(float64(itemSize)), itemCount)
}
func scanFile(pathItem string, size *int64, count *int) {
files, _ := os.ReadDir(pathItem)
for _, f := range files {
if f.IsDir() {
scanFile(path.Join(pathItem, f.Name()), size, count)
} else {
fileInfo, err := f.Info()
if err != nil {
continue
}
*count++
*size += fileInfo.Size()
}
}
}
-1
View File
@@ -215,7 +215,6 @@ func handleSnapTar(sourceDir, targetDir, name, exclusionRules string) error {
exStr := ""
excludes := strings.Split(exclusionRules, ";")
excludes = append(excludes, "*.sock")
for _, exclude := range excludes {
if len(exclude) == 0 {
continue
+20 -53
View File
@@ -30,7 +30,7 @@ type ISSHService interface {
GetSSHInfo() (*dto.SSHInfo, error)
OperateSSH(operation string) error
UpdateByFile(value string) error
Update(req dto.SSHUpdate) error
Update(key, value string) error
GenerateSSH(req dto.GenerateSSH) error
AnalysisLog(req dto.SearchForAnalysis) (*dto.AnalysisRes, error)
LoadSSHSecret(mode string) (string, error)
@@ -45,7 +45,6 @@ func NewISSHService() ISSHService {
func (u *SSHService) GetSSHInfo() (*dto.SSHInfo, error) {
data := dto.SSHInfo{
AutoStart: true,
Status: constant.StatusEnable,
Message: "",
Port: "22",
@@ -69,17 +68,6 @@ func (u *SSHService) GetSSHInfo() (*dto.SSHInfo, error) {
}
}
out, err := systemctl.RunSystemCtl("is-enabled", serviceName)
if err != nil {
data.AutoStart = false
} else {
if out == "alias\n" {
data.AutoStart, _ = systemctl.IsEnable("ssh")
} else {
data.AutoStart = out == "enabled\n"
}
}
sshConf, err := os.ReadFile(sshPath)
if err != nil {
data.Message = err.Error()
@@ -110,28 +98,22 @@ func (u *SSHService) GetSSHInfo() (*dto.SSHInfo, error) {
}
func (u *SSHService) OperateSSH(operation string) error {
serviceName, err := loadServiceName()
if err != nil {
return err
}
sudo := cmd.SudoHandleCmd()
if operation == "enable" || operation == "disable" {
serviceName += ".service"
}
stdout, err := cmd.Execf("%s systemctl %s %s", sudo, operation, serviceName)
if err != nil {
if strings.Contains(stdout, "alias name or linked unit file") {
stdout, err := cmd.Execf("%s systemctl %s ssh", sudo, operation)
if err != nil {
return fmt.Errorf("%s ssh(alias name or linked unit file) failed, stdout: %s, err: %v", operation, stdout, err)
}
if operation == "start" || operation == "stop" || operation == "restart" {
serviceName, err := loadServiceName()
if err != nil {
return err
}
return fmt.Errorf("%s %s failed, stdout: %s, err: %v", operation, serviceName, stdout, err)
sudo := cmd.SudoHandleCmd()
stdout, err := cmd.Execf("%s systemctl %s %s", sudo, operation, serviceName)
if err != nil {
return fmt.Errorf("%s %s failed, stdout: %s, err: %v", operation, serviceName, stdout, err)
}
return nil
}
return nil
return fmt.Errorf("not support such operation: %s", operation)
}
func (u *SSHService) Update(req dto.SSHUpdate) error {
func (u *SSHService) Update(key, value string) error {
serviceName, err := loadServiceName()
if err != nil {
return err
@@ -142,7 +124,10 @@ func (u *SSHService) Update(req dto.SSHUpdate) error {
return err
}
lines := strings.Split(string(sshConf), "\n")
newFiles := updateSSHConf(lines, req.Key, req.NewValue)
newFiles := updateSSHConf(lines, key, value)
if err := settingRepo.Update(key, value); err != nil {
return err
}
file, err := os.OpenFile(sshPath, os.O_WRONLY|os.O_TRUNC, 0666)
if err != nil {
return err
@@ -152,28 +137,10 @@ func (u *SSHService) Update(req dto.SSHUpdate) error {
return err
}
sudo := cmd.SudoHandleCmd()
if req.Key == "Port" {
if key == "Port" {
stdout, _ := cmd.Execf("%s getenforce", sudo)
if stdout == "Enforcing\n" {
_, _ = cmd.Execf("%s semanage port -a -t ssh_port_t -p tcp %s", sudo, req.NewValue)
}
ruleItem := dto.PortRuleUpdate{
OldRule: dto.PortRuleOperate{
Operation: "remove",
Port: req.OldValue,
Protocol: "tcp",
Strategy: "accept",
},
NewRule: dto.PortRuleOperate{
Operation: "add",
Port: req.NewValue,
Protocol: "tcp",
Strategy: "accept",
},
}
if err := NewIFirewallService().UpdatePortRule(ruleItem); err != nil {
global.LOG.Errorf("reset firewall rules %s -> %s failed, err: %v", req.OldValue, req.OldValue, err)
_, _ = cmd.Execf("%s semanage port -a -t ssh_port_t -p tcp %s", sudo, value)
}
}
@@ -658,7 +625,7 @@ func loadFailedSecureDatas(line string) dto.SSHHistory {
return data
}
index := 0
if strings.Contains(line, " invalid user") {
if strings.Contains("line", " invalid user") {
index = 2
}
data = dto.SSHHistory{
+99 -42
View File
@@ -19,6 +19,7 @@ import (
"time"
"github.com/1Panel-dev/1Panel/backend/i18n"
"github.com/1Panel-dev/1Panel/backend/utils/common"
"github.com/spf13/afero"
"github.com/1Panel-dev/1Panel/backend/utils/compose"
@@ -58,7 +59,7 @@ type IWebsiteService interface {
UpdateWebsite(req request.WebsiteUpdate) error
DeleteWebsite(req request.WebsiteDelete) error
GetWebsite(id uint) (response.WebsiteDTO, error)
CreateWebsiteDomain(create request.WebsiteDomainCreate) ([]model.WebsiteDomain, error)
CreateWebsiteDomain(create request.WebsiteDomainCreate) (model.WebsiteDomain, error)
GetWebsiteDomain(websiteId uint) ([]model.WebsiteDomain, error)
DeleteWebsiteDomain(domainId uint) error
@@ -170,35 +171,67 @@ func (w WebsiteService) GetWebsites() ([]response.WebsiteDTO, error) {
}
func (w WebsiteService) CreateWebsite(create request.WebsiteCreate) (err error) {
primaryDomainArray := strings.Split(create.PrimaryDomain, ":")
primaryDomain := primaryDomainArray[0]
if exist, _ := websiteRepo.GetBy(websiteRepo.WithDomain(primaryDomain)); len(exist) > 0 {
if exist, _ := websiteRepo.GetBy(websiteRepo.WithDomain(create.PrimaryDomain)); len(exist) > 0 {
return buserr.New(constant.ErrDomainIsExist)
}
if exist, _ := websiteRepo.GetBy(websiteRepo.WithAlias(create.Alias)); len(exist) > 0 {
return buserr.New(constant.ErrAliasIsExist)
}
if exist, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithDomain(create.PrimaryDomain)); len(exist) > 0 {
return buserr.New(constant.ErrDomainIsExist)
}
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
if err != nil {
return err
}
defaultHttpPort := nginxInstall.HttpPort
primaryDomainArray := strings.Split(create.PrimaryDomain, ":")
primaryDomain := primaryDomainArray[0]
var (
otherDomains []model.WebsiteDomain
domains []model.WebsiteDomain
domains []model.WebsiteDomain
ports = make(map[int]struct{})
)
domains, _, _, err = getWebsiteDomains(create.PrimaryDomain, defaultHttpPort, 0)
if err != nil {
return err
domainArray := strings.Split(create.OtherDomains, "\n")
domainArray = append(domainArray, create.PrimaryDomain)
for _, domain := range domainArray {
if domain == "" {
continue
}
domainModel, err := getDomain(domain, defaultHttpPort)
if err != nil {
return err
}
if reflect.DeepEqual(domainModel, model.WebsiteDomain{}) {
continue
}
domains = append(domains, domainModel)
if domainModel.Port != defaultHttpPort {
ports[domainModel.Port] = struct{}{}
}
}
otherDomains, _, _, err = getWebsiteDomains(create.OtherDomains, defaultHttpPort, 0)
if err != nil {
return err
for port := range ports {
if existPorts, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithPort(port)); len(existPorts) == 0 {
errMap := make(map[string]interface{})
errMap["port"] = port
appInstall, _ := appInstallRepo.GetFirst(appInstallRepo.WithPort(port))
if appInstall.ID > 0 {
errMap["type"] = i18n.GetMsgByKey("TYPE_APP")
errMap["name"] = appInstall.Name
return buserr.WithMap("ErrPortExist", errMap, nil)
}
runtime, _ := runtimeRepo.GetFirst(runtimeRepo.WithPort(port))
if runtime != nil {
errMap["type"] = i18n.GetMsgByKey("TYPE_RUNTIME")
errMap["name"] = runtime.Name
return buserr.WithMap("ErrPortExist", errMap, nil)
}
if common.ScanPort(create.Port) {
return buserr.WithDetail(constant.ErrPortInUsed, create.Port, nil)
}
}
}
domains = append(domains, otherDomains...)
defaultDate, _ := time.Parse(constant.DateLayout, constant.DefaultDate)
website := &model.Website{
@@ -448,34 +481,58 @@ func (w WebsiteService) DeleteWebsite(req request.WebsiteDelete) error {
return nil
}
func (w WebsiteService) CreateWebsiteDomain(create request.WebsiteDomainCreate) ([]model.WebsiteDomain, error) {
func (w WebsiteService) CreateWebsiteDomain(create request.WebsiteDomainCreate) (model.WebsiteDomain, error) {
var (
domainModels []model.WebsiteDomain
addPorts []int
addDomains []string
domainModel model.WebsiteDomain
ports []int
domains []string
)
httpPort, _, err := getAppInstallPort(constant.AppOpenresty)
if err != nil {
return nil, err
return domainModel, err
}
if create.Port != httpPort {
if existPorts, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithPort(create.Port)); len(existPorts) == 0 {
if existAppInstall, _ := appInstallRepo.GetFirst(appInstallRepo.WithPort(create.Port)); existAppInstall.ID > 0 {
return domainModel, buserr.WithMap(constant.ErrPortInOtherApp, map[string]interface{}{"port": create.Port, "apps": existAppInstall.App.Name}, nil)
}
if common.ScanPort(create.Port) {
return domainModel, buserr.WithDetail(constant.ErrPortInUsed, create.Port, nil)
}
}
}
if existDomains, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithDomain(create.Domain), websiteDomainRepo.WithPort(create.Port)); len(existDomains) > 0 {
return domainModel, buserr.WithDetail(constant.ErrDomainIsExist, create.Domain, nil)
}
website, err := websiteRepo.GetFirst(commonRepo.WithByID(create.WebsiteID))
if err != nil {
return nil, err
return domainModel, err
}
if oldDomains, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithWebsiteId(create.WebsiteID), websiteDomainRepo.WithPort(create.Port)); len(oldDomains) == 0 {
ports = append(ports, create.Port)
}
domainModels, addPorts, addDomains, err = getWebsiteDomains(create.Domains, httpPort, create.WebsiteID)
if err != nil {
return nil, err
}
go func() {
_ = OperateFirewallPort(nil, addPorts)
}()
if err := addListenAndServerName(website, addPorts, addDomains); err != nil {
return nil, err
if oldDomains, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithWebsiteId(create.WebsiteID), websiteDomainRepo.WithDomain(create.Domain)); len(oldDomains) == 0 {
domains = append(domains, create.Domain)
}
return domainModels, websiteDomainRepo.BatchCreate(context.TODO(), domainModels)
if err := addListenAndServerName(website, ports, domains); err != nil {
return domainModel, err
}
domainModel = model.WebsiteDomain{
Domain: create.Domain,
Port: create.Port,
WebsiteID: create.WebsiteID,
}
if create.Port != httpPort {
go func() {
_ = OperateFirewallPort(nil, []int{create.Port})
}()
}
return domainModel, websiteDomainRepo.Create(context.TODO(), &domainModel)
}
func (w WebsiteService) GetWebsiteDomain(websiteId uint) ([]model.WebsiteDomain, error) {
@@ -1249,7 +1306,6 @@ func (w WebsiteService) ChangePHPVersion(req request.WebsitePHPVersionReq) error
fpmConfDir = path.Join(confDir, "php-fpm.conf")
phpDir = path.Join(constant.RuntimeDir, runtime.Type, runtime.Name, "php")
oldFmContent, _ = fileOp.GetContent(fpmConfDir)
newComposeByte []byte
)
envParams := make(map[string]string, len(envs))
handleMap(envs, envParams)
@@ -1269,13 +1325,7 @@ func (w WebsiteService) ChangePHPVersion(req request.WebsitePHPVersionReq) error
if busErr = env.Write(envParams, envPath); busErr != nil {
return busErr
}
newComposeByte, busErr = changeServiceName(composePath, appInstall.ServiceName)
if busErr != nil {
return err
}
if busErr = fileOp.WriteFile(composePath, bytes.NewReader(newComposeByte), 0775); busErr != nil {
if busErr = fileOp.WriteFile(composePath, strings.NewReader(appDetail.DockerCompose), 0775); busErr != nil {
return busErr
}
if !req.RetainConfig {
@@ -1305,7 +1355,7 @@ func (w WebsiteService) ChangePHPVersion(req request.WebsitePHPVersionReq) error
appInstall.AppDetailId = runtime.AppDetailID
appInstall.AppId = appDetail.AppId
appInstall.Version = appDetail.Version
appInstall.DockerCompose = string(newComposeByte)
appInstall.DockerCompose = appDetail.DockerCompose
_ = appInstallRepo.Save(context.Background(), &appInstall)
website.RuntimeID = req.RuntimeID
@@ -2093,8 +2143,15 @@ func (w WebsiteService) OperateRedirect(req request.NginxRedirectReq) (err error
})
}
case "404":
if req.KeepPath && !req.RedirectRoot {
target = req.Target + "$request_uri"
}
if req.RedirectRoot {
target = "/"
} else {
if req.KeepPath {
target = req.Target + "$request_uri"
}
}
block = &components.Block{
Directives: []components.IDirective{
@@ -2109,7 +2166,7 @@ func (w WebsiteService) OperateRedirect(req request.NginxRedirectReq) (err error
Directives: []components.IDirective{
&components.Directive{
Name: "return",
Parameters: []string{req.Redirect, target},
Parameters: []string{"301", target},
},
},
},
-59
View File
@@ -11,7 +11,6 @@ import (
"github.com/1Panel-dev/1Panel/backend/buserr"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/files"
"github.com/1Panel-dev/1Panel/backend/utils/ssl"
"path"
"strconv"
@@ -31,7 +30,6 @@ type IWebsiteSSLService interface {
GetWebsiteSSL(websiteId uint) (response.WebsiteSSLDTO, error)
Delete(id uint) error
Update(update request.WebsiteSSLUpdate) error
Upload(req request.WebsiteSSLUpload) error
}
func NewIWebsiteSSLService() IWebsiteSSLService {
@@ -291,60 +289,3 @@ func (w WebsiteSSLService) Update(update request.WebsiteSSLUpdate) error {
websiteSSL.AutoRenew = update.AutoRenew
return websiteSSLRepo.Save(websiteSSL)
}
func (w WebsiteSSLService) Upload(req request.WebsiteSSLUpload) error {
newSSL := &model.WebsiteSSL{
Provider: constant.Manual,
}
if req.Type == "local" {
fileOp := files.NewFileOp()
if !fileOp.Stat(req.PrivateKeyPath) {
return buserr.New("ErrSSLKeyNotFound")
}
if !fileOp.Stat(req.CertificatePath) {
return buserr.New("ErrSSLCertificateNotFound")
}
if content, err := fileOp.GetContent(req.PrivateKeyPath); err != nil {
return err
} else {
newSSL.PrivateKey = string(content)
}
if content, err := fileOp.GetContent(req.CertificatePath); err != nil {
return err
} else {
newSSL.Pem = string(content)
}
} else {
newSSL.PrivateKey = req.PrivateKey
newSSL.Pem = req.Certificate
}
privateKeyCertBlock, _ := pem.Decode([]byte(newSSL.PrivateKey))
if privateKeyCertBlock == nil {
return buserr.New("ErrSSLKeyFormat")
}
certBlock, _ := pem.Decode([]byte(newSSL.Pem))
if certBlock == nil {
return buserr.New("ErrSSLCertificateFormat")
}
cert, err := x509.ParseCertificate(certBlock.Bytes)
if err != nil {
return err
}
newSSL.ExpireDate = cert.NotAfter
newSSL.StartDate = cert.NotBefore
newSSL.Type = cert.Issuer.CommonName
if len(cert.Issuer.Organization) > 0 {
newSSL.Organization = cert.Issuer.Organization[0]
} else {
newSSL.Organization = cert.Issuer.CommonName
}
if len(cert.DNSNames) > 0 {
newSSL.PrimaryDomain = cert.DNSNames[0]
newSSL.Domains = strings.Join(cert.DNSNames, ",")
}
return websiteSSLRepo.Create(context.Background(), newSSL)
}
+1 -108
View File
@@ -3,13 +3,9 @@ package service
import (
"fmt"
"github.com/1Panel-dev/1Panel/backend/buserr"
"github.com/1Panel-dev/1Panel/backend/i18n"
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
"github.com/1Panel-dev/1Panel/backend/utils/common"
"github.com/1Panel-dev/1Panel/backend/utils/nginx/components"
"gopkg.in/yaml.v3"
"path"
"reflect"
"strconv"
"strings"
"time"
@@ -40,10 +36,7 @@ func getDomain(domainStr string, defaultPort int) (model.WebsiteDomain, error) {
portStr := domainArray[1]
portN, err := strconv.Atoi(portStr)
if err != nil {
return model.WebsiteDomain{}, buserr.WithName("ErrTypePort", portStr)
}
if portN <= 0 || portN > 65535 {
return model.WebsiteDomain{}, buserr.New("ErrTypePortRange")
return model.WebsiteDomain{}, err
}
domain.Port = portN
return domain, nil
@@ -648,103 +641,3 @@ func chownRootDir(path string) error {
}
return nil
}
func changeServiceName(composePath, newServiceName string) (composeByte []byte, err error) {
composeMap := make(map[string]interface{})
fileOp := files.NewFileOp()
composeContent, _ := fileOp.GetContent(composePath)
if err = yaml.Unmarshal(composeContent, &composeMap); err != nil {
return
}
value, ok := composeMap["services"]
if !ok {
err = buserr.New(constant.ErrFileParse)
return
}
servicesMap := value.(map[string]interface{})
index := 0
serviceName := ""
for k := range servicesMap {
serviceName = k
if index > 0 {
continue
}
index++
}
if newServiceName != serviceName {
servicesMap[newServiceName] = servicesMap[serviceName]
delete(servicesMap, serviceName)
}
return yaml.Marshal(composeMap)
}
func getWebsiteDomains(domains string, defaultPort int, websiteID uint) (domainModels []model.WebsiteDomain, addPorts []int, addDomains []string, err error) {
var (
ports = make(map[int]struct{})
)
domainArray := strings.Split(domains, "\n")
for _, domain := range domainArray {
if domain == "" {
continue
}
if !common.IsValidDomain(domain) {
err = buserr.WithName("ErrDomainFormat", domain)
return
}
var domainModel model.WebsiteDomain
domainModel, err = getDomain(domain, defaultPort)
if err != nil {
return
}
if reflect.DeepEqual(domainModel, model.WebsiteDomain{}) {
continue
}
domainModel.WebsiteID = websiteID
domainModels = append(domainModels, domainModel)
if domainModel.Port != defaultPort {
ports[domainModel.Port] = struct{}{}
}
if exist, _ := websiteDomainRepo.GetFirst(websiteDomainRepo.WithDomain(domainModel.Domain), websiteDomainRepo.WithWebsiteId(websiteID)); exist.ID == 0 {
addDomains = append(addDomains, domainModel.Domain)
}
}
for _, domain := range domainModels {
if exist, _ := websiteDomainRepo.GetFirst(websiteDomainRepo.WithDomain(domain.Domain), websiteDomainRepo.WithPort(domain.Port)); exist.ID > 0 {
website, _ := websiteRepo.GetFirst(commonRepo.WithByID(exist.WebsiteID))
err = buserr.WithName(constant.ErrDomainIsUsed, website.PrimaryDomain)
return
}
}
for port := range ports {
if existPorts, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithPort(port)); len(existPorts) == 0 {
errMap := make(map[string]interface{})
errMap["port"] = port
appInstall, _ := appInstallRepo.GetFirst(appInstallRepo.WithPort(port))
if appInstall.ID > 0 {
errMap["type"] = i18n.GetMsgByKey("TYPE_APP")
errMap["name"] = appInstall.Name
err = buserr.WithMap("ErrPortExist", errMap, nil)
return
}
runtime, _ := runtimeRepo.GetFirst(runtimeRepo.WithPort(port))
if runtime != nil {
errMap["type"] = i18n.GetMsgByKey("TYPE_RUNTIME")
errMap["name"] = runtime.Name
err = buserr.WithMap("ErrPortExist", errMap, nil)
return
}
if common.ScanPort(port) {
err = buserr.WithDetail(constant.ErrPortInUsed, port, nil)
return
}
}
if existPorts, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithWebsiteId(websiteID), websiteDomainRepo.WithPort(port)); len(existPorts) == 0 {
addPorts = append(addPorts, port)
}
}
return
}
-11
View File
@@ -76,14 +76,3 @@ func WithNameAndErr(Key string, name string, err error) BusinessError {
Err: err,
}
}
func WithName(Key string, name string) BusinessError {
paramMap := map[string]interface{}{}
if name != "" {
paramMap["name"] = name
}
return BusinessError{
Msg: Key,
Map: paramMap,
}
}
-2
View File
@@ -2,8 +2,6 @@ package configs
type System struct {
Port string `mapstructure:"port"`
Ipv6 string `mapstructure:"ipv6"`
BindAddress string `mapstructure:"bindAddress"`
SSL string `mapstructure:"ssl"`
DbFile string `mapstructure:"db_file"`
DbPath string `mapstructure:"db_path"`
+3 -3
View File
@@ -6,13 +6,13 @@ const (
Error = "Error"
Stopped = "Stopped"
Installing = "Installing"
Syncing = "Syncing"
DownloadErr = "DownloadErr"
DirNotFound = "DirNotFound"
Upgrading = "Upgrading"
UpgradeErr = "UpgradeErr"
PullErr = "PullErr"
Rebuilding = "Rebuilding"
Syncing = "Syncing"
SyncSuccess = "SyncSuccess"
SyncErr = "SyncErr"
ContainerPrefix = "1Panel-"
-2
View File
@@ -4,6 +4,4 @@ type DBContext string
const (
DB DBContext = "db"
SystemRestart = "systemRestart"
)

Some files were not shown because too many files have changed in this diff Show More