mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-10-09 16:00:29 +00:00
Compare commits
14
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2879f2a56 | ||
|
|
67221e7f70 | ||
|
|
c76cc07c1c | ||
|
|
7a091a152e | ||
|
|
d2087641f7 | ||
|
|
321ed00734 | ||
|
|
8ff160408f | ||
|
|
662eae1ba4 | ||
|
|
f808e81958 | ||
|
|
f161bcbc31 | ||
|
|
73f789062b | ||
|
|
1fdf4ffd2f | ||
|
|
6d58fe7a1e | ||
|
|
c8bbfada8c |
@@ -1 +0,0 @@
|
||||
custom: ["https://afdian.net/a/1Panel"]
|
||||
@@ -1,20 +0,0 @@
|
||||
name: Build
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
jobs:
|
||||
sonarcloud:
|
||||
name: SonarCloud
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: SonarCloud Scan
|
||||
uses: SonarSource/sonarcloud-github-action@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUBTOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
+5
-25
@@ -4,30 +4,9 @@
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
build/1panel
|
||||
|
||||
# Mac
|
||||
.DS_Store
|
||||
*/.DS_Store
|
||||
|
||||
# VS Code
|
||||
.vscode
|
||||
*.project
|
||||
*.factorypath
|
||||
|
||||
# IntelliJ IDEA
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
# NetBeans
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
.nb-gradle/
|
||||
build/1panel
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
@@ -35,7 +14,8 @@ nbdist/
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Dependency directories
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
/pkg/
|
||||
backend/__debug_bin
|
||||
cmd/server/__debug_bin
|
||||
@@ -51,5 +31,5 @@ dist/
|
||||
1panel.service
|
||||
install.sh
|
||||
quick_start.sh
|
||||
cmd/server/fileList.txt
|
||||
.fileList.txt
|
||||
cmd/server/web/.DS_Store
|
||||
cmd/server/.DS_Store
|
||||
|
||||
@@ -29,6 +29,10 @@ build_backend_on_darwin:
|
||||
cd $(SERVER_PATH) \
|
||||
&& GOOS=linux GOARCH=amd64 $(GOBUILD) -trimpath -ldflags '-s -w' -o $(BUILD_PATH)/$(APP_NAME) $(MAIN)
|
||||
|
||||
build_backend_on_archlinux:
|
||||
cd $(SERVER_PATH) \
|
||||
&& GOOS=$(GOOS) GOARCH=$(GOARCH) $(GOBUILD) -trimpath -ldflags '-s -w' -o $(BUILD_PATH)/$(APP_NAME) $(MAIN)
|
||||
|
||||
build_all: build_frontend build_backend_on_linux
|
||||
|
||||
build_on_local: clean_assets build_frontend build_backend_on_darwin upx_bin
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
[README_EN.md](README_EN.md)
|
||||
<p align="center"><a href="https://1panel.cn"><img src="http://1panel.oss-cn-hangzhou.aliyuncs.com/img/1panel-logo.png" alt="1Panel" width="300" /></a></p>
|
||||
<p align="center"><b>现代化、开源的 Linux 服务器运维管理面板</b></p>
|
||||
<p align="center">
|
||||
<a href="https://www.gnu.org/licenses/gpl-3.0.html"><img src="https://shields.io/github/license/1Panel-dev/1Panel?color=%231890FF" alt="License: GPL v3"></a>
|
||||
<a href="https://www.gnu.org/licenses/gpl-3.0.html"><img src="https://shields.io/github/license/1Panel-dev/1Panel" alt="License: GPL v3"></a>
|
||||
<a href="https://app.codacy.com/gh/1Panel-dev/1Panel?utm_source=github.com&utm_medium=referral&utm_content=1Panel-dev/1Panel&utm_campaign=Badge_Grade_Dashboard"><img src="https://app.codacy.com/project/badge/Grade/da67574fd82b473992781d1386b937ef" alt="Codacy"></a>
|
||||
<a href="https://github.com/1Panel-dev/1Panel/releases"><img src="https://img.shields.io/github/v/release/1Panel-dev/1Panel" alt="GitHub release"></a>
|
||||
<a href="https://github.com/1Panel-dev/1Panel"><img src="https://img.shields.io/github/stars/1Panel-dev/1Panel?color=%231890FF&style=flat-square" alt="Stars"></a>
|
||||
<a href="https://app.fossa.com/projects/git%2Bgithub.com%2F1Panel-dev%2F1Panel?ref=badge_shield"><img src="https://app.fossa.com/api/projects/git%2Bgithub.com%2F1Panel-dev%2F1Panel.svg?type=shield" alt="FOSSA Status"></a><br>
|
||||
[<a href="docs/README_TW.md">中文(繁體)</a>] | [<a href="docs/README_EN.md">English</a>] | [<a href="docs/README_JP.md">日本語</a>]
|
||||
<a href="https://app.fossa.com/projects/git%2Bgithub.com%2F1Panel-dev%2F1Panel?ref=badge_shield"><img src="https://app.fossa.com/api/projects/git%2Bgithub.com%2F1Panel-dev%2F1Panel.svg?type=shield" alt="FOSSA Status"></a>
|
||||
</p>
|
||||
|
||||
------------------------------
|
||||
@@ -16,8 +16,7 @@
|
||||
- **快速建站**:深度集成 Wordpress 和 [Halo](https://github.com/halo-dev/halo/),域名绑定、SSL 证书配置等一键搞定;
|
||||
- **高效管理**:通过 Web 端轻松管理 Linux 服务器,包括主机监控、文件管理、数据库管理、容器管理等;
|
||||
- **安全可靠**:基于容器来管理和部署应用,最小漏洞暴露面,提供防火墙和日志审计等功能;
|
||||
- **一键备份**:支持一键备份和恢复,备份数据到各类云端存储,永不丢失;
|
||||
- **应用商店**:精选各类高质量开源工具和应用软件,助力您轻松安装和升级。
|
||||
- **一键备份**:支持一键备份和恢复,备份数据到各类云端存储,永不丢失。
|
||||
|
||||
## UI 展示
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
[中文 README.md](README.md)
|
||||
<p align="center"><a href="https://1panel.cn"><img src="http://1panel.oss-cn-hangzhou.aliyuncs.com/img/1panel-logo.png" alt="1Panel" width="300" /></a></p>
|
||||
<p align="center"><b>Modern and Open-Source Linux Server Operation and Management Panel</b></p>
|
||||
<p align="center">
|
||||
<a href="https://www.gnu.org/licenses/gpl-3.0.html"><img src="https://shields.io/github/license/1Panel-dev/1Panel" alt="License: GPL v3"></a>
|
||||
<a href="https://app.codacy.com/gh/1Panel-dev/1Panel?utm_source=github.com&utm_medium=referral&utm_content=1Panel-dev/1Panel&utm_campaign=Badge_Grade_Dashboard"><img src="https://app.codacy.com/project/badge/Grade/da67574fd82b473992781d1386b937ef" alt="Codacy"></a>
|
||||
<a href="https://github.com/1Panel-dev/1Panel/releases"><img src="https://img.shields.io/github/v/release/1Panel-dev/1Panel" alt="GitHub release"></a>
|
||||
<a href="https://github.com/1Panel-dev/1Panel"><img src="https://img.shields.io/github/stars/1Panel-dev/1Panel?color=%231890FF&style=flat-square" alt="Stars"></a><br>
|
||||
[<a href="../README.md">中文(简体)</a>] | [<a href="README_TW.md">中文(繁體)</a>] | [<a href="README_JP.md">日本語</a>]
|
||||
<a href="https://github.com/1Panel-dev/1Panel"><img src="https://img.shields.io/github/stars/1Panel-dev/1Panel?color=%231890FF&style=flat-square" alt="Stars"></a>
|
||||
</p>
|
||||
|
||||
------------------------------
|
||||
@@ -15,8 +15,7 @@
|
||||
- **Quick website building**: Deeply integrated with Wordpress and [Halo](https://github.com/halo-dev/halo/), with one-click solutions for domain name binding, SSL certificate configuration, and more;
|
||||
- **Efficient management**: Easily manage Linux servers through the web interface, including application management, host monitoring, file management, database management, container management, and more;
|
||||
- **Secure and reliable**: Minimal vulnerability exposure, with firewall and security audit functions provided;
|
||||
- **One-click backup**: Support for one-click backup and restore, with backup data stored in the cloud and never lost;
|
||||
- **App Store**: Curate a variety of high-quality open-source tools and application software, enabling you to easily install and upgrade them.
|
||||
- **One-click backup**: Support for one-click backup and restore, with backup data stored in the cloud and never lost.
|
||||
|
||||
## UI Display
|
||||
|
||||
@@ -37,7 +37,7 @@ func (b *BaseApi) SearchApp(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/sync [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"应用商店同步","formatEN":"App store synchronization"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"应用商店同步","formatEN":"App store synchronization"}
|
||||
func (b *BaseApi) SyncApp(c *gin.Context) {
|
||||
go appService.SyncAppListFromLocal()
|
||||
res, err := appService.GetAppUpdate()
|
||||
@@ -50,8 +50,11 @@ func (b *BaseApi) SyncApp(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
global.LOG.Infof("sync app list start ...")
|
||||
if err := appService.SyncAppListFromRemote(); err != nil {
|
||||
global.LOG.Errorf("Synchronization with the App Store failed [%s]", err.Error())
|
||||
global.LOG.Errorf("sync app list error [%s]", err.Error())
|
||||
} else {
|
||||
global.LOG.Infof("sync app list success!")
|
||||
}
|
||||
}()
|
||||
helper.SuccessWithData(c, "")
|
||||
@@ -90,14 +93,14 @@ func (b *BaseApi) GetApp(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/detail/:appId/:version/:type [get]
|
||||
func (b *BaseApi) GetAppDetail(c *gin.Context) {
|
||||
appID, err := helper.GetIntParamByKey(c, "appId")
|
||||
appId, err := helper.GetIntParamByKey(c, "appId")
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||
return
|
||||
}
|
||||
version := c.Param("version")
|
||||
appType := c.Param("type")
|
||||
appDetailDTO, err := appService.GetAppDetail(appID, version, appType)
|
||||
appDetailDTO, err := appService.GetAppDetail(appId, version, appType)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -127,22 +130,6 @@ func (b *BaseApi) GetAppDetailByID(c *gin.Context) {
|
||||
helper.SuccessWithData(c, appDetailDTO)
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary Get Ignore App
|
||||
// @Description 获取忽略的应用版本
|
||||
// @Accept json
|
||||
// @Success 200 {object} response.IgnoredApp
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/ingored [get]
|
||||
func (b *BaseApi) GetIgnoredApp(c *gin.Context) {
|
||||
res, err := appService.GetIgnoredApp()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary Install app
|
||||
// @Description 安装应用
|
||||
@@ -151,7 +138,7 @@ func (b *BaseApi) GetIgnoredApp(c *gin.Context) {
|
||||
// @Success 200 {object} model.AppInstall
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/install [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||
@@ -13,8 +14,8 @@ import (
|
||||
)
|
||||
|
||||
// @Tags App
|
||||
// @Summary Page app installed
|
||||
// @Description 分页获取已安装应用列表
|
||||
// @Summary List app installed
|
||||
// @Description 获取已安装应用列表
|
||||
// @Accept json
|
||||
// @Param request body request.AppInstalledSearch true "request"
|
||||
// @Success 200
|
||||
@@ -46,41 +47,21 @@ func (b *BaseApi) SearchAppInstalled(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary List app installed
|
||||
// @Description 获取已安装应用列表
|
||||
// @Accept json
|
||||
// @Success 200 array dto.AppInstallInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/list [get]
|
||||
func (b *BaseApi) ListAppInstalled(c *gin.Context) {
|
||||
list, err := appInstallService.GetInstallList()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, list)
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary Check app installed
|
||||
// @Description 检查应用安装情况
|
||||
// @Accept json
|
||||
// @Param request body request.AppInstalledInfo true "request"
|
||||
// @Param key path string true "request"
|
||||
// @Success 200 {object} response.AppInstalledCheck
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/check [post]
|
||||
// @Router /apps/installed/check/:key [get]
|
||||
func (b *BaseApi) CheckAppInstalled(c *gin.Context) {
|
||||
var req request.AppInstalledInfo
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
key, ok := c.Params.Get("key")
|
||||
if !ok {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error key in path"))
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
checkData, err := appInstallService.CheckExist(req)
|
||||
checkData, err := appInstallService.CheckExist(key)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -92,17 +73,17 @@ func (b *BaseApi) CheckAppInstalled(c *gin.Context) {
|
||||
// @Summary Search app port by key
|
||||
// @Description 获取应用端口
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithNameAndType true "request"
|
||||
// @Param key path string true "request"
|
||||
// @Success 200 {integer} port
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/loadport [post]
|
||||
// @Router /apps/installed/loadport/:key [get]
|
||||
func (b *BaseApi) LoadPort(c *gin.Context) {
|
||||
var req dto.OperationWithNameAndType
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
key, ok := c.Params.Get("key")
|
||||
if !ok {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error key in path"))
|
||||
return
|
||||
}
|
||||
port, err := appInstallService.LoadPort(req)
|
||||
port, err := appInstallService.LoadPort(key)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -114,17 +95,17 @@ func (b *BaseApi) LoadPort(c *gin.Context) {
|
||||
// @Summary Search app password by key
|
||||
// @Description 获取应用连接信息
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithNameAndType true "request"
|
||||
// @Param key path string true "request"
|
||||
// @Success 200 {string} response.DatabaseConn
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/conninfo/:key [get]
|
||||
func (b *BaseApi) LoadConnInfo(c *gin.Context) {
|
||||
var req dto.OperationWithNameAndType
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
key, ok := c.Params.Get("key")
|
||||
if !ok {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error key in path"))
|
||||
return
|
||||
}
|
||||
conn, err := appInstallService.LoadConnInfo(req)
|
||||
conn, err := appInstallService.LoadConnInfo(key)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -137,7 +118,7 @@ func (b *BaseApi) LoadConnInfo(c *gin.Context) {
|
||||
// @Description 删除前检查
|
||||
// @Accept json
|
||||
// @Param appInstallId path integer true "App install id"
|
||||
// @Success 200 {array} dto.AppResource
|
||||
// @Success 200 {anrry} dto.AppResource
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/delete/check/:appInstallId [get]
|
||||
func (b *BaseApi) DeleteCheck(c *gin.Context) {
|
||||
@@ -161,7 +142,7 @@ func (b *BaseApi) DeleteCheck(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/sync [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"同步已安装应用列表","formatEN":"Sync the list of installed apps"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"同步已安装应用列表","formatEN":"Sync the list of installed apps"}
|
||||
func (b *BaseApi) SyncInstalled(c *gin.Context) {
|
||||
if err := appInstallService.SyncAll(false); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
@@ -178,7 +159,7 @@ func (b *BaseApi) SyncInstalled(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/op [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["installId","operate"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -197,7 +178,7 @@ func (b *BaseApi) OperateInstalled(c *gin.Context) {
|
||||
// @Description 通过 key 获取应用 service
|
||||
// @Accept json
|
||||
// @Param key path string true "request"
|
||||
// @Success 200 {array} response.AppService
|
||||
// @Success 200 {anrry} response.AppService
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/services/:key [get]
|
||||
func (b *BaseApi) GetServices(c *gin.Context) {
|
||||
@@ -215,7 +196,7 @@ func (b *BaseApi) GetServices(c *gin.Context) {
|
||||
// @Description 通过 install id 获取应用更新版本
|
||||
// @Accept json
|
||||
// @Param appInstallId path integer true "request"
|
||||
// @Success 200 {array} dto.AppVersion
|
||||
// @Success 200 {anrry} dto.AppVersion
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/:appInstallId/versions [get]
|
||||
func (b *BaseApi) GetUpdateVersions(c *gin.Context) {
|
||||
@@ -240,7 +221,7 @@ func (b *BaseApi) GetUpdateVersions(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/port/change [post]
|
||||
// @x-panel-log {"bodyKeys":["key","name","port"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"应用端口修改 [key]-[name] => [port]","formatEN":"Application port update [key]-[name] => [port]"}
|
||||
// @x-panel-log {"bodyKeys":["key","name","port"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"应用端口修改 [key]-[name] => [port]","formatEN":"Application port update [key]-[name] => [port]"}
|
||||
func (b *BaseApi) ChangeAppPort(c *gin.Context) {
|
||||
var req request.PortUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -262,17 +243,17 @@ func (b *BaseApi) ChangeAppPort(c *gin.Context) {
|
||||
// @Summary Search default config by key
|
||||
// @Description 通过 key 获取应用默认配置
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithNameAndType true "request"
|
||||
// @Param key path string true "request"
|
||||
// @Success 200 {string} content
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/conf [post]
|
||||
// @Router /apps/installed/conf/:key [get]
|
||||
func (b *BaseApi) GetDefaultConfig(c *gin.Context) {
|
||||
var req dto.OperationWithNameAndType
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
key := c.Param("key")
|
||||
if key == "" {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||
return
|
||||
}
|
||||
content, err := appInstallService.GetDefaultConfigByKey(req.Type, req.Name)
|
||||
content, err := appInstallService.GetDefaultConfigByKey(key)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -311,7 +292,7 @@ func (b *BaseApi) GetParams(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/params/update [post]
|
||||
// @x-panel-log {"bodyKeys":["installId"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"应用参数修改 [installId]","formatEN":"Application param update [installId]"}
|
||||
// @x-panel-log {"bodyKeys":["installId"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"应用参数修改 [installId]","formatEN":"Application param update [installId]"}
|
||||
func (b *BaseApi) UpdateInstalled(c *gin.Context) {
|
||||
var req request.AppInstalledUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -324,25 +305,3 @@ func (b *BaseApi) UpdateInstalled(c *gin.Context) {
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary ignore App Update
|
||||
// @Description 忽略应用升级版本
|
||||
// @Accept json
|
||||
// @Param request body request.AppInstalledIgnoreUpgrade true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/ignore [post]
|
||||
// @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 := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := appInstallService.IgnoreUpgrade(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
|
||||
"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/model"
|
||||
@@ -19,7 +17,6 @@ type BaseApi struct{}
|
||||
// @Summary User login
|
||||
// @Description 用户登录
|
||||
// @Accept json
|
||||
// @Param EntranceCode header string true "安全入口 base64 加密串"
|
||||
// @Param request body dto.Login true "request"
|
||||
// @Success 200 {object} dto.UserLoginInfo
|
||||
// @Router /auth/login [post]
|
||||
@@ -35,13 +32,8 @@ func (b *BaseApi) Login(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
}
|
||||
entranceItem := c.Request.Header.Get("EntranceCode")
|
||||
var entrance []byte
|
||||
if len(entranceItem) != 0 {
|
||||
entrance, _ = base64.StdEncoding.DecodeString(entranceItem)
|
||||
}
|
||||
|
||||
user, err := authService.Login(c, req, string(entrance))
|
||||
user, err := authService.Login(c, req)
|
||||
go saveLoginLogs(c, err)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
@@ -57,7 +49,6 @@ func (b *BaseApi) Login(c *gin.Context) {
|
||||
// @Param request body dto.MFALogin true "request"
|
||||
// @Success 200 {object} dto.UserLoginInfo
|
||||
// @Router /auth/mfalogin [post]
|
||||
// @Header 200 {string} EntranceCode "安全入口"
|
||||
func (b *BaseApi) MFALogin(c *gin.Context) {
|
||||
var req dto.MFALogin
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -68,13 +59,8 @@ func (b *BaseApi) MFALogin(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
entranceItem := c.Request.Header.Get("EntranceCode")
|
||||
var entrance []byte
|
||||
if len(entranceItem) != 0 {
|
||||
entrance, _ = base64.StdEncoding.DecodeString(entranceItem)
|
||||
}
|
||||
|
||||
user, err := authService.MFALogin(c, req, string(entrance))
|
||||
user, err := authService.MFALogin(c, req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -134,20 +120,6 @@ func (b *BaseApi) CheckIsDemo(c *gin.Context) {
|
||||
helper.SuccessWithData(c, global.CONF.System.IsDemo)
|
||||
}
|
||||
|
||||
// @Tags Auth
|
||||
// @Summary Load System Language
|
||||
// @Description 获取系统语言设置
|
||||
// @Success 200
|
||||
// @Router /auth/language [get]
|
||||
func (b *BaseApi) GetLanguage(c *gin.Context) {
|
||||
settingInfo, err := settingService.GetSettingInfo()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, settingInfo.Language)
|
||||
}
|
||||
|
||||
func saveLoginLogs(c *gin.Context, err error) {
|
||||
var logs model.LoginLog
|
||||
if err != nil {
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup [post]
|
||||
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建备份账号 [type]","formatEN":"create backup account [type]"}
|
||||
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建备份账号 [type]","formatEN":"create backup account [type]"}
|
||||
func (b *BaseApi) CreateBackup(c *gin.Context) {
|
||||
var req dto.BackupOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -60,7 +60,7 @@ func (b *BaseApi) CreateBackup(c *gin.Context) {
|
||||
// @Description 获取 bucket 列表
|
||||
// @Accept json
|
||||
// @Param request body dto.ForBuckets true "request"
|
||||
// @Success 200 {array} string
|
||||
// @Success 200 {anrry} string
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/search [post]
|
||||
func (b *BaseApi) ListBuckets(c *gin.Context) {
|
||||
@@ -98,22 +98,6 @@ func (b *BaseApi) ListBuckets(c *gin.Context) {
|
||||
helper.SuccessWithData(c, buckets)
|
||||
}
|
||||
|
||||
// @Tags Backup Account
|
||||
// @Summary Load OneDrive info
|
||||
// @Description 获取 OneDrive 信息
|
||||
// @Accept json
|
||||
// @Success 200 string clientID
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/onedrive [get]
|
||||
func (b *BaseApi) LoadOneDriveInfo(c *gin.Context) {
|
||||
clientID, err := backupService.LoadOneDriveInfo()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, clientID)
|
||||
}
|
||||
|
||||
// @Tags Backup Account
|
||||
// @Summary Delete backup account
|
||||
// @Description 删除备份账号
|
||||
@@ -122,7 +106,7 @@ func (b *BaseApi) LoadOneDriveInfo(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/del [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -176,7 +160,7 @@ func (b *BaseApi) SearchBackupRecords(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/record/download [post]
|
||||
// @x-panel-log {"bodyKeys":["source","fileName"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"下载备份记录 [source][fileName]","formatEN":"download backup records [source][fileName]"}
|
||||
// @x-panel-log {"bodyKeys":["source","fileName"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"下载备份记录 [source][fileName]","formatEN":"download backup records [source][fileName]"}
|
||||
func (b *BaseApi) DownloadRecord(c *gin.Context) {
|
||||
var req dto.DownloadRecord
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -204,7 +188,7 @@ func (b *BaseApi) DownloadRecord(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/record/del [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -231,7 +215,7 @@ func (b *BaseApi) DeleteBackupRecord(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/update [post]
|
||||
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新备份账号 [types]","formatEN":"update backup account [types]"}
|
||||
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新备份账号 [types]","formatEN":"update backup account [types]"}
|
||||
func (b *BaseApi) UpdateBackup(c *gin.Context) {
|
||||
var req dto.BackupOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -269,7 +253,7 @@ func (b *BaseApi) UpdateBackup(c *gin.Context) {
|
||||
// @Tags Backup Account
|
||||
// @Summary List backup accounts
|
||||
// @Description 获取备份账号列表
|
||||
// @Success 200 {array} dto.BackupInfo
|
||||
// @Success 200 {anrry} dto.BackupInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/search [get]
|
||||
func (b *BaseApi) ListBackup(c *gin.Context) {
|
||||
@@ -287,7 +271,7 @@ func (b *BaseApi) ListBackup(c *gin.Context) {
|
||||
// @Description 获取备份账号内文件列表
|
||||
// @Accept json
|
||||
// @Param request body dto.BackupSearchFile true "request"
|
||||
// @Success 200 {array} string
|
||||
// @Success 200 {anrry} string
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/search/files [post]
|
||||
func (b *BaseApi) LoadFilesFromBackup(c *gin.Context) {
|
||||
@@ -317,7 +301,7 @@ func (b *BaseApi) LoadFilesFromBackup(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/ [post]
|
||||
// @x-panel-log {"bodyKeys":["type","name","detailName"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"备份 [type] 数据 [name][detailName]","formatEN":"backup [type] data [name][detailName]"}
|
||||
// @x-panel-log {"bodyKeys":["type","name","detailName"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"备份 [type] 数据 [name][detailName]","formatEN":"backup [type] data [name][detailName]"}
|
||||
func (b *BaseApi) Backup(c *gin.Context) {
|
||||
var req dto.CommonBackup
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -335,7 +319,7 @@ func (b *BaseApi) Backup(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
case "mysql", "mariadb":
|
||||
case "mysql":
|
||||
if err := backupService.MysqlBackup(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -362,7 +346,7 @@ func (b *BaseApi) Backup(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/recover [post]
|
||||
// @x-panel-log {"bodyKeys":["type","name","detailName","file"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"从 [file] 恢复 [type] 数据 [name][detailName]","formatEN":"recover [type] data [name][detailName] from [file]"}
|
||||
// @x-panel-log {"bodyKeys":["type","name","detailName","file"],"paramKeys":[],"BeforeFuntions":[],"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -383,7 +367,7 @@ func (b *BaseApi) Recover(c *gin.Context) {
|
||||
req.File = downloadPath
|
||||
}
|
||||
switch req.Type {
|
||||
case "mysql", "mariadb":
|
||||
case "mysql":
|
||||
if err := backupService.MysqlRecover(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -415,7 +399,7 @@ func (b *BaseApi) Recover(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/recover/byupload [post]
|
||||
// @x-panel-log {"bodyKeys":["type","name","detailName","file"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"从 [file] 恢复 [type] 数据 [name][detailName]","formatEN":"recover [type] data [name][detailName] from [file]"}
|
||||
// @x-panel-log {"bodyKeys":["type","name","detailName","file"],"paramKeys":[],"BeforeFuntions":[],"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -428,7 +412,7 @@ func (b *BaseApi) RecoverByUpload(c *gin.Context) {
|
||||
}
|
||||
|
||||
switch req.Type {
|
||||
case "mysql", "mariadb":
|
||||
case "mysql":
|
||||
if err := backupService.MysqlRecoverByUpload(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/command [post]
|
||||
// @x-panel-log {"bodyKeys":["name","command"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建快捷命令 [name][command]","formatEN":"create quick command [name][command]"}
|
||||
// @x-panel-log {"bodyKeys":["name","command"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建快捷命令 [name][command]","formatEN":"create quick command [name][command]"}
|
||||
func (b *BaseApi) CreateCommand(c *gin.Context) {
|
||||
var req dto.CommandOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -85,7 +85,7 @@ func (b *BaseApi) ListCommand(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/command/del [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -112,7 +112,7 @@ func (b *BaseApi) DeleteCommand(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/command/update [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新快捷命令 [name]","formatEN":"update quick command [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新快捷命令 [name]","formatEN":"update quick command [name]"}
|
||||
func (b *BaseApi) UpdateCommand(c *gin.Context) {
|
||||
var req dto.CommandOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/template [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 compose 模版 [name]","formatEN":"create compose template [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建 compose 模版 [name]","formatEN":"create compose template [name]"}
|
||||
func (b *BaseApi) CreateComposeTemplate(c *gin.Context) {
|
||||
var req dto.ComposeTemplateCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -66,7 +66,7 @@ func (b *BaseApi) SearchComposeTemplate(c *gin.Context) {
|
||||
// @Summary List compose templates
|
||||
// @Description 获取容器编排模版列表
|
||||
// @Produce json
|
||||
// @Success 200 {array} dto.ComposeTemplateInfo
|
||||
// @Success 200 {anrry} dto.ComposeTemplateInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/template [get]
|
||||
func (b *BaseApi) ListComposeTemplate(c *gin.Context) {
|
||||
@@ -87,7 +87,7 @@ func (b *BaseApi) ListComposeTemplate(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/template/del [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -114,7 +114,7 @@ func (b *BaseApi) DeleteComposeTemplate(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/template/update [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
|
||||
+33
-220
@@ -40,23 +40,6 @@ func (b *BaseApi) SearchContainer(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary List containers
|
||||
// @Description 获取容器名称
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/list [post]
|
||||
func (b *BaseApi) ListContainer(c *gin.Context) {
|
||||
list, err := containerService.List()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, list)
|
||||
}
|
||||
|
||||
// @Tags Container Compose
|
||||
// @Summary Page composes
|
||||
// @Description 获取编排列表分页
|
||||
@@ -95,7 +78,7 @@ func (b *BaseApi) SearchCompose(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/compose/test [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"检测 compose [name] 格式","formatEN":"check compose [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"检测 compose [name] 格式","formatEN":"check compose [name]"}
|
||||
func (b *BaseApi) TestCompose(c *gin.Context) {
|
||||
var req dto.ComposeCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -123,7 +106,7 @@ func (b *BaseApi) TestCompose(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/compose [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 compose [name]","formatEN":"create compose [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建 compose [name]","formatEN":"create compose [name]"}
|
||||
func (b *BaseApi) CreateCompose(c *gin.Context) {
|
||||
var req dto.ComposeCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -151,7 +134,7 @@ func (b *BaseApi) CreateCompose(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/compose/operate [post]
|
||||
// @x-panel-log {"bodyKeys":["name","operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"compose [operation] [name]","formatEN":"compose [operation] [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name","operation"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"compose [operation] [name]","formatEN":"compose [operation] [name]"}
|
||||
func (b *BaseApi) OperatorCompose(c *gin.Context) {
|
||||
var req dto.ComposeOperation
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -170,97 +153,17 @@ func (b *BaseApi) OperatorCompose(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary Update container
|
||||
// @Description 更新容器
|
||||
// @Accept json
|
||||
// @Param request body dto.ContainerOperate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/update [post]
|
||||
// @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 := 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
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary Load container info
|
||||
// @Description 获取容器表单信息
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithName true "request"
|
||||
// @Success 200 {object} dto.ContainerOperate
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/info [post]
|
||||
func (b *BaseApi) ContainerInfo(c *gin.Context) {
|
||||
var req dto.OperationWithName
|
||||
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)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Summary Load container limits
|
||||
// @Description 获取容器限制
|
||||
// @Success 200 {object} dto.ResourceLimit
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/limit [get]
|
||||
func (b *BaseApi) LoadResourceLimit(c *gin.Context) {
|
||||
data, err := containerService.LoadResourceLimit()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Summary Load container stats
|
||||
// @Description 获取容器列表资源占用
|
||||
// @Success 200 {array} dto.ContainerListStats
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/list/stats [get]
|
||||
func (b *BaseApi) ContainerListStats(c *gin.Context) {
|
||||
datas, err := containerService.ContainerListStats()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, datas)
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary Create container
|
||||
// @Description 创建容器
|
||||
// @Accept json
|
||||
// @Param request body dto.ContainerOperate true "request"
|
||||
// @Param request body dto.ContainerCreate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers [post]
|
||||
// @x-panel-log {"bodyKeys":["name","image"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建容器 [name][image]","formatEN":"create container [name][image]"}
|
||||
// @x-panel-log {"bodyKeys":["name","image"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建容器 [name][image]","formatEN":"create container [name][image]"}
|
||||
func (b *BaseApi) ContainerCreate(c *gin.Context) {
|
||||
var req dto.ContainerOperate
|
||||
var req dto.ContainerCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
@@ -276,32 +179,6 @@ func (b *BaseApi) ContainerCreate(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary Upgrade container
|
||||
// @Description 更新容器镜像
|
||||
// @Accept json
|
||||
// @Param request body dto.ContainerUpgrade true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/upgrade [post]
|
||||
// @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 := 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
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary Clean container
|
||||
// @Description 容器清理
|
||||
@@ -310,7 +187,7 @@ func (b *BaseApi) ContainerUpgrade(c *gin.Context) {
|
||||
// @Success 200 {object} dto.ContainerPruneReport
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/prune [post]
|
||||
// @x-panel-log {"bodyKeys":["pruneType"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清理容器 [pruneType]","formatEN":"clean container [pruneType]"}
|
||||
// @x-panel-log {"bodyKeys":["pruneType"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"清理容器 [pruneType]","formatEN":"clean container [pruneType]"}
|
||||
func (b *BaseApi) ContainerPrune(c *gin.Context) {
|
||||
var req dto.ContainerPrune
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -337,7 +214,7 @@ func (b *BaseApi) ContainerPrune(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/clean/log [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清理容器 [name] 日志","formatEN":"clean container [name] logs"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"清理容器 [name] 日志","formatEN":"clean container [name] logs"}
|
||||
func (b *BaseApi) CleanContainerLog(c *gin.Context) {
|
||||
var req dto.OperationWithName
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -355,24 +232,6 @@ func (b *BaseApi) CleanContainerLog(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary Load container log
|
||||
// @Description 获取容器操作日志
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithNameAndType true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/load/log [post]
|
||||
func (b *BaseApi) LoadContainerLog(c *gin.Context) {
|
||||
var req dto.OperationWithNameAndType
|
||||
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 Operate Container
|
||||
// @Description 容器操作
|
||||
@@ -381,7 +240,7 @@ func (b *BaseApi) LoadContainerLog(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/operate [post]
|
||||
// @x-panel-log {"bodyKeys":["name","operation","newName"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"容器 [name] 执行 [operation] [newName]","formatEN":"container [operation] [name] [newName]"}
|
||||
// @x-panel-log {"bodyKeys":["name","operation","newName"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"容器 [name] 执行 [operation] [newName]","formatEN":"container [operation] [name] [newName]"}
|
||||
func (b *BaseApi) ContainerOperation(c *gin.Context) {
|
||||
var req dto.ContainerOperation
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -403,7 +262,7 @@ func (b *BaseApi) ContainerOperation(c *gin.Context) {
|
||||
// @Summary Container stats
|
||||
// @Description 容器监控信息
|
||||
// @Param id path integer true "容器id"
|
||||
// @Success 200 {object} dto.ContainerStats
|
||||
// @Success 200 {object} dto.ContainterStats
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/stats/:id [get]
|
||||
func (b *BaseApi) ContainerStats(c *gin.Context) {
|
||||
@@ -451,29 +310,27 @@ func (b *BaseApi) Inspect(c *gin.Context) {
|
||||
// @Tags Container
|
||||
// @Summary Container logs
|
||||
// @Description 容器日志
|
||||
// @Param container query string false "容器名称"
|
||||
// @Param since query string false "时间筛选"
|
||||
// @Param follow query string false "是否追踪"
|
||||
// @Param tail query string false "显示行号"
|
||||
// @Accept json
|
||||
// @Param request body dto.ContainerLog true "request"
|
||||
// @Success 200 {string} logs
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/search/log [post]
|
||||
func (b *BaseApi) ContainerLogs(c *gin.Context) {
|
||||
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
|
||||
var req dto.ContainerLog
|
||||
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
|
||||
}
|
||||
logs, err := containerService.ContainerLogs(req)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("gin context http handler failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
defer wsConn.Close()
|
||||
|
||||
container := c.Query("container")
|
||||
since := c.Query("since")
|
||||
follow := c.Query("follow") == "true"
|
||||
tail := c.Query("tail")
|
||||
|
||||
if err := containerService.ContainerLogs(wsConn, container, since, tail, follow); err != nil {
|
||||
_ = wsConn.WriteMessage(1, []byte(err.Error()))
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, logs)
|
||||
}
|
||||
|
||||
// @Tags Container Network
|
||||
@@ -507,23 +364,6 @@ func (b *BaseApi) SearchNetwork(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Container Network
|
||||
// @Summary List networks
|
||||
// @Description 获取容器网络列表
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {array} dto.Options
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/network [get]
|
||||
func (b *BaseApi) ListNetwork(c *gin.Context) {
|
||||
list, err := containerService.ListNetwork()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, list)
|
||||
}
|
||||
|
||||
// @Tags Container Network
|
||||
// @Summary Delete network
|
||||
// @Description 删除容器网络
|
||||
@@ -532,7 +372,7 @@ func (b *BaseApi) ListNetwork(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/network/del [post]
|
||||
// @x-panel-log {"bodyKeys":["names"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除容器网络 [names]","formatEN":"delete container network [names]"}
|
||||
// @x-panel-log {"bodyKeys":["names"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"删除容器网络 [names]","formatEN":"delete container network [names]"}
|
||||
func (b *BaseApi) DeleteNetwork(c *gin.Context) {
|
||||
var req dto.BatchDelete
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -559,7 +399,7 @@ func (b *BaseApi) DeleteNetwork(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/network [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建容器网络 name","formatEN":"create container network [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建容器网络 name","formatEN":"create container network [name]"}
|
||||
func (b *BaseApi) CreateNetwork(c *gin.Context) {
|
||||
var req dto.NetworkCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -613,10 +453,11 @@ func (b *BaseApi) SearchVolume(c *gin.Context) {
|
||||
// @Summary List volumes
|
||||
// @Description 获取容器存储卷列表
|
||||
// @Accept json
|
||||
// @Param request body dto.PageInfo true "request"
|
||||
// @Produce json
|
||||
// @Success 200 {array} dto.Options
|
||||
// @Success 200 {object} dto.PageResult
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/volume [get]
|
||||
// @Router /containers/volume/search [get]
|
||||
func (b *BaseApi) ListVolume(c *gin.Context) {
|
||||
list, err := containerService.ListVolume()
|
||||
if err != nil {
|
||||
@@ -634,7 +475,7 @@ func (b *BaseApi) ListVolume(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/volume/del [post]
|
||||
// @x-panel-log {"bodyKeys":["names"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除容器存储卷 [names]","formatEN":"delete container volume [names]"}
|
||||
// @x-panel-log {"bodyKeys":["names"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"删除容器存储卷 [names]","formatEN":"delete container volume [names]"}
|
||||
func (b *BaseApi) DeleteVolume(c *gin.Context) {
|
||||
var req dto.BatchDelete
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -661,7 +502,7 @@ func (b *BaseApi) DeleteVolume(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/volume [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建容器存储卷 [name]","formatEN":"create container volume [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建容器存储卷 [name]","formatEN":"create container volume [name]"}
|
||||
func (b *BaseApi) CreateVolume(c *gin.Context) {
|
||||
var req dto.VolumeCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -688,7 +529,7 @@ func (b *BaseApi) CreateVolume(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/compose/update [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 compose [name]","formatEN":"update compose information [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新 compose [name]","formatEN":"update compose information [name]"}
|
||||
func (b *BaseApi) ComposeUpdate(c *gin.Context) {
|
||||
var req dto.ComposeUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -706,31 +547,3 @@ func (b *BaseApi) ComposeUpdate(c *gin.Context) {
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Container Compose
|
||||
// @Summary Container Compose logs
|
||||
// @Description docker-compose 日志
|
||||
// @Param compose query string false "compose 文件地址"
|
||||
// @Param since query string false "时间筛选"
|
||||
// @Param follow query string false "是否追踪"
|
||||
// @Param tail query string false "显示行号"
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/compose/search/log [get]
|
||||
func (b *BaseApi) ComposeLogs(c *gin.Context) {
|
||||
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("gin context http handler failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
defer wsConn.Close()
|
||||
|
||||
compose := c.Query("compose")
|
||||
since := c.Query("since")
|
||||
follow := c.Query("follow") == "true"
|
||||
tail := c.Query("tail")
|
||||
|
||||
if err := containerService.ComposeLogs(wsConn, compose, since, tail, follow); err != nil {
|
||||
_ = wsConn.WriteMessage(1, []byte(err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /cronjobs [post]
|
||||
// @x-panel-log {"bodyKeys":["type","name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建计划任务 [type][name]","formatEN":"create cronjob [type][name]"}
|
||||
// @x-panel-log {"bodyKeys":["type","name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建计划任务 [type][name]","formatEN":"create cronjob [type][name]"}
|
||||
func (b *BaseApi) CreateCronjob(c *gin.Context) {
|
||||
var req dto.CronjobCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -94,28 +94,6 @@ func (b *BaseApi) SearchJobRecords(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Cronjob
|
||||
// @Summary Load Cronjob record log
|
||||
// @Description 获取计划任务记录日志
|
||||
// @Accept json
|
||||
// @Param request body dto.OperateByID true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /cronjob/record/log [post]
|
||||
func (b *BaseApi) LoadRecordLog(c *gin.Context) {
|
||||
var req dto.OperateByID
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
content, err := cronjobService.LoadRecordLog(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, content)
|
||||
}
|
||||
|
||||
// @Tags Cronjob
|
||||
// @Summary Clean job records
|
||||
// @Description 清空计划任务记录
|
||||
@@ -124,7 +102,7 @@ func (b *BaseApi) LoadRecordLog(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /cronjobs/records/clean [post]
|
||||
// @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"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -148,7 +126,7 @@ func (b *BaseApi) CleanRecord(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /cronjobs/del [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -175,7 +153,7 @@ func (b *BaseApi) DeleteCronjob(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /cronjobs/update [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -202,7 +180,7 @@ func (b *BaseApi) UpdateCronjob(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /cronjobs/status [post]
|
||||
// @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]."}
|
||||
// @x-panel-log {"bodyKeys":["id","status"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -229,7 +207,7 @@ func (b *BaseApi) UpdateCronjobStatus(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /cronjobs/download [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["recordID"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -246,8 +224,7 @@ func (b *BaseApi) TargetDownload(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.File(filePath)
|
||||
helper.SuccessWithData(c, filePath)
|
||||
}
|
||||
|
||||
// @Tags Cronjob
|
||||
@@ -258,7 +235,7 @@ func (b *BaseApi) TargetDownload(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /cronjobs/handle [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
|
||||
@@ -1,207 +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/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Create database
|
||||
// @Description 创建远程数据库
|
||||
// @Accept json
|
||||
// @Param request body dto.DatabaseCreate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/db [post]
|
||||
// @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 := 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
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Check database
|
||||
// @Description 检测远程数据库连接性
|
||||
// @Accept json
|
||||
// @Param request body dto.DatabaseCreate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/db/check [post]
|
||||
// @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 := 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))
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Page databases
|
||||
// @Description 获取远程数据库列表分页
|
||||
// @Accept json
|
||||
// @Param request body dto.DatabaseSearch true "request"
|
||||
// @Success 200 {object} dto.PageResult
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/db/search [post]
|
||||
func (b *BaseApi) SearchDatabase(c *gin.Context) {
|
||||
var req dto.DatabaseSearch
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
total, list, err := databaseService.SearchWithPage(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, dto.PageResult{
|
||||
Items: list,
|
||||
Total: total,
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary List databases
|
||||
// @Description 获取远程数据库列表
|
||||
// @Success 200 {array} dto.DatabaseOption
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/db/list/:type [get]
|
||||
func (b *BaseApi) ListDatabase(c *gin.Context) {
|
||||
dbType, err := helper.GetStrParamByKey(c, "type")
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
list, err := databaseService.List(dbType)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, list)
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Get databases
|
||||
// @Description 获取远程数据库
|
||||
// @Success 200 {object} dto.DatabaseInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/db/:name [get]
|
||||
func (b *BaseApi) GetDatabase(c *gin.Context) {
|
||||
name, err := helper.GetStrParamByKey(c, "name")
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
data, err := databaseService.Get(name)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Check before delete remote database
|
||||
// @Description Mysql 远程数据库删除前检查
|
||||
// @Accept json
|
||||
// @Param request body dto.OperateByID true "request"
|
||||
// @Success 200 {array} string
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /db/remote/del/check [post]
|
||||
func (b *BaseApi) DeleteCheckDatabase(c *gin.Context) {
|
||||
var req dto.OperateByID
|
||||
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
|
||||
}
|
||||
|
||||
apps, err := databaseService.DeleteCheck(req.ID)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, apps)
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Delete database
|
||||
// @Description 删除远程数据库
|
||||
// @Accept json
|
||||
// @Param request body dto.DatabaseDelete true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/db/del [post]
|
||||
// @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 := 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.Delete(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Update database
|
||||
// @Description 更新远程数据库
|
||||
// @Accept json
|
||||
// @Param request body dto.DatabaseUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/db/update [post]
|
||||
// @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 := 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.Update(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 mysql 数据库 [name]","formatEN":"create mysql database [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建 mysql 数据库 [name]","formatEN":"create mysql database [name]"}
|
||||
func (b *BaseApi) CreateMysql(c *gin.Context) {
|
||||
var req dto.MysqlDBCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -54,7 +54,7 @@ func (b *BaseApi) CreateMysql(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/description/update [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -80,7 +80,7 @@ func (b *BaseApi) UpdateMysqlDescription(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/change/password [post]
|
||||
// @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"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -115,7 +115,7 @@ func (b *BaseApi) ChangeMysqlPassword(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/change/access [post]
|
||||
// @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"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -141,9 +141,9 @@ func (b *BaseApi) ChangeMysqlAccess(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/variables/update [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"调整 mysql 数据库性能参数","formatEN":"adjust mysql database performance parameters"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"调整 mysql 数据库性能参数","formatEN":"adjust mysql database performance parameters"}
|
||||
func (b *BaseApi) UpdateMysqlVariables(c *gin.Context) {
|
||||
var req dto.MysqlVariablesUpdate
|
||||
var req []dto.MysqlVariablesUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
@@ -164,7 +164,7 @@ func (b *BaseApi) UpdateMysqlVariables(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/conffile/update [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 mysql 数据库配置信息","formatEN":"update the mysql database configuration information"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新 mysql 数据库配置信息","formatEN":"update the mysql database configuration information"}
|
||||
func (b *BaseApi) UpdateMysqlConfByFile(c *gin.Context) {
|
||||
var req dto.MysqlConfUpdateByFile
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -188,12 +188,12 @@ func (b *BaseApi) UpdateMysqlConfByFile(c *gin.Context) {
|
||||
// @Summary Page mysql databases
|
||||
// @Description 获取 mysql 数据库列表分页
|
||||
// @Accept json
|
||||
// @Param request body dto.MysqlDBSearch true "request"
|
||||
// @Param request body dto.SearchWithPage true "request"
|
||||
// @Success 200 {object} dto.PageResult
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/search [post]
|
||||
func (b *BaseApi) SearchMysql(c *gin.Context) {
|
||||
var req dto.MysqlDBSearch
|
||||
var req dto.SearchWithPage
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
@@ -216,11 +216,11 @@ func (b *BaseApi) SearchMysql(c *gin.Context) {
|
||||
// @Description 获取 mysql 数据库列表
|
||||
// @Accept json
|
||||
// @Param request body dto.PageInfo true "request"
|
||||
// @Success 200 {array} dto.MysqlOption
|
||||
// @Success 200 {anrry} string
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/options [get]
|
||||
func (b *BaseApi) ListDBName(c *gin.Context) {
|
||||
list, err := mysqlService.ListDBOption()
|
||||
list, err := mysqlService.ListDBName()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -229,41 +229,16 @@ func (b *BaseApi) ListDBName(c *gin.Context) {
|
||||
helper.SuccessWithData(c, list)
|
||||
}
|
||||
|
||||
// @Tags Database Mysql
|
||||
// @Summary Load mysql database from remote
|
||||
// @Description 从服务器获取
|
||||
// @Accept json
|
||||
// @Param request body dto.MysqlLoadDB true "request"
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/load [post]
|
||||
func (b *BaseApi) LoadDBFromRemote(c *gin.Context) {
|
||||
var req dto.MysqlLoadDB
|
||||
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
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Database Mysql
|
||||
// @Summary Check before delete mysql database
|
||||
// @Description Mysql 数据库删除前检查
|
||||
// @Accept json
|
||||
// @Param request body dto.MysqlDBDeleteCheck true "request"
|
||||
// @Success 200 {array} string
|
||||
// @Param request body dto.OperateByID true "request"
|
||||
// @Success 200 {anrry} string
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/del/check [post]
|
||||
func (b *BaseApi) DeleteCheckMysql(c *gin.Context) {
|
||||
var req dto.MysqlDBDeleteCheck
|
||||
var req dto.OperateByID
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
@@ -273,7 +248,7 @@ func (b *BaseApi) DeleteCheckMysql(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
apps, err := mysqlService.DeleteCheck(req)
|
||||
apps, err := mysqlService.DeleteCheck(req.ID)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -289,7 +264,7 @@ func (b *BaseApi) DeleteCheckMysql(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/del [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -314,18 +289,11 @@ func (b *BaseApi) DeleteMysql(c *gin.Context) {
|
||||
// @Tags Database Mysql
|
||||
// @Summary Load mysql base info
|
||||
// @Description 获取 mysql 基础信息
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithNameAndType true "request"
|
||||
// @Success 200 {object} dto.DBBaseInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/baseinfo [post]
|
||||
// @Router /databases/baseinfo [get]
|
||||
func (b *BaseApi) LoadBaseinfo(c *gin.Context) {
|
||||
var req dto.OperationWithNameAndType
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
data, err := mysqlService.LoadBaseInfo(req)
|
||||
data, err := mysqlService.LoadBaseInfo()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -334,43 +302,14 @@ func (b *BaseApi) LoadBaseinfo(c *gin.Context) {
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Load Database file
|
||||
// @Description 获取数据库文件
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithNameAndType true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/load/file [post]
|
||||
func (b *BaseApi) LoadDatabaseFile(c *gin.Context) {
|
||||
var req dto.OperationWithNameAndType
|
||||
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)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, content)
|
||||
}
|
||||
|
||||
// @Tags Database Mysql
|
||||
// @Summary Load mysql remote access
|
||||
// @Description 获取 mysql 远程访问权限
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithNameAndType true "request"
|
||||
// @Success 200 {boolean} isRemote
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/remote [post]
|
||||
// @Router /databases/remote [get]
|
||||
func (b *BaseApi) LoadRemoteAccess(c *gin.Context) {
|
||||
var req dto.OperationWithNameAndType
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
isRemote, err := mysqlService.LoadRemoteAccess(req)
|
||||
isRemote, err := mysqlService.LoadRemoteAccess()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -382,18 +321,11 @@ func (b *BaseApi) LoadRemoteAccess(c *gin.Context) {
|
||||
// @Tags Database Mysql
|
||||
// @Summary Load mysql status info
|
||||
// @Description 获取 mysql 状态信息
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithNameAndType true "request"
|
||||
// @Success 200 {object} dto.MysqlStatus
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/status [post]
|
||||
// @Router /databases/status [get]
|
||||
func (b *BaseApi) LoadStatus(c *gin.Context) {
|
||||
var req dto.OperationWithNameAndType
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
data, err := mysqlService.LoadStatus(req)
|
||||
data, err := mysqlService.LoadStatus()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -405,18 +337,11 @@ func (b *BaseApi) LoadStatus(c *gin.Context) {
|
||||
// @Tags Database Mysql
|
||||
// @Summary Load mysql variables info
|
||||
// @Description 获取 mysql 性能参数信息
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithNameAndType true "request"
|
||||
// @Success 200 {object} dto.MysqlVariables
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/variables [post]
|
||||
// @Router /databases/variables [get]
|
||||
func (b *BaseApi) LoadVariables(c *gin.Context) {
|
||||
var req dto.OperationWithNameAndType
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
data, err := mysqlService.LoadVariables(req)
|
||||
data, err := mysqlService.LoadVariables()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
|
||||
@@ -70,7 +70,7 @@ func (b *BaseApi) LoadPersistenceConf(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/redis/conf/update [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 redis 数据库配置信息","formatEN":"update the redis database configuration information"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新 redis 数据库配置信息","formatEN":"update the redis database configuration information"}
|
||||
func (b *BaseApi) UpdateRedisConf(c *gin.Context) {
|
||||
var req dto.RedisConfUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -92,13 +92,13 @@ func (b *BaseApi) UpdateRedisConf(c *gin.Context) {
|
||||
// @Summary Change redis password
|
||||
// @Description 更新 redis 密码
|
||||
// @Accept json
|
||||
// @Param request body dto.ChangeRedisPass true "request"
|
||||
// @Param request body dto.ChangeDBInfo true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/redis/password [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改 redis 数据库密码","formatEN":"change the password of the redis database"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改 redis 数据库密码","formatEN":"change the password of the redis database"}
|
||||
func (b *BaseApi) ChangeRedisPassword(c *gin.Context) {
|
||||
var req dto.ChangeRedisPass
|
||||
var req dto.ChangeDBInfo
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
@@ -131,7 +131,7 @@ func (b *BaseApi) ChangeRedisPassword(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/redis/persistence/update [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"redis 数据库持久化配置更新","formatEN":"redis database persistence configuration update"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"redis 数据库持久化配置更新","formatEN":"redis database persistence configuration update"}
|
||||
func (b *BaseApi) UpdateRedisPersistenceConf(c *gin.Context) {
|
||||
var req dto.RedisConfPersistenceUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -184,7 +184,7 @@ func (b *BaseApi) RedisBackupList(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/redis/conffile/update [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 redis 数据库配置信息","formatEN":"update the redis database configuration information"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新 redis 数据库配置信息","formatEN":"update the redis database configuration information"}
|
||||
func (b *BaseApi) UpdateRedisConfByFile(c *gin.Context) {
|
||||
var req dto.RedisConfUpdateByFile
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
||||
@@ -62,7 +62,7 @@ func (b *BaseApi) LoadDaemonJson(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/daemonjson/update [post]
|
||||
// @x-panel-log {"bodyKeys":["key", "value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 docker daemon.json 配置 [key]=>[value]","formatEN":"Updated the docker daemon.json configuration [key]=>[value]"}
|
||||
// @x-panel-log {"bodyKeys":["key", "value"],"paramKeys":[],"BeforeFuntions":[],"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -86,7 +86,7 @@ func (b *BaseApi) UpdateDaemonJson(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/daemonjson/update [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 docker daemon.json 日志配置","formatEN":"Updated the docker daemon.json log option"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -110,7 +110,7 @@ func (b *BaseApi) UpdateLogOption(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/daemonjson/update/byfile [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 docker daemon.json 配置","formatEN":"Updated the docker daemon.json configuration"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新 docker daemon.json 配置","formatEN":"Updated the docker daemon.json configuration"}
|
||||
func (b *BaseApi) UpdateDaemonJsonByFile(c *gin.Context) {
|
||||
var req dto.DaemonJsonUpdateByFile
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -138,7 +138,7 @@ func (b *BaseApi) UpdateDaemonJsonByFile(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/docker/operate [post]
|
||||
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"docker 服务 [operation]","formatEN":"[operation] docker service"}
|
||||
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"docker 服务 [operation]","formatEN":"[operation] docker service"}
|
||||
func (b *BaseApi) OperateDocker(c *gin.Context) {
|
||||
var req dto.DockerOperation
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
||||
@@ -21,9 +21,8 @@ var (
|
||||
imageService = service.NewIImageService()
|
||||
dockerService = service.NewIDockerService()
|
||||
|
||||
mysqlService = service.NewIMysqlService()
|
||||
databaseService = service.NewIDatabaseService()
|
||||
redisService = service.NewIRedisService()
|
||||
mysqlService = service.NewIMysqlService()
|
||||
redisService = service.NewIRedisService()
|
||||
|
||||
cronjobService = service.NewICronjobService()
|
||||
|
||||
@@ -50,7 +49,4 @@ var (
|
||||
upgradeService = service.NewIUpgradeService()
|
||||
|
||||
runtimeService = service.NewRuntimeService()
|
||||
processService = service.NewIProcessService()
|
||||
|
||||
hostToolService = service.NewIHostToolService()
|
||||
)
|
||||
|
||||
+78
-27
@@ -52,7 +52,7 @@ func (b *BaseApi) ListFiles(c *gin.Context) {
|
||||
// @Description 分页获取上传文件
|
||||
// @Accept json
|
||||
// @Param request body request.SearchUploadWithPage true "request"
|
||||
// @Success 200 {array} response.FileInfo
|
||||
// @Success 200 {anrry} response.FileInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/upload/search [post]
|
||||
func (b *BaseApi) SearchUploadWithPage(c *gin.Context) {
|
||||
@@ -81,7 +81,7 @@ func (b *BaseApi) SearchUploadWithPage(c *gin.Context) {
|
||||
// @Description 加载文件树
|
||||
// @Accept json
|
||||
// @Param request body request.FileOption true "request"
|
||||
// @Success 200 {array} response.FileTree
|
||||
// @Success 200 {anrry} response.FileTree
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/tree [post]
|
||||
func (b *BaseApi) GetFileTree(c *gin.Context) {
|
||||
@@ -106,7 +106,7 @@ func (b *BaseApi) GetFileTree(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files [post]
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建文件/文件夹 [path]","formatEN":"Create dir or file [path]"}
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建文件/文件夹 [path]","formatEN":"Create dir or file [path]"}
|
||||
func (b *BaseApi) CreateFile(c *gin.Context) {
|
||||
var req request.FileCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -129,7 +129,7 @@ func (b *BaseApi) CreateFile(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/del [post]
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除文件/文件夹 [path]","formatEN":"Delete dir or file [path]"}
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"删除文件/文件夹 [path]","formatEN":"Delete dir or file [path]"}
|
||||
func (b *BaseApi) DeleteFile(c *gin.Context) {
|
||||
var req request.FileDelete
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -152,7 +152,7 @@ func (b *BaseApi) DeleteFile(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/batch/del [post]
|
||||
// @x-panel-log {"bodyKeys":["paths"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"批量删除文件/文件夹 [paths]","formatEN":"Batch delete dir or file [paths]"}
|
||||
// @x-panel-log {"bodyKeys":["paths"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"批量删除文件/文件夹 [paths]","formatEN":"Batch delete dir or file [paths]"}
|
||||
func (b *BaseApi) BatchDeleteFile(c *gin.Context) {
|
||||
var req request.FileBatchDelete
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -175,7 +175,7 @@ func (b *BaseApi) BatchDeleteFile(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/mode [post]
|
||||
// @x-panel-log {"bodyKeys":["path","mode"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改权限 [paths] => [mode]","formatEN":"Change mode [paths] => [mode]"}
|
||||
// @x-panel-log {"bodyKeys":["path","mode"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改权限 [paths] => [mode]","formatEN":"Change mode [paths] => [mode]"}
|
||||
func (b *BaseApi) ChangeFileMode(c *gin.Context) {
|
||||
var req request.FileCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -198,7 +198,7 @@ func (b *BaseApi) ChangeFileMode(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/owner [post]
|
||||
// @x-panel-log {"bodyKeys":["path","user","group"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改用户/组 [paths] => [user]/[group]","formatEN":"Change owner [paths] => [user]/[group]"}
|
||||
// @x-panel-log {"bodyKeys":["path","user","group"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改用户/组 [paths] => [user]/[group]","formatEN":"Change owner [paths] => [user]/[group]"}
|
||||
func (b *BaseApi) ChangeFileOwner(c *gin.Context) {
|
||||
var req request.FileRoleUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -220,7 +220,7 @@ func (b *BaseApi) ChangeFileOwner(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/compress [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"压缩文件 [name]","formatEN":"Compress file [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"压缩文件 [name]","formatEN":"Compress file [name]"}
|
||||
func (b *BaseApi) CompressFile(c *gin.Context) {
|
||||
var req request.FileCompress
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -243,7 +243,7 @@ func (b *BaseApi) CompressFile(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/decompress [post]
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"解压 [path]","formatEN":"Decompress file [path]"}
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"解压 [path]","formatEN":"Decompress file [path]"}
|
||||
func (b *BaseApi) DeCompressFile(c *gin.Context) {
|
||||
var req request.FileDeCompress
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -266,7 +266,7 @@ func (b *BaseApi) DeCompressFile(c *gin.Context) {
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"获取文件内容 [path]","formatEN":"Load file content [path]"}
|
||||
func (b *BaseApi) GetContent(c *gin.Context) {
|
||||
var req request.FileOption
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -289,7 +289,7 @@ func (b *BaseApi) GetContent(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/save [post]
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新文件内容 [path]","formatEN":"Update file content [path]"}
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新文件内容 [path]","formatEN":"Update file content [path]"}
|
||||
func (b *BaseApi) SaveContent(c *gin.Context) {
|
||||
var req request.FileEdit
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -310,7 +310,7 @@ func (b *BaseApi) SaveContent(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/upload [post]
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"上传文件 [path]","formatEN":"Upload file [path]"}
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"上传文件 [path]","formatEN":"Upload file [path]"}
|
||||
func (b *BaseApi) UploadFiles(c *gin.Context) {
|
||||
form, err := c.MultipartForm()
|
||||
if err != nil {
|
||||
@@ -356,7 +356,7 @@ 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"}
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"检测文件 [path] 是否存在","formatEN":"Check whether file [path] exists"}
|
||||
func (b *BaseApi) CheckFile(c *gin.Context) {
|
||||
var req request.FilePathCheck
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -384,7 +384,7 @@ func (b *BaseApi) CheckFile(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/rename [post]
|
||||
// @x-panel-log {"bodyKeys":["oldName","newName"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"重命名 [oldName] => [newName]","formatEN":"Rename [oldName] => [newName]"}
|
||||
// @x-panel-log {"bodyKeys":["oldName","newName"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"重命名 [oldName] => [newName]","formatEN":"Rename [oldName] => [newName]"}
|
||||
func (b *BaseApi) ChangeFileName(c *gin.Context) {
|
||||
var req request.FileRename
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -406,7 +406,7 @@ func (b *BaseApi) ChangeFileName(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/wget [post]
|
||||
// @x-panel-log {"bodyKeys":["url","path","name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"下载 url => [path]/[name]","formatEN":"Download url => [path]/[name]"}
|
||||
// @x-panel-log {"bodyKeys":["url","path","name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"下载 url => [path]/[name]","formatEN":"Download url => [path]/[name]"}
|
||||
func (b *BaseApi) WgetFile(c *gin.Context) {
|
||||
var req request.FileWget
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -431,7 +431,7 @@ func (b *BaseApi) WgetFile(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/move [post]
|
||||
// @x-panel-log {"bodyKeys":["oldPaths","newPath"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"移动文件 [oldPaths] => [newPath]","formatEN":"Move [oldPaths] => [newPath]"}
|
||||
// @x-panel-log {"bodyKeys":["oldPaths","newPath"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"移动文件 [oldPaths] => [newPath]","formatEN":"Move [oldPaths] => [newPath]"}
|
||||
func (b *BaseApi) MoveFile(c *gin.Context) {
|
||||
var req request.FileMove
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -453,7 +453,7 @@ func (b *BaseApi) MoveFile(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/download [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"下载文件 [name]","formatEN":"Download file [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"下载文件 [name]","formatEN":"Download file [name]"}
|
||||
func (b *BaseApi) Download(c *gin.Context) {
|
||||
filePath := c.Query("path")
|
||||
file, err := os.Open(filePath)
|
||||
@@ -474,7 +474,7 @@ func (b *BaseApi) Download(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/chunkdownload [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"下载文件 [name]","formatEN":"Download file [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"下载文件 [name]","formatEN":"Download file [name]"}
|
||||
func (b *BaseApi) DownloadChunkFiles(c *gin.Context) {
|
||||
var req request.FileChunkDownload
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -532,7 +532,7 @@ func (b *BaseApi) DownloadChunkFiles(c *gin.Context) {
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, _ = file.Seek(startPos, 0)
|
||||
file.Seek(startPos, 0)
|
||||
reader := io.LimitReader(file, endPos-startPos+1)
|
||||
_, err = io.CopyBuffer(c.Writer, reader, buffer)
|
||||
if err != nil {
|
||||
@@ -544,6 +544,28 @@ func (b *BaseApi) DownloadChunkFiles(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags File
|
||||
// @Summary Download file with path
|
||||
// @Description 下载指定文件
|
||||
// @Accept json
|
||||
// @Param request body dto.FilePath true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/download/bypath [post]
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"下载文件 [path]","formatEN":"Download file [path]"}
|
||||
func (b *BaseApi) DownloadFile(c *gin.Context) {
|
||||
var req dto.FilePath
|
||||
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
|
||||
}
|
||||
c.File(req.Path)
|
||||
}
|
||||
|
||||
// @Tags File
|
||||
// @Summary Load file size
|
||||
// @Description 获取文件夹大小
|
||||
@@ -552,7 +574,7 @@ func (b *BaseApi) DownloadChunkFiles(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/size [post]
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"获取文件夹大小 [path]","formatEN":"Load file size [path]"}
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"获取文件夹大小 [path]","formatEN":"Load file size [path]"}
|
||||
func (b *BaseApi) Size(c *gin.Context) {
|
||||
var req request.DirSizeReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -567,6 +589,33 @@ func (b *BaseApi) Size(c *gin.Context) {
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
// @Tags File
|
||||
// @Summary Read file
|
||||
// @Description 读取文件
|
||||
// @Accept json
|
||||
// @Param request body dto.FilePath true "request"
|
||||
// @Success 200 {string} content
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/loadfile [post]
|
||||
func (b *BaseApi) LoadFromFile(c *gin.Context) {
|
||||
var req dto.FilePath
|
||||
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
|
||||
}
|
||||
|
||||
content, err := os.ReadFile(req.Path)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, string(content))
|
||||
}
|
||||
|
||||
func mergeChunks(fileName string, fileDir string, dstDir string, chunkCount int) error {
|
||||
if _, err := os.Stat(path.Dir(dstDir)); err != nil && os.IsNotExist(err) {
|
||||
if err = os.MkdirAll(path.Dir(dstDir), os.ModePerm); err != nil {
|
||||
@@ -634,12 +683,7 @@ func (b *BaseApi) UploadChunkFiles(c *gin.Context) {
|
||||
}
|
||||
filename := c.PostForm("filename")
|
||||
fileDir := filepath.Join(tmpDir, filename)
|
||||
if chunkIndex == 0 {
|
||||
if fileOp.Stat(fileDir) {
|
||||
_ = fileOp.DeleteDir(fileDir)
|
||||
}
|
||||
_ = os.MkdirAll(fileDir, 0755)
|
||||
}
|
||||
_ = os.MkdirAll(fileDir, 0755)
|
||||
filePath := filepath.Join(fileDir, filename)
|
||||
|
||||
defer func() {
|
||||
@@ -690,12 +734,19 @@ var wsUpgrade = websocket.Upgrader{
|
||||
},
|
||||
}
|
||||
|
||||
var WsManager = websocket2.Manager{
|
||||
Group: make(map[string]*websocket2.Client),
|
||||
Register: make(chan *websocket2.Client, 128),
|
||||
UnRegister: make(chan *websocket2.Client, 128),
|
||||
ClientCount: 0,
|
||||
}
|
||||
|
||||
func (b *BaseApi) Ws(c *gin.Context) {
|
||||
ws, err := wsUpgrade.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
wsClient := websocket2.NewWsClient("fileClient", ws)
|
||||
wsClient := websocket2.NewWsClient("wsClient", ws)
|
||||
go wsClient.Read()
|
||||
go wsClient.Write()
|
||||
}
|
||||
|
||||
@@ -38,10 +38,6 @@ func (b *BaseApi) SearchFirewallRule(c *gin.Context) {
|
||||
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, list, err := firewallService.SearchWithPage(req)
|
||||
if err != nil {
|
||||
@@ -63,7 +59,7 @@ func (b *BaseApi) SearchFirewallRule(c *gin.Context) {
|
||||
// @Success 200 {object} dto.PageResult
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/firewall/operate [post]
|
||||
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] 防火墙","formatEN":"[operation] firewall"}
|
||||
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"[operation] 防火墙","formatEN":"[operation] firewall"}
|
||||
func (b *BaseApi) OperateFirewall(c *gin.Context) {
|
||||
var req dto.FirewallOperation
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -91,7 +87,7 @@ func (b *BaseApi) OperateFirewall(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/firewall/port [post]
|
||||
// @x-panel-log {"bodyKeys":["port","strategy"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"添加端口规则 [strategy] [port]","formatEN":"create port rules [strategy][port]"}
|
||||
// @x-panel-log {"bodyKeys":["port","strategy"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"添加端口规则 [strategy] [port]","formatEN":"create port rules [strategy][port]"}
|
||||
func (b *BaseApi) OperatePortRule(c *gin.Context) {
|
||||
var req dto.PortRuleOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -117,7 +113,7 @@ func (b *BaseApi) OperatePortRule(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/firewall/ip [post]
|
||||
// @x-panel-log {"bodyKeys":["strategy","address"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"添加 ip 规则 [strategy] [address]","formatEN":"create address rules [strategy][address]"}
|
||||
// @x-panel-log {"bodyKeys":["strategy","address"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"添加 ip 规则 [strategy] [address]","formatEN":"create address rules [strategy][address]"}
|
||||
func (b *BaseApi) OperateIPRule(c *gin.Context) {
|
||||
var req dto.AddrRuleOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -160,31 +156,6 @@ func (b *BaseApi) BatchOperateRule(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Firewall
|
||||
// @Summary Update rule description
|
||||
// @Description 更新防火墙描述
|
||||
// @Accept json
|
||||
// @Param request body dto.UpdateFirewallDescription true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/firewall/update/description [post]
|
||||
func (b *BaseApi) UpdateFirewallDescription(c *gin.Context) {
|
||||
var req dto.UpdateFirewallDescription
|
||||
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
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Firewall
|
||||
// @Summary Create group
|
||||
// @Description 更新端口防火墙规则
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /groups [post]
|
||||
// @x-panel-log {"bodyKeys":["name","type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建组 [name][type]","formatEN":"create group [name][type]"}
|
||||
// @x-panel-log {"bodyKeys":["name","type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建组 [name][type]","formatEN":"create group [name][type]"}
|
||||
func (b *BaseApi) CreateGroup(c *gin.Context) {
|
||||
var req dto.GroupCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -42,7 +42,7 @@ func (b *BaseApi) CreateGroup(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /groups/del [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -69,7 +69,7 @@ func (b *BaseApi) DeleteGroup(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /groups/update [post]
|
||||
// @x-panel-log {"bodyKeys":["name","type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新组 [name][type]","formatEN":"update group [name][type]"}
|
||||
// @x-panel-log {"bodyKeys":["name","type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新组 [name][type]","formatEN":"update group [name][type]"}
|
||||
func (b *BaseApi) UpdateGroup(c *gin.Context) {
|
||||
var req dto.GroupUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
||||
@@ -17,6 +17,25 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func GeneratePaginationFromReq(c *gin.Context) (*dto.PageInfo, bool) {
|
||||
p, ok1 := c.GetQuery("page")
|
||||
ps, ok2 := c.GetQuery("pageSize")
|
||||
if !(ok1 && ok2) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
page, err := strconv.Atoi(p)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
pageSize, err := strconv.Atoi(ps)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return &dto.PageInfo{Page: page, PageSize: pageSize}, true
|
||||
}
|
||||
|
||||
func ErrorWithDetail(ctx *gin.Context, code int, msgKey string, err error) {
|
||||
res := dto.Response{
|
||||
Code: code,
|
||||
@@ -113,15 +132,3 @@ func GetTxAndContext() (tx *gorm.DB, ctx context.Context) {
|
||||
ctx = context.WithValue(context.Background(), constant.DB, tx)
|
||||
return
|
||||
}
|
||||
|
||||
func CheckBindAndValidate(req interface{}, c *gin.Context) error {
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return err
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
+61
-27
@@ -1,11 +1,13 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
|
||||
"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/1Panel-dev/1Panel/backend/utils/copier"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@@ -17,7 +19,7 @@ import (
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts [post]
|
||||
// @x-panel-log {"bodyKeys":["name","addr"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建主机 [name][addr]","formatEN":"create host [name][addr]"}
|
||||
// @x-panel-log {"bodyKeys":["name","addr"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建主机 [name][addr]","formatEN":"create host [name][addr]"}
|
||||
func (b *BaseApi) CreateHost(c *gin.Context) {
|
||||
var req dto.HostOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -28,6 +30,22 @@ func (b *BaseApi) CreateHost(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if req.AuthMode == "password" && len(req.Password) != 0 {
|
||||
password, err := base64.StdEncoding.DecodeString(req.Password)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
req.Password = string(password)
|
||||
}
|
||||
if req.AuthMode == "key" && len(req.PrivateKey) != 0 {
|
||||
privateKey, err := base64.StdEncoding.DecodeString(req.PrivateKey)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
req.PrivateKey = string(privateKey)
|
||||
}
|
||||
|
||||
host, err := hostService.Create(req)
|
||||
if err != nil {
|
||||
@@ -84,7 +102,7 @@ func (b *BaseApi) TestByID(c *gin.Context) {
|
||||
// @Description 加载主机树
|
||||
// @Accept json
|
||||
// @Param request body dto.SearchForTree true "request"
|
||||
// @Success 200 {array} dto.HostTree
|
||||
// @Success 200 {anrry} dto.HostTree
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/tree [post]
|
||||
func (b *BaseApi) HostTree(c *gin.Context) {
|
||||
@@ -108,7 +126,7 @@ func (b *BaseApi) HostTree(c *gin.Context) {
|
||||
// @Description 获取主机列表分页
|
||||
// @Accept json
|
||||
// @Param request body dto.SearchHostWithPage true "request"
|
||||
// @Success 200 {array} dto.HostTree
|
||||
// @Success 200 {anrry} dto.HostTree
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/search [post]
|
||||
func (b *BaseApi) SearchHost(c *gin.Context) {
|
||||
@@ -130,6 +148,33 @@ func (b *BaseApi) SearchHost(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Host
|
||||
// @Summary Load host info
|
||||
// @Description 加载主机信息
|
||||
// @Accept json
|
||||
// @Param id path integer true "request"
|
||||
// @Success 200 {object} dto.HostInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/:id [get]
|
||||
func (b *BaseApi) GetHostInfo(c *gin.Context) {
|
||||
id, err := helper.GetParamID(c)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
host, err := hostService.GetHostInfo(id)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
var hostDto dto.HostInfo
|
||||
if err := copier.Copy(&hostDto, host); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, hostDto)
|
||||
}
|
||||
|
||||
// @Tags Host
|
||||
// @Summary Delete host
|
||||
// @Description 删除主机
|
||||
@@ -138,7 +183,7 @@ func (b *BaseApi) SearchHost(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/del [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -165,7 +210,7 @@ func (b *BaseApi) DeleteHost(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/update [post]
|
||||
// @x-panel-log {"bodyKeys":["name","addr"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新主机信息 [name][addr]","formatEN":"update host [name][addr]"}
|
||||
// @x-panel-log {"bodyKeys":["name","addr"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新主机信息 [name][addr]","formatEN":"update host [name][addr]"}
|
||||
func (b *BaseApi) UpdateHost(c *gin.Context) {
|
||||
var req dto.HostOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -176,30 +221,21 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
|
||||
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)
|
||||
if req.AuthMode == "password" && len(req.Password) != 0 {
|
||||
password, err := base64.StdEncoding.DecodeString(req.Password)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
req.PrivateKey = ""
|
||||
req.PassPhrase = ""
|
||||
req.Password = string(password)
|
||||
}
|
||||
if len(req.PrivateKey) != 0 && req.AuthMode == "key" {
|
||||
req.PrivateKey, err = hostService.EncryptHost(req.PrivateKey)
|
||||
if req.AuthMode == "key" && len(req.PrivateKey) != 0 {
|
||||
privateKey, err := base64.StdEncoding.DecodeString(req.PrivateKey)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if len(req.PassPhrase) != 0 {
|
||||
req.PassPhrase, err = encrypt.StringEncrypt(req.PassPhrase)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
req.Password = ""
|
||||
req.PrivateKey = string(privateKey)
|
||||
}
|
||||
|
||||
upMap := make(map[string]interface{})
|
||||
@@ -210,12 +246,10 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
|
||||
upMap["user"] = req.User
|
||||
upMap["auth_mode"] = req.AuthMode
|
||||
upMap["remember_password"] = req.RememberPassword
|
||||
if req.AuthMode == "password" {
|
||||
if len(req.Password) != 0 {
|
||||
upMap["password"] = req.Password
|
||||
upMap["private_key"] = ""
|
||||
upMap["pass_phrase"] = ""
|
||||
} else {
|
||||
upMap["password"] = ""
|
||||
}
|
||||
if len(req.PrivateKey) != 0 {
|
||||
upMap["private_key"] = req.PrivateKey
|
||||
upMap["pass_phrase"] = req.PassPhrase
|
||||
}
|
||||
@@ -235,7 +269,7 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/update/group [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id","group"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
|
||||
@@ -1,213 +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/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Get tool
|
||||
// @Description 获取主机工具状态
|
||||
// @Accept json
|
||||
// @Param request body request.HostToolReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool [post]
|
||||
func (b *BaseApi) GetToolStatus(c *gin.Context) {
|
||||
var req request.HostToolReq
|
||||
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
|
||||
}
|
||||
|
||||
config, err := hostToolService.GetToolStatus(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, config)
|
||||
}
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Create Host tool Config
|
||||
// @Description 创建主机工具配置
|
||||
// @Accept json
|
||||
// @Param request body request.HostToolCreate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool/create [post]
|
||||
// @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 := 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 := hostToolService.CreateToolConfig(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Operate tool
|
||||
// @Description 操作主机工具
|
||||
// @Accept json
|
||||
// @Param request body request.HostToolReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool/operate [post]
|
||||
// @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 := 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)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Get tool config
|
||||
// @Description 操作主机工具配置文件
|
||||
// @Accept json
|
||||
// @Param request body request.HostToolConfig true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool/config [post]
|
||||
// @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 := 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
|
||||
}
|
||||
|
||||
config, err := hostToolService.OperateToolConfig(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, config)
|
||||
}
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Get tool
|
||||
// @Description 获取主机工具日志
|
||||
// @Accept json
|
||||
// @Param request body request.HostToolLogReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool/log [post]
|
||||
func (b *BaseApi) GetToolLog(c *gin.Context) {
|
||||
var req request.HostToolLogReq
|
||||
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
|
||||
}
|
||||
|
||||
logContent, err := hostToolService.GetToolLog(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, logContent)
|
||||
}
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Create Supervisor process
|
||||
// @Description 操作守护进程
|
||||
// @Accept json
|
||||
// @Param request body request.SupervisorProcessConfig true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool/supervisor/process [post]
|
||||
// @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 := 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.OperateSupervisorProcess(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Get Supervisor process config
|
||||
// @Description 获取 Supervisor 进程配置
|
||||
// @Accept json
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool/supervisor/process [get]
|
||||
func (b *BaseApi) GetProcess(c *gin.Context) {
|
||||
configs, err := hostToolService.GetSupervisorProcessConfig()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, configs)
|
||||
}
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Get Supervisor process config
|
||||
// @Description 操作 Supervisor 进程文件
|
||||
// @Accept json
|
||||
// @Param request body request.SupervisorProcessFileReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool/supervisor/process/file [post]
|
||||
// @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 := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
content, err := hostToolService.OperateSupervisorProcessFile(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, content)
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func (b *BaseApi) SearchImage(c *gin.Context) {
|
||||
// @Summary List images
|
||||
// @Description 获取镜像列表
|
||||
// @Produce json
|
||||
// @Success 200 {array} dto.Options
|
||||
// @Success 200 {anrry} dto.Options
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/image [get]
|
||||
func (b *BaseApi) ListImage(c *gin.Context) {
|
||||
@@ -64,7 +64,7 @@ func (b *BaseApi) ListImage(c *gin.Context) {
|
||||
// @Success 200 {string} log
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/image/build [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"构建镜像 [name]","formatEN":"build image [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"构建镜像 [name]","formatEN":"build image [name]"}
|
||||
func (b *BaseApi) ImageBuild(c *gin.Context) {
|
||||
var req dto.ImageBuild
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -93,7 +93,7 @@ func (b *BaseApi) ImageBuild(c *gin.Context) {
|
||||
// @Success 200 {string} log
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/image/pull [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["repoID","imageName"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -122,7 +122,7 @@ func (b *BaseApi) ImagePull(c *gin.Context) {
|
||||
// @Success 200 {string} log
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/image/push [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["repoID","tagName","name"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -151,7 +151,7 @@ func (b *BaseApi) ImagePush(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/image/remove [post]
|
||||
// @x-panel-log {"bodyKeys":["names"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"移除镜像 [names]","formatEN":"remove image [names]"}
|
||||
// @x-panel-log {"bodyKeys":["names"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"移除镜像 [names]","formatEN":"remove image [names]"}
|
||||
func (b *BaseApi) ImageRemove(c *gin.Context) {
|
||||
var req dto.BatchDelete
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -179,7 +179,7 @@ func (b *BaseApi) ImageRemove(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/image/save [post]
|
||||
// @x-panel-log {"bodyKeys":["tagName","path","name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"保留 [tagName] 为 [path]/[name]","formatEN":"save [tagName] as [path]/[name]"}
|
||||
// @x-panel-log {"bodyKeys":["tagName","path","name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"保留 [tagName] 为 [path]/[name]","formatEN":"save [tagName] as [path]/[name]"}
|
||||
func (b *BaseApi) ImageSave(c *gin.Context) {
|
||||
var req dto.ImageSave
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -207,7 +207,7 @@ func (b *BaseApi) ImageSave(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/image/tag [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["repoID","targetName"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -235,7 +235,7 @@ func (b *BaseApi) ImageTag(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/image/load [post]
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"从 [path] 加载镜像","formatEN":"load image from [path]"}
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"从 [path] 加载镜像","formatEN":"load image from [path]"}
|
||||
func (b *BaseApi) ImageLoad(c *gin.Context) {
|
||||
var req dto.ImageLoad
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
||||
@@ -44,7 +44,7 @@ func (b *BaseApi) SearchRepo(c *gin.Context) {
|
||||
// @Summary List image repos
|
||||
// @Description 获取镜像仓库列表
|
||||
// @Produce json
|
||||
// @Success 200 {array} dto.ImageRepoOption
|
||||
// @Success 200 {anrry} dto.ImageRepoOption
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/repo [get]
|
||||
func (b *BaseApi) ListRepo(c *gin.Context) {
|
||||
@@ -92,7 +92,7 @@ func (b *BaseApi) CheckRepoStatus(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/repo [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建镜像仓库 [name]","formatEN":"create image repo [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建镜像仓库 [name]","formatEN":"create image repo [name]"}
|
||||
func (b *BaseApi) CreateRepo(c *gin.Context) {
|
||||
var req dto.ImageRepoCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -119,7 +119,7 @@ func (b *BaseApi) CreateRepo(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/repo/del [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -147,7 +147,7 @@ func (b *BaseApi) DeleteRepo(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/repo/update [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
|
||||
@@ -70,7 +70,7 @@ func (b *BaseApi) GetOperationLogs(c *gin.Context) {
|
||||
// @Success 200 {object} dto.PageResult
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /logs/clean [post]
|
||||
// @x-panel-log {"bodyKeys":["logType"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清空 [logType] 日志信息","formatEN":"Clean the [logType] log information"}
|
||||
// @x-panel-log {"bodyKeys":["logType"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"清空 [logType] 日志信息","formatEN":"Clean the [logType] log information"}
|
||||
func (b *BaseApi) CleanLogs(c *gin.Context) {
|
||||
var req dto.CleanLog
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -89,40 +89,3 @@ func (b *BaseApi) CleanLogs(c *gin.Context) {
|
||||
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Logs
|
||||
// @Summary Load system log files
|
||||
// @Description 获取系统日志文件列表
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /logs/system/files [get]
|
||||
func (b *BaseApi) GetSystemFiles(c *gin.Context) {
|
||||
data, err := logService.ListSystemLogFile()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags Logs
|
||||
// @Summary Load system logs
|
||||
// @Description 获取系统日志
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /logs/system [post]
|
||||
func (b *BaseApi) GetSystemLogs(c *gin.Context) {
|
||||
var req dto.OperationWithName
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ func (b *BaseApi) GetNginx(c *gin.Context) {
|
||||
// @Description 获取部分 OpenResty 配置信息
|
||||
// @Accept json
|
||||
// @Param request body request.NginxScopeReq true "request"
|
||||
// @Success 200 {array} response.NginxParam
|
||||
// @Success 200 {anrry} response.NginxParam
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /openResty/scope [post]
|
||||
func (b *BaseApi) GetNginxConfigByScope(c *gin.Context) {
|
||||
@@ -53,7 +53,7 @@ func (b *BaseApi) GetNginxConfigByScope(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /openResty/update [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -90,7 +90,7 @@ func (b *BaseApi) GetNginxStatus(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /openResty/file [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 nginx 配置","formatEN":"Update nginx conf"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新 nginx 配置","formatEN":"Update nginx conf"}
|
||||
func (b *BaseApi) UpdateNginxFile(c *gin.Context) {
|
||||
var req request.NginxConfigFileUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
||||
@@ -1,40 +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"
|
||||
websocket2 "github.com/1Panel-dev/1Panel/backend/utils/websocket"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func (b *BaseApi) ProcessWs(c *gin.Context) {
|
||||
ws, err := wsUpgrade.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
wsClient := websocket2.NewWsClient("processClient", ws)
|
||||
go wsClient.Read()
|
||||
go wsClient.Write()
|
||||
}
|
||||
|
||||
// @Tags Process
|
||||
// @Summary Stop Process
|
||||
// @Description 停止进程
|
||||
// @Param request body request.ProcessReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /process/stop [post]
|
||||
// @x-panel-log {"bodyKeys":["PID"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"结束进程 [PID]","formatEN":"结束进程 [PID]"}
|
||||
func (b *BaseApi) StopProcess(c *gin.Context) {
|
||||
var req request.ProcessReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := processService.StopProcess(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
@@ -18,7 +18,8 @@ import (
|
||||
// @Router /runtimes/search [post]
|
||||
func (b *BaseApi) SearchRuntimes(c *gin.Context) {
|
||||
var req request.RuntimeSearch
|
||||
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, items, err := runtimeService.Page(req)
|
||||
@@ -40,10 +41,11 @@ func (b *BaseApi) SearchRuntimes(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /runtimes [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建运行环境 [name]","formatEN":"Create runtime [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建运行环境 [name]","formatEN":"Create runtime [name]"}
|
||||
func (b *BaseApi) CreateRuntime(c *gin.Context) {
|
||||
var req request.RuntimeCreate
|
||||
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 := runtimeService.Create(req); err != nil {
|
||||
@@ -61,13 +63,14 @@ func (b *BaseApi) CreateRuntime(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /runtimes/del [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除网站 [name]","formatEN":"Delete website [name]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"删除网站 [name]","formatEN":"Delete website [name]"}
|
||||
func (b *BaseApi) DeleteRuntime(c *gin.Context) {
|
||||
var req request.RuntimeDelete
|
||||
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 := runtimeService.Delete(req)
|
||||
err := runtimeService.Delete(req.ID)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -83,10 +86,11 @@ func (b *BaseApi) DeleteRuntime(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /runtimes/update [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新运行环境 [name]","formatEN":"Update runtime [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新运行环境 [name]","formatEN":"Update runtime [name]"}
|
||||
func (b *BaseApi) UpdateRuntime(c *gin.Context) {
|
||||
var req request.RuntimeUpdate
|
||||
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 := runtimeService.Update(req); err != nil {
|
||||
@@ -117,88 +121,3 @@ func (b *BaseApi) GetRuntime(c *gin.Context) {
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
// @Tags Runtime
|
||||
// @Summary Get Node package scripts
|
||||
// @Description 获取 Node 项目的 scripts
|
||||
// @Accept json
|
||||
// @Param request body request.NodePackageReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /runtimes/node/package [post]
|
||||
func (b *BaseApi) GetNodePackageRunScript(c *gin.Context) {
|
||||
var req request.NodePackageReq
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
res, err := runtimeService.GetNodePackageRunScript(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
// @Tags Runtime
|
||||
// @Summary Operate runtime
|
||||
// @Description 操作运行环境
|
||||
// @Accept json
|
||||
// @Param request body request.RuntimeOperate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /runtimes/operate [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"操作运行环境 [name]","formatEN":"Operate runtime [name]"}
|
||||
func (b *BaseApi) OperateRuntime(c *gin.Context) {
|
||||
var req request.RuntimeOperate
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
err := runtimeService.OperateRuntime(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Runtime
|
||||
// @Summary Get Node modules
|
||||
// @Description 获取 Node 项目的 modules
|
||||
// @Accept json
|
||||
// @Param request body request.NodeModuleReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /runtimes/node/modules [post]
|
||||
func (b *BaseApi) GetNodeModules(c *gin.Context) {
|
||||
var req request.NodeModuleReq
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
res, err := runtimeService.GetNodeModules(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
// @Tags Runtime
|
||||
// @Summary Operate Node modules
|
||||
// @Description 操作 Node 项目 modules
|
||||
// @Accept json
|
||||
// @Param request body request.NodeModuleReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /runtimes/node/modules/operate [post]
|
||||
func (b *BaseApi) OperateNodeModules(c *gin.Context) {
|
||||
var req request.NodeModuleOperateReq
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
err := runtimeService.OperateNodeModules(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@ package v1
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
@@ -46,7 +44,7 @@ func (b *BaseApi) GetSystemAvailable(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/update [post]
|
||||
// @x-panel-log {"bodyKeys":["key","value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统配置 [key] => [value]","formatEN":"update system setting [key] => [value]"}
|
||||
// @x-panel-log {"bodyKeys":["key","value"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改系统配置 [key] => [value]","formatEN":"update system setting [key] => [value]"}
|
||||
func (b *BaseApi) UpdateSetting(c *gin.Context) {
|
||||
var req dto.SettingUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -73,7 +71,7 @@ func (b *BaseApi) UpdateSetting(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/password/update [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统密码","formatEN":"update system password"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改系统密码","formatEN":"update system password"}
|
||||
func (b *BaseApi) UpdatePassword(c *gin.Context) {
|
||||
var req dto.PasswordUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -100,7 +98,7 @@ func (b *BaseApi) UpdatePassword(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/ssl/update [post]
|
||||
// @x-panel-log {"bodyKeys":["ssl"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统 ssl => [ssl]","formatEN":"update system ssl => [ssl]"}
|
||||
// @x-panel-log {"bodyKeys":["ssl"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改系统 ssl => [ssl]","formatEN":"update system ssl => [ssl]"}
|
||||
func (b *BaseApi) UpdateSSL(c *gin.Context) {
|
||||
var req dto.SSLUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -134,22 +132,6 @@ func (b *BaseApi) LoadFromCert(c *gin.Context) {
|
||||
helper.SuccessWithData(c, info)
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
// @Summary Download system cert
|
||||
// @Description 下载证书
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/ssl/download [post]
|
||||
func (b *BaseApi) DownloadSSL(c *gin.Context) {
|
||||
pathItem := path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt")
|
||||
if _, err := os.Stat(pathItem); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.File(pathItem)
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
// @Summary Update system port
|
||||
// @Description 更新系统端口
|
||||
@@ -158,7 +140,7 @@ func (b *BaseApi) DownloadSSL(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/port/update [post]
|
||||
// @x-panel-log {"bodyKeys":["serverPort"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统端口 => [serverPort]","formatEN":"update system port => [serverPort]"}
|
||||
// @x-panel-log {"bodyKeys":["serverPort"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改系统端口 => [serverPort]","formatEN":"update system port => [serverPort]"}
|
||||
func (b *BaseApi) UpdatePort(c *gin.Context) {
|
||||
var req dto.PortUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -185,7 +167,7 @@ func (b *BaseApi) UpdatePort(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/expired/handle [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"重置过期密码","formatEN":"reset an expired Password"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"重置过期密码","formatEN":"reset an expired Password"}
|
||||
func (b *BaseApi) HandlePasswordExpired(c *gin.Context) {
|
||||
var req dto.PasswordUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -227,7 +209,7 @@ func (b *BaseApi) LoadTimeZone(c *gin.Context) {
|
||||
// @Success 200 {string} ntime
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/time/sync [post]
|
||||
// @x-panel-log {"bodyKeys":["ntpSite"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"系统时间同步[ntpSite]","formatEN":"sync system time [ntpSite]"}
|
||||
// @x-panel-log {"bodyKeys":["ntpSite"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"系统时间同步[ntpSite]","formatEN":"sync system time [ntpSite]"}
|
||||
func (b *BaseApi) SyncTime(c *gin.Context) {
|
||||
var req dto.SyncTime
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -257,7 +239,7 @@ func (b *BaseApi) LoadBaseDir(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/monitor/clean [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清空监控数据","formatEN":"clean monitor datas"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"清空监控数据","formatEN":"clean monitor datas"}
|
||||
func (b *BaseApi) CleanMonitor(c *gin.Context) {
|
||||
if err := global.DB.Exec("DELETE FROM monitor_bases").Error; err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
@@ -275,53 +257,14 @@ func (b *BaseApi) CleanMonitor(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
// @Summary Scan system
|
||||
// @Description 扫描系统垃圾文件
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/scan [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"扫描系统垃圾文件","formatEN":"scan System Junk Files"}
|
||||
func (b *BaseApi) ScanSystem(c *gin.Context) {
|
||||
helper.SuccessWithData(c, settingService.SystemScan())
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
// @Summary System clean
|
||||
// @Description 清理系统垃圾文件
|
||||
// @Accept json
|
||||
// @Param request body []dto.Clean true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/clean [post]
|
||||
// @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 := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
settingService.SystemClean(req)
|
||||
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
// @Summary Load mfa info
|
||||
// @Description 获取 mfa 信息
|
||||
// @Accept json
|
||||
// @Param request body dto.MfaCredential true "request"
|
||||
// @Success 200 {object} mfa.Otp
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/mfa [post]
|
||||
func (b *BaseApi) LoadMFA(c *gin.Context) {
|
||||
var req dto.MfaRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
otp, err := mfa.GetOtp("admin", req.Title, req.Interval)
|
||||
// @Router /settings/mfa [get]
|
||||
func (b *BaseApi) GetMFA(c *gin.Context) {
|
||||
otp, err := mfa.GetOtp("admin")
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -338,24 +281,19 @@ func (b *BaseApi) LoadMFA(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/mfa/bind [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"mfa 绑定","formatEN":"bind mfa"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"mfa 绑定","formatEN":"bind mfa"}
|
||||
func (b *BaseApi) MFABind(c *gin.Context) {
|
||||
var req dto.MfaCredential
|
||||
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)
|
||||
success := mfa.ValidCode(req.Code, req.Secret)
|
||||
if !success {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, errors.New("code is not valid"))
|
||||
return
|
||||
}
|
||||
|
||||
if err := settingService.Update("MFAInterval", req.Interval); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := settingService.Update("MFAStatus", "enable"); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/snapshot [post]
|
||||
// @x-panel-log {"bodyKeys":["from", "description"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建系统快照 [description] 到 [from]","formatEN":"Create system backup [description] to [from]"}
|
||||
// @x-panel-log {"bodyKeys":["from", "description"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建系统快照 [description] 到 [from]","formatEN":"Create system backup [description] to [from]"}
|
||||
func (b *BaseApi) CreateSnapshot(c *gin.Context) {
|
||||
var req dto.SnapshotCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -42,7 +42,7 @@ func (b *BaseApi) CreateSnapshot(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/snapshot/import [post]
|
||||
// @x-panel-log {"bodyKeys":["from", "names"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"从 [from] 同步系统快照 [names]","formatEN":"Sync system snapshots [names] from [from]"}
|
||||
// @x-panel-log {"bodyKeys":["from", "names"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"从 [from] 同步系统快照 [names]","formatEN":"Sync system snapshots [names] from [from]"}
|
||||
func (b *BaseApi) ImportSnapshot(c *gin.Context) {
|
||||
var req dto.SnapshotImport
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -60,32 +60,6 @@ func (b *BaseApi) ImportSnapshot(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
// @Summary Load Snapshot status
|
||||
// @Description 获取快照状态
|
||||
// @Accept json
|
||||
// @Param request body dto.OperateByID true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/snapshot/status [post]
|
||||
func (b *BaseApi) LoadSnapShotStatus(c *gin.Context) {
|
||||
var req dto.OperateByID
|
||||
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)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
// @Summary Update snapshot description
|
||||
// @Description 更新快照描述信息
|
||||
@@ -94,7 +68,7 @@ func (b *BaseApi) LoadSnapShotStatus(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/snapshot/description/update [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -145,7 +119,7 @@ func (b *BaseApi) SearchSnapshot(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/snapshot/recover [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -172,7 +146,7 @@ func (b *BaseApi) RecoverSnapshot(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/snapshot/rollback [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -199,7 +173,7 @@ func (b *BaseApi) RollbackSnapshot(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/snapshot/del [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
|
||||
+15
-57
@@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Load host SSH setting info
|
||||
// @Summary Load host ssh setting info
|
||||
// @Description 加载 SSH 配置信息
|
||||
// @Success 200 {object} dto.SSHInfo
|
||||
// @Security ApiKeyAuth
|
||||
@@ -24,13 +24,13 @@ func (b *BaseApi) GetSSHInfo(c *gin.Context) {
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Operate SSH
|
||||
// @Summary Operate ssh
|
||||
// @Description 修改 SSH 服务状态
|
||||
// @Accept json
|
||||
// @Param request body dto.Operate true "request"
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/ssh/operate [post]
|
||||
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] SSH ","formatEN":"[operation] SSH"}
|
||||
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"[operation] SSH ","formatEN":"[operation] SSH"}
|
||||
func (b *BaseApi) OperateSSH(c *gin.Context) {
|
||||
var req dto.Operate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -50,14 +50,14 @@ func (b *BaseApi) OperateSSH(c *gin.Context) {
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Update host SSH setting
|
||||
// @Summary Update host ssh setting
|
||||
// @Description 更新 SSH 配置
|
||||
// @Accept json
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["key","value"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改 SSH 配置 [key] => [value]","formatEN":"update SSH setting [key] => [value]"}
|
||||
func (b *BaseApi) UpdateSSH(c *gin.Context) {
|
||||
var req dto.SettingUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -77,14 +77,14 @@ func (b *BaseApi) UpdateSSH(c *gin.Context) {
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Update host SSH setting by file
|
||||
// @Summary Update host ssh setting by file
|
||||
// @Description 上传文件更新 SSH 配置
|
||||
// @Accept json
|
||||
// @Param request body dto.SSHConf true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/conffile/update [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改 SSH 配置文件","formatEN":"update SSH conf"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改 SSH 配置文件","formatEN":"update SSH conf"}
|
||||
func (b *BaseApi) UpdateSSHByfile(c *gin.Context) {
|
||||
var req dto.SSHConf
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -104,14 +104,14 @@ func (b *BaseApi) UpdateSSHByfile(c *gin.Context) {
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Generate host SSH secret
|
||||
// @Description 生成 SSH 密钥
|
||||
// @Summary Generate host ssh secret
|
||||
// @Description 生成 ssh 密钥
|
||||
// @Accept json
|
||||
// @Param request body dto.GenerateSSH true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/ssh/generate [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"生成 SSH 密钥 ","formatEN":"generate SSH secret"}
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"生成 SSH 密钥 ","formatEN":"generate SSH secret"}
|
||||
func (b *BaseApi) GenerateSSH(c *gin.Context) {
|
||||
var req dto.GenerateSSH
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -131,8 +131,8 @@ func (b *BaseApi) GenerateSSH(c *gin.Context) {
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Load host SSH secret
|
||||
// @Description 获取 SSH 密钥
|
||||
// @Summary Load host ssh secret
|
||||
// @Description 获取 ssh 密钥
|
||||
// @Accept json
|
||||
// @Param request body dto.GenerateLoad true "request"
|
||||
// @Success 200
|
||||
@@ -158,40 +158,13 @@ func (b *BaseApi) LoadSSHSecret(c *gin.Context) {
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Analysis host SSH logs
|
||||
// @Description 分析 SSH 登录日志
|
||||
// @Accept json
|
||||
// @Param request body dto.SearchForAnalysis true "request"
|
||||
// @Success 200 {array} dto.SSHLogAnalysis
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/ssh/log/analysis [post]
|
||||
func (b *BaseApi) AnalysisLog(c *gin.Context) {
|
||||
var req dto.SearchForAnalysis
|
||||
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 := sshService.AnalysisLog(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Load host SSH logs
|
||||
// @Description 获取 SSH 登录日志
|
||||
// @Summary Load host ssh logs
|
||||
// @Description 获取 ssh 登录日志
|
||||
// @Accept json
|
||||
// @Param request body dto.SearchSSHLog true "request"
|
||||
// @Success 200 {object} dto.SSHLog
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/ssh/log [post]
|
||||
// @Router /host/ssh/logs [post]
|
||||
func (b *BaseApi) LoadSSHLogs(c *gin.Context) {
|
||||
var req dto.SearchSSHLog
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -210,18 +183,3 @@ func (b *BaseApi) LoadSSHLogs(c *gin.Context) {
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Load host SSH conf
|
||||
// @Description 获取 SSH 配置文件
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/ssh/conf [get]
|
||||
func (b *BaseApi) LoadSSHConf(c *gin.Context) {
|
||||
data, err := sshService.LoadSSHConf()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/copier"
|
||||
@@ -20,27 +22,24 @@ import (
|
||||
)
|
||||
|
||||
func (b *BaseApi) WsSsh(c *gin.Context) {
|
||||
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("gin context http handler failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
defer wsConn.Close()
|
||||
|
||||
id, err := strconv.Atoi(c.Query("id"))
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "invalid param id in request")) {
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
cols, err := strconv.Atoi(c.DefaultQuery("cols", "80"))
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "invalid param cols in request")) {
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
rows, err := strconv.Atoi(c.DefaultQuery("rows", "40"))
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "invalid param rows in request")) {
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
host, err := hostService.GetHostInfo(uint(id))
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "load host info by id failed")) {
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
var connInfo ssh.ConnInfo
|
||||
@@ -50,12 +49,24 @@ func (b *BaseApi) WsSsh(c *gin.Context) {
|
||||
connInfo.PassPhrase = []byte(host.PassPhrase)
|
||||
}
|
||||
|
||||
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("gin context http handler failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
defer wsConn.Close()
|
||||
|
||||
client, err := connInfo.NewClient()
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "failed to set up the connection. Please check the host information")) {
|
||||
return
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
ssConn, err := connInfo.NewSshConn(cols, rows)
|
||||
if wshandleError(wsConn, err) {
|
||||
return
|
||||
}
|
||||
defer ssConn.Close()
|
||||
|
||||
sws, err := terminal.NewLogicSshWsSession(cols, rows, true, connInfo.Client, wsConn)
|
||||
if wshandleError(wsConn, err) {
|
||||
return
|
||||
@@ -74,25 +85,28 @@ func (b *BaseApi) WsSsh(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (b *BaseApi) RedisWsSsh(c *gin.Context) {
|
||||
cols, err := strconv.Atoi(c.DefaultQuery("cols", "80"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
rows, err := strconv.Atoi(c.DefaultQuery("rows", "40"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
redisConf, err := redisService.LoadConf()
|
||||
if err != nil {
|
||||
global.LOG.Errorf("load redis container failed, err: %v", err)
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("gin context http handler failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
cols, err := strconv.Atoi(c.DefaultQuery("cols", "80"))
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "invalid param cols in request")) {
|
||||
return
|
||||
}
|
||||
rows, err := strconv.Atoi(c.DefaultQuery("rows", "40"))
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "invalid param rows in request")) {
|
||||
return
|
||||
}
|
||||
redisConf, err := redisService.LoadConf()
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "load redis container failed")) {
|
||||
return
|
||||
}
|
||||
|
||||
defer wsConn.Close()
|
||||
commands := "redis-cli"
|
||||
if len(redisConf.Requirepass) != 0 {
|
||||
@@ -124,6 +138,24 @@ func (b *BaseApi) RedisWsSsh(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (b *BaseApi) ContainerWsSsh(c *gin.Context) {
|
||||
containerID := c.Query("containerid")
|
||||
command := c.Query("command")
|
||||
user := c.Query("user")
|
||||
if len(command) == 0 || len(containerID) == 0 {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error param of command or containerID"))
|
||||
return
|
||||
}
|
||||
cols, err := strconv.Atoi(c.DefaultQuery("cols", "80"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
rows, err := strconv.Atoi(c.DefaultQuery("rows", "40"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("gin context http handler failed, err: %v", err)
|
||||
@@ -131,23 +163,6 @@ func (b *BaseApi) ContainerWsSsh(c *gin.Context) {
|
||||
}
|
||||
defer wsConn.Close()
|
||||
|
||||
containerID := c.Query("containerid")
|
||||
command := c.Query("command")
|
||||
user := c.Query("user")
|
||||
if len(command) == 0 || len(containerID) == 0 {
|
||||
if wshandleError(wsConn, errors.New("error param of command or containerID")) {
|
||||
return
|
||||
}
|
||||
}
|
||||
cols, err := strconv.Atoi(c.DefaultQuery("cols", "80"))
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "invalid param cols in request")) {
|
||||
return
|
||||
}
|
||||
rows, err := strconv.Atoi(c.DefaultQuery("rows", "40"))
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "invalid param rows in request")) {
|
||||
return
|
||||
}
|
||||
|
||||
cmds := []string{"exec", containerID, command}
|
||||
if len(user) != 0 {
|
||||
cmds = []string{"exec", "-u", user, containerID, command}
|
||||
|
||||
@@ -52,7 +52,7 @@ func (b *BaseApi) GetNotesByVersion(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/upgrade [post]
|
||||
// @x-panel-log {"bodyKeys":["version"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新系统 => [version]","formatEN":"upgrade service => [version]"}
|
||||
// @x-panel-log {"bodyKeys":["version"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新系统 => [version]","formatEN":"upgrade service => [version]"}
|
||||
func (b *BaseApi) Upgrade(c *gin.Context) {
|
||||
var req dto.Upgrade
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
||||
+24
-157
@@ -36,7 +36,7 @@ func (b *BaseApi) PageWebsite(c *gin.Context) {
|
||||
// @Tags Website
|
||||
// @Summary List websites
|
||||
// @Description 获取网站列表
|
||||
// @Success 200 {array} response.WebsiteDTO
|
||||
// @Success 200 {anrry} response.WebsiteDTO
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/list [get]
|
||||
func (b *BaseApi) GetWebsites(c *gin.Context) {
|
||||
@@ -51,7 +51,7 @@ func (b *BaseApi) GetWebsites(c *gin.Context) {
|
||||
// @Tags Website
|
||||
// @Summary List website names
|
||||
// @Description 获取网站列表
|
||||
// @Success 200 {array} string
|
||||
// @Success 200 {anrry} string
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/options [get]
|
||||
func (b *BaseApi) GetWebsiteOptions(c *gin.Context) {
|
||||
@@ -71,7 +71,7 @@ func (b *BaseApi) GetWebsiteOptions(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites [post]
|
||||
// @x-panel-log {"bodyKeys":["primaryDomain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建网站 [primaryDomain]","formatEN":"Create website [primaryDomain]"}
|
||||
// @x-panel-log {"bodyKeys":["primaryDomain"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建网站 [primaryDomain]","formatEN":"Create website [primaryDomain]"}
|
||||
func (b *BaseApi) CreateWebsite(c *gin.Context) {
|
||||
var req request.WebsiteCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -95,7 +95,7 @@ func (b *BaseApi) CreateWebsite(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/operate [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -118,7 +118,7 @@ func (b *BaseApi) OpWebsite(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/del [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -142,7 +142,7 @@ func (b *BaseApi) DeleteWebsite(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/update [post]
|
||||
// @x-panel-log {"bodyKeys":["primaryDomain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新网站 [primaryDomain]","formatEN":"Update website [primaryDomain]"}
|
||||
// @x-panel-log {"bodyKeys":["primaryDomain"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新网站 [primaryDomain]","formatEN":"Update website [primaryDomain]"}
|
||||
func (b *BaseApi) UpdateWebsite(c *gin.Context) {
|
||||
var req request.WebsiteUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -207,7 +207,7 @@ func (b *BaseApi) GetWebsiteNginx(c *gin.Context) {
|
||||
// @Description 通过网站 id 查询域名
|
||||
// @Accept json
|
||||
// @Param websiteId path integer true "request"
|
||||
// @Success 200 {array} model.WebsiteDomain
|
||||
// @Success 200 {anrry} model.WebsiteDomain
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/domains/:websiteId [get]
|
||||
func (b *BaseApi) GetWebDomains(c *gin.Context) {
|
||||
@@ -232,7 +232,7 @@ func (b *BaseApi) GetWebDomains(c *gin.Context) {
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 {
|
||||
@@ -255,7 +255,7 @@ func (b *BaseApi) DeleteWebDomain(c *gin.Context) {
|
||||
// @Success 200 {object} model.WebsiteDomain
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/domains [post]
|
||||
// @x-panel-log {"bodyKeys":["domain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建域名 [domain]","formatEN":"Create domain [domain]"}
|
||||
// @x-panel-log {"bodyKeys":["domain"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建域名 [domain]","formatEN":"Create domain [domain]"}
|
||||
func (b *BaseApi) CreateWebDomain(c *gin.Context) {
|
||||
var req request.WebsiteDomainCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -300,7 +300,7 @@ func (b *BaseApi) GetNginxConfig(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/config/update [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -344,7 +344,7 @@ func (b *BaseApi) GetHTTPSConfig(c *gin.Context) {
|
||||
// @Success 200 {object} response.WebsiteHTTPS
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/:id/https [post]
|
||||
// @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"}
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -367,7 +367,7 @@ func (b *BaseApi) UpdateHTTPSConfig(c *gin.Context) {
|
||||
// @Description 网站创建前检查
|
||||
// @Accept json
|
||||
// @Param request body request.WebsiteInstallCheckReq true "request"
|
||||
// @Success 200 {array} response.WebsitePreInstallCheck
|
||||
// @Success 200 {anrry} request.WebsitePreInstallCheck
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/check [post]
|
||||
func (b *BaseApi) CreateWebsiteCheck(c *gin.Context) {
|
||||
@@ -414,7 +414,7 @@ func (b *BaseApi) GetWebsiteWafConfig(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/waf/update [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -428,28 +428,6 @@ func (b *BaseApi) UpdateWebsiteWafConfig(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Website WAF
|
||||
// @Summary Update website waf file
|
||||
// @Description 更新 网站 waf 配置文件
|
||||
// @Accept json
|
||||
// @Param request body request.WebsiteWafUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/waf/file/update [post]
|
||||
// @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 := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := websiteService.UpdateWafFile(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Website Nginx
|
||||
// @Summary Update website nginx conf
|
||||
// @Description 更新 网站 nginx 配置
|
||||
@@ -458,7 +436,7 @@ func (b *BaseApi) UpdateWebsiteWafFile(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/nginx/update [post]
|
||||
// @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"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -480,7 +458,7 @@ func (b *BaseApi) UpdateWebsiteNginxConfig(c *gin.Context) {
|
||||
// @Success 200 {object} response.WebsiteLog
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/log [post]
|
||||
// @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"}
|
||||
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -503,7 +481,7 @@ func (b *BaseApi) OpWebsiteLog(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/default/server [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -547,7 +525,7 @@ func (b *BaseApi) GetWebsitePHPConfig(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/php/config [post]
|
||||
// @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"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -563,13 +541,13 @@ func (b *BaseApi) UpdateWebsitePHPConfig(c *gin.Context) {
|
||||
|
||||
// @Tags Website PHP
|
||||
// @Summary Update php conf
|
||||
// @Description 更新 php 配置文件
|
||||
// @Description 更新 php 配置
|
||||
// @Accept json
|
||||
// @Param request body request.WebsitePHPFileUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/php/update [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -583,28 +561,6 @@ func (b *BaseApi) UpdatePHPFile(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Website PHP
|
||||
// @Summary Update php version
|
||||
// @Description 变更 php 版本
|
||||
// @Accept json
|
||||
// @Param request body request.WebsitePHPVersionReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/php/version [post]
|
||||
// @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 := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := websiteService.ChangePHPVersion(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Get rewrite conf
|
||||
// @Description 获取伪静态配置
|
||||
@@ -635,7 +591,7 @@ func (b *BaseApi) GetRewriteConfig(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/rewrite/update [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["websiteID"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -657,7 +613,7 @@ func (b *BaseApi) UpdateRewriteConfig(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/dir/update [post]
|
||||
// @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"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -679,7 +635,7 @@ func (b *BaseApi) UpdateSiteDir(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/dir/permission [post]
|
||||
// @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"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -723,7 +679,7 @@ func (b *BaseApi) GetProxyConfig(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/proxies/update [post]
|
||||
// @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"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -746,7 +702,7 @@ func (b *BaseApi) UpdateProxyConfig(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/proxy/file [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["websiteID"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -845,92 +801,3 @@ func (b *BaseApi) UpdateAntiLeech(c *gin.Context) {
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Update redirect conf
|
||||
// @Description 修改重定向配置
|
||||
// @Accept json
|
||||
// @Param request body request.NginxRedirectReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/redirect/update [post]
|
||||
// @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 := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
err := websiteService.OperateRedirect(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Get redirect conf
|
||||
// @Description 获取重定向配置
|
||||
// @Accept json
|
||||
// @Param request body request.WebsiteProxyReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/redirect [post]
|
||||
func (b *BaseApi) GetRedirectConfig(c *gin.Context) {
|
||||
var req request.WebsiteRedirectReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
res, err := websiteService.GetRedirect(req.WebsiteID)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Update redirect file
|
||||
// @Description 更新重定向文件
|
||||
// @Accept json
|
||||
// @Param request body request.NginxRedirectUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/redirect/file [post]
|
||||
// @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 := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := websiteService.UpdateRedirectFile(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Get website dir
|
||||
// @Description 获取网站目录配置
|
||||
// @Accept json
|
||||
// @Param request body request.WebsiteCommonReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/dir [post]
|
||||
func (b *BaseApi) GetDirConfig(c *gin.Context) {
|
||||
var req request.WebsiteCommonReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
res, err := websiteService.LoadWebsiteDirConfig(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ func (b *BaseApi) PageWebsiteAcmeAccount(c *gin.Context) {
|
||||
// @Success 200 {object} response.WebsiteAcmeAccountDTO
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/acme [post]
|
||||
// @x-panel-log {"bodyKeys":["email"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建网站 acme [email]","formatEN":"Create website acme [email]"}
|
||||
// @x-panel-log {"bodyKeys":["email"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建网站 acme [email]","formatEN":"Create website acme [email]"}
|
||||
func (b *BaseApi) CreateWebsiteAcmeAccount(c *gin.Context) {
|
||||
var req request.WebsiteAcmeAccountCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -64,7 +64,7 @@ func (b *BaseApi) CreateWebsiteAcmeAccount(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/acme/del [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
|
||||
@@ -41,7 +41,7 @@ func (b *BaseApi) PageWebsiteDnsAccount(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/dns [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建网站 dns [name]","formatEN":"Create website dns [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建网站 dns [name]","formatEN":"Create website dns [name]"}
|
||||
func (b *BaseApi) CreateWebsiteDnsAccount(c *gin.Context) {
|
||||
var req request.WebsiteDnsAccountCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -63,7 +63,7 @@ func (b *BaseApi) CreateWebsiteDnsAccount(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/dns/update [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新网站 dns [name]","formatEN":"Update website dns [name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新网站 dns [name]","formatEN":"Update website dns [name]"}
|
||||
func (b *BaseApi) UpdateWebsiteDnsAccount(c *gin.Context) {
|
||||
var req request.WebsiteDnsAccountUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -85,7 +85,7 @@ func (b *BaseApi) UpdateWebsiteDnsAccount(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/dns/del [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
|
||||
@@ -35,7 +35,7 @@ func (b *BaseApi) PageWebsiteSSL(c *gin.Context) {
|
||||
Items: accounts,
|
||||
})
|
||||
} else {
|
||||
list, err := websiteSSLService.Search(req)
|
||||
list, err := websiteSSLService.Search()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -52,7 +52,7 @@ func (b *BaseApi) PageWebsiteSSL(c *gin.Context) {
|
||||
// @Success 200 {object} request.WebsiteSSLCreate
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/ssl [post]
|
||||
// @x-panel-log {"bodyKeys":["primaryDomain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建网站 ssl [primaryDomain]","formatEN":"Create website ssl [primaryDomain]"}
|
||||
// @x-panel-log {"bodyKeys":["primaryDomain"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建网站 ssl [primaryDomain]","formatEN":"Create website ssl [primaryDomain]"}
|
||||
func (b *BaseApi) CreateWebsiteSSL(c *gin.Context) {
|
||||
var req request.WebsiteSSLCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -75,7 +75,7 @@ func (b *BaseApi) CreateWebsiteSSL(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/ssl/renew [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["SSLId"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -94,7 +94,7 @@ func (b *BaseApi) RenewWebsiteSSL(c *gin.Context) {
|
||||
// @Description 解析网站 ssl
|
||||
// @Accept json
|
||||
// @Param request body request.WebsiteDNSReq true "request"
|
||||
// @Success 200 {array} response.WebsiteDNSRes
|
||||
// @Success 200 {anrry} response.WebsiteDNSRes
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/ssl/resolve [post]
|
||||
func (b *BaseApi) GetDNSResolve(c *gin.Context) {
|
||||
@@ -119,7 +119,7 @@ func (b *BaseApi) GetDNSResolve(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/ssl/del [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -185,7 +185,7 @@ func (b *BaseApi) GetWebsiteSSLById(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/ssl/update [post]
|
||||
// @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]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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 := c.ShouldBindJSON(&req); err != nil {
|
||||
|
||||
+1
-13
@@ -15,10 +15,6 @@ type AuthParam struct {
|
||||
RootPassword string `json:"PANEL_DB_ROOT_PASSWORD"`
|
||||
}
|
||||
|
||||
type RedisAuthParam struct {
|
||||
RootPassword string `json:"PANEL_REDIS_ROOT_PASSWORD"`
|
||||
}
|
||||
|
||||
type ContainerExec struct {
|
||||
ContainerName string `json:"containerName"`
|
||||
DbParam AppDatabase `json:"dbParam"`
|
||||
@@ -67,8 +63,7 @@ type LocalAppInstallDefine struct {
|
||||
}
|
||||
|
||||
type ExtraProperties struct {
|
||||
Tags []Tag `json:"tags"`
|
||||
Version string `json:"version"`
|
||||
Tags []Tag `json:"tags"`
|
||||
}
|
||||
|
||||
type AppProperty struct {
|
||||
@@ -98,7 +93,6 @@ type AppConfigVersion struct {
|
||||
type Tag struct {
|
||||
Key string `json:"key"`
|
||||
Name string `json:"name"`
|
||||
Sort int `json:"sort"`
|
||||
}
|
||||
|
||||
type AppForm struct {
|
||||
@@ -134,9 +128,3 @@ var AppToolMap = map[string]string{
|
||||
"mysql": "phpmyadmin",
|
||||
"redis": "redis-commander",
|
||||
}
|
||||
|
||||
type AppInstallInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Key string `json:"key"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
@@ -11,15 +11,9 @@ type UserLoginInfo struct {
|
||||
MfaStatus string `json:"mfaStatus"`
|
||||
}
|
||||
|
||||
type MfaRequest struct {
|
||||
Title string `json:"title"`
|
||||
Interval int `json:"interval"`
|
||||
}
|
||||
|
||||
type MfaCredential struct {
|
||||
Secret string `json:"secret"`
|
||||
Code string `json:"code"`
|
||||
Interval string `json:"interval"`
|
||||
Secret string `json:"secret"`
|
||||
Code string `json:"code"`
|
||||
}
|
||||
|
||||
type Login struct {
|
||||
@@ -29,7 +23,6 @@ type Login struct {
|
||||
Captcha string `json:"captcha"`
|
||||
CaptchaID string `json:"captchaID"`
|
||||
AuthMethod string `json:"authMethod"`
|
||||
Language string `json:"language"`
|
||||
}
|
||||
|
||||
type MFALogin struct {
|
||||
|
||||
+16
-11
@@ -8,17 +8,22 @@ type BackupOperate struct {
|
||||
Bucket string `json:"bucket"`
|
||||
AccessKey string `json:"accessKey"`
|
||||
Credential string `json:"credential"`
|
||||
BackupPath string `json:"backupPath"`
|
||||
Vars string `json:"vars" validate:"required"`
|
||||
}
|
||||
|
||||
type BackupInfo struct {
|
||||
ID uint `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Type string `json:"type"`
|
||||
Bucket string `json:"bucket"`
|
||||
BackupPath string `json:"backupPath"`
|
||||
Vars string `json:"vars"`
|
||||
ID uint `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Type string `json:"type"`
|
||||
Bucket string `json:"bucket"`
|
||||
Vars string `json:"vars"`
|
||||
}
|
||||
|
||||
type BackupSearch struct {
|
||||
PageInfo
|
||||
Type string `json:"type" validate:"required,oneof=website mysql"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
DetailName string `json:"detailName"`
|
||||
}
|
||||
|
||||
type BackupSearchFile struct {
|
||||
@@ -26,13 +31,13 @@ type BackupSearchFile struct {
|
||||
}
|
||||
|
||||
type CommonBackup struct {
|
||||
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website"`
|
||||
Type string `json:"type" validate:"required,oneof=app mysql redis website"`
|
||||
Name string `json:"name"`
|
||||
DetailName string `json:"detailName"`
|
||||
}
|
||||
type CommonRecover struct {
|
||||
Source string `json:"source" validate:"required,oneof=OSS S3 SFTP MINIO LOCAL COS KODO OneDrive"`
|
||||
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website"`
|
||||
Source string `json:"source" validate:"required,oneof=OSS S3 SFTP MINIO LOCAL COS KODO"`
|
||||
Type string `json:"type" validate:"required,oneof=app mysql redis website"`
|
||||
Name string `json:"name"`
|
||||
DetailName string `json:"detailName"`
|
||||
File string `json:"file"`
|
||||
@@ -55,7 +60,7 @@ type BackupRecords struct {
|
||||
}
|
||||
|
||||
type DownloadRecord struct {
|
||||
Source string `json:"source" validate:"required,oneof=OSS S3 SFTP MINIO LOCAL COS KODO OneDrive"`
|
||||
Source string `json:"source" validate:"required,oneof=OSS S3 SFTP MINIO LOCAL COS KODO"`
|
||||
FileDir string `json:"fileDir" validate:"required"`
|
||||
FileName string `json:"fileName" validate:"required"`
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ package dto
|
||||
|
||||
type SearchWithPage struct {
|
||||
PageInfo
|
||||
Info string `json:"info"`
|
||||
OrderBy string `json:"orderBy"`
|
||||
Order string `json:"order"`
|
||||
Info string `json:"info"`
|
||||
}
|
||||
|
||||
type PageInfo struct {
|
||||
|
||||
@@ -5,8 +5,6 @@ import "time"
|
||||
type PageContainer struct {
|
||||
PageInfo
|
||||
Name string `json:"name"`
|
||||
OrderBy string `json:"orderBy"`
|
||||
Order string `json:"order"`
|
||||
Filters string `json:"filters"`
|
||||
}
|
||||
|
||||
@@ -24,33 +22,22 @@ type ContainerInfo struct {
|
||||
State string `json:"state"`
|
||||
RunTime string `json:"runTime"`
|
||||
|
||||
Network []string `json:"network"`
|
||||
Ports []string `json:"ports"`
|
||||
CPUPercent float64 `json:"cpuPercent"`
|
||||
MemoryPercent float64 `json:"memoryPercent"`
|
||||
Ports []string `json:"ports"`
|
||||
|
||||
IsFromApp bool `json:"isFromApp"`
|
||||
IsFromCompose bool `json:"isFromCompose"`
|
||||
}
|
||||
|
||||
type ResourceLimit struct {
|
||||
CPU int `json:"cpu"`
|
||||
Memory int `json:"memory"`
|
||||
}
|
||||
|
||||
type ContainerOperate struct {
|
||||
ContainerID string `json:"containerID"`
|
||||
ForcePull bool `json:"forcePull"`
|
||||
type ContainerCreate struct {
|
||||
Name string `json:"name"`
|
||||
Image string `json:"image"`
|
||||
Network string `json:"network"`
|
||||
PublishAllPorts bool `json:"publishAllPorts"`
|
||||
ExposedPorts []PortHelper `json:"exposedPorts"`
|
||||
Tty bool `json:"tty"`
|
||||
OpenStdin bool `json:"openStdin"`
|
||||
Cmd []string `json:"cmd"`
|
||||
Entrypoint []string `json:"entrypoint"`
|
||||
CPUShares int64 `json:"cpuShares"`
|
||||
NanoCPUs float64 `json:"nanoCPUs"`
|
||||
Memory float64 `json:"memory"`
|
||||
NanoCPUs int64 `json:"nanoCPUs"`
|
||||
Memory int64 `json:"memory"`
|
||||
AutoRemove bool `json:"autoRemove"`
|
||||
Volumes []VolumeHelper `json:"volumes"`
|
||||
Labels []string `json:"labels"`
|
||||
@@ -58,27 +45,7 @@ type ContainerOperate struct {
|
||||
RestartPolicy string `json:"restartPolicy"`
|
||||
}
|
||||
|
||||
type ContainerUpgrade struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Image string `json:"image" validate:"required"`
|
||||
ForcePull bool `json:"forcePull"`
|
||||
}
|
||||
|
||||
type ContainerListStats struct {
|
||||
ContainerID string `json:"containerID"`
|
||||
|
||||
CPUTotalUsage uint64 `json:"cpuTotalUsage"`
|
||||
SystemUsage uint64 `json:"systemUsage"`
|
||||
CPUPercent float64 `json:"cpuPercent"`
|
||||
PercpuUsage int `json:"percpuUsage"`
|
||||
|
||||
MemoryCache uint64 `json:"memoryCache"`
|
||||
MemoryUsage uint64 `json:"memoryUsage"`
|
||||
MemoryLimit uint64 `json:"memoryLimit"`
|
||||
MemoryPercent float64 `json:"memoryPercent"`
|
||||
}
|
||||
|
||||
type ContainerStats struct {
|
||||
type ContainterStats struct {
|
||||
CPUPercent float64 `json:"cpuPercent"`
|
||||
Memory float64 `json:"memory"`
|
||||
Cache float64 `json:"cache"`
|
||||
@@ -102,6 +69,11 @@ type PortHelper struct {
|
||||
Protocol string `json:"protocol"`
|
||||
}
|
||||
|
||||
type ContainerLog struct {
|
||||
ContainerID string `json:"containerID" validate:"required"`
|
||||
Mode string `json:"mode" validate:"required"`
|
||||
}
|
||||
|
||||
type ContainerOperation struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Operation string `json:"operation" validate:"required,oneof=start stop restart kill pause unpause rename remove"`
|
||||
@@ -110,7 +82,7 @@ type ContainerOperation struct {
|
||||
|
||||
type ContainerPrune struct {
|
||||
PruneType string `json:"pruneType" validate:"required,oneof=container image volume network"`
|
||||
WithTagAll bool `json:"withTagAll"`
|
||||
WithTagAll bool `josn:"withTagAll"`
|
||||
}
|
||||
|
||||
type ContainerPruneReport struct {
|
||||
|
||||
@@ -13,8 +13,6 @@ type CronjobCreate struct {
|
||||
Second int `json:"second" validate:"number"`
|
||||
|
||||
Script string `json:"script"`
|
||||
ContainerName string `json:"containerName"`
|
||||
AppID string `json:"appID"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBName string `json:"dbName"`
|
||||
@@ -36,8 +34,6 @@ type CronjobUpdate struct {
|
||||
Second int `json:"second" validate:"number"`
|
||||
|
||||
Script string `json:"script"`
|
||||
ContainerName string `json:"containerName"`
|
||||
AppID string `json:"appID"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBName string `json:"dbName"`
|
||||
@@ -80,8 +76,6 @@ type CronjobInfo struct {
|
||||
Second int `json:"second"`
|
||||
|
||||
Script string `json:"script"`
|
||||
ContainerName string `json:"containerName"`
|
||||
AppID string `json:"appID"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBName string `json:"dbName"`
|
||||
|
||||
@@ -3,10 +3,10 @@ package dto
|
||||
import "time"
|
||||
|
||||
type DashboardBase struct {
|
||||
WebsiteNumber int `json:"websiteNumber"`
|
||||
DatabaseNumber int `json:"databaseNumber"`
|
||||
CronjobNumber int `json:"cronjobNumber"`
|
||||
AppInstalledNumber int `json:"appInstalledNumber"`
|
||||
WebsiteNumber int `json:"websiteNumber"`
|
||||
DatabaseNumber int `json:"databaseNumber"`
|
||||
CronjobNumber int `json:"cronjobNumber"`
|
||||
AppInstalldNumber int `json:"appInstalldNumber"`
|
||||
|
||||
Hostname string `json:"hostname"`
|
||||
OS string `json:"os"`
|
||||
|
||||
+29
-115
@@ -2,20 +2,10 @@ package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type MysqlDBSearch struct {
|
||||
PageInfo
|
||||
Info string `json:"info"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
OrderBy string `json:"orderBy"`
|
||||
Order string `json:"order"`
|
||||
}
|
||||
|
||||
type MysqlDBInfo struct {
|
||||
ID uint `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Name string `json:"name"`
|
||||
From string `json:"from"`
|
||||
MysqlName string `json:"mysqlName"`
|
||||
Format string `json:"format"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
@@ -24,18 +14,8 @@ type MysqlDBInfo struct {
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type MysqlOption struct {
|
||||
ID uint `json:"id"`
|
||||
From string `json:"from"`
|
||||
Type string `json:"type"`
|
||||
Database string `json:"database"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type MysqlDBCreate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
From string `json:"from" validate:"required,oneof=local remote"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
Format string `json:"format" validate:"required,oneof=utf8mb4 utf8 gbk big5"`
|
||||
Username string `json:"username" validate:"required"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
@@ -43,24 +23,10 @@ type MysqlDBCreate struct {
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type MysqlLoadDB struct {
|
||||
From string `json:"from" validate:"required,oneof=local remote"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
}
|
||||
|
||||
type MysqlDBDeleteCheck struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
}
|
||||
|
||||
type MysqlDBDelete struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
ForceDelete bool `json:"forceDelete"`
|
||||
DeleteBackup bool `json:"deleteBackup"`
|
||||
ID uint `json:"id" validate:"required"`
|
||||
ForceDelete bool `json:"forceDelete"`
|
||||
DeleteBackup bool `json:"deleteBackup"`
|
||||
}
|
||||
|
||||
type MysqlStatus struct {
|
||||
@@ -124,27 +90,17 @@ type MysqlVariables struct {
|
||||
}
|
||||
|
||||
type MysqlVariablesUpdate struct {
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
Variables []MysqlVariablesUpdateHelper `json:"variables"`
|
||||
}
|
||||
|
||||
type MysqlVariablesUpdateHelper struct {
|
||||
Param string `json:"param"`
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
type MysqlConfUpdateByFile struct {
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
File string `json:"file"`
|
||||
MysqlName string `json:"mysqlName" validate:"required"`
|
||||
File string `json:"file"`
|
||||
}
|
||||
|
||||
type ChangeDBInfo struct {
|
||||
ID uint `json:"id"`
|
||||
From string `json:"from" validate:"required,oneof=local remote"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
Value string `json:"value" validate:"required"`
|
||||
ID uint `json:"id"`
|
||||
Value string `json:"value" validate:"required"`
|
||||
}
|
||||
|
||||
type DBBaseInfo struct {
|
||||
@@ -153,11 +109,30 @@ type DBBaseInfo struct {
|
||||
Port int64 `json:"port"`
|
||||
}
|
||||
|
||||
// redis
|
||||
type ChangeRedisPass struct {
|
||||
Value string `json:"value" validate:"required"`
|
||||
type SearchDBWithPage struct {
|
||||
PageInfo
|
||||
MysqlName string `json:"mysqlName" validate:"required"`
|
||||
}
|
||||
|
||||
type BackupDB struct {
|
||||
MysqlName string `json:"mysqlName" validate:"required"`
|
||||
DBName string `json:"dbName" validate:"required"`
|
||||
}
|
||||
|
||||
type RecoverDB struct {
|
||||
MysqlName string `json:"mysqlName" validate:"required"`
|
||||
DBName string `json:"dbName" validate:"required"`
|
||||
BackupName string `json:"backupName" validate:"required"`
|
||||
}
|
||||
|
||||
type UploadRecover struct {
|
||||
MysqlName string `json:"mysqlName" validate:"required"`
|
||||
DBName string `json:"dbName" validate:"required"`
|
||||
FileName string `json:"fileName"`
|
||||
FileDir string `json:"fileDir"`
|
||||
}
|
||||
|
||||
// redis
|
||||
type RedisConfUpdate struct {
|
||||
Timeout string `json:"timeout"`
|
||||
Maxclients string `json:"maxclients"`
|
||||
@@ -216,64 +191,3 @@ type RedisBackupRecover struct {
|
||||
FileName string `json:"fileName"`
|
||||
FileDir string `json:"fileDir"`
|
||||
}
|
||||
|
||||
// database
|
||||
type DatabaseSearch struct {
|
||||
PageInfo
|
||||
Info string `json:"info"`
|
||||
Type string `json:"type"`
|
||||
OrderBy string `json:"orderBy"`
|
||||
Order string `json:"order"`
|
||||
}
|
||||
|
||||
type DatabaseInfo struct {
|
||||
ID uint `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Name string `json:"name" validate:"max=256"`
|
||||
From string `json:"from"`
|
||||
Type string `json:"type"`
|
||||
Version string `json:"version"`
|
||||
Address string `json:"address"`
|
||||
Port uint `json:"port"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type DatabaseOption struct {
|
||||
ID uint `json:"id"`
|
||||
Type string `json:"type"`
|
||||
From string `json:"from"`
|
||||
Database string `json:"database"`
|
||||
Version string `json:"version"`
|
||||
Address string `json:"address"`
|
||||
}
|
||||
|
||||
type DatabaseCreate struct {
|
||||
Name string `json:"name" validate:"required,max=256"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
From string `json:"from" validate:"required,oneof=local remote"`
|
||||
Version string `json:"version" validate:"required"`
|
||||
Address string `json:"address"`
|
||||
Port uint `json:"port"`
|
||||
Username string `json:"username" validate:"required"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type DatabaseUpdate struct {
|
||||
ID uint `json:"id"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
Version string `json:"version" validate:"required"`
|
||||
Address string `json:"address"`
|
||||
Port uint `json:"port"`
|
||||
Username string `json:"username" validate:"required"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type DatabaseDelete struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
ForceDelete bool `json:"forceDelete"`
|
||||
DeleteBackup bool `json:"deleteBackup"`
|
||||
}
|
||||
|
||||
@@ -9,10 +9,8 @@ type FirewallBaseInfo struct {
|
||||
|
||||
type RuleSearch struct {
|
||||
PageInfo
|
||||
Info string `json:"info"`
|
||||
Status string `json:"status"`
|
||||
Strategy string `json:"strategy"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
Info string `json:"info"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
}
|
||||
|
||||
type FirewallOperation struct {
|
||||
@@ -25,26 +23,12 @@ type PortRuleOperate struct {
|
||||
Port string `json:"port" validate:"required"`
|
||||
Protocol string `json:"protocol" validate:"required,oneof=tcp udp tcp/udp"`
|
||||
Strategy string `json:"strategy" validate:"required,oneof=accept drop"`
|
||||
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type UpdateFirewallDescription struct {
|
||||
Type string `json:"type"`
|
||||
Address string `json:"address"`
|
||||
Port string `json:"port"`
|
||||
Protocol string `json:"protocol"`
|
||||
Strategy string `json:"strategy" validate:"required,oneof=accept drop"`
|
||||
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type AddrRuleOperate struct {
|
||||
Operation string `json:"operation" validate:"required,oneof=add remove"`
|
||||
Address string `json:"address" validate:"required"`
|
||||
Strategy string `json:"strategy" validate:"required,oneof=accept drop"`
|
||||
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type PortRuleUpdate struct {
|
||||
|
||||
+10
-11
@@ -5,41 +5,40 @@ import "time"
|
||||
type ImageInfo struct {
|
||||
ID string `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
IsUsed bool `json:"isUsed"`
|
||||
Tags []string `json:"tags"`
|
||||
Size string `json:"size"`
|
||||
}
|
||||
|
||||
type ImageLoad struct {
|
||||
Path string `json:"path" validate:"required"`
|
||||
Path string `josn:"path" validate:"required"`
|
||||
}
|
||||
|
||||
type ImageBuild struct {
|
||||
From string `json:"from" validate:"required"`
|
||||
From string `josn:"from" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Dockerfile string `json:"dockerfile" validate:"required"`
|
||||
Tags []string `json:"tags"`
|
||||
Dockerfile string `josn:"dockerfile" validate:"required"`
|
||||
Tags []string `josn:"tags"`
|
||||
}
|
||||
|
||||
type ImagePull struct {
|
||||
RepoID uint `json:"repoID"`
|
||||
ImageName string `json:"imageName" validate:"required"`
|
||||
RepoID uint `josn:"repoID"`
|
||||
ImageName string `josn:"imageName" validate:"required"`
|
||||
}
|
||||
|
||||
type ImageTag struct {
|
||||
RepoID uint `json:"repoID"`
|
||||
RepoID uint `josn:"repoID"`
|
||||
SourceID string `json:"sourceID" validate:"required"`
|
||||
TargetName string `json:"targetName" validate:"required"`
|
||||
TargetName string `josn:"targetName" validate:"required"`
|
||||
}
|
||||
|
||||
type ImagePush struct {
|
||||
RepoID uint `json:"repoID" validate:"required"`
|
||||
RepoID uint `josn:"repoID" validate:"required"`
|
||||
TagName string `json:"tagName" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
}
|
||||
|
||||
type ImageSave struct {
|
||||
TagName string `json:"tagName" validate:"required"`
|
||||
Path string `json:"path" validate:"required"`
|
||||
Path string `josn:"path" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ type ImageRepoCreate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
DownloadUrl string `json:"downloadUrl"`
|
||||
Protocol string `json:"protocol"`
|
||||
Username string `json:"username" validate:"max=256"`
|
||||
Password string `json:"password" validate:"max=256"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Auth bool `json:"auth"`
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ type ImageRepoUpdate struct {
|
||||
ID uint `json:"id"`
|
||||
DownloadUrl string `json:"downloadUrl"`
|
||||
Protocol string `json:"protocol"`
|
||||
Username string `json:"username" validate:"max=256"`
|
||||
Password string `json:"password" validate:"max=256"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Auth bool `json:"auth"`
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ type AppSearch struct {
|
||||
Tags []string `json:"tags"`
|
||||
Type string `json:"type"`
|
||||
Recommend bool `json:"recommend"`
|
||||
Resource string `json:"resource"`
|
||||
}
|
||||
|
||||
type AppInstallCreate struct {
|
||||
@@ -42,11 +41,6 @@ type AppInstalledSearch struct {
|
||||
Unused bool `json:"unused"`
|
||||
}
|
||||
|
||||
type AppInstalledInfo struct {
|
||||
Key string `json:"key" validate:"required"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type AppBackupSearch struct {
|
||||
dto.PageInfo
|
||||
AppInstallID uint `json:"appInstallID"`
|
||||
@@ -64,7 +58,6 @@ type AppInstalledOperate struct {
|
||||
ForceDelete bool `json:"forceDelete"`
|
||||
DeleteBackup bool `json:"deleteBackup"`
|
||||
DeleteDB bool `json:"deleteDB"`
|
||||
Backup bool `json:"backup"`
|
||||
}
|
||||
|
||||
type AppInstalledUpdate struct {
|
||||
@@ -73,11 +66,6 @@ type AppInstalledUpdate struct {
|
||||
AppContainerConfig
|
||||
}
|
||||
|
||||
type AppInstalledIgnoreUpgrade struct {
|
||||
DetailID uint `json:"detailID" validate:"required"`
|
||||
Operate string `json:"operate" validate:"required,oneof=cancel ignore"`
|
||||
}
|
||||
|
||||
type PortUpdate struct {
|
||||
Key string `json:"key"`
|
||||
Name string `json:"name"`
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
package request
|
||||
|
||||
type HostToolReq struct {
|
||||
Type string `json:"type" validate:"required,oneof=supervisord"`
|
||||
Operate string `json:"operate" validate:"oneof=status restart start stop"`
|
||||
}
|
||||
|
||||
type HostToolCreate struct {
|
||||
Type string `json:"type" validate:"required"`
|
||||
SupervisorConfig
|
||||
}
|
||||
|
||||
type SupervisorConfig struct {
|
||||
ConfigPath string `json:"configPath"`
|
||||
ServiceName string `json:"serviceName"`
|
||||
}
|
||||
|
||||
type HostToolLogReq struct {
|
||||
Type string `json:"type" validate:"required,oneof=supervisord"`
|
||||
}
|
||||
|
||||
type HostToolConfig struct {
|
||||
Type string `json:"type" validate:"required,oneof=supervisord"`
|
||||
Operate string `json:"operate" validate:"oneof=get set"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type SupervisorProcessConfig struct {
|
||||
Name string `json:"name"`
|
||||
Operate string `json:"operate"`
|
||||
Command string `json:"command"`
|
||||
User string `json:"user"`
|
||||
Dir string `json:"dir"`
|
||||
Numprocs string `json:"numprocs"`
|
||||
}
|
||||
type SupervisorProcessFileReq struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Operate string `json:"operate" validate:"required,oneof=get clear update" `
|
||||
Content string `json:"content"`
|
||||
File string `json:"file" validate:"required,oneof=out.log err.log config"`
|
||||
}
|
||||
@@ -3,8 +3,9 @@ package request
|
||||
import "github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
|
||||
type NginxConfigFileUpdate struct {
|
||||
Content string `json:"content" validate:"required"`
|
||||
Backup bool `json:"backup" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
FilePath string `json:"filePath" validate:"required"`
|
||||
Backup bool `json:"backup" validate:"required"`
|
||||
}
|
||||
|
||||
type NginxScopeReq struct {
|
||||
@@ -65,23 +66,3 @@ type NginxAntiLeechUpdate struct {
|
||||
LogEnable bool `json:"logEnable"`
|
||||
Blocked bool `json:"blocked"`
|
||||
}
|
||||
|
||||
type NginxRedirectReq struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
Domains []string `json:"domains"`
|
||||
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"`
|
||||
Target string `json:"target" validate:"required"`
|
||||
Operate string `json:"operate" validate:"required"`
|
||||
RedirectRoot bool `json:"redirectRoot"`
|
||||
}
|
||||
|
||||
type NginxRedirectUpdate struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
package request
|
||||
|
||||
type ProcessReq struct {
|
||||
PID int32 `json:"PID" validate:"required"`
|
||||
}
|
||||
@@ -17,20 +17,10 @@ type RuntimeCreate struct {
|
||||
Image string `json:"image"`
|
||||
Type string `json:"type"`
|
||||
Version string `json:"version"`
|
||||
Source string `json:"source"`
|
||||
CodeDir string `json:"codeDir"`
|
||||
NodeConfig
|
||||
}
|
||||
|
||||
type NodeConfig struct {
|
||||
Install bool `json:"install"`
|
||||
Clean bool `json:"clean"`
|
||||
Port int `json:"port"`
|
||||
}
|
||||
|
||||
type RuntimeDelete struct {
|
||||
ID uint `json:"id"`
|
||||
ForceDelete bool `json:"forceDelete"`
|
||||
ID uint `json:"id"`
|
||||
}
|
||||
|
||||
type RuntimeUpdate struct {
|
||||
@@ -39,28 +29,4 @@ type RuntimeUpdate struct {
|
||||
Params map[string]interface{} `json:"params"`
|
||||
Image string `json:"image"`
|
||||
Version string `json:"version"`
|
||||
Rebuild bool `json:"rebuild"`
|
||||
Source string `json:"source"`
|
||||
CodeDir string `json:"codeDir"`
|
||||
NodeConfig
|
||||
}
|
||||
|
||||
type NodePackageReq struct {
|
||||
CodeDir string `json:"codeDir"`
|
||||
}
|
||||
|
||||
type RuntimeOperate struct {
|
||||
Operate string `json:"operate"`
|
||||
ID uint `json:"ID"`
|
||||
}
|
||||
|
||||
type NodeModuleOperateReq struct {
|
||||
Operate string `json:"operate" validate:"oneof=install uninstall update"`
|
||||
ID uint `json:"ID" validate:"required"`
|
||||
Module string `json:"module"`
|
||||
PkgManager string `json:"pkgManager" validate:"oneof=npm yarn"`
|
||||
}
|
||||
|
||||
type NodeModuleReq struct {
|
||||
ID uint `json:"ID" validate:"required"`
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@ import (
|
||||
type WebsiteSearch struct {
|
||||
dto.PageInfo
|
||||
Name string `json:"name"`
|
||||
OrderBy string `json:"orderBy"`
|
||||
Order string `json:"order"`
|
||||
WebsiteGroupID uint `json:"websiteGroupId"`
|
||||
}
|
||||
|
||||
@@ -75,12 +73,6 @@ type WebsiteWafReq struct {
|
||||
Rule string `json:"rule" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsiteRedirectUpdate struct {
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
Key string `json:"key" validate:"required"`
|
||||
Enable bool `json:"enable" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsiteWafUpdate struct {
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
Key string `json:"key" validate:"required"`
|
||||
@@ -121,18 +113,15 @@ type WebsiteDomainDelete struct {
|
||||
}
|
||||
|
||||
type WebsiteHTTPSOp struct {
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
Enable bool `json:"enable" validate:"required"`
|
||||
WebsiteSSLID uint `json:"websiteSSLId"`
|
||||
Type string `json:"type" validate:"oneof=existed auto manual"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
Certificate string `json:"certificate"`
|
||||
PrivateKeyPath string `json:"privateKeyPath"`
|
||||
CertificatePath string `json:"certificatePath"`
|
||||
ImportType string `json:"importType"`
|
||||
HttpConfig string `json:"httpConfig" validate:"oneof=HTTPSOnly HTTPAlso HTTPToHTTPS"`
|
||||
SSLProtocol []string `json:"SSLProtocol"`
|
||||
Algorithm string `json:"algorithm"`
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
Enable bool `json:"enable" validate:"required"`
|
||||
WebsiteSSLID uint `json:"websiteSSLId"`
|
||||
Type string `json:"type" validate:"oneof=existed auto manual"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
Certificate string `json:"certificate"`
|
||||
HttpConfig string `json:"HttpConfig" validate:"oneof=HTTPSOnly HTTPAlso HTTPToHTTPS"`
|
||||
SSLProtocol []string `json:"SSLProtocol"`
|
||||
Algorithm string `json:"algorithm"`
|
||||
}
|
||||
|
||||
type WebsiteNginxUpdate struct {
|
||||
@@ -141,11 +130,9 @@ type WebsiteNginxUpdate struct {
|
||||
}
|
||||
|
||||
type WebsiteLogReq struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Operate string `json:"operate" validate:"required"`
|
||||
LogType string `json:"logType" validate:"required"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Operate string `json:"operate" validate:"required"`
|
||||
LogType string `json:"logType" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsiteDefaultUpdate struct {
|
||||
@@ -166,12 +153,6 @@ type WebsitePHPFileUpdate struct {
|
||||
Content string `json:"content" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsitePHPVersionReq struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
RuntimeID uint `json:"runtimeID" validate:"required"`
|
||||
RetainConfig bool `json:"retainConfig" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsiteUpdateDir struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
SiteDir string `json:"siteDir" validate:"required"`
|
||||
@@ -203,17 +184,3 @@ type WebsiteProxyConfig struct {
|
||||
type WebsiteProxyReq struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsiteRedirectReq struct {
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsiteWafFileUpdate struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
Type string `json:"type" validate:"required,oneof=cc ip_white ip_block url_white url_block cookie_block args_check post_check ua_check file_ext_block"`
|
||||
}
|
||||
|
||||
type WebsiteCommonReq struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import "github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
|
||||
type WebsiteSSLSearch struct {
|
||||
dto.PageInfo
|
||||
AcmeAccountID string `json:"acmeAccountID"`
|
||||
}
|
||||
|
||||
type WebsiteSSLCreate struct {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||
"time"
|
||||
|
||||
@@ -14,9 +13,8 @@ type AppRes struct {
|
||||
}
|
||||
|
||||
type AppUpdateRes struct {
|
||||
CanUpdate bool `json:"canUpdate"`
|
||||
AppStoreLastModified int `json:"appStoreLastModified"`
|
||||
AppList *dto.AppList `json:"appList"`
|
||||
CanUpdate bool `json:"canUpdate"`
|
||||
AppStoreLastModified int `json:"appStoreLastModified"`
|
||||
}
|
||||
|
||||
type AppDTO struct {
|
||||
@@ -41,8 +39,6 @@ type AppInstalledCheck struct {
|
||||
AppInstallID uint `json:"appInstallId"`
|
||||
ContainerName string `json:"containerName"`
|
||||
InstallPath string `json:"installPath"`
|
||||
HttpPort int `json:"httpPort"`
|
||||
HttpsPort int `json:"httpsPort"`
|
||||
}
|
||||
|
||||
type AppDetailDTO struct {
|
||||
@@ -52,13 +48,6 @@ type AppDetailDTO struct {
|
||||
Image string `json:"image"`
|
||||
}
|
||||
|
||||
type IgnoredApp struct {
|
||||
Icon string `json:"icon"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
DetailID uint `json:"detailID"`
|
||||
}
|
||||
|
||||
type AppInstalledDTO struct {
|
||||
model.AppInstall
|
||||
Total int `json:"total"`
|
||||
@@ -79,7 +68,6 @@ type AppService struct {
|
||||
Label string `json:"label"`
|
||||
Value string `json:"value"`
|
||||
Config interface{} `json:"config"`
|
||||
From string `json:"from"`
|
||||
}
|
||||
|
||||
type AppParam struct {
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
package response
|
||||
|
||||
type HostToolRes struct {
|
||||
Type string `json:"type"`
|
||||
Config interface{} `json:"config"`
|
||||
}
|
||||
|
||||
type Supervisor struct {
|
||||
ConfigPath string `json:"configPath"`
|
||||
IncludeDir string `json:"includeDir"`
|
||||
LogPath string `json:"logPath"`
|
||||
IsExist bool `json:"isExist"`
|
||||
Init bool `json:"init"`
|
||||
Msg string `json:"msg"`
|
||||
Version string `json:"version"`
|
||||
Status string `json:"status"`
|
||||
CtlExist bool `json:"ctlExist"`
|
||||
ServiceName string `json:"serviceName"`
|
||||
}
|
||||
|
||||
type HostToolConfig struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type SupervisorProcessConfig struct {
|
||||
Name string `json:"name"`
|
||||
Command string `json:"command"`
|
||||
User string `json:"user"`
|
||||
Dir string `json:"dir"`
|
||||
Numprocs string `json:"numprocs"`
|
||||
Msg string `json:"msg"`
|
||||
Status []ProcessStatus `json:"status"`
|
||||
}
|
||||
|
||||
type ProcessStatus struct {
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
PID string `json:"PID"`
|
||||
Uptime string `json:"uptime"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
@@ -34,22 +34,3 @@ type NginxAntiLeechRes struct {
|
||||
LogEnable bool `json:"logEnable"`
|
||||
Blocked bool `json:"blocked"`
|
||||
}
|
||||
|
||||
type NginxRedirectConfig struct {
|
||||
WebsiteID uint `json:"websiteID"`
|
||||
Name string `json:"name"`
|
||||
Domains []string `json:"domains"`
|
||||
KeepPath bool `json:"keepPath"`
|
||||
Enable bool `json:"enable"`
|
||||
Type string `json:"type"`
|
||||
Redirect string `json:"redirect"`
|
||||
Path string `json:"path"`
|
||||
Target string `json:"target"`
|
||||
FilePath string `json:"filePath"`
|
||||
Content string `json:"content"`
|
||||
RedirectRoot bool `json:"redirectRoot"`
|
||||
}
|
||||
|
||||
type NginxFile struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
@@ -1,56 +1,9 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"time"
|
||||
)
|
||||
import "github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
|
||||
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"`
|
||||
}
|
||||
|
||||
type PackageScripts struct {
|
||||
Name string `json:"name"`
|
||||
Script string `json:"script"`
|
||||
}
|
||||
|
||||
func NewRuntimeDTO(runtime model.Runtime) RuntimeDTO {
|
||||
return RuntimeDTO{
|
||||
ID: runtime.ID,
|
||||
Name: runtime.Name,
|
||||
Resource: runtime.Resource,
|
||||
AppDetailID: runtime.AppDetailID,
|
||||
Status: runtime.Status,
|
||||
Type: runtime.Type,
|
||||
Image: runtime.Image,
|
||||
Message: runtime.Message,
|
||||
CreatedAt: runtime.CreatedAt,
|
||||
CodeDir: runtime.CodeDir,
|
||||
Version: runtime.Version,
|
||||
Port: runtime.Port,
|
||||
Path: runtime.GetPath(),
|
||||
}
|
||||
}
|
||||
|
||||
type NodeModule struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
License string `json:"license"`
|
||||
Description string `json:"description"`
|
||||
type RuntimeRes struct {
|
||||
model.Runtime
|
||||
AppParams []AppParam `json:"appParams"`
|
||||
AppID uint `json:"appId"`
|
||||
}
|
||||
|
||||
@@ -26,8 +26,9 @@ type WebsiteNginxConfig struct {
|
||||
}
|
||||
|
||||
type WebsiteWafConfig struct {
|
||||
Enable bool `json:"enable"`
|
||||
Content string `json:"content"`
|
||||
Enable bool `json:"enable"`
|
||||
FilePath string `json:"filePath"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type WebsiteHTTPS struct {
|
||||
@@ -41,8 +42,6 @@ type WebsiteHTTPS struct {
|
||||
type WebsiteLog struct {
|
||||
Enable bool `json:"enable"`
|
||||
Content string `json:"content"`
|
||||
End bool `json:"end"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
type PHPConfig struct {
|
||||
@@ -54,10 +53,3 @@ type PHPConfig struct {
|
||||
type NginxRewriteRes struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type WebsiteDirConfig struct {
|
||||
Dirs []string `json:"dirs"`
|
||||
User string `json:"user"`
|
||||
UserGroup string `json:"userGroup"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import "time"
|
||||
type SettingInfo struct {
|
||||
UserName string `json:"userName"`
|
||||
Email string `json:"email"`
|
||||
SystemIP string `json:"systemIP"`
|
||||
SystemVersion string `json:"systemVersion"`
|
||||
|
||||
SessionTimeout string `json:"sessionTimeout"`
|
||||
@@ -13,14 +12,10 @@ type SettingInfo struct {
|
||||
TimeZone string `json:"timeZone"`
|
||||
NtpSite string `json:"ntpSite"`
|
||||
|
||||
Port string `json:"port"`
|
||||
PanelName string `json:"panelName"`
|
||||
Theme string `json:"theme"`
|
||||
Language string `json:"language"`
|
||||
DefaultNetwork string `json:"defaultNetwork"`
|
||||
LastCleanTime string `json:"lastCleanTime"`
|
||||
LastCleanSize string `json:"lastCleanSize"`
|
||||
LastCleanData string `json:"lastCleanData"`
|
||||
Port string `json:"port"`
|
||||
PanelName string `json:"panelName"`
|
||||
Theme string `json:"theme"`
|
||||
Language string `json:"language"`
|
||||
|
||||
ServerPort string `json:"serverPort"`
|
||||
SSL string `json:"ssl"`
|
||||
@@ -33,7 +28,6 @@ type SettingInfo struct {
|
||||
ComplexityVerification string `json:"complexityVerification"`
|
||||
MFAStatus string `json:"mfaStatus"`
|
||||
MFASecret string `json:"mfaSecret"`
|
||||
MFAInterval string `json:"mfaInterval"`
|
||||
|
||||
MonitorStatus string `json:"monitorStatus"`
|
||||
MonitorInterval string `json:"monitorInterval"`
|
||||
@@ -79,22 +73,8 @@ type PortUpdate struct {
|
||||
ServerPort uint `json:"serverPort" validate:"required,number,max=65535,min=1"`
|
||||
}
|
||||
|
||||
type SnapshotStatus struct {
|
||||
Panel string `json:"panel"`
|
||||
PanelInfo string `json:"panelInfo"`
|
||||
DaemonJson string `json:"daemonJson"`
|
||||
AppData string `json:"appData"`
|
||||
PanelData string `json:"panelData"`
|
||||
BackupData string `json:"backupData"`
|
||||
|
||||
Compress string `json:"compress"`
|
||||
Size string `json:"size"`
|
||||
Upload string `json:"upload"`
|
||||
}
|
||||
|
||||
type SnapshotCreate struct {
|
||||
ID uint `json:"id"`
|
||||
From string `json:"from" validate:"required,oneof=OSS S3 SFTP MINIO COS KODO OneDrive"`
|
||||
From string `json:"from" validate:"required,oneof=OSS S3 SFTP MINIO COS KODO"`
|
||||
Description string `json:"description" validate:"max=256"`
|
||||
}
|
||||
type SnapshotRecover struct {
|
||||
@@ -139,29 +119,3 @@ type SyncTime struct {
|
||||
type Upgrade struct {
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
type CleanData struct {
|
||||
SystemClean []CleanTree `json:"systemClean"`
|
||||
UploadClean []CleanTree `json:"uploadClean"`
|
||||
DownloadClean []CleanTree `json:"downloadClean"`
|
||||
SystemLogClean []CleanTree `json:"systemLogClean"`
|
||||
}
|
||||
|
||||
type CleanTree struct {
|
||||
ID string `json:"id"`
|
||||
Label string `json:"label"`
|
||||
Children []CleanTree `json:"children"`
|
||||
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
|
||||
Size uint64 `json:"size"`
|
||||
IsCheck bool `json:"isCheck"`
|
||||
IsRecommend bool `json:"isRecommend"`
|
||||
}
|
||||
|
||||
type Clean struct {
|
||||
TreeType string `json:"treeType"`
|
||||
Name string `json:"name"`
|
||||
Size uint64 `json:"size"`
|
||||
}
|
||||
|
||||
@@ -36,27 +36,6 @@ type SSHLog struct {
|
||||
SuccessfulCount int `json:"successfulCount"`
|
||||
FailedCount int `json:"failedCount"`
|
||||
}
|
||||
|
||||
type SearchForAnalysis struct {
|
||||
PageInfo
|
||||
OrderBy string `json:"orderBy" validate:"required,oneof=Success Failed"`
|
||||
}
|
||||
|
||||
type AnalysisRes struct {
|
||||
Total int64 `json:"total"`
|
||||
Items []SSHLogAnalysis `json:"items"`
|
||||
SuccessfulCount int `json:"successfulCount"`
|
||||
FailedCount int `json:"failedCount"`
|
||||
}
|
||||
|
||||
type SSHLogAnalysis struct {
|
||||
Address string `json:"address"`
|
||||
Area string `json:"area"`
|
||||
SuccessfulCount int `json:"successfulCount"`
|
||||
FailedCount int `json:"failedCount"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type SSHHistory struct {
|
||||
Date time.Time `json:"date"`
|
||||
DateStr string `json:"dateStr"`
|
||||
|
||||
@@ -12,5 +12,4 @@ type AppDetail struct {
|
||||
DownloadUrl string `json:"downloadUrl" gorm:"type:varchar;"`
|
||||
DownloadCallBackUrl string `json:"downloadCallBackUrl" gorm:"type:longtext;"`
|
||||
Update bool `json:"update"`
|
||||
IgnoreUpgrade bool `json:"ignoreUpgrade"`
|
||||
}
|
||||
|
||||
@@ -6,5 +6,4 @@ type AppInstallResource struct {
|
||||
LinkId uint `json:"linkId" gorm:"type:integer;not null;"`
|
||||
ResourceId uint `json:"resourceId" gorm:"type:integer;"`
|
||||
Key string `json:"key" gorm:"type:varchar(64);not null"`
|
||||
From string `json:"from" gorm:"type:varchar(64);not null;default:local"`
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ type BackupAccount struct {
|
||||
Bucket string `gorm:"type:varchar(256)" json:"bucket"`
|
||||
AccessKey string `gorm:"type:varchar(256)" json:"accessKey"`
|
||||
Credential string `gorm:"type:varchar(256)" json:"credential"`
|
||||
BackupPath string `gorm:"type:varchar(256)" json:"backupPath"`
|
||||
Vars string `gorm:"type:longText" json:"vars"`
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,8 @@ type Cronjob struct {
|
||||
Minute uint64 `gorm:"type:decimal" json:"minute"`
|
||||
Second uint64 `gorm:"type:decimal" json:"second"`
|
||||
|
||||
ContainerName string `gorm:"type:varchar(64)" json:"containerName"`
|
||||
Script string `gorm:"longtext" json:"script"`
|
||||
Website string `gorm:"type:varchar(64)" json:"website"`
|
||||
AppID string `gorm:"type:varchar(64)" json:"appID"`
|
||||
DBName string `gorm:"type:varchar(64)" json:"dbName"`
|
||||
URL string `gorm:"type:varchar(256)" json:"url"`
|
||||
SourceDir string `gorm:"type:varchar(256)" json:"sourceDir"`
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package model
|
||||
|
||||
type Database struct {
|
||||
BaseModel
|
||||
AppInstallID uint `json:"appInstallID" gorm:"type:decimal"`
|
||||
Name string `json:"name" gorm:"type:varchar(64);not null;unique"`
|
||||
Type string `json:"type" gorm:"type:varchar(64);not null"`
|
||||
Version string `json:"version" gorm:"type:varchar(64);not null"`
|
||||
From string `json:"from" gorm:"type:varchar(64);not null"`
|
||||
Address string `json:"address" gorm:"type:varchar(64);not null"`
|
||||
Port uint `json:"port" gorm:"type:decimal;not null"`
|
||||
Username string `json:"username" gorm:"type:varchar(64)"`
|
||||
Password string `json:"password" gorm:"type:varchar(64)"`
|
||||
Description string `json:"description" gorm:"type:varchar(256);"`
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package model
|
||||
type DatabaseMysql struct {
|
||||
BaseModel
|
||||
Name string `json:"name" gorm:"type:varchar(256);not null"`
|
||||
From string `json:"from" gorm:"type:varchar(256);not null;default:local"`
|
||||
MysqlName string `json:"mysqlName" gorm:"type:varchar(64);not null"`
|
||||
Format string `json:"format" gorm:"type:varchar(64);not null"`
|
||||
Username string `json:"username" gorm:"type:varchar(256);not null"`
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
package model
|
||||
|
||||
type Firewall struct {
|
||||
BaseModel
|
||||
|
||||
Type string `gorm:"type:varchar(64);not null" json:"type"`
|
||||
Port string `gorm:"type:varchar(64);not null" json:"port"`
|
||||
Protocol string `gorm:"type:varchar(64);not null" json:"protocol"`
|
||||
Address string `gorm:"type:varchar(64);not null" json:"address"`
|
||||
Strategy string `gorm:"type:varchar(64);not null" json:"strategy"`
|
||||
Description string `gorm:"type:varchar(64);not null" json:"description"`
|
||||
}
|
||||
@@ -1,10 +1,5 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"path"
|
||||
)
|
||||
|
||||
type Runtime struct {
|
||||
BaseModel
|
||||
Name string `gorm:"type:varchar;not null" json:"name"`
|
||||
@@ -18,23 +13,5 @@ type Runtime struct {
|
||||
Type string `gorm:"type:varchar;not null" json:"type"`
|
||||
Status string `gorm:"type:varchar;not null" json:"status"`
|
||||
Resource string `gorm:"type:varchar;not null" json:"resource"`
|
||||
Port int `gorm:"type:integer;" json:"port"`
|
||||
Message string `gorm:"type:longtext;" json:"message"`
|
||||
CodeDir string `gorm:"type:varchar;" json:"codeDir"`
|
||||
}
|
||||
|
||||
func (r *Runtime) GetComposePath() string {
|
||||
return path.Join(r.GetPath(), "docker-compose.yml")
|
||||
}
|
||||
|
||||
func (r *Runtime) GetEnvPath() string {
|
||||
return path.Join(r.GetPath(), ".env")
|
||||
}
|
||||
|
||||
func (r *Runtime) GetPath() string {
|
||||
return path.Join(constant.RuntimeDir, r.Type, r.Name)
|
||||
}
|
||||
|
||||
func (r *Runtime) GetLogPath() string {
|
||||
return path.Join(r.GetPath(), "build.log")
|
||||
}
|
||||
|
||||
@@ -17,18 +17,3 @@ type Snapshot struct {
|
||||
RollbackMessage string `json:"rollbackMessage" gorm:"type:varchar(256)"`
|
||||
LastRollbackedAt string `json:"lastRollbackedAt" gorm:"type:varchar(64)"`
|
||||
}
|
||||
|
||||
type SnapshotStatus struct {
|
||||
BaseModel
|
||||
SnapID uint `gorm:"type:decimal" json:"snapID"`
|
||||
Panel string `json:"panel" gorm:"type:varchar(64);default:Running"`
|
||||
PanelInfo string `json:"panelInfo" gorm:"type:varchar(64);default:Running"`
|
||||
DaemonJson string `json:"daemonJson" gorm:"type:varchar(64);default:Running"`
|
||||
AppData string `json:"appData" gorm:"type:varchar(64);default:Running"`
|
||||
PanelData string `json:"panelData" gorm:"type:varchar(64);default:Running"`
|
||||
BackupData string `json:"backupData" gorm:"type:varchar(64);default:Running"`
|
||||
|
||||
Compress string `json:"compress" gorm:"type:varchar(64);default:Waiting"`
|
||||
Size string `json:"size" gorm:"type:varchar(64)"`
|
||||
Upload string `json:"upload" gorm:"type:varchar(64);default:Waiting"`
|
||||
}
|
||||
|
||||
@@ -4,5 +4,4 @@ type Tag struct {
|
||||
BaseModel
|
||||
Key string `json:"key" gorm:"type:varchar(64);not null"`
|
||||
Name string `json:"name" gorm:"type:varchar(64);not null"`
|
||||
Sort int `json:"sort" gorm:"type:int;not null;default:1"`
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ func (a AppRepo) Page(page, size int, opts ...DBOption) (int64, []model.App, err
|
||||
db := getDb(opts...).Model(&model.App{})
|
||||
count := int64(0)
|
||||
db = db.Count(&count)
|
||||
err := db.Limit(size).Offset(size * (page - 1)).Preload("AppTags").Find(&apps).Error
|
||||
err := db.Debug().Limit(size).Offset(size * (page - 1)).Preload("AppTags").Find(&apps).Error
|
||||
return count, apps, err
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ type AppDetailRepo struct {
|
||||
type IAppDetailRepo interface {
|
||||
WithVersion(version string) DBOption
|
||||
WithAppId(id uint) DBOption
|
||||
WithIgnored() DBOption
|
||||
GetFirst(opts ...DBOption) (model.AppDetail, error)
|
||||
Update(ctx context.Context, detail model.AppDetail) error
|
||||
BatchCreate(ctx context.Context, details []model.AppDetail) error
|
||||
@@ -32,19 +31,12 @@ func (a AppDetailRepo) WithVersion(version string) DBOption {
|
||||
return g.Where("version = ?", version)
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppDetailRepo) WithAppId(id uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("app_id = ?", id)
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppDetailRepo) WithIgnored() DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("ignore_upgrade = 1")
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppDetailRepo) GetFirst(opts ...DBOption) (model.AppDetail, error) {
|
||||
var detail model.AppDetail
|
||||
err := getDb(opts...).Model(&model.AppDetail{}).Find(&detail).Error
|
||||
|
||||
@@ -3,7 +3,6 @@ package repo
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"gorm.io/gorm/clause"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
@@ -127,7 +126,7 @@ func (a *AppInstallRepo) Create(ctx context.Context, install *model.AppInstall)
|
||||
}
|
||||
|
||||
func (a *AppInstallRepo) Save(ctx context.Context, install *model.AppInstall) error {
|
||||
return getTx(ctx).Save(&install).Error
|
||||
return getTx(ctx).Omit(clause.Associations).Save(&install).Error
|
||||
}
|
||||
|
||||
func (a *AppInstallRepo) DeleteBy(opts ...DBOption) error {
|
||||
@@ -161,7 +160,6 @@ type RootInfo struct {
|
||||
Name string `json:"name"`
|
||||
Port int64 `json:"port"`
|
||||
HttpsPort int64 `json:"httpsPort"`
|
||||
UserName string `json:"userName"`
|
||||
Password string `json:"password"`
|
||||
UserPassword string `json:"userPassword"`
|
||||
ContainerName string `json:"containerName"`
|
||||
@@ -194,28 +192,10 @@ func (a *AppInstallRepo) LoadBaseInfo(key string, name string) (*RootInfo, error
|
||||
if err := json.Unmarshal([]byte(appInstall.Env), &envMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch app.Key {
|
||||
case "mysql", "mariadb":
|
||||
password, ok := envMap["PANEL_DB_ROOT_PASSWORD"].(string)
|
||||
if ok {
|
||||
info.Password = password
|
||||
}
|
||||
case "redis":
|
||||
password, ok := envMap["PANEL_REDIS_ROOT_PASSWORD"].(string)
|
||||
if ok {
|
||||
info.Password = password
|
||||
}
|
||||
case "mongodb", "postgresql":
|
||||
user, ok := envMap["PANEL_DB_ROOT_USER"].(string)
|
||||
if ok {
|
||||
info.UserName = user
|
||||
}
|
||||
password, ok := envMap["PANEL_DB_ROOT_PASSWORD"].(string)
|
||||
if ok {
|
||||
info.Password = password
|
||||
}
|
||||
password, ok := envMap["PANEL_DB_ROOT_PASSWORD"].(string)
|
||||
if ok {
|
||||
info.Password = password
|
||||
}
|
||||
|
||||
userPassword, ok := envMap["PANEL_DB_USER_PASSWORD"].(string)
|
||||
if ok {
|
||||
info.UserPassword = userPassword
|
||||
@@ -229,6 +209,5 @@ func (a *AppInstallRepo) LoadBaseInfo(key string, name string) (*RootInfo, error
|
||||
info.Env = appInstall.Env
|
||||
info.Param = appInstall.Param
|
||||
info.Version = appInstall.Version
|
||||
info.Key = app.Key
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
@@ -17,14 +16,12 @@ type ICommonRepo interface {
|
||||
WithByName(name string) DBOption
|
||||
WithByType(tp string) DBOption
|
||||
WithOrderBy(orderStr string) DBOption
|
||||
WithOrderRuleBy(orderBy, order string) DBOption
|
||||
WithByGroupID(groupID uint) DBOption
|
||||
WithLikeName(name string) DBOption
|
||||
WithIdsIn(ids []uint) DBOption
|
||||
WithByDate(startTime, endTime time.Time) DBOption
|
||||
WithByStartDate(startTime time.Time) DBOption
|
||||
WithByStatus(status string) DBOption
|
||||
WithByFrom(from string) DBOption
|
||||
}
|
||||
|
||||
type CommonRepo struct{}
|
||||
@@ -81,12 +78,6 @@ func (c *CommonRepo) WithByStatus(status string) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CommonRepo) WithByFrom(from string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("`from` = ?", from)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CommonRepo) WithLikeName(name string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
if len(name) == 0 {
|
||||
@@ -102,21 +93,6 @@ func (c *CommonRepo) WithOrderBy(orderStr string) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CommonRepo) WithOrderRuleBy(orderBy, order string) DBOption {
|
||||
switch order {
|
||||
case constant.OrderDesc:
|
||||
order = "desc"
|
||||
case constant.OrderAsc:
|
||||
order = "asc"
|
||||
default:
|
||||
orderBy = "created_at"
|
||||
order = "desc"
|
||||
}
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Order(fmt.Sprintf("%s %s", orderBy, order))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CommonRepo) WithIdsIn(ids []uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("id in (?)", ids)
|
||||
|
||||
@@ -15,7 +15,6 @@ type IComposeTemplateRepo interface {
|
||||
Update(id uint, vars map[string]interface{}) error
|
||||
Delete(opts ...DBOption) error
|
||||
|
||||
GetRecord(opts ...DBOption) (model.Compose, error)
|
||||
CreateRecord(compose *model.Compose) error
|
||||
DeleteRecord(opts ...DBOption) error
|
||||
ListRecord() ([]model.Compose, error)
|
||||
@@ -73,16 +72,6 @@ func (u *ComposeTemplateRepo) Delete(opts ...DBOption) error {
|
||||
return db.Delete(&model.ComposeTemplate{}).Error
|
||||
}
|
||||
|
||||
func (u *ComposeTemplateRepo) GetRecord(opts ...DBOption) (model.Compose, error) {
|
||||
var compose model.Compose
|
||||
db := global.DB
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
err := db.First(&compose).Error
|
||||
return compose, err
|
||||
}
|
||||
|
||||
func (u *ComposeTemplateRepo) ListRecord() ([]model.Compose, error) {
|
||||
var composes []model.Compose
|
||||
if err := global.DB.Find(&composes).Error; err != nil {
|
||||
|
||||
@@ -22,7 +22,6 @@ type ICronjobRepo interface {
|
||||
WithByJobID(id int) DBOption
|
||||
WithByBackupID(id uint) DBOption
|
||||
WithByRecordDropID(id int) DBOption
|
||||
WithByRecordFile(file string) DBOption
|
||||
Save(id uint, cronjob model.Cronjob) error
|
||||
Update(id uint, vars map[string]interface{}) error
|
||||
Delete(opts ...DBOption) error
|
||||
@@ -84,7 +83,7 @@ func (u *CronjobRepo) Page(page, size int, opts ...DBOption) (int64, []model.Cro
|
||||
}
|
||||
count := int64(0)
|
||||
db = db.Count(&count)
|
||||
err := db.Limit(size).Offset(size * (page - 1)).Find(&cronjobs).Error
|
||||
err := db.Order("created_at desc").Limit(size).Offset(size * (page - 1)).Find(&cronjobs).Error
|
||||
return count, cronjobs, err
|
||||
}
|
||||
|
||||
@@ -122,12 +121,6 @@ func (c *CronjobRepo) WithByBackupID(id uint) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CronjobRepo) WithByRecordFile(file string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("records = ?", file)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CronjobRepo) WithByRecordDropID(id int) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("id < ?", id)
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type DatabaseRepo struct{}
|
||||
|
||||
type IDatabaseRepo interface {
|
||||
GetList(opts ...DBOption) ([]model.Database, error)
|
||||
Page(limit, offset int, opts ...DBOption) (int64, []model.Database, error)
|
||||
Create(ctx context.Context, database *model.Database) error
|
||||
Update(id uint, vars map[string]interface{}) error
|
||||
Delete(ctx context.Context, opts ...DBOption) error
|
||||
Get(opts ...DBOption) (model.Database, error)
|
||||
WithByFrom(from string) DBOption
|
||||
WithoutByFrom(from string) DBOption
|
||||
WithAppInstallID(appInstallID uint) DBOption
|
||||
WithTypeList(dbType string) DBOption
|
||||
}
|
||||
|
||||
func NewIDatabaseRepo() IDatabaseRepo {
|
||||
return &DatabaseRepo{}
|
||||
}
|
||||
|
||||
func (d *DatabaseRepo) Get(opts ...DBOption) (model.Database, error) {
|
||||
var database model.Database
|
||||
db := global.DB
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
if err := db.First(&database).Error; err != nil {
|
||||
return database, err
|
||||
}
|
||||
pass, err := encrypt.StringDecrypt(database.Password)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("decrypt database %s password failed, err: %v", database.Name, err)
|
||||
}
|
||||
database.Password = pass
|
||||
return database, nil
|
||||
}
|
||||
|
||||
func (d *DatabaseRepo) Page(page, size int, opts ...DBOption) (int64, []model.Database, error) {
|
||||
var databases []model.Database
|
||||
db := global.DB.Model(&model.Database{})
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
count := int64(0)
|
||||
db = db.Count(&count)
|
||||
if err := db.Limit(size).Offset(size * (page - 1)).Find(&databases).Error; err != nil {
|
||||
return count, databases, err
|
||||
}
|
||||
for i := 0; i < len(databases); i++ {
|
||||
pass, err := encrypt.StringDecrypt(databases[i].Password)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("decrypt database db %s password failed, err: %v", databases[i].Name, err)
|
||||
}
|
||||
databases[i].Password = pass
|
||||
}
|
||||
return count, databases, nil
|
||||
}
|
||||
|
||||
func (d *DatabaseRepo) GetList(opts ...DBOption) ([]model.Database, error) {
|
||||
var databases []model.Database
|
||||
db := global.DB.Model(&model.Database{})
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
if err := db.Find(&databases).Error; err != nil {
|
||||
return databases, err
|
||||
}
|
||||
for i := 0; i < len(databases); i++ {
|
||||
pass, err := encrypt.StringDecrypt(databases[i].Password)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("decrypt database db %s password failed, err: %v", databases[i].Name, err)
|
||||
}
|
||||
databases[i].Password = pass
|
||||
}
|
||||
return databases, nil
|
||||
}
|
||||
|
||||
func (d *DatabaseRepo) WithByFrom(from string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("`from` = ?", from)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DatabaseRepo) WithoutByFrom(from string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("`from` != ?", from)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DatabaseRepo) WithTypeList(dbType string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
if !strings.Contains(dbType, ",") {
|
||||
return g.Where("`type` = ?", dbType)
|
||||
}
|
||||
types := strings.Split(dbType, ",")
|
||||
var (
|
||||
rules []string
|
||||
values []interface{}
|
||||
)
|
||||
for _, ty := range types {
|
||||
if len(ty) != 0 {
|
||||
rules = append(rules, "`type` = ?")
|
||||
values = append(values, ty)
|
||||
}
|
||||
}
|
||||
return g.Where(strings.Join(rules, " OR "), values...)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DatabaseRepo) WithAppInstallID(appInstallID uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("app_install_id = ?", appInstallID)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DatabaseRepo) Create(ctx context.Context, database *model.Database) error {
|
||||
pass, err := encrypt.StringEncrypt(database.Password)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decrypt database db %s password failed, err: %v", database.Name, err)
|
||||
}
|
||||
database.Password = pass
|
||||
return getTx(ctx).Create(database).Error
|
||||
}
|
||||
|
||||
func (d *DatabaseRepo) Update(id uint, vars map[string]interface{}) error {
|
||||
return global.DB.Model(&model.Database{}).Where("id = ?", id).Updates(vars).Error
|
||||
}
|
||||
|
||||
func (d *DatabaseRepo) Delete(ctx context.Context, opts ...DBOption) error {
|
||||
return getTx(ctx, opts...).Delete(&model.Database{}).Error
|
||||
}
|
||||
@@ -2,11 +2,9 @@ package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -15,13 +13,13 @@ type MysqlRepo struct{}
|
||||
type IMysqlRepo interface {
|
||||
Get(opts ...DBOption) (model.DatabaseMysql, error)
|
||||
WithByMysqlName(mysqlName string) DBOption
|
||||
WithByFrom(from string) DBOption
|
||||
List(opts ...DBOption) ([]model.DatabaseMysql, error)
|
||||
Page(limit, offset int, opts ...DBOption) (int64, []model.DatabaseMysql, error)
|
||||
Create(ctx context.Context, mysql *model.DatabaseMysql) error
|
||||
Delete(ctx context.Context, opts ...DBOption) error
|
||||
Update(id uint, vars map[string]interface{}) error
|
||||
DeleteLocal(ctx context.Context) error
|
||||
UpdateDatabaseInfo(id uint, vars map[string]interface{}) error
|
||||
DeleteAll(ctx context.Context) error
|
||||
}
|
||||
|
||||
func NewIMysqlRepo() IMysqlRepo {
|
||||
@@ -34,64 +32,33 @@ func (u *MysqlRepo) Get(opts ...DBOption) (model.DatabaseMysql, error) {
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
if err := db.First(&mysql).Error; err != nil {
|
||||
return mysql, err
|
||||
}
|
||||
|
||||
pass, err := encrypt.StringDecrypt(mysql.Password)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("decrypt database db %s password failed, err: %v", mysql.Name, err)
|
||||
}
|
||||
mysql.Password = pass
|
||||
err := db.First(&mysql).Error
|
||||
return mysql, err
|
||||
}
|
||||
|
||||
func (u *MysqlRepo) List(opts ...DBOption) ([]model.DatabaseMysql, error) {
|
||||
var mysqls []model.DatabaseMysql
|
||||
var users []model.DatabaseMysql
|
||||
db := global.DB.Model(&model.DatabaseMysql{})
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
if err := db.Find(&mysqls).Error; err != nil {
|
||||
return mysqls, err
|
||||
}
|
||||
for i := 0; i < len(mysqls); i++ {
|
||||
pass, err := encrypt.StringDecrypt(mysqls[i].Password)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("decrypt database db %s password failed, err: %v", mysqls[i].Name, err)
|
||||
}
|
||||
mysqls[i].Password = pass
|
||||
}
|
||||
return mysqls, nil
|
||||
err := db.Find(&users).Error
|
||||
return users, err
|
||||
}
|
||||
|
||||
func (u *MysqlRepo) Page(page, size int, opts ...DBOption) (int64, []model.DatabaseMysql, error) {
|
||||
var mysqls []model.DatabaseMysql
|
||||
var users []model.DatabaseMysql
|
||||
db := global.DB.Model(&model.DatabaseMysql{})
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
count := int64(0)
|
||||
db = db.Count(&count)
|
||||
if err := db.Limit(size).Offset(size * (page - 1)).Find(&mysqls).Error; err != nil {
|
||||
return count, mysqls, err
|
||||
}
|
||||
for i := 0; i < len(mysqls); i++ {
|
||||
pass, err := encrypt.StringDecrypt(mysqls[i].Password)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("decrypt database db %s password failed, err: %v", mysqls[i].Name, err)
|
||||
}
|
||||
mysqls[i].Password = pass
|
||||
}
|
||||
return count, mysqls, nil
|
||||
err := db.Limit(size).Offset(size * (page - 1)).Find(&users).Error
|
||||
return count, users, err
|
||||
}
|
||||
|
||||
func (u *MysqlRepo) Create(ctx context.Context, mysql *model.DatabaseMysql) error {
|
||||
pass, err := encrypt.StringEncrypt(mysql.Password)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decrypt database db %s password failed, err: %v", mysql.Name, err)
|
||||
}
|
||||
mysql.Password = pass
|
||||
return getTx(ctx).Create(mysql).Error
|
||||
}
|
||||
|
||||
@@ -99,25 +66,23 @@ func (u *MysqlRepo) Delete(ctx context.Context, opts ...DBOption) error {
|
||||
return getTx(ctx, opts...).Delete(&model.DatabaseMysql{}).Error
|
||||
}
|
||||
|
||||
func (u *MysqlRepo) DeleteLocal(ctx context.Context) error {
|
||||
return getTx(ctx).Where("`from` = ?", "local").Delete(&model.DatabaseMysql{}).Error
|
||||
func (u *MysqlRepo) DeleteAll(ctx context.Context) error {
|
||||
return getTx(ctx).Where("1 = 1").Delete(&model.DatabaseMysql{}).Error
|
||||
}
|
||||
|
||||
func (u *MysqlRepo) Update(id uint, vars map[string]interface{}) error {
|
||||
return global.DB.Model(&model.DatabaseMysql{}).Where("id = ?", id).Updates(vars).Error
|
||||
}
|
||||
|
||||
func (u *MysqlRepo) UpdateDatabaseInfo(id uint, vars map[string]interface{}) error {
|
||||
if err := global.DB.Model(&model.AppInstall{}).Where("id = ?", id).Updates(vars).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *MysqlRepo) WithByMysqlName(mysqlName string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("mysql_name = ?", mysqlName)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *MysqlRepo) WithByFrom(from string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
if len(from) != 0 {
|
||||
return g.Where("`from` = ?", from)
|
||||
}
|
||||
return g
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,12 +19,6 @@ type IHostRepo interface {
|
||||
Create(host *model.Host) error
|
||||
Update(id uint, vars map[string]interface{}) error
|
||||
Delete(opts ...DBOption) error
|
||||
|
||||
GetFirewallRecord(opts ...DBOption) (model.Firewall, error)
|
||||
ListFirewallRecord() ([]model.Firewall, error)
|
||||
SaveFirewallRecord(firewall *model.Firewall) error
|
||||
DeleteFirewallRecordByID(id uint) error
|
||||
DeleteFirewallRecord(fType, port, protocol, address, strategy string) error
|
||||
}
|
||||
|
||||
func NewIHostRepo() IHostRepo {
|
||||
@@ -112,48 +106,3 @@ func (h *HostRepo) Delete(opts ...DBOption) error {
|
||||
}
|
||||
return db.Delete(&model.Host{}).Error
|
||||
}
|
||||
|
||||
func (h *HostRepo) GetFirewallRecord(opts ...DBOption) (model.Firewall, error) {
|
||||
var firewall model.Firewall
|
||||
db := global.DB
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
err := db.First(&firewall).Error
|
||||
return firewall, err
|
||||
}
|
||||
|
||||
func (h *HostRepo) ListFirewallRecord() ([]model.Firewall, error) {
|
||||
var datas []model.Firewall
|
||||
if err := global.DB.Find(&datas).Error; err != nil {
|
||||
return datas, nil
|
||||
}
|
||||
return datas, nil
|
||||
}
|
||||
|
||||
func (h *HostRepo) SaveFirewallRecord(firewall *model.Firewall) error {
|
||||
if firewall.ID != 0 {
|
||||
return global.DB.Save(firewall).Error
|
||||
}
|
||||
var data model.Firewall
|
||||
if firewall.Type == "port" {
|
||||
_ = global.DB.Where("type = ? AND port = ? AND protocol = ? AND address = ? AND strategy = ?", "port", firewall.Port, firewall.Protocol, firewall.Address, firewall.Strategy).First(&data)
|
||||
if data.ID != 0 {
|
||||
firewall.ID = data.ID
|
||||
}
|
||||
} else {
|
||||
_ = global.DB.Where("type = ? AND address = ? AND strategy = ?", "address", firewall.Address, firewall.Strategy).First(&data)
|
||||
if data.ID != 0 {
|
||||
firewall.ID = data.ID
|
||||
}
|
||||
}
|
||||
return global.DB.Save(firewall).Error
|
||||
}
|
||||
|
||||
func (h *HostRepo) DeleteFirewallRecordByID(id uint) error {
|
||||
return global.DB.Where("id = ?", id).Delete(&model.Firewall{}).Error
|
||||
}
|
||||
|
||||
func (h *HostRepo) DeleteFirewallRecord(fType, port, protocol, address, strategy string) error {
|
||||
return global.DB.Where("type = ? AND port = ? AND protocol = ? AND address = ? AND strategy = ?", fType, port, protocol, address, strategy).Delete(&model.Firewall{}).Error
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -17,13 +15,11 @@ type IRuntimeRepo interface {
|
||||
WithNotId(id uint) DBOption
|
||||
WithStatus(status string) DBOption
|
||||
WithDetailId(id uint) DBOption
|
||||
WithPort(port int) DBOption
|
||||
Page(page, size int, opts ...DBOption) (int64, []model.Runtime, error)
|
||||
Create(ctx context.Context, runtime *model.Runtime) error
|
||||
Save(runtime *model.Runtime) error
|
||||
DeleteBy(opts ...DBOption) error
|
||||
GetFirst(opts ...DBOption) (*model.Runtime, error)
|
||||
List(opts ...DBOption) ([]model.Runtime, error)
|
||||
}
|
||||
|
||||
func NewIRunTimeRepo() IRuntimeRepo {
|
||||
@@ -60,12 +56,6 @@ func (r *RuntimeRepo) WithNotId(id uint) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RuntimeRepo) WithPort(port int) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("port = ?", port)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RuntimeRepo) Page(page, size int, opts ...DBOption) (int64, []model.Runtime, error) {
|
||||
var runtimes []model.Runtime
|
||||
db := getDb(opts...).Model(&model.Runtime{})
|
||||
@@ -75,16 +65,6 @@ func (r *RuntimeRepo) Page(page, size int, opts ...DBOption) (int64, []model.Run
|
||||
return count, runtimes, err
|
||||
}
|
||||
|
||||
func (r *RuntimeRepo) List(opts ...DBOption) ([]model.Runtime, error) {
|
||||
var runtimes []model.Runtime
|
||||
db := global.DB.Model(&model.Runtime{})
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
err := db.Find(&runtimes).Error
|
||||
return runtimes, err
|
||||
}
|
||||
|
||||
func (r *RuntimeRepo) Create(ctx context.Context, runtime *model.Runtime) error {
|
||||
db := getTx(ctx).Model(&model.Runtime{})
|
||||
return db.Create(&runtime).Error
|
||||
|
||||
@@ -12,12 +12,6 @@ type ISnapshotRepo interface {
|
||||
Update(id uint, vars map[string]interface{}) error
|
||||
Page(limit, offset int, opts ...DBOption) (int64, []model.Snapshot, error)
|
||||
Delete(opts ...DBOption) error
|
||||
|
||||
GetStatus(snapID uint) (model.SnapshotStatus, error)
|
||||
GetStatusList(opts ...DBOption) ([]model.SnapshotStatus, error)
|
||||
CreateStatus(snap *model.SnapshotStatus) error
|
||||
DeleteStatus(snapID uint) error
|
||||
UpdateStatus(id uint, vars map[string]interface{}) error
|
||||
}
|
||||
|
||||
func NewISnapshotRepo() ISnapshotRepo {
|
||||
@@ -73,33 +67,3 @@ func (u *SnapshotRepo) Delete(opts ...DBOption) error {
|
||||
}
|
||||
return db.Delete(&model.Snapshot{}).Error
|
||||
}
|
||||
|
||||
func (u *SnapshotRepo) GetStatus(snapID uint) (model.SnapshotStatus, error) {
|
||||
var data model.SnapshotStatus
|
||||
if err := global.DB.Where("snap_id = ?", snapID).First(&data).Error; err != nil {
|
||||
return data, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (u *SnapshotRepo) GetStatusList(opts ...DBOption) ([]model.SnapshotStatus, error) {
|
||||
var status []model.SnapshotStatus
|
||||
db := global.DB.Model(&model.SnapshotStatus{})
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
err := db.Find(&status).Error
|
||||
return status, err
|
||||
}
|
||||
|
||||
func (u *SnapshotRepo) CreateStatus(snap *model.SnapshotStatus) error {
|
||||
return global.DB.Create(snap).Error
|
||||
}
|
||||
|
||||
func (u *SnapshotRepo) DeleteStatus(snapID uint) error {
|
||||
return global.DB.Where("snap_id = ?", snapID).Delete(&model.SnapshotStatus{}).Error
|
||||
}
|
||||
|
||||
func (u *SnapshotRepo) UpdateStatus(id uint, vars map[string]interface{}) error {
|
||||
return global.DB.Model(&model.SnapshotStatus{}).Where("id = ?", id).Updates(vars).Error
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ func (t TagRepo) DeleteAll(ctx context.Context) error {
|
||||
|
||||
func (t TagRepo) All() ([]model.Tag, error) {
|
||||
var tags []model.Tag
|
||||
if err := getDb().Where("1 = 1 ").Order("sort asc").Find(&tags).Error; err != nil {
|
||||
if err := getDb().Where("1 = 1 ").Find(&tags).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tags, nil
|
||||
|
||||
@@ -26,7 +26,6 @@ type IWebsiteRepo interface {
|
||||
SaveWithoutCtx(app *model.Website) error
|
||||
DeleteBy(ctx context.Context, opts ...DBOption) error
|
||||
Create(ctx context.Context, app *model.Website) error
|
||||
DeleteAll(ctx context.Context) error
|
||||
}
|
||||
|
||||
func NewIWebsiteRepo() IWebsiteRepo {
|
||||
@@ -132,7 +131,3 @@ func (w *WebsiteRepo) SaveWithoutCtx(website *model.Website) error {
|
||||
func (w *WebsiteRepo) DeleteBy(ctx context.Context, opts ...DBOption) error {
|
||||
return getTx(ctx, opts...).Delete(&model.Website{}).Error
|
||||
}
|
||||
|
||||
func (w *WebsiteRepo) DeleteAll(ctx context.Context) error {
|
||||
return getTx(ctx).Where("1 = 1 ").Delete(&model.Website{}).Error
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ type IWebsiteDomainRepo interface {
|
||||
Create(ctx context.Context, app *model.WebsiteDomain) error
|
||||
Save(ctx context.Context, app *model.WebsiteDomain) error
|
||||
DeleteBy(ctx context.Context, opts ...DBOption) error
|
||||
DeleteAll(ctx context.Context) error
|
||||
}
|
||||
|
||||
func NewIWebsiteDomainRepo() IWebsiteDomainRepo {
|
||||
@@ -86,7 +85,3 @@ func (w WebsiteDomainRepo) Save(ctx context.Context, app *model.WebsiteDomain) e
|
||||
func (w WebsiteDomainRepo) DeleteBy(ctx context.Context, opts ...DBOption) error {
|
||||
return getTx(ctx, opts...).Delete(&model.WebsiteDomain{}).Error
|
||||
}
|
||||
|
||||
func (w WebsiteDomainRepo) DeleteAll(ctx context.Context) error {
|
||||
return getTx(ctx).Where("1 = 1 ").Delete(&model.WebsiteDomain{}).Error
|
||||
}
|
||||
|
||||
+111
-214
@@ -5,14 +5,6 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"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"
|
||||
@@ -27,6 +19,11 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||
http2 "github.com/1Panel-dev/1Panel/backend/utils/http"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type AppService struct {
|
||||
@@ -42,7 +39,6 @@ type IAppService interface {
|
||||
GetAppUpdate() (*response.AppUpdateRes, error)
|
||||
GetAppDetailByID(id uint) (*response.AppDetailDTO, error)
|
||||
SyncAppListFromLocal()
|
||||
GetIgnoredApp() ([]response.IgnoredApp, error)
|
||||
}
|
||||
|
||||
func NewIAppService() IAppService {
|
||||
@@ -61,9 +57,6 @@ func (a AppService) PageApp(req request.AppSearch) (interface{}, error) {
|
||||
if req.Recommend {
|
||||
opts = append(opts, appRepo.GetRecommend())
|
||||
}
|
||||
if req.Resource != "" {
|
||||
opts = append(opts, appRepo.WithResource(req.Resource))
|
||||
}
|
||||
if len(req.Tags) != 0 {
|
||||
tags, err := tagRepo.GetByKeys(req.Tags)
|
||||
if err != nil {
|
||||
@@ -89,16 +82,12 @@ func (a AppService) PageApp(req request.AppSearch) (interface{}, error) {
|
||||
return nil, err
|
||||
}
|
||||
var appDTOs []*response.AppDTO
|
||||
for _, ap := range apps {
|
||||
ap.ReadMe = ""
|
||||
ap.Website = ""
|
||||
ap.Document = ""
|
||||
ap.Github = ""
|
||||
for _, a := range apps {
|
||||
appDTO := &response.AppDTO{
|
||||
App: ap,
|
||||
App: a,
|
||||
}
|
||||
appDTOs = append(appDTOs, appDTO)
|
||||
appTags, err := appTagRepo.GetByAppId(ap.ID)
|
||||
appTags, err := appTagRepo.GetByAppId(a.ID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
@@ -111,7 +100,7 @@ func (a AppService) PageApp(req request.AppSearch) (interface{}, error) {
|
||||
continue
|
||||
}
|
||||
appDTO.Tags = tags
|
||||
installs, _ := appInstallRepo.ListBy(appInstallRepo.WithAppId(ap.ID))
|
||||
installs, _ := appInstallRepo.ListBy(appInstallRepo.WithAppId(a.ID))
|
||||
appDTO.Installed = len(installs) > 0
|
||||
}
|
||||
res.Items = appDTOs
|
||||
@@ -154,12 +143,12 @@ func (a AppService) GetApp(key string) (*response.AppDTO, error) {
|
||||
return &appDTO, nil
|
||||
}
|
||||
|
||||
func (a AppService) GetAppDetail(appID uint, version, appType string) (response.AppDetailDTO, error) {
|
||||
func (a AppService) GetAppDetail(appId uint, version, appType string) (response.AppDetailDTO, error) {
|
||||
var (
|
||||
appDetailDTO response.AppDetailDTO
|
||||
opts []repo.DBOption
|
||||
)
|
||||
opts = append(opts, appDetailRepo.WithAppId(appID), appDetailRepo.WithVersion(version))
|
||||
opts = append(opts, appDetailRepo.WithAppId(appId), appDetailRepo.WithVersion(version))
|
||||
detail, err := appDetailRepo.GetFirst(opts...)
|
||||
if err != nil {
|
||||
return appDetailDTO, err
|
||||
@@ -168,50 +157,47 @@ func (a AppService) GetAppDetail(appID uint, version, appType string) (response.
|
||||
appDetailDTO.Enable = true
|
||||
|
||||
if appType == "runtime" {
|
||||
app, err := appRepo.GetFirst(commonRepo.WithByID(appID))
|
||||
app, err := appRepo.GetFirst(commonRepo.WithByID(appId))
|
||||
if err != nil {
|
||||
return appDetailDTO, err
|
||||
}
|
||||
fileOp := files.NewFileOp()
|
||||
versionPath := path.Join(constant.AppResourceDir, app.Resource, app.Key, detail.Version)
|
||||
if !fileOp.Stat(versionPath) || detail.Update {
|
||||
if !fileOp.Stat(versionPath) {
|
||||
if err = downloadApp(app, detail, nil); err != nil {
|
||||
return appDetailDTO, err
|
||||
}
|
||||
}
|
||||
switch app.Type {
|
||||
case constant.RuntimePHP:
|
||||
buildPath := path.Join(versionPath, "build")
|
||||
paramsPath := path.Join(buildPath, "config.json")
|
||||
if !fileOp.Stat(paramsPath) {
|
||||
return appDetailDTO, buserr.New(constant.ErrFileNotExist)
|
||||
}
|
||||
param, err := fileOp.GetContent(paramsPath)
|
||||
if err != nil {
|
||||
return appDetailDTO, err
|
||||
}
|
||||
paramMap := make(map[string]interface{})
|
||||
if err := json.Unmarshal(param, ¶mMap); err != nil {
|
||||
return appDetailDTO, err
|
||||
}
|
||||
appDetailDTO.Params = paramMap
|
||||
composePath := path.Join(buildPath, "docker-compose.yml")
|
||||
if !fileOp.Stat(composePath) {
|
||||
return appDetailDTO, buserr.New(constant.ErrFileNotExist)
|
||||
}
|
||||
compose, err := fileOp.GetContent(composePath)
|
||||
if err != nil {
|
||||
return appDetailDTO, err
|
||||
}
|
||||
composeMap := make(map[string]interface{})
|
||||
if err := yaml.Unmarshal(compose, &composeMap); err != nil {
|
||||
return appDetailDTO, err
|
||||
}
|
||||
if service, ok := composeMap["services"]; ok {
|
||||
servicesMap := service.(map[string]interface{})
|
||||
for k := range servicesMap {
|
||||
appDetailDTO.Image = k
|
||||
}
|
||||
buildPath := path.Join(versionPath, "build")
|
||||
paramsPath := path.Join(buildPath, "config.json")
|
||||
if !fileOp.Stat(paramsPath) {
|
||||
return appDetailDTO, buserr.New(constant.ErrFileNotExist)
|
||||
}
|
||||
param, err := fileOp.GetContent(paramsPath)
|
||||
if err != nil {
|
||||
return appDetailDTO, err
|
||||
}
|
||||
paramMap := make(map[string]interface{})
|
||||
if err := json.Unmarshal(param, ¶mMap); err != nil {
|
||||
return appDetailDTO, err
|
||||
}
|
||||
appDetailDTO.Params = paramMap
|
||||
composePath := path.Join(buildPath, "docker-compose.yml")
|
||||
if !fileOp.Stat(composePath) {
|
||||
return appDetailDTO, buserr.New(constant.ErrFileNotExist)
|
||||
}
|
||||
compose, err := fileOp.GetContent(composePath)
|
||||
if err != nil {
|
||||
return appDetailDTO, err
|
||||
}
|
||||
composeMap := make(map[string]interface{})
|
||||
if err := yaml.Unmarshal(compose, &composeMap); err != nil {
|
||||
return appDetailDTO, err
|
||||
}
|
||||
if service, ok := composeMap["services"]; ok {
|
||||
servicesMap := service.(map[string]interface{})
|
||||
for k := range servicesMap {
|
||||
appDetailDTO.Image = k
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -246,34 +232,13 @@ func (a AppService) GetAppDetailByID(id uint) (*response.AppDetailDTO, error) {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (a AppService) GetIgnoredApp() ([]response.IgnoredApp, error) {
|
||||
var res []response.IgnoredApp
|
||||
details, _ := appDetailRepo.GetBy(appDetailRepo.WithIgnored())
|
||||
if len(details) == 0 {
|
||||
return res, nil
|
||||
}
|
||||
for _, detail := range details {
|
||||
app, err := appRepo.GetFirst(commonRepo.WithByID(detail.AppId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = append(res, response.IgnoredApp{
|
||||
Name: app.Name,
|
||||
Version: detail.Version,
|
||||
DetailID: detail.ID,
|
||||
Icon: app.Icon,
|
||||
})
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (appInstall *model.AppInstall, err error) {
|
||||
if err = docker.CreateDefaultDockerNetwork(); err != nil {
|
||||
err = buserr.WithDetail(constant.Err1PanelNetworkFailed, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
if list, _ := appInstallRepo.ListBy(commonRepo.WithByName(req.Name)); len(list) > 0 {
|
||||
err = buserr.New(constant.ErrAppNameExist)
|
||||
err = buserr.New(constant.ErrNameIsExist)
|
||||
return
|
||||
}
|
||||
var (
|
||||
@@ -282,6 +247,14 @@ func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (
|
||||
appDetail model.AppDetail
|
||||
app model.App
|
||||
)
|
||||
httpPort, err = checkPort("PANEL_APP_PORT_HTTP", req.Params)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
httpsPort, err = checkPort("PANEL_APP_PORT_HTTPS", req.Params)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
appDetail, err = appDetailRepo.GetFirst(commonRepo.WithByID(req.AppDetailId))
|
||||
if err != nil {
|
||||
return
|
||||
@@ -290,29 +263,6 @@ func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if DatabaseKeys[app.Key] > 0 {
|
||||
if existDatabases, _ := databaseRepo.GetList(commonRepo.WithByName(req.Name)); len(existDatabases) > 0 {
|
||||
err = buserr.New(constant.ErrRemoteExist)
|
||||
return
|
||||
}
|
||||
}
|
||||
for key := range req.Params {
|
||||
if !strings.Contains(key, "PANEL_APP_PORT") {
|
||||
continue
|
||||
}
|
||||
var port int
|
||||
if port, err = checkPort(key, req.Params); err == nil {
|
||||
if key == "PANEL_APP_PORT_HTTP" {
|
||||
httpPort = port
|
||||
}
|
||||
if key == "PANEL_APP_PORT_HTTPS" {
|
||||
httpsPort = port
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err = checkRequiredAndLimit(app); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -366,20 +316,13 @@ func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (
|
||||
appInstall.ContainerName = containerName
|
||||
|
||||
index := 0
|
||||
serviceName := ""
|
||||
for k := range servicesMap {
|
||||
serviceName = k
|
||||
appInstall.ServiceName = k
|
||||
if index > 0 {
|
||||
continue
|
||||
}
|
||||
index++
|
||||
}
|
||||
if app.Limit == 0 && appInstall.Name != serviceName {
|
||||
servicesMap[appInstall.Name] = servicesMap[serviceName]
|
||||
delete(servicesMap, serviceName)
|
||||
serviceName = appInstall.Name
|
||||
}
|
||||
appInstall.ServiceName = serviceName
|
||||
|
||||
if err = addDockerComposeCommonParam(composeMap, appInstall.ServiceName, req.AppContainerConfig, req.Params); err != nil {
|
||||
return
|
||||
@@ -403,14 +346,6 @@ func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (
|
||||
}
|
||||
}
|
||||
}()
|
||||
if hostName, ok := req.Params["PANEL_DB_HOST"]; ok {
|
||||
database, _ := databaseRepo.Get(commonRepo.WithByName(hostName.(string)))
|
||||
if !reflect.DeepEqual(database, model.Database{}) {
|
||||
req.Params["PANEL_DB_HOST"] = database.Address
|
||||
req.Params["PANEL_DB_PORT"] = database.Port
|
||||
req.Params["PANEL_DB_HOST_NAME"] = hostName
|
||||
}
|
||||
}
|
||||
paramByte, err = json.Marshal(req.Params)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -423,17 +358,15 @@ func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if err = copyData(app, appDetail, appInstall, req); err != nil {
|
||||
if appInstall.Status == constant.Installing {
|
||||
appInstall.Status = constant.Error
|
||||
appInstall.Message = err.Error()
|
||||
_ = appInstallRepo.Save(context.Background(), appInstall)
|
||||
}
|
||||
}()
|
||||
if err = copyData(app, appDetail, appInstall, req); err != nil {
|
||||
_ = appInstallRepo.Save(context.Background(), appInstall)
|
||||
return
|
||||
}
|
||||
if err = runScript(appInstall, "init"); err != nil {
|
||||
if err = upAppPre(app, appInstall); err != nil {
|
||||
return
|
||||
}
|
||||
upApp(appInstall)
|
||||
@@ -456,11 +389,11 @@ func (a AppService) SyncAppListFromLocal() {
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
global.LOG.Errorf("Sync local app failed %v", err)
|
||||
global.LOG.Errorf("sync app failed %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
global.LOG.Infof("Starting local application synchronization ...")
|
||||
global.LOG.Infof("start sync local apps...")
|
||||
dirEntries, err = os.ReadDir(localAppDir)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -537,13 +470,9 @@ func (a AppService) SyncAppListFromLocal() {
|
||||
oldDetail, exist := appDetails[version]
|
||||
if exist {
|
||||
newDetail.ID = oldDetail.ID
|
||||
delete(appDetails, version)
|
||||
}
|
||||
app.Details[i] = newDetail
|
||||
}
|
||||
for _, v := range appDetails {
|
||||
app.Details = append(app.Details, v)
|
||||
}
|
||||
}
|
||||
app.TagsKey = append(app.TagsKey, constant.AppResourceLocal)
|
||||
apps[app.Key] = app
|
||||
@@ -666,14 +595,17 @@ func (a AppService) SyncAppListFromLocal() {
|
||||
}
|
||||
}
|
||||
tx.Commit()
|
||||
global.LOG.Infof("Synchronization of local applications completed")
|
||||
global.LOG.Infof("sync local apps success")
|
||||
}
|
||||
|
||||
func (a AppService) GetAppUpdate() (*response.AppUpdateRes, error) {
|
||||
res := &response.AppUpdateRes{
|
||||
CanUpdate: false,
|
||||
}
|
||||
|
||||
setting, err := NewISettingService().GetSettingInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
versionUrl := fmt.Sprintf("%s/%s/1panel.json.version.txt", global.CONF.System.AppRepo, global.CONF.System.Mode)
|
||||
versionRes, err := http2.GetHttpRes(versionUrl)
|
||||
if err != nil {
|
||||
@@ -685,35 +617,22 @@ func (a AppService) GetAppUpdate() (*response.AppUpdateRes, error) {
|
||||
return nil, err
|
||||
}
|
||||
lastModifiedStr := string(body)
|
||||
|
||||
lastModified, err := strconv.Atoi(lastModifiedStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
setting, err := NewISettingService().GetSettingInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
appStoreLastModified, _ := strconv.Atoi(setting.AppStoreLastModified)
|
||||
res.AppStoreLastModified = appStoreLastModified
|
||||
if setting.AppStoreLastModified == "" || lastModified != appStoreLastModified {
|
||||
res.CanUpdate = true
|
||||
return res, err
|
||||
}
|
||||
list, err := getAppList()
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
if list.Extra.Version != "" && setting.SystemVersion != list.Extra.Version && !common.CompareVersion(setting.SystemVersion, list.Extra.Version) {
|
||||
global.LOG.Errorf("The current version is too low to synchronize with the App Store. The minimum required version is %s", list.Extra.Version)
|
||||
return nil, buserr.New("ErrVersionTooLow")
|
||||
}
|
||||
res.AppList = list
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func getAppFromRepo(downloadPath string) error {
|
||||
downloadUrl := downloadPath
|
||||
global.LOG.Infof("[AppStore] download file from %s", downloadUrl)
|
||||
global.LOG.Infof("download file from %s", downloadUrl)
|
||||
fileOp := files.NewFileOp()
|
||||
packagePath := path.Join(constant.ResourceDir, path.Base(downloadUrl))
|
||||
if err := fileOp.DownloadFile(downloadUrl, packagePath); err != nil {
|
||||
@@ -728,51 +647,26 @@ func getAppFromRepo(downloadPath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getAppList() (*dto.AppList, error) {
|
||||
list := &dto.AppList{}
|
||||
if err := getAppFromRepo(fmt.Sprintf("%s/%s/1panel.json.zip", global.CONF.System.AppRepo, global.CONF.System.Mode)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
listFile := path.Join(constant.ResourceDir, "1panel.json")
|
||||
content, err := os.ReadFile(listFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = json.Unmarshal(content, list); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func (a AppService) SyncAppListFromRemote() (err error) {
|
||||
global.LOG.Infof("Starting synchronization with App Store...")
|
||||
func (a AppService) SyncAppListFromRemote() error {
|
||||
updateRes, err := a.GetAppUpdate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !updateRes.CanUpdate {
|
||||
global.LOG.Infof("The App Store is at the latest version")
|
||||
return
|
||||
return nil
|
||||
}
|
||||
if err = getAppFromRepo(fmt.Sprintf("%s/%s/1panel.json.zip", global.CONF.System.AppRepo, global.CONF.System.Mode)); err != nil {
|
||||
return err
|
||||
}
|
||||
listFile := path.Join(constant.ResourceDir, "1panel.json")
|
||||
content, err := os.ReadFile(listFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
list := &dto.AppList{}
|
||||
if updateRes.AppList == nil {
|
||||
list, err = getAppList()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
list = updateRes.AppList
|
||||
}
|
||||
|
||||
if err = NewISettingService().Update("AppStoreLastModified", strconv.Itoa(list.LastModified)); err != nil {
|
||||
if err := json.Unmarshal(content, list); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = NewISettingService().Update("AppStoreLastModified", strconv.Itoa(updateRes.AppStoreLastModified))
|
||||
}
|
||||
}()
|
||||
|
||||
var (
|
||||
tags []*model.Tag
|
||||
@@ -783,12 +677,11 @@ func (a AppService) SyncAppListFromRemote() (err error) {
|
||||
tags = append(tags, &model.Tag{
|
||||
Key: t.Key,
|
||||
Name: t.Name,
|
||||
Sort: t.Sort,
|
||||
})
|
||||
}
|
||||
oldApps, err := appRepo.GetBy(appRepo.WithResource(constant.AppResourceRemote))
|
||||
if err != nil {
|
||||
return
|
||||
return err
|
||||
}
|
||||
for _, old := range oldApps {
|
||||
oldAppIds = append(oldAppIds, old.ID)
|
||||
@@ -821,8 +714,8 @@ func (a AppService) SyncAppListFromRemote() (err error) {
|
||||
for _, v := range versions {
|
||||
version := v.Name
|
||||
detail := detailsMap[version]
|
||||
versionUrl := fmt.Sprintf("%s/%s/%s", baseRemoteUrl, app.Key, version)
|
||||
dockerComposeUrl := fmt.Sprintf("%s/%s", versionUrl, "docker-compose.yml")
|
||||
|
||||
dockerComposeUrl := fmt.Sprintf("%s/%s/%s/%s", baseRemoteUrl, app.Key, version, "docker-compose.yml")
|
||||
composeRes, err := http.Get(dockerComposeUrl)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -835,10 +728,12 @@ func (a AppService) SyncAppListFromRemote() (err error) {
|
||||
|
||||
paramByte, _ := json.Marshal(v.AppForm)
|
||||
detail.Params = string(paramByte)
|
||||
detail.DownloadUrl = fmt.Sprintf("%s/%s", versionUrl, app.Key+"-"+version+".tar.gz")
|
||||
detail.DownloadUrl = v.DownloadUrl
|
||||
detail.DownloadCallBackUrl = v.DownloadCallBackUrl
|
||||
detail.Update = true
|
||||
detail.LastModified = v.LastModified
|
||||
if v.LastModified > detail.LastModified {
|
||||
detail.Update = true
|
||||
detail.LastModified = v.LastModified
|
||||
}
|
||||
detailsMap[version] = detail
|
||||
}
|
||||
var newDetails []model.AppDetail
|
||||
@@ -877,32 +772,32 @@ func (a AppService) SyncAppListFromRemote() (err error) {
|
||||
tx, ctx := getTxAndContext()
|
||||
defer tx.Rollback()
|
||||
if len(addAppArray) > 0 {
|
||||
if err = appRepo.BatchCreate(ctx, addAppArray); err != nil {
|
||||
return
|
||||
if err := appRepo.BatchCreate(ctx, addAppArray); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(deleteAppArray) > 0 {
|
||||
if err = appRepo.BatchDelete(ctx, deleteAppArray); err != nil {
|
||||
return
|
||||
if err := appRepo.BatchDelete(ctx, deleteAppArray); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = appDetailRepo.DeleteByAppIds(ctx, deleteIds); err != nil {
|
||||
return
|
||||
if err := appDetailRepo.DeleteByAppIds(ctx, deleteIds); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err = tagRepo.DeleteAll(ctx); err != nil {
|
||||
return
|
||||
if err := tagRepo.DeleteAll(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(tags) > 0 {
|
||||
if err = tagRepo.BatchCreate(ctx, tags); err != nil {
|
||||
return
|
||||
if err := tagRepo.BatchCreate(ctx, tags); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, t := range tags {
|
||||
tagMap[t.Key] = t.ID
|
||||
}
|
||||
}
|
||||
for _, update := range updateAppArray {
|
||||
if err = appRepo.Save(ctx, &update); err != nil {
|
||||
return
|
||||
if err := appRepo.Save(ctx, &update); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
apps := append(addAppArray, updateAppArray...)
|
||||
@@ -946,33 +841,35 @@ func (a AppService) SyncAppListFromRemote() (err error) {
|
||||
}
|
||||
}
|
||||
if len(addDetails) > 0 {
|
||||
if err = appDetailRepo.BatchCreate(ctx, addDetails); err != nil {
|
||||
return
|
||||
if err := appDetailRepo.BatchCreate(ctx, addDetails); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(deleteDetails) > 0 {
|
||||
if err = appDetailRepo.BatchDelete(ctx, deleteDetails); err != nil {
|
||||
return
|
||||
if err := appDetailRepo.BatchDelete(ctx, deleteDetails); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, u := range updateDetails {
|
||||
if err = appDetailRepo.Update(ctx, u); err != nil {
|
||||
return
|
||||
if err := appDetailRepo.Update(ctx, u); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(oldAppIds) > 0 {
|
||||
if err = appTagRepo.DeleteByAppIds(ctx, oldAppIds); err != nil {
|
||||
return
|
||||
if err := appTagRepo.DeleteByAppIds(ctx, oldAppIds); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(appTags) > 0 {
|
||||
if err = appTagRepo.BatchCreate(ctx, appTags); err != nil {
|
||||
return
|
||||
if err := appTagRepo.BatchCreate(ctx, appTags); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
tx.Commit()
|
||||
global.LOG.Infof("Synchronization with the App Store was successful!")
|
||||
return
|
||||
if err := NewISettingService().Update("AppStoreLastModified", strconv.Itoa(list.LastModified)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -11,8 +11,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/i18n"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
@@ -41,47 +39,27 @@ type AppInstallService struct {
|
||||
|
||||
type IAppInstallService interface {
|
||||
Page(req request.AppInstalledSearch) (int64, []response.AppInstalledDTO, error)
|
||||
CheckExist(req request.AppInstalledInfo) (*response.AppInstalledCheck, error)
|
||||
LoadPort(req dto.OperationWithNameAndType) (int64, error)
|
||||
LoadConnInfo(req dto.OperationWithNameAndType) (response.DatabaseConn, error)
|
||||
CheckExist(key string) (*response.AppInstalledCheck, error)
|
||||
LoadPort(key string) (int64, error)
|
||||
LoadConnInfo(key string) (response.DatabaseConn, error)
|
||||
SearchForWebsite(req request.AppInstalledSearch) ([]response.AppInstalledDTO, error)
|
||||
Operate(req request.AppInstalledOperate) error
|
||||
Update(req request.AppInstalledUpdate) error
|
||||
IgnoreUpgrade(req request.AppInstalledIgnoreUpgrade) error
|
||||
SyncAll(systemInit bool) error
|
||||
GetServices(key string) ([]response.AppService, error)
|
||||
GetUpdateVersions(installId uint) ([]dto.AppVersion, error)
|
||||
GetParams(id uint) (*response.AppConfig, error)
|
||||
ChangeAppPort(req request.PortUpdate) error
|
||||
GetDefaultConfigByKey(key, name string) (string, error)
|
||||
GetDefaultConfigByKey(key string) (string, error)
|
||||
DeleteCheck(installId uint) ([]dto.AppResource, error)
|
||||
|
||||
GetInstallList() ([]dto.AppInstallInfo, error)
|
||||
}
|
||||
|
||||
func NewIAppInstalledService() IAppInstallService {
|
||||
return &AppInstallService{}
|
||||
}
|
||||
|
||||
func (a *AppInstallService) GetInstallList() ([]dto.AppInstallInfo, error) {
|
||||
var datas []dto.AppInstallInfo
|
||||
appInstalls, err := appInstallRepo.ListBy()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, install := range appInstalls {
|
||||
datas = append(datas, dto.AppInstallInfo{ID: install.ID, Key: install.App.Key, Name: install.Name})
|
||||
}
|
||||
return datas, nil
|
||||
}
|
||||
|
||||
func (a *AppInstallService) Page(req request.AppInstalledSearch) (int64, []response.AppInstalledDTO, error) {
|
||||
var (
|
||||
opts []repo.DBOption
|
||||
total int64
|
||||
installs []model.AppInstall
|
||||
err error
|
||||
)
|
||||
var opts []repo.DBOption
|
||||
|
||||
if req.Name != "" {
|
||||
opts = append(opts, commonRepo.WithLikeName(req.Name))
|
||||
@@ -107,53 +85,36 @@ func (a *AppInstallService) Page(req request.AppInstalledSearch) (int64, []respo
|
||||
opts = append(opts, appInstallRepo.WithAppIdsIn(appIds))
|
||||
}
|
||||
|
||||
if req.Update {
|
||||
installs, err = appInstallRepo.ListBy(opts...)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
} else {
|
||||
total, installs, err = appInstallRepo.Page(req.Page, req.PageSize, opts...)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
total, installs, err := appInstallRepo.Page(req.Page, req.PageSize, opts...)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
installDTOs, err := handleInstalled(installs, req.Update)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
if req.Update {
|
||||
total = int64(len(installDTOs))
|
||||
}
|
||||
|
||||
return total, installDTOs, nil
|
||||
}
|
||||
|
||||
func (a *AppInstallService) CheckExist(req request.AppInstalledInfo) (*response.AppInstalledCheck, error) {
|
||||
func (a *AppInstallService) CheckExist(key string) (*response.AppInstalledCheck, error) {
|
||||
res := &response.AppInstalledCheck{
|
||||
IsExist: false,
|
||||
}
|
||||
|
||||
app, err := appRepo.GetFirst(appRepo.WithKey(req.Key))
|
||||
app, err := appRepo.GetFirst(appRepo.WithKey(key))
|
||||
if err != nil {
|
||||
return res, nil
|
||||
}
|
||||
res.App = app.Name
|
||||
|
||||
var appInstall model.AppInstall
|
||||
if len(req.Name) == 0 {
|
||||
appInstall, _ = appInstallRepo.GetFirst(appInstallRepo.WithAppId(app.ID))
|
||||
} else {
|
||||
appInstall, _ = appInstallRepo.GetFirst(appInstallRepo.WithAppId(app.ID), commonRepo.WithByName(req.Name))
|
||||
}
|
||||
|
||||
appInstall, _ := appInstallRepo.GetFirst(appInstallRepo.WithAppId(app.ID))
|
||||
if reflect.DeepEqual(appInstall, model.AppInstall{}) {
|
||||
return res, nil
|
||||
}
|
||||
if err = syncByID(appInstall.ID); err != nil {
|
||||
if err := syncById(appInstall.ID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
appInstall, _ = appInstallRepo.GetFirst(commonRepo.WithByID(appInstall.ID))
|
||||
|
||||
res.ContainerName = appInstall.ContainerName
|
||||
res.Name = appInstall.Name
|
||||
@@ -162,24 +123,22 @@ func (a *AppInstallService) CheckExist(req request.AppInstalledInfo) (*response.
|
||||
res.Status = appInstall.Status
|
||||
res.AppInstallID = appInstall.ID
|
||||
res.IsExist = true
|
||||
res.InstallPath = path.Join(constant.AppInstallDir, appInstall.App.Key, appInstall.Name)
|
||||
res.HttpPort = appInstall.HttpPort
|
||||
res.HttpsPort = appInstall.HttpsPort
|
||||
res.InstallPath = path.Join(constant.AppInstallDir, app.Key, appInstall.Name)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (a *AppInstallService) LoadPort(req dto.OperationWithNameAndType) (int64, error) {
|
||||
app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Name)
|
||||
func (a *AppInstallService) LoadPort(key string) (int64, error) {
|
||||
app, err := appInstallRepo.LoadBaseInfo(key, "")
|
||||
if err != nil {
|
||||
return int64(0), nil
|
||||
}
|
||||
return app.Port, nil
|
||||
}
|
||||
|
||||
func (a *AppInstallService) LoadConnInfo(req dto.OperationWithNameAndType) (response.DatabaseConn, error) {
|
||||
func (a *AppInstallService) LoadConnInfo(key string) (response.DatabaseConn, error) {
|
||||
var data response.DatabaseConn
|
||||
app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Name)
|
||||
app, err := appInstallRepo.LoadBaseInfo(key, "")
|
||||
if err != nil {
|
||||
return data, nil
|
||||
}
|
||||
@@ -239,28 +198,28 @@ func (a *AppInstallService) Operate(req request.AppInstalledOperate) error {
|
||||
if err != nil {
|
||||
return handleErr(install, err, out)
|
||||
}
|
||||
return syncByID(install.ID)
|
||||
return syncById(install.ID)
|
||||
case constant.Stop:
|
||||
out, err := compose.Stop(dockerComposePath)
|
||||
if err != nil {
|
||||
return handleErr(install, err, out)
|
||||
}
|
||||
return syncByID(install.ID)
|
||||
return syncById(install.ID)
|
||||
case constant.Restart:
|
||||
out, err := compose.Restart(dockerComposePath)
|
||||
if err != nil {
|
||||
return handleErr(install, err, out)
|
||||
}
|
||||
return syncByID(install.ID)
|
||||
return syncById(install.ID)
|
||||
case constant.Delete:
|
||||
if err := deleteAppInstall(install, req.DeleteBackup, req.ForceDelete, req.DeleteDB); err != nil && !req.ForceDelete {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case constant.Sync:
|
||||
return syncByID(install.ID)
|
||||
return syncById(install.ID)
|
||||
case constant.Upgrade:
|
||||
return upgradeInstall(install.ID, req.DetailId, req.Backup)
|
||||
return upgradeInstall(install.ID, req.DetailId)
|
||||
default:
|
||||
return errors.New("operate not support")
|
||||
}
|
||||
@@ -393,15 +352,6 @@ func (a *AppInstallService) Update(req request.AppInstalledUpdate) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *AppInstallService) IgnoreUpgrade(req request.AppInstalledIgnoreUpgrade) error {
|
||||
appDetail, err := appDetailRepo.GetFirst(commonRepo.WithByID(req.DetailID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
appDetail.IgnoreUpgrade = req.Operate == "ignore"
|
||||
return appDetailRepo.Update(context.Background(), appDetail)
|
||||
}
|
||||
|
||||
func (a *AppInstallService) SyncAll(systemInit bool) error {
|
||||
allList, err := appInstallRepo.ListBy()
|
||||
if err != nil {
|
||||
@@ -416,63 +366,33 @@ func (a *AppInstallService) SyncAll(systemInit bool) error {
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !systemInit {
|
||||
if err := syncByID(i.ID); err != nil {
|
||||
global.LOG.Errorf("sync install app[%s] error,mgs: %s", i.Name, err.Error())
|
||||
}
|
||||
if err := syncById(i.ID); err != nil {
|
||||
global.LOG.Errorf("sync install app[%s] error,mgs: %s", i.Name, err.Error())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *AppInstallService) GetServices(key string) ([]response.AppService, error) {
|
||||
app, err := appRepo.GetFirst(appRepo.WithKey(key))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
installs, err := appInstallRepo.ListBy(appInstallRepo.WithAppId(app.ID), appInstallRepo.WithStatus(constant.Running))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res []response.AppService
|
||||
if DatabaseKeys[key] > 0 {
|
||||
dbs, _ := databaseRepo.GetList(commonRepo.WithByType(key))
|
||||
if len(dbs) == 0 {
|
||||
return res, nil
|
||||
}
|
||||
for _, db := range dbs {
|
||||
service := response.AppService{
|
||||
Label: db.Name,
|
||||
Value: db.Name,
|
||||
}
|
||||
if db.AppInstallID > 0 {
|
||||
install, err := appInstallRepo.GetFirst(commonRepo.WithByID(db.AppInstallID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
paramMap := make(map[string]string)
|
||||
if install.Param != "" {
|
||||
_ = json.Unmarshal([]byte(install.Param), ¶mMap)
|
||||
}
|
||||
service.Config = paramMap
|
||||
service.From = constant.AppResourceLocal
|
||||
} else {
|
||||
service.From = constant.AppResourceRemote
|
||||
}
|
||||
res = append(res, service)
|
||||
}
|
||||
} else {
|
||||
app, err := appRepo.GetFirst(appRepo.WithKey(key))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
installs, err := appInstallRepo.ListBy(appInstallRepo.WithAppId(app.ID), appInstallRepo.WithStatus(constant.Running))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, install := range installs {
|
||||
paramMap := make(map[string]string)
|
||||
if install.Param != "" {
|
||||
_ = json.Unmarshal([]byte(install.Param), ¶mMap)
|
||||
}
|
||||
res = append(res, response.AppService{
|
||||
Label: install.Name,
|
||||
Value: install.ServiceName,
|
||||
Config: paramMap,
|
||||
})
|
||||
for _, install := range installs {
|
||||
paramMap := make(map[string]string)
|
||||
if install.Param != "" {
|
||||
_ = json.Unmarshal([]byte(install.Param), ¶mMap)
|
||||
}
|
||||
res = append(res, response.AppService{
|
||||
Label: install.Name,
|
||||
Value: install.ServiceName,
|
||||
Config: paramMap,
|
||||
})
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
@@ -492,9 +412,6 @@ func (a *AppInstallService) GetUpdateVersions(installId uint) ([]dto.AppVersion,
|
||||
return versions, err
|
||||
}
|
||||
for _, detail := range details {
|
||||
if detail.IgnoreUpgrade {
|
||||
continue
|
||||
}
|
||||
if common.IsCrossVersion(install.Version, detail.Version) && !app.CrossVersionUpdate {
|
||||
continue
|
||||
}
|
||||
@@ -518,7 +435,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
|
||||
}
|
||||
|
||||
@@ -536,9 +453,9 @@ func (a *AppInstallService) ChangeAppPort(req request.PortUpdate) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *AppInstallService) DeleteCheck(installID uint) ([]dto.AppResource, error) {
|
||||
func (a *AppInstallService) DeleteCheck(installId uint) ([]dto.AppResource, error) {
|
||||
var res []dto.AppResource
|
||||
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(installID))
|
||||
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -562,8 +479,8 @@ func (a *AppInstallService) DeleteCheck(installID uint) ([]dto.AppResource, erro
|
||||
})
|
||||
}
|
||||
}
|
||||
if app.Type == constant.Runtime {
|
||||
resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithLinkId(appInstall.ID), commonRepo.WithByFrom(constant.AppResourceLocal))
|
||||
if app.Type == "runtime" {
|
||||
resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithLinkId(appInstall.ID))
|
||||
for _, resource := range resources {
|
||||
linkInstall, _ := appInstallRepo.GetFirst(commonRepo.WithByID(resource.AppInstallId))
|
||||
res = append(res, dto.AppResource{
|
||||
@@ -575,22 +492,22 @@ func (a *AppInstallService) DeleteCheck(installID uint) ([]dto.AppResource, erro
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (a *AppInstallService) GetDefaultConfigByKey(key, name string) (string, error) {
|
||||
baseInfo, err := appInstallRepo.LoadBaseInfo(key, name)
|
||||
func (a *AppInstallService) GetDefaultConfigByKey(key string) (string, error) {
|
||||
appInstall, err := getAppInstallByKey(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
fileOp := files.NewFileOp()
|
||||
filePath := path.Join(constant.AppResourceDir, "remote", baseInfo.Key, baseInfo.Version, "conf")
|
||||
filePath := path.Join(constant.AppResourceDir, "remote", appInstall.App.Key, appInstall.Version, "conf")
|
||||
if !fileOp.Stat(filePath) {
|
||||
filePath = path.Join(constant.AppResourceDir, baseInfo.Key, "versions", baseInfo.Version, "conf")
|
||||
filePath = path.Join(constant.AppResourceDir, appInstall.App.Key, "versions", appInstall.Version, "conf")
|
||||
}
|
||||
if !fileOp.Stat(filePath) {
|
||||
return "", buserr.New(constant.ErrPathNotFound)
|
||||
}
|
||||
|
||||
if key == constant.AppMysql || key == constant.AppMariaDB {
|
||||
if key == constant.AppMysql {
|
||||
filePath = path.Join(filePath, "my.cnf")
|
||||
}
|
||||
if key == constant.AppRedis {
|
||||
@@ -621,10 +538,10 @@ func (a *AppInstallService) GetParams(id uint) (*response.AppConfig, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = json.Unmarshal([]byte(detail.Params), &appForm); err != nil {
|
||||
if err := json.Unmarshal([]byte(detail.Params), &appForm); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = json.Unmarshal([]byte(install.Env), &envs); err != nil {
|
||||
if err := json.Unmarshal([]byte(install.Env), &envs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, form := range appForm.FormFields {
|
||||
@@ -654,42 +571,30 @@ func (a *AppInstallService) GetParams(id uint) (*response.AppConfig, error) {
|
||||
appParam.Values = form.Values
|
||||
}
|
||||
params = append(params, appParam)
|
||||
} else {
|
||||
params = append(params, response.AppParam{
|
||||
Edit: form.Edit,
|
||||
Key: form.EnvKey,
|
||||
Rule: form.Rule,
|
||||
Type: form.Type,
|
||||
LabelZh: form.LabelZh,
|
||||
LabelEn: form.LabelEn,
|
||||
Value: form.Default,
|
||||
Values: form.Values,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
config := getAppCommonConfig(envs)
|
||||
config.DockerCompose = install.DockerCompose
|
||||
res.Params = params
|
||||
if config.ContainerName == "" {
|
||||
config.ContainerName = install.ContainerName
|
||||
}
|
||||
res.AppContainerConfig = config
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func syncByID(installID uint) error {
|
||||
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(installID))
|
||||
func syncById(installId uint) error {
|
||||
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if appInstall.Status == constant.Installing {
|
||||
return nil
|
||||
}
|
||||
|
||||
containerNames, err := getContainerNames(appInstall)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cli, err := docker.NewClient()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -715,16 +620,16 @@ func syncByID(installID uint) error {
|
||||
errorContainers = append(errorContainers, n.Names[0])
|
||||
}
|
||||
}
|
||||
for _, name := range containerNames {
|
||||
for _, old := range containerNames {
|
||||
exist := false
|
||||
for _, container := range containers {
|
||||
if common.ExistWithStrArray(name, container.Names) {
|
||||
for _, new := range containers {
|
||||
if common.ExistWithStrArray(old, new.Names) {
|
||||
exist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !exist {
|
||||
notFoundContainers = append(notFoundContainers, name)
|
||||
notFoundContainers = append(notFoundContainers, old)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -737,10 +642,10 @@ func syncByID(installID uint) error {
|
||||
|
||||
if containerCount == 0 {
|
||||
appInstall.Status = constant.Error
|
||||
appInstall.Message = i18n.GetMsgWithMap("ErrContainerNotFound", map[string]interface{}{"name": strings.Join(containerNames, ",")})
|
||||
appInstall.Message = "container is not found"
|
||||
return appInstallRepo.Save(context.Background(), &appInstall)
|
||||
}
|
||||
if errCount == 0 && existedCount == 0 && notFoundCount == 0 {
|
||||
if errCount == 0 && existedCount == 0 {
|
||||
appInstall.Status = constant.Running
|
||||
return appInstallRepo.Save(context.Background(), &appInstall)
|
||||
}
|
||||
@@ -755,14 +660,22 @@ func syncByID(installID uint) error {
|
||||
appInstall.Status = constant.UnHealthy
|
||||
}
|
||||
|
||||
var errMsg string
|
||||
var errMsg strings.Builder
|
||||
if errCount > 0 {
|
||||
errMsg += i18n.GetMsgWithMap("ErrContainerMsg", map[string]interface{}{"name": strings.Join(errorContainers, ",")})
|
||||
errMsg.Write([]byte(string(rune(errCount)) + " error containers:"))
|
||||
for _, e := range errorContainers {
|
||||
errMsg.Write([]byte(e))
|
||||
}
|
||||
errMsg.Write([]byte("\n"))
|
||||
}
|
||||
if notFoundCount > 0 {
|
||||
errMsg += i18n.GetMsgWithMap("ErrContainerNotFound", map[string]interface{}{"name": strings.Join(notFoundContainers, ",")})
|
||||
errMsg.Write([]byte(string(rune(notFoundCount)) + " not found containers:"))
|
||||
for _, e := range notFoundContainers {
|
||||
errMsg.Write([]byte(e))
|
||||
}
|
||||
errMsg.Write([]byte("\n"))
|
||||
}
|
||||
appInstall.Message = errMsg
|
||||
appInstall.Message = errMsg.String()
|
||||
return appInstallRepo.Save(context.Background(), &appInstall)
|
||||
}
|
||||
|
||||
@@ -783,11 +696,7 @@ func updateInstallInfoInDB(appKey, appName, param string, isRestart bool, value
|
||||
envKey := ""
|
||||
switch param {
|
||||
case "password":
|
||||
if appKey == "mysql" || appKey == "mariadb" {
|
||||
envKey = "PANEL_DB_ROOT_PASSWORD="
|
||||
} else {
|
||||
envKey = "PANEL_REDIS_ROOT_PASSWORD="
|
||||
}
|
||||
envKey = "PANEL_DB_ROOT_PASSWORD="
|
||||
case "port":
|
||||
envKey = "PANEL_APP_PORT_HTTP="
|
||||
case "user-password":
|
||||
@@ -816,10 +725,6 @@ func updateInstallInfoInDB(appKey, appName, param string, isRestart bool, value
|
||||
if param == "password" {
|
||||
oldVal = fmt.Sprintf("\"PANEL_DB_ROOT_PASSWORD\":\"%v\"", appInstall.Password)
|
||||
newVal = fmt.Sprintf("\"PANEL_DB_ROOT_PASSWORD\":\"%v\"", value)
|
||||
if appKey == "redis" {
|
||||
oldVal = fmt.Sprintf("\"PANEL_REDIS_ROOT_PASSWORD\":\"%v\"", appInstall.Password)
|
||||
newVal = fmt.Sprintf("\"PANEL_REDIS_ROOT_PASSWORD\":\"%v\"", value)
|
||||
}
|
||||
_ = appInstallRepo.BatchUpdateBy(map[string]interface{}{
|
||||
"param": strings.ReplaceAll(appInstall.Param, oldVal, newVal),
|
||||
"env": strings.ReplaceAll(appInstall.Env, oldVal, newVal),
|
||||
|
||||
+109
-348
@@ -5,6 +5,12 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"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/i18n"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/subosito/gotenv"
|
||||
"gopkg.in/yaml.v3"
|
||||
"math"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -15,14 +21,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||
|
||||
"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/i18n"
|
||||
"github.com/subosito/gotenv"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/env"
|
||||
|
||||
@@ -51,20 +49,7 @@ var (
|
||||
func checkPort(key string, params map[string]interface{}) (int, error) {
|
||||
port, ok := params[key]
|
||||
if ok {
|
||||
portN := 0
|
||||
var err error
|
||||
switch p := port.(type) {
|
||||
case string:
|
||||
portN, err = strconv.Atoi(p)
|
||||
if err != nil {
|
||||
return portN, nil
|
||||
}
|
||||
case float64:
|
||||
portN = int(math.Ceil(p))
|
||||
case int:
|
||||
portN = p
|
||||
}
|
||||
|
||||
portN := int(math.Ceil(port.(float64)))
|
||||
oldInstalled, _ := appInstallRepo.ListBy(appInstallRepo.WithPort(portN))
|
||||
if len(oldInstalled) > 0 {
|
||||
var apps []string
|
||||
@@ -82,111 +67,23 @@ func checkPort(key string, params map[string]interface{}) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func checkPortExist(port int) error {
|
||||
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)
|
||||
}
|
||||
domain, _ := websiteDomainRepo.GetFirst(websiteDomainRepo.WithPort(port))
|
||||
if domain.ID > 0 {
|
||||
errMap["type"] = i18n.GetMsgByKey("TYPE_DOMAIN")
|
||||
errMap["name"] = domain.Domain
|
||||
return buserr.WithMap("ErrPortExist", errMap, nil)
|
||||
}
|
||||
if common.ScanPort(port) {
|
||||
return buserr.WithDetail(constant.ErrPortInUsed, port, nil)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var DatabaseKeys = map[string]uint{
|
||||
"mysql": 3306,
|
||||
"mariadb": 3306,
|
||||
"postgresql": 5432,
|
||||
"mongodb": 27017,
|
||||
"redis": 6379,
|
||||
"memcached": 11211,
|
||||
}
|
||||
|
||||
func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall, params map[string]interface{}) error {
|
||||
var dbConfig dto.AppDatabase
|
||||
if app.Type == "runtime" && DatabaseKeys[app.Key] > 0 {
|
||||
database := &model.Database{
|
||||
AppInstallID: appInstall.ID,
|
||||
Name: appInstall.Name,
|
||||
Type: app.Key,
|
||||
Version: appInstall.Version,
|
||||
From: "local",
|
||||
Address: appInstall.ServiceName,
|
||||
Port: DatabaseKeys[app.Key],
|
||||
}
|
||||
detail, err := appDetailRepo.GetFirst(commonRepo.WithByID(appInstall.AppDetailId))
|
||||
if app.Type == "runtime" {
|
||||
var authParam dto.AuthParam
|
||||
paramByte, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
formFields := &dto.AppForm{}
|
||||
if err := json.Unmarshal([]byte(detail.Params), formFields); err != nil {
|
||||
if err := json.Unmarshal(paramByte, &authParam); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, form := range formFields.FormFields {
|
||||
if form.EnvKey == "PANEL_APP_PORT_HTTP" {
|
||||
portFloat, ok := form.Default.(float64)
|
||||
if ok {
|
||||
database.Port = uint(int(portFloat))
|
||||
}
|
||||
break
|
||||
if authParam.RootPassword != "" {
|
||||
authByte, err := json.Marshal(authParam)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
switch app.Key {
|
||||
case "mysql", "mariadb", "postgresql", "mongodb":
|
||||
if password, ok := params["PANEL_DB_ROOT_PASSWORD"]; ok {
|
||||
if password != "" {
|
||||
authParam := dto.AuthParam{
|
||||
RootPassword: password.(string),
|
||||
}
|
||||
authByte, err := json.Marshal(authParam)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
appInstall.Param = string(authByte)
|
||||
database.Password = password.(string)
|
||||
if app.Key == "mysql" || app.Key == "mariadb" {
|
||||
database.Username = "root"
|
||||
}
|
||||
if rootUser, ok := params["PANEL_DB_ROOT_USER"]; ok {
|
||||
database.Username = rootUser.(string)
|
||||
}
|
||||
}
|
||||
}
|
||||
case "redis":
|
||||
if password, ok := params["PANEL_REDIS_ROOT_PASSWORD"]; ok {
|
||||
if password != "" {
|
||||
authParam := dto.RedisAuthParam{
|
||||
RootPassword: password.(string),
|
||||
}
|
||||
authByte, err := json.Marshal(authParam)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
appInstall.Param = string(authByte)
|
||||
}
|
||||
database.Password = password.(string)
|
||||
}
|
||||
}
|
||||
if err := databaseRepo.Create(ctx, database); err != nil {
|
||||
return err
|
||||
appInstall.Param = string(authByte)
|
||||
}
|
||||
}
|
||||
if app.Type == "website" || app.Type == "tool" {
|
||||
@@ -194,24 +91,20 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = json.Unmarshal(paramByte, &dbConfig); err != nil {
|
||||
if err := json.Unmarshal(paramByte, &dbConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(dbConfig, dto.AppDatabase{}) && dbConfig.ServiceName != "" {
|
||||
hostName := params["PANEL_DB_HOST_NAME"]
|
||||
if hostName == nil || hostName.(string) == "" {
|
||||
return nil
|
||||
}
|
||||
database, _ := databaseRepo.Get(commonRepo.WithByName(hostName.(string)))
|
||||
if database.ID == 0 {
|
||||
return nil
|
||||
dbInstall, err := appInstallRepo.GetFirst(appInstallRepo.WithServiceName(dbConfig.ServiceName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var resourceId uint
|
||||
if dbConfig.DbName != "" && dbConfig.DbUser != "" && dbConfig.Password != "" {
|
||||
iMysqlRepo := repo.NewIMysqlRepo()
|
||||
oldMysqlDb, _ := iMysqlRepo.Get(commonRepo.WithByName(dbConfig.DbName), iMysqlRepo.WithByFrom(constant.ResourceLocal))
|
||||
oldMysqlDb, _ := iMysqlRepo.Get(commonRepo.WithByName(dbConfig.DbName))
|
||||
resourceId = oldMysqlDb.ID
|
||||
if oldMysqlDb.ID > 0 {
|
||||
if oldMysqlDb.Username != dbConfig.DbUser || oldMysqlDb.Password != dbConfig.Password {
|
||||
@@ -221,11 +114,9 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall
|
||||
var createMysql dto.MysqlDBCreate
|
||||
createMysql.Name = dbConfig.DbName
|
||||
createMysql.Username = dbConfig.DbUser
|
||||
createMysql.Database = database.Name
|
||||
createMysql.Format = "utf8mb4"
|
||||
createMysql.Permission = "%"
|
||||
createMysql.Password = dbConfig.Password
|
||||
createMysql.From = database.From
|
||||
mysqldb, err := NewIMysqlService().Create(ctx, createMysql)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -236,13 +127,8 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall
|
||||
var installResource model.AppInstallResource
|
||||
installResource.ResourceId = resourceId
|
||||
installResource.AppInstallId = appInstall.ID
|
||||
if database.AppInstallID > 0 {
|
||||
installResource.LinkId = database.AppInstallID
|
||||
} else {
|
||||
installResource.LinkId = database.ID
|
||||
}
|
||||
installResource.Key = database.Type
|
||||
installResource.From = database.From
|
||||
installResource.LinkId = dbInstall.ID
|
||||
installResource.Key = dbInstall.App.Key
|
||||
if err := appInstallResourceRepo.Create(ctx, &installResource); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -260,7 +146,7 @@ func handleAppInstallErr(ctx context.Context, install *model.AppInstall) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := deleteLink(ctx, install, true, true, true); err != nil {
|
||||
if err := deleteLink(ctx, install, true, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -275,56 +161,27 @@ func deleteAppInstall(install model.AppInstall, deleteBackup bool, forceDelete b
|
||||
if err != nil && !forceDelete {
|
||||
return handleErr(install, err, out)
|
||||
}
|
||||
if err = runScript(&install, "uninstall"); err != nil {
|
||||
_, _ = compose.Up(install.GetComposePath())
|
||||
return err
|
||||
}
|
||||
}
|
||||
tx, ctx := helper.GetTxAndContext()
|
||||
defer tx.Rollback()
|
||||
if err := appInstallRepo.Delete(ctx, install); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deleteLink(ctx, &install, deleteDB, forceDelete, deleteBackup); err != nil && !forceDelete {
|
||||
if err := deleteLink(ctx, &install, deleteDB, forceDelete); err != nil && !forceDelete {
|
||||
return err
|
||||
}
|
||||
|
||||
if DatabaseKeys[install.App.Key] > 0 {
|
||||
_ = databaseRepo.Delete(ctx, databaseRepo.WithAppInstallID(install.ID))
|
||||
}
|
||||
|
||||
switch install.App.Key {
|
||||
case constant.AppOpenresty:
|
||||
websites, _ := websiteRepo.List()
|
||||
for _, website := range websites {
|
||||
if website.AppInstallID > 0 {
|
||||
websiteAppInstall, _ := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
||||
if websiteAppInstall.AppId > 0 {
|
||||
websiteApp, _ := appRepo.GetFirst(commonRepo.WithByID(websiteAppInstall.AppId))
|
||||
if websiteApp.Type == constant.RuntimePHP {
|
||||
go func() {
|
||||
_, _ = compose.Down(install.GetComposePath())
|
||||
_ = op.DeleteDir(install.GetPath())
|
||||
}()
|
||||
_ = appInstallRepo.Delete(ctx, websiteAppInstall)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ = websiteRepo.DeleteAll(ctx)
|
||||
_ = websiteDomainRepo.DeleteAll(ctx)
|
||||
case constant.AppMysql, constant.AppMariaDB:
|
||||
_ = mysqlRepo.Delete(ctx, mysqlRepo.WithByMysqlName(install.Name))
|
||||
}
|
||||
|
||||
_ = backupRepo.DeleteRecord(ctx, commonRepo.WithByType("app"), commonRepo.WithByName(install.App.Key), backupRepo.WithByDetailName(install.Name))
|
||||
uploadDir := path.Join(global.CONF.System.BaseDir, fmt.Sprintf("1panel/uploads/app/%s/%s", install.App.Key, install.Name))
|
||||
_ = backupRepo.DeleteRecord(ctx, commonRepo.WithByType(install.App.Key))
|
||||
if install.App.Key == constant.AppMysql {
|
||||
_ = mysqlRepo.DeleteAll(ctx)
|
||||
}
|
||||
uploadDir := fmt.Sprintf("%s/1panel/uploads/app/%s/%s", global.CONF.System.BaseDir, install.App.Key, install.Name)
|
||||
if _, err := os.Stat(uploadDir); err == nil {
|
||||
_ = os.RemoveAll(uploadDir)
|
||||
}
|
||||
if deleteBackup {
|
||||
localDir, _ := loadLocalDir()
|
||||
backupDir := path.Join(localDir, fmt.Sprintf("app/%s/%s", install.App.Key, install.Name))
|
||||
backupDir := fmt.Sprintf("%s/app/%s/%s", localDir, install.App.Key, install.Name)
|
||||
if _, err := os.Stat(backupDir); err == nil {
|
||||
_ = os.RemoveAll(backupDir)
|
||||
}
|
||||
@@ -335,25 +192,21 @@ func deleteAppInstall(install model.AppInstall, deleteBackup bool, forceDelete b
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteLink(ctx context.Context, install *model.AppInstall, deleteDB bool, forceDelete bool, deleteBackup bool) error {
|
||||
|
||||
func deleteLink(ctx context.Context, install *model.AppInstall, deleteDB bool, forceDelete bool) error {
|
||||
resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithAppInstallId(install.ID))
|
||||
if len(resources) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, re := range resources {
|
||||
mysqlService := NewIMysqlService()
|
||||
if (re.Key == constant.AppMysql || re.Key == constant.AppMariaDB) && deleteDB {
|
||||
if re.Key == "mysql" && deleteDB {
|
||||
database, _ := mysqlRepo.Get(commonRepo.WithByID(re.ResourceId))
|
||||
if reflect.DeepEqual(database, model.DatabaseMysql{}) {
|
||||
continue
|
||||
}
|
||||
if err := mysqlService.Delete(ctx, dto.MysqlDBDelete{
|
||||
ID: database.ID,
|
||||
ForceDelete: forceDelete,
|
||||
DeleteBackup: deleteBackup,
|
||||
Type: re.Key,
|
||||
Database: database.MysqlName,
|
||||
ID: database.ID,
|
||||
ForceDelete: forceDelete,
|
||||
}); err != nil && !forceDelete {
|
||||
return err
|
||||
}
|
||||
@@ -362,7 +215,7 @@ func deleteLink(ctx context.Context, install *model.AppInstall, deleteDB bool, f
|
||||
return appInstallResourceRepo.DeleteBy(ctx, appInstallResourceRepo.WithAppInstallId(install.ID))
|
||||
}
|
||||
|
||||
func upgradeInstall(installId uint, detailId uint, backup bool) error {
|
||||
func upgradeInstall(installId uint, detailId uint) error {
|
||||
install, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -374,14 +227,13 @@ func upgradeInstall(installId uint, detailId uint, backup bool) error {
|
||||
if install.Version == detail.Version {
|
||||
return errors.New("two version is same")
|
||||
}
|
||||
if err := NewIBackupService().AppBackup(dto.CommonBackup{Name: install.App.Key, DetailName: install.Name}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
install.Status = constant.Upgrading
|
||||
|
||||
go func() {
|
||||
if backup {
|
||||
if err = NewIBackupService().AppBackup(dto.CommonBackup{Name: install.App.Key, DetailName: install.Name}); err != nil {
|
||||
global.LOG.Errorf(i18n.GetMsgWithMap("ErrAppBackup", map[string]interface{}{"name": install.Name, "err": err.Error()}))
|
||||
}
|
||||
}
|
||||
var upErr error
|
||||
defer func() {
|
||||
if upErr != nil {
|
||||
@@ -404,19 +256,15 @@ func upgradeInstall(installId uint, detailId uint, backup bool) error {
|
||||
detailDir = path.Join(constant.ResourceDir, "apps", "local", strings.TrimPrefix(install.App.Key, "local"), detail.Version)
|
||||
}
|
||||
|
||||
command := exec.Command("/bin/bash", "-c", fmt.Sprintf("cp -rn %s/* %s || true", detailDir, install.GetPath()))
|
||||
stdout, _ := command.CombinedOutput()
|
||||
if stdout != nil {
|
||||
global.LOG.Infof("upgrade app [%s] [%s] cp file log : %s ", install.App.Key, install.Name, string(stdout))
|
||||
}
|
||||
fileOp := files.NewFileOp()
|
||||
sourceScripts := path.Join(detailDir, "scripts")
|
||||
if fileOp.Stat(sourceScripts) {
|
||||
dstScripts := path.Join(install.GetPath(), "scripts")
|
||||
_ = fileOp.DeleteDir(dstScripts)
|
||||
_ = fileOp.CreateDir(dstScripts, 0755)
|
||||
scriptCmd := exec.Command("cp", "-rf", sourceScripts+"/.", dstScripts+"/")
|
||||
_, _ = scriptCmd.CombinedOutput()
|
||||
cmd := exec.Command("/bin/bash", "-c", fmt.Sprintf("cp -rf %s/* %s", detailDir, install.GetPath()))
|
||||
stdout, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
if stdout != nil {
|
||||
upErr = errors.New(string(stdout))
|
||||
return
|
||||
}
|
||||
upErr = err
|
||||
return
|
||||
}
|
||||
|
||||
composeMap := make(map[string]interface{})
|
||||
@@ -429,21 +277,20 @@ func upgradeInstall(installId uint, detailId uint, backup bool) error {
|
||||
return
|
||||
}
|
||||
servicesMap := value.(map[string]interface{})
|
||||
if len(servicesMap) == 1 {
|
||||
index := 0
|
||||
oldServiceName := ""
|
||||
for k := range servicesMap {
|
||||
oldServiceName = k
|
||||
index++
|
||||
if index > 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
servicesMap[install.ServiceName] = servicesMap[oldServiceName]
|
||||
if install.ServiceName != oldServiceName {
|
||||
delete(servicesMap, oldServiceName)
|
||||
index := 0
|
||||
oldServiceName := ""
|
||||
for k := range servicesMap {
|
||||
oldServiceName = k
|
||||
index++
|
||||
if index > 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
servicesMap[install.ServiceName] = servicesMap[oldServiceName]
|
||||
if install.ServiceName != oldServiceName {
|
||||
delete(servicesMap, oldServiceName)
|
||||
}
|
||||
|
||||
envs := make(map[string]interface{})
|
||||
if upErr = json.Unmarshal([]byte(install.Env), &envs); upErr != nil {
|
||||
return
|
||||
@@ -471,24 +318,6 @@ func upgradeInstall(installId uint, detailId uint, backup bool) error {
|
||||
install.Version = detail.Version
|
||||
install.AppDetailId = detailId
|
||||
|
||||
images, err := getImages(install)
|
||||
if err != nil {
|
||||
upErr = err
|
||||
return
|
||||
}
|
||||
dockerCli, err := composeV2.NewClient()
|
||||
if err != nil {
|
||||
upErr = err
|
||||
return
|
||||
}
|
||||
|
||||
for _, image := range images {
|
||||
if err = dockerCli.PullImage(image, true); err != nil {
|
||||
upErr = buserr.WithNameAndErr("ErrDockerPullImage", "", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if out, err := compose.Down(install.GetComposePath()); err != nil {
|
||||
if out != "" {
|
||||
upErr = errors.New(out)
|
||||
@@ -496,16 +325,12 @@ func upgradeInstall(installId uint, detailId uint, backup bool) error {
|
||||
}
|
||||
return
|
||||
}
|
||||
fileOp := files.NewFileOp()
|
||||
envParams := make(map[string]string, len(envs))
|
||||
handleMap(envs, envParams)
|
||||
if err = env.Write(envParams, install.GetEnvPath()); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = runScript(&install, "upgrade"); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if upErr = fileOp.WriteFile(install.GetComposePath(), strings.NewReader(install.DockerCompose), 0775); upErr != nil {
|
||||
return
|
||||
}
|
||||
@@ -534,6 +359,7 @@ func getContainerNames(install model.AppInstall) ([]string, error) {
|
||||
return nil, err
|
||||
}
|
||||
containerMap := make(map[string]struct{})
|
||||
containerMap[install.ContainerName] = struct{}{}
|
||||
for _, service := range project.AllServices() {
|
||||
if service.ContainerName == "${CONTAINER_NAME}" || service.ContainerName == "" {
|
||||
continue
|
||||
@@ -544,32 +370,9 @@ func getContainerNames(install model.AppInstall) ([]string, error) {
|
||||
for k := range containerMap {
|
||||
containerNames = append(containerNames, k)
|
||||
}
|
||||
if len(containerNames) == 0 {
|
||||
containerNames = append(containerNames, install.ContainerName)
|
||||
}
|
||||
return containerNames, nil
|
||||
}
|
||||
|
||||
func getImages(install model.AppInstall) ([]string, error) {
|
||||
envStr, err := coverEnvJsonToStr(install.Env)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
project, err := composeV2.GetComposeProject(install.Name, install.GetPath(), []byte(install.DockerCompose), []byte(envStr), true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
imagesMap := make(map[string]struct{})
|
||||
for _, service := range project.AllServices() {
|
||||
imagesMap[service.Image] = struct{}{}
|
||||
}
|
||||
var images []string
|
||||
for k := range imagesMap {
|
||||
images = append(images, k)
|
||||
}
|
||||
return images, nil
|
||||
}
|
||||
|
||||
func coverEnvJsonToStr(envJson string) (string, error) {
|
||||
envMap := make(map[string]interface{})
|
||||
_ = json.Unmarshal([]byte(envJson), &envMap)
|
||||
@@ -609,10 +412,6 @@ func handleMap(params map[string]interface{}, envParams map[string]string) {
|
||||
envParams[k] = t
|
||||
case float64:
|
||||
envParams[k] = strconv.FormatFloat(t, 'f', -1, 32)
|
||||
case uint:
|
||||
envParams[k] = strconv.Itoa(int(t))
|
||||
case int:
|
||||
envParams[k] = strconv.Itoa(t)
|
||||
default:
|
||||
envParams[k] = t.(string)
|
||||
}
|
||||
@@ -634,7 +433,7 @@ func downloadApp(app model.App, appDetail model.AppDetail, appInstall *model.App
|
||||
_ = fileOp.CreateDir(appVersionDir, 0755)
|
||||
}
|
||||
global.LOG.Infof("download app[%s] from %s", app.Name, appDetail.DownloadUrl)
|
||||
filePath := path.Join(appVersionDir, app.Key+"-"+appDetail.Version+".tar.gz")
|
||||
filePath := path.Join(appVersionDir, appDetail.Version+".tar.gz")
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
@@ -649,7 +448,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.TarGz); err != nil {
|
||||
if err = fileOp.Decompress(filePath, appVersionDir, files.TarGz); err != nil {
|
||||
global.LOG.Errorf("decompress app[%s] error %v", app.Name, err)
|
||||
return
|
||||
}
|
||||
@@ -712,32 +511,38 @@ func copyData(app model.App, appDetail model.AppDetail, appInstall *model.AppIns
|
||||
return
|
||||
}
|
||||
|
||||
func runScript(appInstall *model.AppInstall, operate string) error {
|
||||
workDir := appInstall.GetPath()
|
||||
scriptPath := ""
|
||||
switch operate {
|
||||
case "init":
|
||||
scriptPath = path.Join(workDir, "scripts", "init.sh")
|
||||
case "upgrade":
|
||||
scriptPath = path.Join(workDir, "scripts", "upgrade.sh")
|
||||
case "uninstall":
|
||||
scriptPath = path.Join(workDir, "scripts", "uninstall.sh")
|
||||
}
|
||||
if !files.NewFileOp().Stat(scriptPath) {
|
||||
return nil
|
||||
}
|
||||
out, err := cmd.ExecScript(scriptPath, workDir)
|
||||
if err != nil {
|
||||
if out != "" {
|
||||
errMsg := fmt.Sprintf("run script %s error %s", scriptPath, out)
|
||||
global.LOG.Error(errMsg)
|
||||
return errors.New(errMsg)
|
||||
// 处理文件夹权限等问题
|
||||
func upAppPre(app model.App, appInstall *model.AppInstall) error {
|
||||
if app.Key == "nexus" {
|
||||
dataPath := path.Join(appInstall.GetPath(), "data")
|
||||
if err := files.NewFileOp().Chown(dataPath, 200, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getServiceFromInstall(appInstall *model.AppInstall) (service *composeV2.ComposeService, err error) {
|
||||
var (
|
||||
project *types.Project
|
||||
envStr string
|
||||
)
|
||||
envStr, err = coverEnvJsonToStr(appInstall.Env)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
project, err = composeV2.GetComposeProject(appInstall.Name, appInstall.GetPath(), []byte(appInstall.DockerCompose), []byte(envStr), true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
service, err = composeV2.NewComposeService()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
service.SetProject(project)
|
||||
return
|
||||
}
|
||||
|
||||
func checkContainerNameIsExist(containerName, appDir string) (bool, error) {
|
||||
client, err := composeV2.NewDockerClient()
|
||||
if err != nil {
|
||||
@@ -766,30 +571,13 @@ func checkContainerNameIsExist(containerName, appDir string) (bool, error) {
|
||||
func upApp(appInstall *model.AppInstall) {
|
||||
upProject := func(appInstall *model.AppInstall) (err error) {
|
||||
if err == nil {
|
||||
var (
|
||||
out string
|
||||
errMsg string
|
||||
)
|
||||
if appInstall.App.Type != "php" {
|
||||
out, err = compose.Pull(appInstall.GetComposePath())
|
||||
if err != nil {
|
||||
if out != "" {
|
||||
if strings.Contains(out, "no such host") {
|
||||
errMsg = i18n.GetMsgByKey("ErrNoSuchHost") + ":"
|
||||
}
|
||||
if strings.Contains(out, "timeout") {
|
||||
errMsg = i18n.GetMsgByKey("ErrImagePullTimeOut") + ":"
|
||||
}
|
||||
appInstall.Message = errMsg + out
|
||||
}
|
||||
return err
|
||||
}
|
||||
var composeService *composeV2.ComposeService
|
||||
composeService, err = getServiceFromInstall(appInstall)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out, err = compose.Up(appInstall.GetComposePath())
|
||||
err = composeService.ComposeUp()
|
||||
if err != nil {
|
||||
if out != "" {
|
||||
appInstall.Message = errMsg + out
|
||||
}
|
||||
return err
|
||||
}
|
||||
return
|
||||
@@ -799,6 +587,7 @@ func upApp(appInstall *model.AppInstall) {
|
||||
}
|
||||
if err := upProject(appInstall); err != nil {
|
||||
appInstall.Status = constant.Error
|
||||
appInstall.Message = err.Error()
|
||||
} else {
|
||||
appInstall.Status = constant.Running
|
||||
}
|
||||
@@ -809,24 +598,16 @@ func upApp(appInstall *model.AppInstall) {
|
||||
}
|
||||
|
||||
func rebuildApp(appInstall model.AppInstall) error {
|
||||
appInstall.Status = constant.Rebuilding
|
||||
_ = appInstallRepo.Save(context.Background(), &appInstall)
|
||||
go func() {
|
||||
dockerComposePath := appInstall.GetComposePath()
|
||||
out, err := compose.Down(dockerComposePath)
|
||||
if err != nil {
|
||||
_ = handleErr(appInstall, err, out)
|
||||
return
|
||||
}
|
||||
out, err = compose.Up(dockerComposePath)
|
||||
if err != nil {
|
||||
_ = handleErr(appInstall, err, out)
|
||||
return
|
||||
}
|
||||
appInstall.Status = constant.Running
|
||||
_ = appInstallRepo.Save(context.Background(), &appInstall)
|
||||
}()
|
||||
return nil
|
||||
dockerComposePath := appInstall.GetComposePath()
|
||||
out, err := compose.Down(dockerComposePath)
|
||||
if err != nil {
|
||||
return handleErr(appInstall, err, out)
|
||||
}
|
||||
out, err = compose.Up(dockerComposePath)
|
||||
if err != nil {
|
||||
return handleErr(appInstall, err, out)
|
||||
}
|
||||
return syncById(appInstall.ID)
|
||||
}
|
||||
|
||||
func getAppDetails(details []model.AppDetail, versions []dto.AppConfigVersion) map[string]model.AppDetail {
|
||||
@@ -970,7 +751,7 @@ func handleErr(install model.AppInstall, err error, out string) error {
|
||||
func handleInstalled(appInstallList []model.AppInstall, updated bool) ([]response.AppInstalledDTO, error) {
|
||||
var res []response.AppInstalledDTO
|
||||
for _, installed := range appInstallList {
|
||||
if updated && (installed.App.Type == "php" || installed.Status == constant.Installing || (installed.App.Key == constant.AppMysql && installed.Version == "5.6.51")) {
|
||||
if updated && installed.App.Type == "php" {
|
||||
continue
|
||||
}
|
||||
installDTO := response.AppInstalledDTO{
|
||||
@@ -987,22 +768,12 @@ func handleInstalled(appInstallList []model.AppInstall, updated bool) ([]respons
|
||||
}
|
||||
var versions []string
|
||||
for _, detail := range details {
|
||||
if detail.IgnoreUpgrade {
|
||||
continue
|
||||
}
|
||||
if common.IsCrossVersion(installed.Version, detail.Version) && !app.CrossVersionUpdate {
|
||||
continue
|
||||
}
|
||||
versions = append(versions, detail.Version)
|
||||
}
|
||||
versions = common.GetSortedVersions(versions)
|
||||
if len(versions) == 0 {
|
||||
if !updated {
|
||||
installDTO.CanUpdate = false
|
||||
res = append(res, installDTO)
|
||||
}
|
||||
continue
|
||||
}
|
||||
lastVersion := versions[0]
|
||||
if common.IsCrossVersion(installed.Version, lastVersion) {
|
||||
installDTO.CanUpdate = app.CrossVersionUpdate
|
||||
@@ -1032,16 +803,6 @@ func getAppInstallByKey(key string) (model.AppInstall, error) {
|
||||
return appInstall, nil
|
||||
}
|
||||
|
||||
func getAppInstallPort(key string) (httpPort, httpsPort int, err error) {
|
||||
install, err := getAppInstallByKey(key)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
httpPort = install.HttpPort
|
||||
httpsPort = install.HttpsPort
|
||||
return
|
||||
}
|
||||
|
||||
func updateToolApp(installed *model.AppInstall) {
|
||||
tooKey, ok := dto.AppToolMap[installed.App.Key]
|
||||
if !ok {
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"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/encrypt"
|
||||
@@ -20,16 +19,16 @@ type AuthService struct{}
|
||||
type IAuthService interface {
|
||||
CheckIsSafety(code string) (string, error)
|
||||
VerifyCode(code string) (bool, error)
|
||||
Login(c *gin.Context, info dto.Login, entrance string) (*dto.UserLoginInfo, error)
|
||||
Login(c *gin.Context, info dto.Login) (*dto.UserLoginInfo, error)
|
||||
LogOut(c *gin.Context) error
|
||||
MFALogin(c *gin.Context, info dto.MFALogin, entrance string) (*dto.UserLoginInfo, error)
|
||||
MFALogin(c *gin.Context, info dto.MFALogin) (*dto.UserLoginInfo, error)
|
||||
}
|
||||
|
||||
func NewIAuthService() IAuthService {
|
||||
return &AuthService{}
|
||||
}
|
||||
|
||||
func (u *AuthService) Login(c *gin.Context, info dto.Login, entrance string) (*dto.UserLoginInfo, error) {
|
||||
func (u *AuthService) Login(c *gin.Context, info dto.Login) (*dto.UserLoginInfo, error) {
|
||||
nameSetting, err := settingRepo.Get(settingRepo.WithByKey("UserName"))
|
||||
if err != nil {
|
||||
return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error())
|
||||
@@ -45,27 +44,18 @@ func (u *AuthService) Login(c *gin.Context, info dto.Login, entrance string) (*d
|
||||
if info.Password != pass || nameSetting.Value != info.Name {
|
||||
return nil, constant.ErrAuth
|
||||
}
|
||||
entranceSetting, err := settingRepo.Get(settingRepo.WithByKey("SecurityEntrance"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(entranceSetting.Value) != 0 && entranceSetting.Value != entrance {
|
||||
return nil, buserr.New(constant.ErrEntrance)
|
||||
}
|
||||
mfa, err := settingRepo.Get(settingRepo.WithByKey("MFAStatus"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = settingRepo.Update("Language", info.Language); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if mfa.Value == "enable" {
|
||||
return &dto.UserLoginInfo{Name: nameSetting.Value, MfaStatus: mfa.Value}, nil
|
||||
}
|
||||
|
||||
return u.generateSession(c, info.Name, info.AuthMethod)
|
||||
}
|
||||
|
||||
func (u *AuthService) MFALogin(c *gin.Context, info dto.MFALogin, entrance string) (*dto.UserLoginInfo, error) {
|
||||
func (u *AuthService) MFALogin(c *gin.Context, info dto.MFALogin) (*dto.UserLoginInfo, error) {
|
||||
nameSetting, err := settingRepo.Get(settingRepo.WithByKey("UserName"))
|
||||
if err != nil {
|
||||
return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error())
|
||||
@@ -81,22 +71,12 @@ func (u *AuthService) MFALogin(c *gin.Context, info dto.MFALogin, entrance strin
|
||||
if info.Password != pass || nameSetting.Value != info.Name {
|
||||
return nil, constant.ErrAuth
|
||||
}
|
||||
entranceSetting, err := settingRepo.Get(settingRepo.WithByKey("SecurityEntrance"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(entranceSetting.Value) != 0 && entranceSetting.Value != entrance {
|
||||
return nil, buserr.New(constant.ErrEntrance)
|
||||
}
|
||||
|
||||
mfaSecret, err := settingRepo.Get(settingRepo.WithByKey("MFASecret"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mfaInterval, err := settingRepo.Get(settingRepo.WithByKey("MFAInterval"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
success := mfa.ValidCode(info.Code, mfaInterval.Value, mfaSecret.Value)
|
||||
success := mfa.ValidCode(info.Code, mfaSecret.Value)
|
||||
if !success {
|
||||
return nil, constant.ErrAuth
|
||||
}
|
||||
|
||||
@@ -2,12 +2,8 @@ package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
@@ -28,7 +24,6 @@ type BackupService struct{}
|
||||
type IBackupService interface {
|
||||
List() ([]dto.BackupInfo, error)
|
||||
SearchRecordsWithPage(search dto.RecordSearch) (int64, []dto.BackupRecords, error)
|
||||
LoadOneDriveInfo() (string, error)
|
||||
DownloadRecord(info dto.DownloadRecord) (string, error)
|
||||
Create(backupDto dto.BackupOperate) error
|
||||
GetBuckets(backupDto dto.ForBuckets) ([]interface{}, error)
|
||||
@@ -37,7 +32,7 @@ type IBackupService interface {
|
||||
BatchDeleteRecord(ids []uint) error
|
||||
NewClient(backup *model.BackupAccount) (cloud_storage.CloudStorageClient, error)
|
||||
|
||||
ListFiles(req dto.BackupSearchFile) ([]string, error)
|
||||
ListFiles(req dto.BackupSearchFile) ([]interface{}, error)
|
||||
|
||||
MysqlBackup(db dto.CommonBackup) error
|
||||
MysqlRecover(db dto.CommonRecover) error
|
||||
@@ -67,7 +62,6 @@ func (u *BackupService) List() ([]dto.BackupInfo, error) {
|
||||
dtobas = append(dtobas, u.loadByType("MINIO", ops))
|
||||
dtobas = append(dtobas, u.loadByType("COS", ops))
|
||||
dtobas = append(dtobas, u.loadByType("KODO", ops))
|
||||
dtobas = append(dtobas, u.loadByType("OneDrive", ops))
|
||||
return dtobas, err
|
||||
}
|
||||
|
||||
@@ -90,18 +84,6 @@ func (u *BackupService) SearchRecordsWithPage(search dto.RecordSearch) (int64, [
|
||||
return total, dtobas, err
|
||||
}
|
||||
|
||||
func (u *BackupService) LoadOneDriveInfo() (string, error) {
|
||||
OneDriveID, err := settingRepo.Get(settingRepo.WithByKey("OneDriveID"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
idItem, err := base64.StdEncoding.DecodeString(OneDriveID.Value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(idItem), err
|
||||
}
|
||||
|
||||
func (u *BackupService) DownloadRecord(info dto.DownloadRecord) (string, error) {
|
||||
if info.Source == "LOCAL" {
|
||||
return info.FileDir + "/" + info.FileName, nil
|
||||
@@ -114,6 +96,7 @@ func (u *BackupService) DownloadRecord(info dto.DownloadRecord) (string, error)
|
||||
if err := json.Unmarshal([]byte(backup.Vars), &varMap); err != nil {
|
||||
return "", err
|
||||
}
|
||||
varMap["type"] = backup.Type
|
||||
varMap["bucket"] = backup.Bucket
|
||||
switch backup.Type {
|
||||
case constant.Sftp:
|
||||
@@ -122,10 +105,8 @@ func (u *BackupService) DownloadRecord(info dto.DownloadRecord) (string, error)
|
||||
case constant.OSS, constant.S3, constant.MinIo, constant.Cos, constant.Kodo:
|
||||
varMap["accessKey"] = backup.AccessKey
|
||||
varMap["secretKey"] = backup.Credential
|
||||
case constant.OneDrive:
|
||||
varMap["accessToken"] = backup.Credential
|
||||
}
|
||||
backClient, err := cloud_storage.NewCloudStorageClient(backup.Type, varMap)
|
||||
backClient, err := cloud_storage.NewCloudStorageClient(varMap)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("new cloud storage client failed, err: %v", err)
|
||||
}
|
||||
@@ -136,11 +117,6 @@ func (u *BackupService) DownloadRecord(info dto.DownloadRecord) (string, error)
|
||||
}
|
||||
}
|
||||
srcPath := fmt.Sprintf("%s/%s", info.FileDir, info.FileName)
|
||||
if len(backup.BackupPath) != 0 {
|
||||
itemPath := strings.TrimPrefix(backup.BackupPath, "/")
|
||||
itemPath = strings.TrimSuffix(itemPath, "/") + "/"
|
||||
srcPath = itemPath + srcPath
|
||||
}
|
||||
if exist, _ := backClient.Exist(srcPath); exist {
|
||||
isOK, err := backClient.Download(srcPath, targetPath)
|
||||
if !isOK {
|
||||
@@ -158,12 +134,6 @@ func (u *BackupService) Create(backupDto dto.BackupOperate) error {
|
||||
if err := copier.Copy(&backup, &backupDto); err != nil {
|
||||
return errors.WithMessage(constant.ErrStructTransform, err.Error())
|
||||
}
|
||||
|
||||
if backupDto.Type == constant.OneDrive {
|
||||
if err := u.loadAccessToken(&backup); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := backupRepo.Create(&backup); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -175,6 +145,7 @@ func (u *BackupService) GetBuckets(backupDto dto.ForBuckets) ([]interface{}, err
|
||||
if err := json.Unmarshal([]byte(backupDto.Vars), &varMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
varMap["type"] = backupDto.Type
|
||||
switch backupDto.Type {
|
||||
case constant.Sftp:
|
||||
varMap["username"] = backupDto.AccessKey
|
||||
@@ -183,7 +154,7 @@ func (u *BackupService) GetBuckets(backupDto dto.ForBuckets) ([]interface{}, err
|
||||
varMap["accessKey"] = backupDto.AccessKey
|
||||
varMap["secretKey"] = backupDto.Credential
|
||||
}
|
||||
client, err := cloud_storage.NewCloudStorageClient(backupDto.Type, varMap)
|
||||
client, err := cloud_storage.NewCloudStorageClient(varMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -243,17 +214,7 @@ func (u *BackupService) Update(req dto.BackupOperate) error {
|
||||
upMap := make(map[string]interface{})
|
||||
upMap["bucket"] = req.Bucket
|
||||
upMap["credential"] = req.Credential
|
||||
upMap["backup_path"] = req.BackupPath
|
||||
upMap["vars"] = req.Vars
|
||||
backup.Vars = req.Vars
|
||||
|
||||
if req.Type == constant.OneDrive {
|
||||
if err := u.loadAccessToken(&backup); err != nil {
|
||||
return err
|
||||
}
|
||||
upMap["credential"] = backup.Credential
|
||||
upMap["vars"] = backup.Vars
|
||||
}
|
||||
if err := backupRepo.Update(req.ID, upMap); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -273,7 +234,7 @@ func (u *BackupService) Update(req dto.BackupOperate) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *BackupService) ListFiles(req dto.BackupSearchFile) ([]string, error) {
|
||||
func (u *BackupService) ListFiles(req dto.BackupSearchFile) ([]interface{}, error) {
|
||||
backup, err := backupRepo.Get(backupRepo.WithByType(req.Type))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -282,21 +243,7 @@ func (u *BackupService) ListFiles(req dto.BackupSearchFile) ([]string, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
prefix := "system_snapshot"
|
||||
if len(backup.BackupPath) != 0 {
|
||||
prefix = path.Join(strings.TrimPrefix(backup.BackupPath, "/"), prefix)
|
||||
}
|
||||
files, err := client.ListObjects(prefix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var datas []string
|
||||
for _, file := range files {
|
||||
if len(file) != 0 {
|
||||
datas = append(datas, path.Base(file))
|
||||
}
|
||||
}
|
||||
return datas, nil
|
||||
return client.ListObjects("system_snapshot/")
|
||||
}
|
||||
|
||||
func (u *BackupService) NewClient(backup *model.BackupAccount) (cloud_storage.CloudStorageClient, error) {
|
||||
@@ -304,6 +251,7 @@ func (u *BackupService) NewClient(backup *model.BackupAccount) (cloud_storage.Cl
|
||||
if err := json.Unmarshal([]byte(backup.Vars), &varMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
varMap["type"] = backup.Type
|
||||
if backup.Type == "LOCAL" {
|
||||
return nil, errors.New("not support")
|
||||
}
|
||||
@@ -315,11 +263,9 @@ func (u *BackupService) NewClient(backup *model.BackupAccount) (cloud_storage.Cl
|
||||
case constant.OSS, constant.S3, constant.MinIo, constant.Cos, constant.Kodo:
|
||||
varMap["accessKey"] = backup.AccessKey
|
||||
varMap["secretKey"] = backup.Credential
|
||||
case constant.OneDrive:
|
||||
varMap["accessToken"] = backup.Credential
|
||||
}
|
||||
|
||||
backClient, err := cloud_storage.NewCloudStorageClient(backup.Type, varMap)
|
||||
backClient, err := cloud_storage.NewCloudStorageClient(varMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -340,53 +286,6 @@ func (u *BackupService) loadByType(accountType string, accounts []model.BackupAc
|
||||
return dto.BackupInfo{Type: accountType}
|
||||
}
|
||||
|
||||
func (u *BackupService) loadAccessToken(backup *model.BackupAccount) error {
|
||||
varMap := make(map[string]interface{})
|
||||
if err := json.Unmarshal([]byte(backup.Vars), &varMap); err != nil {
|
||||
return fmt.Errorf("unmarshal backup vars failed, err: %v", err)
|
||||
}
|
||||
|
||||
data := url.Values{}
|
||||
data.Set("client_id", global.CONF.System.OneDriveID)
|
||||
data.Set("client_secret", global.CONF.System.OneDriveSc)
|
||||
data.Set("grant_type", "authorization_code")
|
||||
data.Set("code", varMap["code"].(string))
|
||||
data.Set("redirect_uri", constant.OneDriveRedirectURI)
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest("POST", "https://login.microsoftonline.com/common/oauth2/v2.0/token", strings.NewReader(data.Encode()))
|
||||
if err != nil {
|
||||
return fmt.Errorf("new http post client for access token failed, err: %v", err)
|
||||
}
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("request for access token failed, err: %v", err)
|
||||
}
|
||||
delete(varMap, "code")
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("read data from response body failed, err: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
token := map[string]interface{}{}
|
||||
if err := json.Unmarshal(respBody, &token); err != nil {
|
||||
return fmt.Errorf("unmarshal data from response body failed, err: %v", err)
|
||||
}
|
||||
accessToken, ok := token["refresh_token"].(string)
|
||||
if !ok {
|
||||
return errors.New("no such access token in response")
|
||||
}
|
||||
|
||||
itemVars, err := json.Marshal(varMap)
|
||||
if err != nil {
|
||||
return fmt.Errorf("json marshal var map failed, err: %v", err)
|
||||
}
|
||||
backup.Credential = accessToken
|
||||
backup.Vars = string(itemVars)
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadLocalDir() (string, error) {
|
||||
backup, err := backupRepo.Get(commonRepo.WithByType("LOCAL"))
|
||||
if err != nil {
|
||||
|
||||
@@ -34,7 +34,7 @@ func (u *BackupService) AppBackup(req dto.CommonBackup) error {
|
||||
}
|
||||
timeNow := time.Now().Format("20060102150405")
|
||||
|
||||
backupDir := path.Join(localDir, fmt.Sprintf("app/%s/%s", req.Name, req.DetailName))
|
||||
backupDir := fmt.Sprintf("%s/app/%s/%s", localDir, req.Name, req.DetailName)
|
||||
|
||||
fileName := fmt.Sprintf("%s_%s.tar.gz", req.DetailName, timeNow)
|
||||
if err := handleAppBackup(&install, backupDir, fileName); err != nil {
|
||||
@@ -104,16 +104,18 @@ func handleAppBackup(install *model.AppInstall, backupDir, fileName string) erro
|
||||
return err
|
||||
}
|
||||
|
||||
resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithAppInstallId(install.ID))
|
||||
for _, resource := range resources {
|
||||
if resource.Key == "mysql" || resource.Key == "mariadb" {
|
||||
db, err := mysqlRepo.Get(commonRepo.WithByID(resource.ResourceId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := handleMysqlBackup(db.MysqlName, db.Name, tmpDir, fmt.Sprintf("%s.sql.gz", install.Name)); err != nil {
|
||||
return err
|
||||
}
|
||||
resource, _ := appInstallResourceRepo.GetFirst(appInstallResourceRepo.WithAppInstallId(install.ID))
|
||||
if resource.ID != 0 && resource.ResourceId != 0 {
|
||||
mysqlInfo, err := appInstallRepo.LoadBaseInfo(constant.AppMysql, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
db, err := mysqlRepo.Get(commonRepo.WithByID(resource.ResourceId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := handleMysqlBackup(mysqlInfo, tmpDir, db.Name, fmt.Sprintf("%s.sql.gz", install.Name)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +153,7 @@ func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback
|
||||
}
|
||||
|
||||
if !isRollback {
|
||||
rollbackFile := path.Join(global.CONF.System.TmpDir, fmt.Sprintf("app/%s_%s.tar.gz", install.Name, time.Now().Format("20060102150405")))
|
||||
rollbackFile := fmt.Sprintf("%s/original/app/%s_%s.tar.gz", global.CONF.System.BaseDir, install.Name, time.Now().Format("20060102150405"))
|
||||
if err := handleAppBackup(install, path.Dir(rollbackFile), path.Base(rollbackFile)); err != nil {
|
||||
return fmt.Errorf("backup app %s for rollback before recover failed, err: %v", install.Name, err)
|
||||
}
|
||||
@@ -171,67 +173,41 @@ func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback
|
||||
}
|
||||
|
||||
newEnvFile := ""
|
||||
resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithAppInstallId(install.ID))
|
||||
for _, resource := range resources {
|
||||
var database model.Database
|
||||
switch resource.From {
|
||||
case constant.AppResourceRemote:
|
||||
database, err = databaseRepo.Get(commonRepo.WithByID(resource.LinkId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case constant.AppResourceLocal:
|
||||
resourceApp, err := appInstallRepo.GetFirst(commonRepo.WithByID(resource.LinkId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
database, err = databaseRepo.Get(databaseRepo.WithAppInstallID(resourceApp.ID), commonRepo.WithByType(resource.Key), databaseRepo.WithByFrom(constant.AppResourceLocal), commonRepo.WithByName(resourceApp.Name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resource, _ := appInstallResourceRepo.GetFirst(appInstallResourceRepo.WithAppInstallId(install.ID))
|
||||
if resource.ID != 0 && install.App.Key != "mysql" {
|
||||
mysqlInfo, err := appInstallRepo.LoadBaseInfo(resource.Key, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
db, err := mysqlRepo.Get(commonRepo.WithByID(resource.ResourceId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if database.Type == "mysql" || database.Type == "mariadb" {
|
||||
db, err := mysqlRepo.Get(commonRepo.WithByID(resource.ResourceId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newDB, envMap, err := reCreateDB(db.ID, database, oldInstall.Env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
oldHost := fmt.Sprintf("\"PANEL_DB_HOST\":\"%v\"", envMap["PANEL_DB_HOST"].(string))
|
||||
newHost := fmt.Sprintf("\"PANEL_DB_HOST\":\"%v\"", database.Address)
|
||||
oldInstall.Env = strings.ReplaceAll(oldInstall.Env, oldHost, newHost)
|
||||
envMap["PANEL_DB_HOST"] = database.Address
|
||||
newEnvFile, err = coverEnvJsonToStr(oldInstall.Env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = appInstallResourceRepo.BatchUpdateBy(map[string]interface{}{"resource_id": newDB.ID}, commonRepo.WithByID(resource.ID))
|
||||
|
||||
if err := handleMysqlRecover(dto.CommonRecover{
|
||||
Name: newDB.MysqlName,
|
||||
DetailName: newDB.Name,
|
||||
File: fmt.Sprintf("%s/%s.sql.gz", tmpPath, install.Name),
|
||||
}, true); err != nil {
|
||||
global.LOG.Errorf("handle recover from sql.gz failed, err: %v", err)
|
||||
return err
|
||||
}
|
||||
newDB, envMap, err := reCreateDB(db.ID, oldInstall.Env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
oldHost := fmt.Sprintf("\"PANEL_DB_HOST\":\"%v\"", envMap["PANEL_DB_HOST"].(string))
|
||||
newHost := fmt.Sprintf("\"PANEL_DB_HOST\":\"%v\"", mysqlInfo.ServiceName)
|
||||
oldInstall.Env = strings.ReplaceAll(oldInstall.Env, oldHost, newHost)
|
||||
envMap["PANEL_DB_HOST"] = mysqlInfo.ServiceName
|
||||
newEnvFile, err = coverEnvJsonToStr(oldInstall.Env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = appInstallResourceRepo.BatchUpdateBy(map[string]interface{}{"resource_id": newDB.ID}, commonRepo.WithByID(resource.ID))
|
||||
|
||||
if err := handleMysqlRecover(mysqlInfo, tmpPath, newDB.Name, fmt.Sprintf("%s.sql.gz", install.Name), true); err != nil {
|
||||
global.LOG.Errorf("handle recover from sql.gz failed, err: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
appDir := install.GetPath()
|
||||
backPath := fmt.Sprintf("%s_bak", appDir)
|
||||
_ = fileOp.Rename(appDir, backPath)
|
||||
_ = fileOp.CreateDir(appDir, 0755)
|
||||
|
||||
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)
|
||||
return err
|
||||
}
|
||||
_ = fileOp.DeleteDir(backPath)
|
||||
|
||||
if len(newEnvFile) != 0 {
|
||||
envPath := fmt.Sprintf("%s/%s/%s/.env", constant.AppInstallDir, install.App.Key, install.Name)
|
||||
@@ -247,20 +223,18 @@ func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback
|
||||
oldInstall.Status = constant.StatusRunning
|
||||
oldInstall.AppId = install.AppId
|
||||
oldInstall.AppDetailId = install.AppDetailId
|
||||
oldInstall.App.ID = install.AppId
|
||||
if err := appInstallRepo.Save(context.Background(), &oldInstall); err != nil {
|
||||
global.LOG.Errorf("save db app install failed, err: %v", err)
|
||||
return err
|
||||
}
|
||||
isOk = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func reCreateDB(dbID uint, database model.Database, oldEnv string) (*model.DatabaseMysql, map[string]interface{}, error) {
|
||||
func reCreateDB(dbID uint, oldEnv string) (*model.DatabaseMysql, map[string]interface{}, error) {
|
||||
mysqlService := NewIMysqlService()
|
||||
ctx := context.Background()
|
||||
_ = mysqlService.Delete(ctx, dto.MysqlDBDelete{ID: dbID, Database: database.Name, Type: database.Type, DeleteBackup: false, ForceDelete: true})
|
||||
_ = mysqlService.Delete(ctx, dto.MysqlDBDelete{ID: dbID, DeleteBackup: true, ForceDelete: true})
|
||||
|
||||
envMap := make(map[string]interface{})
|
||||
if err := json.Unmarshal([]byte(oldEnv), &envMap); err != nil {
|
||||
@@ -271,8 +245,6 @@ func reCreateDB(dbID uint, database model.Database, oldEnv string) (*model.Datab
|
||||
oldPassword, _ := envMap["PANEL_DB_USER_PASSWORD"].(string)
|
||||
createDB, err := mysqlService.Create(context.Background(), dto.MysqlDBCreate{
|
||||
Name: oldName,
|
||||
From: database.From,
|
||||
Database: database.Name,
|
||||
Format: "utf8mb4",
|
||||
Username: oldUser,
|
||||
Password: oldPassword,
|
||||
@@ -281,5 +253,6 @@ func reCreateDB(dbID uint, database model.Database, oldEnv string) (*model.Datab
|
||||
if err != nil {
|
||||
return nil, envMap, err
|
||||
}
|
||||
|
||||
return createDB, envMap, nil
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -10,9 +12,9 @@ import (
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/mysql/client"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -21,22 +23,24 @@ func (u *BackupService) MysqlBackup(req dto.CommonBackup) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
timeNow := time.Now().Format("20060102150405")
|
||||
targetDir := path.Join(localDir, fmt.Sprintf("database/%s/%s/%s", req.Type, req.Name, req.DetailName))
|
||||
fileName := fmt.Sprintf("%s_%s.sql.gz", req.DetailName, timeNow)
|
||||
|
||||
if err := handleMysqlBackup(req.Name, req.DetailName, targetDir, fileName); err != nil {
|
||||
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
timeNow := time.Now().Format("20060102150405")
|
||||
backupDir := fmt.Sprintf("%s/database/mysql/%s/%s", localDir, req.Name, req.DetailName)
|
||||
fileName := fmt.Sprintf("%s_%s.sql.gz", req.DetailName, timeNow)
|
||||
if err := handleMysqlBackup(app, backupDir, req.DetailName, fileName); err != nil {
|
||||
return err
|
||||
}
|
||||
record := &model.BackupRecord{
|
||||
Type: req.Type,
|
||||
Name: req.Name,
|
||||
Type: "mysql",
|
||||
Name: app.Name,
|
||||
DetailName: req.DetailName,
|
||||
Source: "LOCAL",
|
||||
BackupType: "LOCAL",
|
||||
FileDir: targetDir,
|
||||
FileDir: backupDir,
|
||||
FileName: fileName,
|
||||
}
|
||||
if err := backupRepo.CreateRecord(record); err != nil {
|
||||
@@ -46,13 +50,26 @@ func (u *BackupService) MysqlBackup(req dto.CommonBackup) error {
|
||||
}
|
||||
|
||||
func (u *BackupService) MysqlRecover(req dto.CommonRecover) error {
|
||||
if err := handleMysqlRecover(req, false); err != nil {
|
||||
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fileOp := files.NewFileOp()
|
||||
if !fileOp.Stat(req.File) {
|
||||
return errors.New(fmt.Sprintf("%s file is not exist", req.File))
|
||||
}
|
||||
global.LOG.Infof("recover database %s-%s from backup file %s", req.Name, req.DetailName, req.File)
|
||||
if err := handleMysqlRecover(app, path.Dir(req.File), req.DetailName, path.Base(req.File), false); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *BackupService) MysqlRecoverByUpload(req dto.CommonRecover) error {
|
||||
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
file := req.File
|
||||
fileName := path.Base(req.File)
|
||||
if strings.HasSuffix(fileName, ".tar.gz") {
|
||||
@@ -89,92 +106,77 @@ func (u *BackupService) MysqlRecoverByUpload(req dto.CommonRecover) error {
|
||||
}()
|
||||
}
|
||||
|
||||
req.File = path.Dir(file) + "/" + fileName
|
||||
if err := handleMysqlRecover(req, false); err != nil {
|
||||
if err := handleMysqlRecover(app, path.Dir(file), req.DetailName, fileName, false); err != nil {
|
||||
return err
|
||||
}
|
||||
global.LOG.Info("recover from uploads successful!")
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleMysqlBackup(database, dbName, targetDir, fileName string) error {
|
||||
dbInfo, err := mysqlRepo.Get(commonRepo.WithByName(dbName), mysqlRepo.WithByMysqlName(database))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cli, _, err := LoadMysqlClientByFrom(database)
|
||||
if err != nil {
|
||||
return err
|
||||
func handleMysqlBackup(app *repo.RootInfo, backupDir, dbName, fileName string) error {
|
||||
fileOp := files.NewFileOp()
|
||||
if !fileOp.Stat(backupDir) {
|
||||
if err := os.MkdirAll(backupDir, os.ModePerm); err != nil {
|
||||
return fmt.Errorf("mkdir %s failed, err: %v", backupDir, err)
|
||||
}
|
||||
}
|
||||
outfile, _ := os.OpenFile(backupDir+"/"+fileName, os.O_RDWR|os.O_CREATE, 0755)
|
||||
global.LOG.Infof("start to mysqldump | gzip > %s.gzip", backupDir+"/"+fileName)
|
||||
cmd := exec.Command("docker", "exec", app.ContainerName, "mysqldump", "-uroot", "-p"+app.Password, dbName)
|
||||
gzipCmd := exec.Command("gzip", "-cf")
|
||||
gzipCmd.Stdin, _ = cmd.StdoutPipe()
|
||||
gzipCmd.Stdout = outfile
|
||||
_ = gzipCmd.Start()
|
||||
_ = cmd.Run()
|
||||
_ = gzipCmd.Wait()
|
||||
|
||||
backupInfo := client.BackupInfo{
|
||||
Name: dbName,
|
||||
Format: dbInfo.Format,
|
||||
TargetDir: targetDir,
|
||||
FileName: fileName,
|
||||
|
||||
Timeout: 300,
|
||||
}
|
||||
if err := cli.Backup(backupInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleMysqlRecover(req dto.CommonRecover, isRollback bool) error {
|
||||
func handleMysqlRecover(mysqlInfo *repo.RootInfo, recoverDir, dbName, fileName string, isRollback bool) error {
|
||||
isOk := false
|
||||
fileOp := files.NewFileOp()
|
||||
if !fileOp.Stat(req.File) {
|
||||
return errors.New(fmt.Sprintf("%s file is not exist", req.File))
|
||||
}
|
||||
dbInfo, err := mysqlRepo.Get(commonRepo.WithByName(req.DetailName), mysqlRepo.WithByMysqlName(req.Name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cli, _, err := LoadMysqlClientByFrom(req.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !isRollback {
|
||||
rollbackFile := path.Join(global.CONF.System.TmpDir, fmt.Sprintf("database/%s/%s_%s.sql.gz", req.Type, req.DetailName, time.Now().Format("20060102150405")))
|
||||
if err := cli.Backup(client.BackupInfo{
|
||||
Name: req.DetailName,
|
||||
Format: dbInfo.Format,
|
||||
TargetDir: path.Dir(rollbackFile),
|
||||
FileName: path.Base(rollbackFile),
|
||||
|
||||
Timeout: 300,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("backup mysql db %s for rollback before recover failed, err: %v", req.DetailName, err)
|
||||
rollbackFile := fmt.Sprintf("%s/original/database/%s_%s.sql.gz", global.CONF.System.BaseDir, mysqlInfo.Name, time.Now().Format("20060102150405"))
|
||||
if err := handleMysqlBackup(mysqlInfo, path.Dir(rollbackFile), dbName, path.Base(rollbackFile)); err != nil {
|
||||
return fmt.Errorf("backup mysql db %s for rollback before recover failed, err: %v", mysqlInfo.Name, err)
|
||||
}
|
||||
defer func() {
|
||||
if !isOk {
|
||||
global.LOG.Info("recover failed, start to rollback now")
|
||||
if err := cli.Recover(client.RecoverInfo{
|
||||
Name: req.DetailName,
|
||||
Format: dbInfo.Format,
|
||||
SourceFile: rollbackFile,
|
||||
|
||||
Timeout: 300,
|
||||
}); err != nil {
|
||||
global.LOG.Errorf("rollback mysql db %s from %s failed, err: %v", req.DetailName, rollbackFile, err)
|
||||
if err := handleMysqlRecover(mysqlInfo, path.Dir(rollbackFile), dbName, path.Base(rollbackFile), true); err != nil {
|
||||
global.LOG.Errorf("rollback mysql db %s from %s failed, err: %v", dbName, rollbackFile, err)
|
||||
return
|
||||
}
|
||||
global.LOG.Infof("rollback mysql db %s from %s successful", req.DetailName, rollbackFile)
|
||||
global.LOG.Infof("rollback mysql db %s from %s successful", dbName, rollbackFile)
|
||||
_ = os.RemoveAll(rollbackFile)
|
||||
} else {
|
||||
_ = os.RemoveAll(rollbackFile)
|
||||
}
|
||||
}()
|
||||
}
|
||||
if err := cli.Recover(client.RecoverInfo{
|
||||
Name: req.DetailName,
|
||||
Format: dbInfo.Format,
|
||||
SourceFile: req.File,
|
||||
|
||||
Timeout: 300,
|
||||
}); err != nil {
|
||||
return err
|
||||
file := recoverDir + "/" + fileName
|
||||
fi, _ := os.Open(file)
|
||||
defer fi.Close()
|
||||
cmd := exec.Command("docker", "exec", "-i", mysqlInfo.ContainerName, "mysql", "-uroot", "-p"+mysqlInfo.Password, dbName)
|
||||
if strings.HasSuffix(fileName, ".gz") {
|
||||
gzipFile, err := os.Open(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer gzipFile.Close()
|
||||
gzipReader, err := gzip.NewReader(gzipFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer gzipReader.Close()
|
||||
cmd.Stdin = gzipReader
|
||||
} else {
|
||||
cmd.Stdin = fi
|
||||
}
|
||||
stdout, err := cmd.CombinedOutput()
|
||||
stdStr := strings.ReplaceAll(string(stdout), "mysql: [Warning] Using a password on the command line interface can be insecure.\n", "")
|
||||
if err != nil || strings.HasPrefix(string(stdStr), "ERROR ") {
|
||||
return errors.New(stdStr)
|
||||
}
|
||||
isOk = true
|
||||
return nil
|
||||
|
||||
@@ -43,7 +43,7 @@ func (u *BackupService) RedisBackup() error {
|
||||
fileName = fmt.Sprintf("%s.tar.gz", timeNow)
|
||||
}
|
||||
}
|
||||
backupDir := path.Join(localDir, fmt.Sprintf("database/redis/%s", redisInfo.Name))
|
||||
backupDir := fmt.Sprintf("%s/database/redis/%s", localDir, redisInfo.Name)
|
||||
if err := handleRedisBackup(redisInfo, backupDir, fileName); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -143,7 +143,7 @@ func handleRedisRecover(redisInfo *repo.RootInfo, recoverFile string, isRollback
|
||||
suffix = "tar.gz"
|
||||
}
|
||||
}
|
||||
rollbackFile := path.Join(global.CONF.System.TmpDir, fmt.Sprintf("database/redis/%s_%s.%s", redisInfo.Name, time.Now().Format("20060102150405"), suffix))
|
||||
rollbackFile := fmt.Sprintf("%s/original/database/redis/%s_%s.%s", global.CONF.System.BaseDir, redisInfo.Name, time.Now().Format("20060102150405"), suffix)
|
||||
if err := handleRedisBackup(redisInfo, path.Dir(rollbackFile), path.Base(rollbackFile)); err != nil {
|
||||
return fmt.Errorf("backup database %s for rollback before recover failed, err: %v", redisInfo.Name, err)
|
||||
}
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func handleRuntimeBackup(runtime *model.Runtime, backupDir, fileName string) error {
|
||||
fileOp := files.NewFileOp()
|
||||
tmpDir := fmt.Sprintf("%s/%s", backupDir, strings.ReplaceAll(fileName, ".tar.gz", ""))
|
||||
if !fileOp.Stat(tmpDir) {
|
||||
if err := os.MkdirAll(tmpDir, os.ModePerm); err != nil {
|
||||
return fmt.Errorf("mkdir %s failed, err: %v", backupDir, err)
|
||||
}
|
||||
}
|
||||
defer func() {
|
||||
_ = os.RemoveAll(tmpDir)
|
||||
}()
|
||||
|
||||
remarkInfo, _ := json.Marshal(runtime)
|
||||
remarkInfoPath := fmt.Sprintf("%s/runtime.json", tmpDir)
|
||||
if err := fileOp.SaveFile(remarkInfoPath, string(remarkInfo), fs.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
appPath := runtime.GetPath()
|
||||
if err := handleTar(appPath, tmpDir, "runtime.tar.gz", ""); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := handleTar(tmpDir, backupDir, fileName, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleRuntimeRecover(runtime *model.Runtime, recoverFile string, isRollback bool) error {
|
||||
isOk := false
|
||||
fileOp := files.NewFileOp()
|
||||
if err := handleUnTar(recoverFile, path.Dir(recoverFile)); err != nil {
|
||||
return err
|
||||
}
|
||||
tmpPath := strings.ReplaceAll(recoverFile, ".tar.gz", "")
|
||||
defer func() {
|
||||
go startRuntime(runtime)
|
||||
_ = os.RemoveAll(strings.ReplaceAll(recoverFile, ".tar.gz", ""))
|
||||
}()
|
||||
|
||||
if !fileOp.Stat(tmpPath+"/runtime.json") || !fileOp.Stat(tmpPath+"/runtime.tar.gz") {
|
||||
return errors.New("the wrong recovery package does not have runtime.json or runtime.tar.gz files")
|
||||
}
|
||||
var oldRuntime model.Runtime
|
||||
runtimeJson, err := os.ReadFile(tmpPath + "/runtime.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(runtimeJson, &oldRuntime); err != nil {
|
||||
return fmt.Errorf("unmarshal runtime.json failed, err: %v", err)
|
||||
}
|
||||
if oldRuntime.Type != runtime.Type || oldRuntime.Name != runtime.Name {
|
||||
return errors.New("the current backup file does not match the application")
|
||||
}
|
||||
|
||||
if !isRollback {
|
||||
rollbackFile := path.Join(global.CONF.System.TmpDir, fmt.Sprintf("runtime/%s_%s.tar.gz", runtime.Name, time.Now().Format("20060102150405")))
|
||||
if err := handleRuntimeBackup(runtime, path.Dir(rollbackFile), path.Base(rollbackFile)); err != nil {
|
||||
return fmt.Errorf("backup runtime %s for rollback before recover failed, err: %v", runtime.Name, err)
|
||||
}
|
||||
defer func() {
|
||||
if !isOk {
|
||||
global.LOG.Info("recover failed, start to rollback now")
|
||||
if err := handleRuntimeRecover(runtime, rollbackFile, true); err != nil {
|
||||
global.LOG.Errorf("rollback runtime %s from %s failed, err: %v", runtime.Name, rollbackFile, err)
|
||||
return
|
||||
}
|
||||
global.LOG.Infof("rollback runtime %s from %s successful", runtime.Name, rollbackFile)
|
||||
_ = os.RemoveAll(rollbackFile)
|
||||
} else {
|
||||
_ = os.RemoveAll(rollbackFile)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
newEnvFile, err := coverEnvJsonToStr(runtime.Env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
runtimeDir := runtime.GetPath()
|
||||
backPath := fmt.Sprintf("%s_bak", runtimeDir)
|
||||
_ = fileOp.Rename(runtimeDir, backPath)
|
||||
_ = fileOp.CreateDir(runtimeDir, 0755)
|
||||
|
||||
if err := handleUnTar(tmpPath+"/runtime.tar.gz", fmt.Sprintf("%s/%s", constant.RuntimeDir, runtime.Type)); err != nil {
|
||||
global.LOG.Errorf("handle recover from runtime.tar.gz failed, err: %v", err)
|
||||
_ = fileOp.DeleteDir(runtimeDir)
|
||||
_ = fileOp.Rename(backPath, runtimeDir)
|
||||
return err
|
||||
}
|
||||
_ = fileOp.DeleteDir(backPath)
|
||||
|
||||
if len(newEnvFile) != 0 {
|
||||
envPath := fmt.Sprintf("%s/%s/%s/.env", constant.RuntimeDir, runtime.Type, runtime.Name)
|
||||
file, err := os.OpenFile(envPath, os.O_WRONLY|os.O_TRUNC, 0640)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
_, _ = file.WriteString(newEnvFile)
|
||||
}
|
||||
|
||||
oldRuntime.ID = runtime.ID
|
||||
oldRuntime.Status = constant.RuntimeStarting
|
||||
if err := runtimeRepo.Save(&oldRuntime); err != nil {
|
||||
global.LOG.Errorf("save db app install failed, err: %v", err)
|
||||
return err
|
||||
}
|
||||
isOk = true
|
||||
return nil
|
||||
}
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"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/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||
@@ -31,7 +30,7 @@ func (u *BackupService) WebsiteBackup(req dto.CommonBackup) error {
|
||||
}
|
||||
|
||||
timeNow := time.Now().Format("20060102150405")
|
||||
backupDir := path.Join(localDir, fmt.Sprintf("website/%s", req.Name))
|
||||
backupDir := fmt.Sprintf("%s/website/%s", localDir, req.Name)
|
||||
fileName := fmt.Sprintf("%s_%s.tar.gz", website.PrimaryDomain, timeNow)
|
||||
if err := handleWebsiteBackup(&website, backupDir, fileName); err != nil {
|
||||
return err
|
||||
@@ -81,11 +80,11 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
|
||||
|
||||
temPathWithName := tmpPath + "/" + website.Alias
|
||||
if !fileOp.Stat(tmpPath+"/website.json") || !fileOp.Stat(temPathWithName+".conf") || !fileOp.Stat(temPathWithName+".web.tar.gz") {
|
||||
return buserr.WithDetail(constant.ErrBackupExist, ".conf or .web.tar.gz", nil)
|
||||
return errors.New("the wrong recovery package does not have .conf or .web.tar.gz files")
|
||||
}
|
||||
if website.Type == constant.Deployment {
|
||||
if !fileOp.Stat(temPathWithName + ".app.tar.gz") {
|
||||
return buserr.WithDetail(constant.ErrBackupExist, ".app.tar.gz", nil)
|
||||
return errors.New("the wrong recovery package does not have .app.tar.gz files")
|
||||
}
|
||||
}
|
||||
var oldWebsite model.Website
|
||||
@@ -96,14 +95,13 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
|
||||
if err := json.Unmarshal(websiteJson, &oldWebsite); err != nil {
|
||||
return fmt.Errorf("unmarshal app.json failed, err: %v", err)
|
||||
}
|
||||
|
||||
if err := checkValidOfWebsite(&oldWebsite, website); err != nil {
|
||||
return err
|
||||
if oldWebsite.Alias != website.Alias || oldWebsite.Type != website.Type || oldWebsite.ID != website.ID {
|
||||
return errors.New("the current backup file does not match the application")
|
||||
}
|
||||
|
||||
isOk := false
|
||||
if !isRollback {
|
||||
rollbackFile := path.Join(global.CONF.System.TmpDir, fmt.Sprintf("website/%s_%s.tar.gz", website.Alias, time.Now().Format("20060102150405")))
|
||||
rollbackFile := fmt.Sprintf("%s/original/website/%s_%s.tar.gz", global.CONF.System.BaseDir, website.Alias, time.Now().Format("20060102150405"))
|
||||
if err := handleWebsiteBackup(website, path.Dir(rollbackFile), path.Base(rollbackFile)); err != nil {
|
||||
return fmt.Errorf("backup website %s for rollback before recover failed, err: %v", website.Alias, err)
|
||||
}
|
||||
@@ -132,8 +130,7 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
|
||||
return err
|
||||
}
|
||||
|
||||
switch website.Type {
|
||||
case constant.Deployment:
|
||||
if website.Type == constant.Deployment {
|
||||
app, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -146,19 +143,7 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
|
||||
global.LOG.Errorf("docker-compose restart failed, err: %v", err)
|
||||
return err
|
||||
}
|
||||
case constant.Runtime:
|
||||
runtime, err := runtimeRepo.GetFirst(commonRepo.WithByID(website.RuntimeID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if runtime.Type == constant.RuntimeNode {
|
||||
if err := handleRuntimeRecover(runtime, fmt.Sprintf("%s/%s.runtime.tar.gz", tmpPath, website.Alias), true); err != nil {
|
||||
return err
|
||||
}
|
||||
global.LOG.Info("put runtime.tar.gz into tmp dir successful")
|
||||
}
|
||||
}
|
||||
|
||||
siteDir := fmt.Sprintf("%s/openresty/%s/www/sites", constant.AppInstallDir, nginxInfo.Name)
|
||||
if err := handleUnTar(fmt.Sprintf("%s/%s.web.tar.gz", tmpPath, website.Alias), siteDir); err != nil {
|
||||
global.LOG.Errorf("handle recover from web.tar.gz failed, err: %v", err)
|
||||
@@ -170,7 +155,6 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
|
||||
return errors.New(string(stdout))
|
||||
}
|
||||
|
||||
oldWebsite.ID = website.ID
|
||||
if err := websiteRepo.SaveWithoutCtx(&oldWebsite); err != nil {
|
||||
global.LOG.Errorf("handle save website data failed, err: %v", err)
|
||||
return err
|
||||
@@ -207,8 +191,7 @@ func handleWebsiteBackup(website *model.Website, backupDir, fileName string) err
|
||||
}
|
||||
global.LOG.Info("put openresty conf into tmp dir successful")
|
||||
|
||||
switch website.Type {
|
||||
case constant.Deployment:
|
||||
if website.Type == constant.Deployment {
|
||||
app, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -217,19 +200,7 @@ func handleWebsiteBackup(website *model.Website, backupDir, fileName string) err
|
||||
return err
|
||||
}
|
||||
global.LOG.Info("put app.tar.gz into tmp dir successful")
|
||||
case constant.Runtime:
|
||||
runtime, err := runtimeRepo.GetFirst(commonRepo.WithByID(website.RuntimeID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if runtime.Type == constant.RuntimeNode {
|
||||
if err := handleRuntimeBackup(runtime, tmpDir, fmt.Sprintf("%s.runtime.tar.gz", website.Alias)); err != nil {
|
||||
return err
|
||||
}
|
||||
global.LOG.Info("put runtime.tar.gz into tmp dir successful")
|
||||
}
|
||||
}
|
||||
|
||||
websiteDir := fmt.Sprintf("%s/openresty/%s/www/sites/%s", constant.AppInstallDir, nginxInfo.Name, website.Alias)
|
||||
if err := handleTar(websiteDir, tmpDir, fmt.Sprintf("%s.web.tar.gz", website.Alias), ""); err != nil {
|
||||
return err
|
||||
@@ -241,26 +212,3 @@ func handleWebsiteBackup(website *model.Website, backupDir, fileName string) err
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkValidOfWebsite(oldWebsite, website *model.Website) error {
|
||||
if oldWebsite.Alias != website.Alias || oldWebsite.Type != website.Type {
|
||||
return buserr.WithDetail(constant.ErrBackupMatch, fmt.Sprintf("oldName: %s, oldType: %v", oldWebsite.Alias, oldWebsite.Type), nil)
|
||||
}
|
||||
if oldWebsite.AppInstallID != 0 {
|
||||
_, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
||||
if err != nil {
|
||||
return buserr.WithDetail(constant.ErrBackupMatch, "app", nil)
|
||||
}
|
||||
}
|
||||
if oldWebsite.RuntimeID != 0 {
|
||||
if _, err := runtimeRepo.GetFirst(commonRepo.WithByID(website.RuntimeID)); err != nil {
|
||||
return buserr.WithDetail(constant.ErrBackupMatch, "runtime", nil)
|
||||
}
|
||||
}
|
||||
if oldWebsite.WebsiteSSLID != 0 {
|
||||
if _, err := websiteSSLRepo.GetFirst(commonRepo.WithByID(website.WebsiteSSLID)); err != nil {
|
||||
return buserr.WithDetail(constant.ErrBackupMatch, "ssl", nil)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
+114
-609
@@ -3,12 +3,11 @@ package service
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -19,7 +18,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/cmd"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/docker"
|
||||
"github.com/docker/docker/api/types"
|
||||
@@ -28,34 +26,24 @@ import (
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/gorilla/websocket"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/shirou/gopsutil/v3/cpu"
|
||||
"github.com/shirou/gopsutil/v3/mem"
|
||||
)
|
||||
|
||||
type ContainerService struct{}
|
||||
|
||||
type IContainerService interface {
|
||||
Page(req dto.PageContainer) (int64, interface{}, error)
|
||||
List() ([]string, error)
|
||||
PageNetwork(req dto.SearchWithPage) (int64, interface{}, error)
|
||||
ListNetwork() ([]dto.Options, error)
|
||||
PageVolume(req dto.SearchWithPage) (int64, interface{}, error)
|
||||
ListVolume() ([]dto.Options, error)
|
||||
PageCompose(req dto.SearchWithPage) (int64, interface{}, error)
|
||||
CreateCompose(req dto.ComposeCreate) (string, error)
|
||||
ComposeOperation(req dto.ComposeOperation) error
|
||||
ContainerCreate(req dto.ContainerOperate) error
|
||||
ContainerUpdate(req dto.ContainerOperate) error
|
||||
ContainerUpgrade(req dto.ContainerUpgrade) error
|
||||
ContainerInfo(req dto.OperationWithName) (*dto.ContainerOperate, error)
|
||||
ContainerListStats() ([]dto.ContainerListStats, error)
|
||||
LoadResourceLimit() (*dto.ResourceLimit, error)
|
||||
ContainerCreate(req dto.ContainerCreate) error
|
||||
ContainerLogClean(req dto.OperationWithName) error
|
||||
ContainerOperation(req dto.ContainerOperation) error
|
||||
ContainerLogs(wsConn *websocket.Conn, container, since, tail string, follow bool) error
|
||||
ContainerStats(id string) (*dto.ContainerStats, error)
|
||||
ContainerLogs(param dto.ContainerLog) (string, error)
|
||||
ContainerStats(id string) (*dto.ContainterStats, error)
|
||||
Inspect(req dto.InspectReq) (string, error)
|
||||
DeleteNetwork(req dto.BatchDelete) error
|
||||
CreateNetwork(req dto.NetworkCreate) error
|
||||
@@ -64,9 +52,6 @@ type IContainerService interface {
|
||||
TestCompose(req dto.ComposeCreate) (bool, error)
|
||||
ComposeUpdate(req dto.ComposeUpdate) error
|
||||
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 {
|
||||
@@ -75,8 +60,9 @@ func NewIContainerService() IContainerService {
|
||||
|
||||
func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, error) {
|
||||
var (
|
||||
records []types.Container
|
||||
list []types.Container
|
||||
records []types.Container
|
||||
list []types.Container
|
||||
backDatas []dto.ContainerInfo
|
||||
)
|
||||
client, err := docker.NewDockerClient()
|
||||
if err != nil {
|
||||
@@ -102,30 +88,9 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
|
||||
}
|
||||
}
|
||||
}
|
||||
switch req.OrderBy {
|
||||
case "name":
|
||||
sort.Slice(list, func(i, j int) bool {
|
||||
if req.Order == constant.OrderAsc {
|
||||
return list[i].Names[0][1:] < list[j].Names[0][1:]
|
||||
}
|
||||
return list[i].Names[0][1:] > list[j].Names[0][1:]
|
||||
})
|
||||
case "state":
|
||||
sort.Slice(list, func(i, j int) bool {
|
||||
if req.Order == constant.OrderAsc {
|
||||
return list[i].State < list[j].State
|
||||
}
|
||||
return list[i].State > list[j].State
|
||||
})
|
||||
default:
|
||||
sort.Slice(list, func(i, j int) bool {
|
||||
if req.Order == constant.OrderAsc {
|
||||
return list[i].Created < list[j].Created
|
||||
}
|
||||
return list[i].Created > list[j].Created
|
||||
})
|
||||
}
|
||||
|
||||
sort.Slice(list, func(i, j int) bool {
|
||||
return list[i].Created > list[j].Created
|
||||
})
|
||||
total, start, end := len(list), (req.Page-1)*req.PageSize, req.Page*req.PageSize
|
||||
if start > total {
|
||||
records = make([]types.Container, 0)
|
||||
@@ -136,85 +101,47 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
|
||||
records = list[start:end]
|
||||
}
|
||||
|
||||
backDatas := make([]dto.ContainerInfo, len(records))
|
||||
for i := 0; i < len(records); i++ {
|
||||
item := records[i]
|
||||
IsFromCompose := false
|
||||
if _, ok := item.Labels[composeProjectLabel]; ok {
|
||||
IsFromCompose = true
|
||||
}
|
||||
IsFromApp := false
|
||||
if created, ok := item.Labels[composeCreatedBy]; ok && created == "Apps" {
|
||||
IsFromApp = true
|
||||
}
|
||||
|
||||
ports := simplifyPort(item.Ports)
|
||||
backDatas[i] = dto.ContainerInfo{
|
||||
ContainerID: item.ID,
|
||||
CreateTime: time.Unix(item.Created, 0).Format("2006-01-02 15:04:05"),
|
||||
Name: item.Names[0][1:],
|
||||
ImageId: strings.Split(item.ImageID, ":")[1],
|
||||
ImageName: item.Image,
|
||||
State: item.State,
|
||||
RunTime: item.Status,
|
||||
Ports: ports,
|
||||
IsFromApp: IsFromApp,
|
||||
IsFromCompose: IsFromCompose,
|
||||
}
|
||||
if item.NetworkSettings != nil && len(item.NetworkSettings.Networks) > 0 {
|
||||
networks := make([]string, 0, len(item.NetworkSettings.Networks))
|
||||
for key := range item.NetworkSettings.Networks {
|
||||
networks = append(networks, item.NetworkSettings.Networks[key].IPAddress)
|
||||
}
|
||||
sort.Strings(networks)
|
||||
backDatas[i].Network = networks
|
||||
}
|
||||
}
|
||||
|
||||
return int64(total), backDatas, nil
|
||||
}
|
||||
|
||||
func (u *ContainerService) List() ([]string, error) {
|
||||
client, err := docker.NewDockerClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
containers, err := client.ContainerList(context.Background(), types.ContainerListOptions{All: true})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var datas []string
|
||||
for _, container := range containers {
|
||||
for _, name := range container.Names {
|
||||
if len(name) != 0 {
|
||||
datas = append(datas, strings.TrimPrefix(name, "/"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return datas, nil
|
||||
}
|
||||
|
||||
func (u *ContainerService) ContainerListStats() ([]dto.ContainerListStats, error) {
|
||||
client, err := docker.NewDockerClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
list, err := client.ContainerList(context.Background(), types.ContainerListOptions{All: true})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var datas []dto.ContainerListStats
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(list))
|
||||
for i := 0; i < len(list); i++ {
|
||||
wg.Add(len(records))
|
||||
for _, container := range records {
|
||||
go func(item types.Container) {
|
||||
datas = append(datas, loadCpuAndMem(client, item.ID))
|
||||
IsFromCompose := false
|
||||
if _, ok := item.Labels[composeProjectLabel]; ok {
|
||||
IsFromCompose = true
|
||||
}
|
||||
IsFromApp := false
|
||||
if created, ok := item.Labels[composeCreatedBy]; ok && created == "Apps" {
|
||||
IsFromApp = true
|
||||
}
|
||||
|
||||
var ports []string
|
||||
for _, port := range item.Ports {
|
||||
if port.IP == "::" || port.PublicPort == 0 {
|
||||
continue
|
||||
}
|
||||
ports = append(ports, fmt.Sprintf("%v:%v/%s", port.PublicPort, port.PrivatePort, port.Type))
|
||||
}
|
||||
cpu, mem := loadCpuAndMem(client, item.ID)
|
||||
backDatas = append(backDatas, dto.ContainerInfo{
|
||||
ContainerID: item.ID,
|
||||
CreateTime: time.Unix(item.Created, 0).Format("2006-01-02 15:04:05"),
|
||||
Name: item.Names[0][1:],
|
||||
ImageId: strings.Split(item.ImageID, ":")[1],
|
||||
ImageName: item.Image,
|
||||
State: item.State,
|
||||
RunTime: item.Status,
|
||||
CPUPercent: cpu,
|
||||
MemoryPercent: mem,
|
||||
Ports: ports,
|
||||
IsFromApp: IsFromApp,
|
||||
IsFromCompose: IsFromCompose,
|
||||
})
|
||||
wg.Done()
|
||||
}(list[i])
|
||||
}(container)
|
||||
}
|
||||
wg.Wait()
|
||||
return datas, nil
|
||||
|
||||
return int64(total), backDatas, nil
|
||||
}
|
||||
|
||||
func (u *ContainerService) Inspect(req dto.InspectReq) (string, error) {
|
||||
@@ -226,8 +153,6 @@ func (u *ContainerService) Inspect(req dto.InspectReq) (string, error) {
|
||||
switch req.Type {
|
||||
case "container":
|
||||
inspectInfo, err = client.ContainerInspect(context.Background(), req.ID)
|
||||
case "image":
|
||||
inspectInfo, _, err = client.ImageInspectWithRaw(context.Background(), req.ID)
|
||||
case "network":
|
||||
inspectInfo, err = client.NetworkInspect(context.TODO(), req.ID, types.NetworkInspectOptions{})
|
||||
case "volume":
|
||||
@@ -288,58 +213,63 @@ func (u *ContainerService) Prune(req dto.ContainerPrune) (dto.ContainerPruneRepo
|
||||
return report, nil
|
||||
}
|
||||
|
||||
func (u *ContainerService) LoadResourceLimit() (*dto.ResourceLimit, error) {
|
||||
cpuCounts, err := cpu.Counts(true)
|
||||
func (u *ContainerService) ContainerCreate(req dto.ContainerCreate) error {
|
||||
portMap, err := checkPortStats(req.ExposedPorts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load cpu limit failed, err: %v", err)
|
||||
return err
|
||||
}
|
||||
memoryInfo, err := mem.VirtualMemory()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load memory limit failed, err: %v", err)
|
||||
}
|
||||
|
||||
data := dto.ResourceLimit{
|
||||
CPU: cpuCounts,
|
||||
Memory: int(memoryInfo.Total),
|
||||
}
|
||||
return &data, nil
|
||||
}
|
||||
|
||||
func (u *ContainerService) ContainerCreate(req dto.ContainerOperate) error {
|
||||
client, err := docker.NewDockerClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx := context.Background()
|
||||
newContainer, _ := client.ContainerInspect(ctx, req.Name)
|
||||
if newContainer.ContainerJSONBase != nil {
|
||||
return buserr.New(constant.ErrContainerName)
|
||||
}
|
||||
|
||||
if !checkImageExist(client, req.Image) || req.ForcePull {
|
||||
if err := pullImages(ctx, client, req.Image); err != nil {
|
||||
if !req.ForcePull {
|
||||
return err
|
||||
}
|
||||
global.LOG.Errorf("force pull image %s failed, err: %v", req.Image, err)
|
||||
exposeds := make(nat.PortSet)
|
||||
for port := range portMap {
|
||||
exposeds[port] = struct{}{}
|
||||
}
|
||||
config := &container.Config{
|
||||
Image: req.Image,
|
||||
Cmd: req.Cmd,
|
||||
Env: req.Env,
|
||||
Labels: stringsToMap(req.Labels),
|
||||
Tty: true,
|
||||
OpenStdin: true,
|
||||
ExposedPorts: exposeds,
|
||||
}
|
||||
hostConf := &container.HostConfig{
|
||||
AutoRemove: req.AutoRemove,
|
||||
PublishAllPorts: req.PublishAllPorts,
|
||||
RestartPolicy: container.RestartPolicy{Name: req.RestartPolicy},
|
||||
}
|
||||
if req.RestartPolicy == "on-failure" {
|
||||
hostConf.RestartPolicy.MaximumRetryCount = 5
|
||||
}
|
||||
if req.NanoCPUs != 0 {
|
||||
hostConf.NanoCPUs = req.NanoCPUs * 1000000000
|
||||
}
|
||||
if req.Memory != 0 {
|
||||
hostConf.Memory = req.Memory
|
||||
}
|
||||
if len(req.ExposedPorts) != 0 {
|
||||
hostConf.PortBindings = portMap
|
||||
}
|
||||
if len(req.Volumes) != 0 {
|
||||
config.Volumes = make(map[string]struct{})
|
||||
for _, volume := range req.Volumes {
|
||||
config.Volumes[volume.ContainerDir] = struct{}{}
|
||||
hostConf.Binds = append(hostConf.Binds, fmt.Sprintf("%s:%s:%s", volume.SourceDir, volume.ContainerDir, volume.Mode))
|
||||
}
|
||||
}
|
||||
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)
|
||||
|
||||
ctx := context.Background()
|
||||
if !checkImageExist(client, req.Image) {
|
||||
if err := pullImages(ctx, client, req.Image); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
container, err := client.ContainerCreate(ctx, config, hostConf, &network.NetworkingConfig{}, &v1.Platform{}, req.Name)
|
||||
if err != nil {
|
||||
_ = client.ContainerRemove(ctx, req.Name, types.ContainerRemoveOptions{RemoveVolumes: true, Force: true})
|
||||
return err
|
||||
@@ -352,157 +282,6 @@ func (u *ContainerService) ContainerCreate(req dto.ContainerOperate) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *ContainerService) ContainerInfo(req dto.OperationWithName) (*dto.ContainerOperate, error) {
|
||||
client, err := docker.NewDockerClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx := context.Background()
|
||||
oldContainer, err := client.ContainerInspect(ctx, req.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var data dto.ContainerOperate
|
||||
data.ContainerID = oldContainer.ID
|
||||
data.Name = strings.ReplaceAll(oldContainer.Name, "/", "")
|
||||
data.Image = oldContainer.Config.Image
|
||||
if oldContainer.NetworkSettings != nil {
|
||||
for network := range oldContainer.NetworkSettings.Networks {
|
||||
data.Network = network
|
||||
break
|
||||
}
|
||||
}
|
||||
data.Cmd = oldContainer.Config.Cmd
|
||||
data.OpenStdin = oldContainer.Config.OpenStdin
|
||||
data.Tty = oldContainer.Config.Tty
|
||||
data.Entrypoint = oldContainer.Config.Entrypoint
|
||||
data.Env = oldContainer.Config.Env
|
||||
data.CPUShares = oldContainer.HostConfig.CPUShares
|
||||
for key, val := range oldContainer.Config.Labels {
|
||||
data.Labels = append(data.Labels, fmt.Sprintf("%s=%s", key, val))
|
||||
}
|
||||
for key, val := range oldContainer.HostConfig.PortBindings {
|
||||
var itemPort dto.PortHelper
|
||||
if !strings.Contains(string(key), "/") {
|
||||
continue
|
||||
}
|
||||
itemPort.ContainerPort = strings.Split(string(key), "/")[0]
|
||||
itemPort.Protocol = strings.Split(string(key), "/")[1]
|
||||
for _, binds := range val {
|
||||
itemPort.HostIP = binds.HostIP
|
||||
itemPort.HostPort = binds.HostPort
|
||||
data.ExposedPorts = append(data.ExposedPorts, itemPort)
|
||||
}
|
||||
}
|
||||
data.AutoRemove = oldContainer.HostConfig.AutoRemove
|
||||
data.PublishAllPorts = oldContainer.HostConfig.PublishAllPorts
|
||||
data.RestartPolicy = oldContainer.HostConfig.RestartPolicy.Name
|
||||
if oldContainer.HostConfig.NanoCPUs != 0 {
|
||||
data.NanoCPUs = float64(oldContainer.HostConfig.NanoCPUs) / 1000000000
|
||||
}
|
||||
if oldContainer.HostConfig.Memory != 0 {
|
||||
data.Memory = float64(oldContainer.HostConfig.Memory) / 1024 / 1024
|
||||
}
|
||||
data.Volumes = loadVolumeBinds(oldContainer.HostConfig.Binds)
|
||||
|
||||
return &data, nil
|
||||
}
|
||||
|
||||
func (u *ContainerService) ContainerUpdate(req dto.ContainerOperate) error {
|
||||
client, err := docker.NewDockerClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx := context.Background()
|
||||
newContainer, _ := client.ContainerInspect(ctx, req.Name)
|
||||
if newContainer.ContainerJSONBase != nil && newContainer.ID != req.ContainerID {
|
||||
return buserr.New(constant.ErrContainerName)
|
||||
}
|
||||
|
||||
oldContainer, err := client.ContainerInspect(ctx, req.ContainerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !checkImageExist(client, req.Image) || req.ForcePull {
|
||||
if err := pullImages(ctx, client, req.Image); err != nil {
|
||||
if !req.ForcePull {
|
||||
return err
|
||||
}
|
||||
global.LOG.Errorf("force pull image %s failed, err: %v", req.Image, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := client.ContainerRemove(ctx, req.ContainerID, types.ContainerRemoveOptions{Force: true}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config, hostConf, networkConf, err := loadConfigInfo(false, req, &oldContainer)
|
||||
if err != nil {
|
||||
reCreateAfterUpdate(req.Name, client, oldContainer.Config, oldContainer.HostConfig, oldContainer.NetworkSettings)
|
||||
return err
|
||||
}
|
||||
|
||||
global.LOG.Infof("new container info %s has been update, now start to recreate", req.Name)
|
||||
container, err := client.ContainerCreate(ctx, config, hostConf, networkConf, &v1.Platform{}, req.Name)
|
||||
if err != nil {
|
||||
reCreateAfterUpdate(req.Name, client, oldContainer.Config, oldContainer.HostConfig, oldContainer.NetworkSettings)
|
||||
return fmt.Errorf("update container failed, err: %v", err)
|
||||
}
|
||||
global.LOG.Infof("update container %s successful! now check if the container is started.", req.Name)
|
||||
if err := client.ContainerStart(ctx, container.ID, types.ContainerStartOptions{}); err != nil {
|
||||
return fmt.Errorf("update successful but start failed, err: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *ContainerService) ContainerUpgrade(req dto.ContainerUpgrade) error {
|
||||
client, err := docker.NewDockerClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx := context.Background()
|
||||
oldContainer, err := client.ContainerInspect(ctx, req.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !checkImageExist(client, req.Image) || req.ForcePull {
|
||||
if err := pullImages(ctx, client, req.Image); err != nil {
|
||||
if !req.ForcePull {
|
||||
return err
|
||||
}
|
||||
global.LOG.Errorf("force pull image %s failed, err: %v", req.Image, err)
|
||||
}
|
||||
}
|
||||
config := oldContainer.Config
|
||||
config.Image = req.Image
|
||||
hostConf := oldContainer.HostConfig
|
||||
var networkConf network.NetworkingConfig
|
||||
if oldContainer.NetworkSettings != nil {
|
||||
for networkKey := range oldContainer.NetworkSettings.Networks {
|
||||
networkConf.EndpointsConfig = map[string]*network.EndpointSettings{networkKey: {}}
|
||||
break
|
||||
}
|
||||
}
|
||||
if err := client.ContainerRemove(ctx, req.Name, types.ContainerRemoveOptions{Force: true}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
global.LOG.Infof("new container info %s has been update, now start to recreate", req.Name)
|
||||
container, err := client.ContainerCreate(ctx, config, hostConf, &networkConf, &v1.Platform{}, req.Name)
|
||||
if err != nil {
|
||||
reCreateAfterUpdate(req.Name, client, oldContainer.Config, oldContainer.HostConfig, oldContainer.NetworkSettings)
|
||||
return fmt.Errorf("upgrade container failed, err: %v", err)
|
||||
}
|
||||
global.LOG.Infof("upgrade container %s successful! now check if the container is started.", req.Name)
|
||||
if err := client.ContainerStart(ctx, container.ID, types.ContainerStartOptions{}); err != nil {
|
||||
return fmt.Errorf("upgrade successful but start failed, err: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *ContainerService) ContainerOperation(req dto.ContainerOperation) error {
|
||||
var err error
|
||||
ctx := context.Background()
|
||||
@@ -525,10 +304,6 @@ func (u *ContainerService) ContainerOperation(req dto.ContainerOperation) error
|
||||
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})
|
||||
@@ -541,15 +316,11 @@ func (u *ContainerService) ContainerLogClean(req dto.OperationWithName) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx := context.Background()
|
||||
containerItem, err := client.ContainerInspect(ctx, req.Name)
|
||||
container, err := client.ContainerInspect(context.Background(), req.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := client.ContainerStop(ctx, containerItem.ID, container.StopOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
file, err := os.OpenFile(containerItem.LogPath, os.O_RDWR|os.O_CREATE, 0666)
|
||||
file, err := os.OpenFile(container.LogPath, os.O_RDWR|os.O_CREATE, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -558,61 +329,22 @@ func (u *ContainerService) ContainerLogClean(req dto.OperationWithName) error {
|
||||
return err
|
||||
}
|
||||
_, _ = file.Seek(0, 0)
|
||||
|
||||
files, _ := filepath.Glob(fmt.Sprintf("%s.*", containerItem.LogPath))
|
||||
for _, file := range files {
|
||||
_ = os.Remove(file)
|
||||
}
|
||||
|
||||
if err := client.ContainerStart(ctx, containerItem.ID, types.ContainerStartOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
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)
|
||||
func (u *ContainerService) ContainerLogs(req dto.ContainerLog) (string, error) {
|
||||
cmd := exec.Command("docker", "logs", req.ContainerID)
|
||||
if req.Mode != "all" {
|
||||
cmd = exec.Command("docker", "logs", req.ContainerID, "--since", req.Mode)
|
||||
}
|
||||
command := fmt.Sprintf("docker logs %s", container)
|
||||
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()
|
||||
stdout, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return err
|
||||
return "", errors.New(string(stdout))
|
||||
}
|
||||
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 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
|
||||
return string(stdout), nil
|
||||
}
|
||||
|
||||
func (u *ContainerService) ContainerStats(id string) (*dto.ContainerStats, error) {
|
||||
func (u *ContainerService) ContainerStats(id string) (*dto.ContainterStats, error) {
|
||||
client, err := docker.NewDockerClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -633,7 +365,7 @@ func (u *ContainerService) ContainerStats(id string) (*dto.ContainerStats, error
|
||||
if err := json.Unmarshal(body, &stats); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data dto.ContainerStats
|
||||
var data dto.ContainterStats
|
||||
data.CPUPercent = calculateCPUPercentUnix(stats)
|
||||
data.IORead, data.IOWrite = calculateBlockIO(stats.BlkioStats)
|
||||
data.Memory = float64(stats.MemoryStats.Usage) / 1024 / 1024
|
||||
@@ -646,57 +378,15 @@ func (u *ContainerService) ContainerStats(id string) (*dto.ContainerStats, error
|
||||
return &data, nil
|
||||
}
|
||||
|
||||
func (u *ContainerService) LoadContainerLogs(req dto.OperationWithNameAndType) string {
|
||||
filePath := ""
|
||||
switch req.Type {
|
||||
case "image-pull", "image-push", "image-build", "compose-create":
|
||||
filePath = path.Join(global.CONF.System.TmpDir, fmt.Sprintf("docker_logs/%s", req.Name))
|
||||
case "compose-detail":
|
||||
client, err := docker.NewDockerClient()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
options := types.ContainerListOptions{All: true}
|
||||
options.Filters = filters.NewArgs()
|
||||
options.Filters.Add("label", fmt.Sprintf("%s=%s", composeProjectLabel, req.Name))
|
||||
containers, err := client.ContainerList(context.Background(), options)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
for _, container := range containers {
|
||||
config := container.Labels[composeConfigLabel]
|
||||
workdir := container.Labels[composeWorkdirLabel]
|
||||
if len(config) != 0 && len(workdir) != 0 && strings.Contains(config, workdir) {
|
||||
filePath = config
|
||||
break
|
||||
} else {
|
||||
filePath = workdir
|
||||
break
|
||||
}
|
||||
}
|
||||
if req.Type == "compose-create" {
|
||||
filePath = path.Join(path.Dir(filePath), "compose.log")
|
||||
}
|
||||
}
|
||||
if _, err := os.Stat(filePath); err != nil {
|
||||
return ""
|
||||
}
|
||||
content, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(content)
|
||||
}
|
||||
|
||||
func stringsToMap(list []string) map[string]string {
|
||||
var labelMap = make(map[string]string)
|
||||
var lableMap = make(map[string]string)
|
||||
for _, label := range list {
|
||||
if strings.Contains(label, "=") {
|
||||
sps := strings.SplitN(label, "=", 2)
|
||||
labelMap[sps[0]] = sps[1]
|
||||
lableMap[sps[0]] = sps[1]
|
||||
}
|
||||
}
|
||||
return labelMap
|
||||
return lableMap
|
||||
}
|
||||
|
||||
func calculateCPUPercentUnix(stats *types.StatsJSON) float64 {
|
||||
@@ -772,36 +462,26 @@ func pullImages(ctx context.Context, client *client.Client, image string) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadCpuAndMem(client *client.Client, container string) dto.ContainerListStats {
|
||||
data := dto.ContainerListStats{
|
||||
ContainerID: container,
|
||||
}
|
||||
func loadCpuAndMem(client *client.Client, container string) (float64, float64) {
|
||||
res, err := client.ContainerStats(context.Background(), container, false)
|
||||
if err != nil {
|
||||
return data
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
res.Body.Close()
|
||||
return data
|
||||
return 0, 0
|
||||
}
|
||||
res.Body.Close()
|
||||
var stats *types.StatsJSON
|
||||
if err := json.Unmarshal(body, &stats); err != nil {
|
||||
return data
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
data.CPUTotalUsage = stats.CPUStats.CPUUsage.TotalUsage - stats.PreCPUStats.CPUUsage.TotalUsage
|
||||
data.SystemUsage = stats.CPUStats.SystemUsage - stats.PreCPUStats.SystemUsage
|
||||
data.CPUPercent = calculateCPUPercentUnix(stats)
|
||||
data.PercpuUsage = len(stats.CPUStats.CPUUsage.PercpuUsage)
|
||||
|
||||
data.MemoryCache = stats.MemoryStats.Stats["cache"]
|
||||
data.MemoryUsage = stats.MemoryStats.Usage
|
||||
data.MemoryLimit = stats.MemoryStats.Limit
|
||||
data.MemoryPercent = calculateMemPercentUnix(stats.MemoryStats)
|
||||
return data
|
||||
CPUPercent := calculateCPUPercentUnix(stats)
|
||||
MemPercent := calculateMemPercentUnix(stats.MemoryStats)
|
||||
return CPUPercent, MemPercent
|
||||
}
|
||||
|
||||
func checkPortStats(ports []dto.PortHelper) (nat.PortMap, error) {
|
||||
@@ -849,178 +529,3 @@ func checkPortStats(ports []dto.PortHelper) (nat.PortMap, error) {
|
||||
}
|
||||
return portMap, nil
|
||||
}
|
||||
|
||||
func loadConfigInfo(isCreate bool, req dto.ContainerOperate, oldContainer *types.ContainerJSON) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error) {
|
||||
var config container.Config
|
||||
var hostConf container.HostConfig
|
||||
if !isCreate {
|
||||
config = *oldContainer.Config
|
||||
hostConf = *oldContainer.HostConfig
|
||||
}
|
||||
var networkConf network.NetworkingConfig
|
||||
|
||||
portMap, err := checkPortStats(req.ExposedPorts)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
exposed := make(nat.PortSet)
|
||||
for port := range portMap {
|
||||
exposed[port] = struct{}{}
|
||||
}
|
||||
config.Image = req.Image
|
||||
config.Cmd = req.Cmd
|
||||
config.Entrypoint = req.Entrypoint
|
||||
config.Env = req.Env
|
||||
config.Labels = stringsToMap(req.Labels)
|
||||
config.ExposedPorts = exposed
|
||||
config.OpenStdin = req.OpenStdin
|
||||
config.Tty = req.Tty
|
||||
|
||||
if len(req.Network) != 0 {
|
||||
switch req.Network {
|
||||
case "host", "none", "bridge":
|
||||
hostConf.NetworkMode = container.NetworkMode(req.Network)
|
||||
}
|
||||
networkConf.EndpointsConfig = map[string]*network.EndpointSettings{req.Network: {}}
|
||||
} else {
|
||||
networkConf = network.NetworkingConfig{}
|
||||
}
|
||||
|
||||
hostConf.AutoRemove = req.AutoRemove
|
||||
hostConf.CPUShares = req.CPUShares
|
||||
hostConf.PublishAllPorts = req.PublishAllPorts
|
||||
hostConf.RestartPolicy = container.RestartPolicy{Name: req.RestartPolicy}
|
||||
if req.RestartPolicy == "on-failure" {
|
||||
hostConf.RestartPolicy.MaximumRetryCount = 5
|
||||
}
|
||||
hostConf.NanoCPUs = int64(req.NanoCPUs * 1000000000)
|
||||
hostConf.Memory = int64(req.Memory * 1024 * 1024)
|
||||
hostConf.MemorySwap = 0
|
||||
hostConf.PortBindings = portMap
|
||||
hostConf.Binds = []string{}
|
||||
config.Volumes = make(map[string]struct{})
|
||||
for _, volume := range req.Volumes {
|
||||
config.Volumes[volume.ContainerDir] = struct{}{}
|
||||
hostConf.Binds = append(hostConf.Binds, fmt.Sprintf("%s:%s:%s", volume.SourceDir, volume.ContainerDir, volume.Mode))
|
||||
}
|
||||
return &config, &hostConf, &networkConf, nil
|
||||
}
|
||||
|
||||
func reCreateAfterUpdate(name string, client *client.Client, config *container.Config, hostConf *container.HostConfig, networkConf *types.NetworkSettings) {
|
||||
ctx := context.Background()
|
||||
|
||||
var oldNetworkConf network.NetworkingConfig
|
||||
if networkConf != nil {
|
||||
for networkKey := range networkConf.Networks {
|
||||
oldNetworkConf.EndpointsConfig = map[string]*network.EndpointSettings{networkKey: {}}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
oldContainer, err := client.ContainerCreate(ctx, config, hostConf, &oldNetworkConf, &v1.Platform{}, name)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("recreate after container update failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
if err := client.ContainerStart(ctx, oldContainer.ID, types.ContainerStartOptions{}); err != nil {
|
||||
global.LOG.Errorf("restart after container update failed, err: %v", err)
|
||||
}
|
||||
global.LOG.Errorf("recreate after container update successful")
|
||||
}
|
||||
|
||||
func loadVolumeBinds(binds []string) []dto.VolumeHelper {
|
||||
var datas []dto.VolumeHelper
|
||||
for _, bind := range binds {
|
||||
parts := strings.Split(bind, ":")
|
||||
var volumeItem dto.VolumeHelper
|
||||
if len(parts) > 3 {
|
||||
continue
|
||||
}
|
||||
volumeItem.SourceDir = parts[0]
|
||||
if len(parts) == 1 {
|
||||
volumeItem.ContainerDir = parts[0]
|
||||
volumeItem.Mode = "rw"
|
||||
}
|
||||
if len(parts) == 2 {
|
||||
switch parts[1] {
|
||||
case "r", "ro":
|
||||
volumeItem.ContainerDir = parts[0]
|
||||
volumeItem.Mode = "ro"
|
||||
case "rw":
|
||||
volumeItem.ContainerDir = parts[0]
|
||||
volumeItem.Mode = "rw"
|
||||
default:
|
||||
volumeItem.ContainerDir = parts[1]
|
||||
volumeItem.Mode = "rw"
|
||||
}
|
||||
}
|
||||
if len(parts) == 3 {
|
||||
volumeItem.ContainerDir = parts[1]
|
||||
if parts[2] == "r" {
|
||||
volumeItem.Mode = "ro"
|
||||
} else {
|
||||
volumeItem.Mode = parts[2]
|
||||
}
|
||||
}
|
||||
datas = append(datas, volumeItem)
|
||||
}
|
||||
return datas
|
||||
}
|
||||
|
||||
func simplifyPort(ports []types.Port) []string {
|
||||
var datas []string
|
||||
if len(ports) == 0 {
|
||||
return datas
|
||||
}
|
||||
if len(ports) == 1 {
|
||||
ip := ""
|
||||
if len(ports[0].IP) != 0 {
|
||||
ip = ports[0].IP + ":"
|
||||
}
|
||||
itemPortStr := fmt.Sprintf("%s%v/%s", ip, ports[0].PrivatePort, ports[0].Type)
|
||||
if ports[0].PublicPort != 0 {
|
||||
itemPortStr = fmt.Sprintf("%s%v->%v/%s", ip, ports[0].PublicPort, ports[0].PrivatePort, ports[0].Type)
|
||||
}
|
||||
datas = append(datas, itemPortStr)
|
||||
return datas
|
||||
}
|
||||
|
||||
sort.Slice(ports, func(i, j int) bool {
|
||||
return ports[i].PrivatePort < ports[j].PrivatePort
|
||||
})
|
||||
start := ports[0]
|
||||
|
||||
for i := 1; i < len(ports); i++ {
|
||||
if ports[i].PrivatePort != ports[i-1].PrivatePort+1 || ports[i].IP != ports[i-1].IP || ports[i].PublicPort != ports[i-1].PublicPort+1 || ports[i].Type != ports[i-1].Type {
|
||||
if ports[i-1].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, 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, itemPortStr)
|
||||
}
|
||||
start = ports[i]
|
||||
} 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, 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, itemPortStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
return datas
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user