Skip to content

Commit 394339d

Browse files
feat: support mongodb management (#12486)
#### What this PR does / why we need it? Refs #7759 #### Summary of your change #### Please indicate you've done the following: - [ ] Made sure tests are passing and test coverage is added if needed. - [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/). - [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
1 parent 8362578 commit 394339d

File tree

52 files changed

+4338
-31
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+4338
-31
lines changed

agent/app/api/v2/backup.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,11 @@ func (b *BaseApi) Backup(c *gin.Context) {
415415
helper.InternalServer(c, err)
416416
return
417417
}
418+
case "mongodb":
419+
if err := backupService.MongodbBackup(req); err != nil {
420+
helper.InternalServer(c, err)
421+
return
422+
}
418423
case constant.AppPostgresql, constant.AppPostgresqlCluster:
419424
if err := backupService.PostgresqlBackup(req); err != nil {
420425
helper.InternalServer(c, err)
@@ -475,6 +480,11 @@ func (b *BaseApi) Recover(c *gin.Context) {
475480
helper.InternalServer(c, err)
476481
return
477482
}
483+
case "mongodb":
484+
if err := backupService.MongodbRecover(req); err != nil {
485+
helper.InternalServer(c, err)
486+
return
487+
}
478488
case constant.AppPostgresql, constant.AppPostgresqlCluster:
479489
if err := backupService.PostgresqlRecover(req); err != nil {
480490
helper.InternalServer(c, err)
@@ -530,6 +540,11 @@ func (b *BaseApi) RecoverByUpload(c *gin.Context) {
530540
helper.InternalServer(c, err)
531541
return
532542
}
543+
case "mongodb":
544+
if err := backupService.MongodbRecoverByUpload(req); err != nil {
545+
helper.InternalServer(c, err)
546+
return
547+
}
533548
case constant.AppPostgresql, constant.AppPostgresqlCluster:
534549
if err := backupService.PostgresqlRecoverByUpload(req); err != nil {
535550
helper.InternalServer(c, err)
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
package v2
2+
3+
import (
4+
"context"
5+
"encoding/base64"
6+
7+
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
8+
"github.com/1Panel-dev/1Panel/agent/app/dto"
9+
"github.com/gin-gonic/gin"
10+
)
11+
12+
// @Tags Database Mongodb
13+
// @Summary Create mongodb database
14+
// @Accept json
15+
// @Param request body dto.MongodbDBCreate true "request"
16+
// @Success 200
17+
// @Security ApiKeyAuth
18+
// @Security Timestamp
19+
// @Router /databases/mongodb [post]
20+
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 mongodb 数据库 [name]","formatEN":"create mongodb database [name]"}
21+
func (b *BaseApi) CreateMongodb(c *gin.Context) {
22+
var req dto.MongodbDBCreate
23+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
24+
return
25+
}
26+
27+
if len(req.Password) != 0 {
28+
password, err := base64.StdEncoding.DecodeString(req.Password)
29+
if err != nil {
30+
helper.BadRequest(c, err)
31+
return
32+
}
33+
req.Password = string(password)
34+
}
35+
36+
if _, err := mongodbService.Create(context.Background(), req); err != nil {
37+
helper.InternalServer(c, err)
38+
return
39+
}
40+
helper.Success(c)
41+
}
42+
43+
// @Tags Database Mongodb
44+
// @Summary Page mongodb databases
45+
// @Accept json
46+
// @Param request body dto.MongodbDBSearch true "request"
47+
// @Success 200 {object} dto.PageResult
48+
// @Security ApiKeyAuth
49+
// @Security Timestamp
50+
// @Router /databases/mongodb/search [post]
51+
func (b *BaseApi) SearchMongodb(c *gin.Context) {
52+
var req dto.MongodbDBSearch
53+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
54+
return
55+
}
56+
57+
total, list, err := mongodbService.SearchWithPage(req)
58+
if err != nil {
59+
helper.InternalServer(c, err)
60+
return
61+
}
62+
63+
helper.SuccessWithData(c, dto.PageResult{
64+
Items: list,
65+
Total: total,
66+
})
67+
}
68+
69+
// @Tags Database Mongodb
70+
// @Summary Update mongodb database description
71+
// @Accept json
72+
// @Param request body dto.UpdateDescription true "request"
73+
// @Success 200
74+
// @Security ApiKeyAuth
75+
// @Security Timestamp
76+
// @Router /databases/mongodb/description [post]
77+
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mongodbs","output_column":"name","output_value":"name"}],"formatZH":"mongodb 数据库 [name] 描述信息修改 [description]","formatEN":"The description of the mongodb database [name] is modified => [description]"}
78+
func (b *BaseApi) UpdateMongodbDescription(c *gin.Context) {
79+
var req dto.UpdateDescription
80+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
81+
return
82+
}
83+
84+
if err := mongodbService.UpdateDescription(req); err != nil {
85+
helper.InternalServer(c, err)
86+
return
87+
}
88+
helper.Success(c)
89+
}
90+
91+
// @Tags Database Mongodb
92+
// @Summary Load mongodb database from remote
93+
// @Accept json
94+
// @Param request body dto.MongodbLoadDB true "request"
95+
// @Success 200
96+
// @Security ApiKeyAuth
97+
// @Security Timestamp
98+
// @Router /databases/mongodb/load [post]
99+
func (b *BaseApi) LoadMongodbFromRemote(c *gin.Context) {
100+
var req dto.MongodbLoadDB
101+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
102+
return
103+
}
104+
105+
if err := mongodbService.LoadFromRemote(req); err != nil {
106+
helper.InternalServer(c, err)
107+
return
108+
}
109+
helper.Success(c)
110+
}
111+
112+
// @Tags Database Mongodb
113+
// @Summary Bind mongodb database user info
114+
// @Accept json
115+
// @Param request body dto.MongodbBind true "request"
116+
// @Success 200
117+
// @Security ApiKeyAuth
118+
// @Security Timestamp
119+
// @Router /databases/mongodb/bind [post]
120+
// @x-panel-log {"bodyKeys":["database", "name", "username"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"绑定 mongodb 数据库 [database] [name] 用户 [username]","formatEN":"bind mongodb database [database] [name] user [username]"}
121+
func (b *BaseApi) BindMongodbUser(c *gin.Context) {
122+
var req dto.MongodbBind
123+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
124+
return
125+
}
126+
127+
if len(req.Password) != 0 {
128+
password, err := base64.StdEncoding.DecodeString(req.Password)
129+
if err != nil {
130+
helper.BadRequest(c, err)
131+
return
132+
}
133+
req.Password = string(password)
134+
}
135+
136+
if err := mongodbService.BindUser(req); err != nil {
137+
helper.InternalServer(c, err)
138+
return
139+
}
140+
helper.Success(c)
141+
}
142+
143+
// @Tags Database Mongodb
144+
// @Summary Change mongodb database password
145+
// @Accept json
146+
// @Param request body dto.MongodbPassword true "request"
147+
// @Success 200
148+
// @Security ApiKeyAuth
149+
// @Security Timestamp
150+
// @Router /databases/mongodb/password [post]
151+
// @x-panel-log {"bodyKeys":["database", "name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 mongodb 数据库 [database] [name] 密码","formatEN":"update mongodb database [database] [name] password"}
152+
func (b *BaseApi) ChangeMongodbPassword(c *gin.Context) {
153+
var req dto.MongodbPassword
154+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
155+
return
156+
}
157+
158+
if len(req.Password) != 0 {
159+
password, err := base64.StdEncoding.DecodeString(req.Password)
160+
if err != nil {
161+
helper.BadRequest(c, err)
162+
return
163+
}
164+
req.Password = string(password)
165+
}
166+
167+
if err := mongodbService.ChangePassword(req); err != nil {
168+
helper.InternalServer(c, err)
169+
return
170+
}
171+
helper.Success(c)
172+
}
173+
174+
// @Tags Database Mongodb
175+
// @Summary Load mongodb privileges
176+
// @Accept json
177+
// @Param request body dto.MongodbPrivilegesLoad true "request"
178+
// @Success 200 {string} string
179+
// @Security ApiKeyAuth
180+
// @Security Timestamp
181+
// @Router /databases/mongodb/privileges [post]
182+
func (b *BaseApi) LoadMongodbPrivileges(c *gin.Context) {
183+
var req dto.MongodbPrivilegesLoad
184+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
185+
return
186+
}
187+
188+
permission, err := mongodbService.LoadPrivileges(req)
189+
if err != nil {
190+
helper.InternalServer(c, err)
191+
return
192+
}
193+
helper.SuccessWithData(c, permission)
194+
}
195+
196+
// @Tags Database Mongodb
197+
// @Summary Change mongodb privileges
198+
// @Accept json
199+
// @Param request body dto.MongodbPrivileges true "request"
200+
// @Success 200
201+
// @Security ApiKeyAuth
202+
// @Security Timestamp
203+
// @Router /databases/mongodb/privileges/change [post]
204+
// @x-panel-log {"bodyKeys":["database", "username"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 mongodb 数据库 [database] 用户 [username] 权限","formatEN":"update mongodb database [database] user [username] privileges"}
205+
func (b *BaseApi) ChangeMongodbPrivileges(c *gin.Context) {
206+
var req dto.MongodbPrivileges
207+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
208+
return
209+
}
210+
211+
if err := mongodbService.ChangePrivileges(req); err != nil {
212+
helper.InternalServer(c, err)
213+
return
214+
}
215+
helper.Success(c)
216+
}
217+
218+
// @Tags Database Mongodb
219+
// @Summary Check before delete mongodb database
220+
// @Accept json
221+
// @Param request body dto.MongodbDBDeleteCheck true "request"
222+
// @Success 200 {array} string
223+
// @Security ApiKeyAuth
224+
// @Security Timestamp
225+
// @Router /databases/mongodb/del/check [post]
226+
func (b *BaseApi) DeleteCheckMongodb(c *gin.Context) {
227+
var req dto.MongodbDBDeleteCheck
228+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
229+
return
230+
}
231+
232+
apps, err := mongodbService.DeleteCheck(req)
233+
if err != nil {
234+
helper.InternalServer(c, err)
235+
return
236+
}
237+
helper.SuccessWithData(c, apps)
238+
}
239+
240+
// @Tags Database Mongodb
241+
// @Summary Delete mongodb database
242+
// @Accept json
243+
// @Param request body dto.MongodbDBDelete true "request"
244+
// @Success 200
245+
// @Security ApiKeyAuth
246+
// @Security Timestamp
247+
// @Router /databases/mongodb/del [post]
248+
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mongodbs","output_column":"name","output_value":"name"}],"formatZH":"删除 mongodb 数据库 [name]","formatEN":"delete mongodb database [name]"}
249+
func (b *BaseApi) DeleteMongodb(c *gin.Context) {
250+
var req dto.MongodbDBDelete
251+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
252+
return
253+
}
254+
255+
tx, ctx := helper.GetTxAndContext()
256+
if err := mongodbService.Delete(ctx, req); err != nil {
257+
helper.InternalServer(c, err)
258+
tx.Rollback()
259+
return
260+
}
261+
tx.Commit()
262+
helper.Success(c)
263+
}

agent/app/api/v2/entry.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ var (
3131
dbCommonService = service.NewIDBCommonService()
3232
mysqlService = service.NewIMysqlService()
3333
postgresqlService = service.NewIPostgresqlService()
34+
mongodbService = service.NewIMongodbService()
3435
databaseService = service.NewIDatabaseService()
3536
redisService = service.NewIRedisService()
3637

agent/app/api/v2/terminal.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,19 +213,29 @@ func loadContainerInitCmd(c *gin.Context) ([]string, error) {
213213
func loadDatabaseInitCmd(c *gin.Context) ([]string, error) {
214214
database := c.Query("database")
215215
databaseType := c.Query("databaseType")
216-
if len(database) == 0 || len(databaseType) == 0 {
216+
if len(databaseType) == 0 {
217217
return nil, fmt.Errorf("error param of database: %s or database type: %s", database, databaseType)
218218
}
219219
databaseConn, err := appInstallService.LoadConnInfo(dto.OperationWithNameAndType{Type: databaseType, Name: database})
220220
if err != nil {
221221
return nil, fmt.Errorf("no such database in db, err: %v", err)
222222
}
223+
if len(databaseConn.ContainerName) == 0 {
224+
return nil, fmt.Errorf("no such database container for database: %s or database type: %s", database, databaseType)
225+
}
223226
commands := []string{"exec", "-it", databaseConn.ContainerName}
224227
switch databaseType {
225228
case "mysql", "mysql-cluster":
226229
commands = append(commands, []string{"mysql", "-uroot", "-p" + databaseConn.Password}...)
227230
case "mariadb":
228231
commands = append(commands, []string{"mariadb", "-uroot", "-p" + databaseConn.Password}...)
232+
case "mongodb":
233+
commands = append(commands, []string{
234+
"mongosh",
235+
"--username", databaseConn.Username,
236+
"--password", databaseConn.Password,
237+
"--authenticationDatabase", "admin",
238+
}...)
229239
case "postgresql", "postgresql-cluster":
230240
commands = []string{"exec", "-e", fmt.Sprintf("PGPASSWORD=%s", databaseConn.Password), "-it", databaseConn.ContainerName, "psql", "-t", "-U", databaseConn.Username}
231241
}

agent/app/dto/backup.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ type UploadForRecover struct {
6565
}
6666

6767
type CommonBackup struct {
68-
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website postgresql mysql-cluster postgresql-cluster redis-cluster container compose"`
68+
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website postgresql mongodb mysql-cluster postgresql-cluster redis-cluster container compose"`
6969
Name string `json:"name"`
7070
DetailName string `json:"detailName"`
7171
Secret string `json:"secret"`
@@ -78,7 +78,7 @@ type CommonBackup struct {
7878
}
7979
type CommonRecover struct {
8080
DownloadAccountID uint `json:"downloadAccountID" validate:"required"`
81-
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website postgresql mysql-cluster postgresql-cluster redis-cluster container compose"`
81+
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website postgresql mongodb mysql-cluster postgresql-cluster redis-cluster container compose"`
8282
Name string `json:"name"`
8383
DetailName string `json:"detailName"`
8484
File string `json:"file"`

0 commit comments

Comments
 (0)