mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/1Panel-dev/1Panel.git
synced 2026-09-20 16:13:59 +08:00
148 lines
3.6 KiB
Go
148 lines
3.6 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"fmt"
|
|
"net"
|
|
"net/url"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
|
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
|
"go.mongodb.org/mongo-driver/v2/mongo"
|
|
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
|
"go.mongodb.org/mongo-driver/v2/mongo/readpref"
|
|
)
|
|
|
|
type mongodbConnectionInfo struct {
|
|
Address string
|
|
Port uint
|
|
InitialDB string
|
|
Username string
|
|
Password string
|
|
Timeout uint
|
|
SSL bool
|
|
RootCert string
|
|
ClientKey string
|
|
ClientCert string
|
|
SkipVerify bool
|
|
}
|
|
|
|
func mongodbConnectionInfoFromCreate(req dto.DatabaseCreate) mongodbConnectionInfo {
|
|
return mongodbConnectionInfo{
|
|
Address: req.Address,
|
|
Port: req.Port,
|
|
InitialDB: req.InitialDB,
|
|
Username: req.Username,
|
|
Password: req.Password,
|
|
Timeout: req.Timeout,
|
|
SSL: req.SSL,
|
|
RootCert: req.RootCert,
|
|
ClientKey: req.ClientKey,
|
|
ClientCert: req.ClientCert,
|
|
SkipVerify: req.SkipVerify,
|
|
}
|
|
}
|
|
|
|
func mongodbConnectionInfoFromModel(db model.Database) mongodbConnectionInfo {
|
|
return mongodbConnectionInfo{
|
|
Address: db.Address,
|
|
Port: db.Port,
|
|
InitialDB: db.InitialDB,
|
|
Username: db.Username,
|
|
Password: db.Password,
|
|
Timeout: db.Timeout,
|
|
SSL: db.SSL,
|
|
RootCert: db.RootCert,
|
|
ClientKey: db.ClientKey,
|
|
ClientCert: db.ClientCert,
|
|
SkipVerify: db.SkipVerify,
|
|
}
|
|
}
|
|
|
|
func loadRemoteMongodbConnection(database string) (mongodbConnectionInfo, error) {
|
|
db, err := databaseRepo.Get(repo.WithByName(database))
|
|
if err != nil {
|
|
return mongodbConnectionInfo{}, err
|
|
}
|
|
return mongodbConnectionInfoFromModel(db), nil
|
|
}
|
|
|
|
func newRemoteMongodbClient(info mongodbConnectionInfo) (*mongo.Client, context.Context, context.CancelFunc, error) {
|
|
timeout := time.Duration(info.Timeout) * time.Second
|
|
if timeout == 0 {
|
|
timeout = 30 * time.Second
|
|
}
|
|
|
|
clientOptions := options.Client().ApplyURI(buildRemoteMongodbURI(info)).
|
|
SetServerSelectionTimeout(timeout).
|
|
SetConnectTimeout(timeout)
|
|
if info.SSL {
|
|
tlsConfig, err := buildRemoteMongodbTLSConfig(info)
|
|
if err != nil {
|
|
return nil, nil, nil, err
|
|
}
|
|
clientOptions.SetTLSConfig(tlsConfig)
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
client, err := mongo.Connect(clientOptions)
|
|
if err != nil {
|
|
cancel()
|
|
return nil, nil, nil, err
|
|
}
|
|
if err := client.Ping(ctx, readpref.Primary()); err != nil {
|
|
_ = client.Disconnect(context.Background())
|
|
cancel()
|
|
return nil, nil, nil, err
|
|
}
|
|
return client, ctx, cancel, nil
|
|
}
|
|
|
|
func buildRemoteMongodbURI(info mongodbConnectionInfo) string {
|
|
uri := url.URL{
|
|
Scheme: "mongodb",
|
|
Host: net.JoinHostPort(info.Address, strconv.Itoa(int(info.Port))),
|
|
Path: "/",
|
|
}
|
|
uri.User = url.UserPassword(info.Username, info.Password)
|
|
query := url.Values{}
|
|
authSource := info.InitialDB
|
|
if authSource == "" {
|
|
authSource = "admin"
|
|
}
|
|
query.Set("authSource", authSource)
|
|
query.Set("directConnection", "true")
|
|
uri.RawQuery = query.Encode()
|
|
return uri.String()
|
|
}
|
|
|
|
func buildRemoteMongodbTLSConfig(info mongodbConnectionInfo) (*tls.Config, error) {
|
|
tlsConfig := &tls.Config{
|
|
MinVersion: tls.VersionTLS12,
|
|
InsecureSkipVerify: info.SkipVerify,
|
|
}
|
|
|
|
if info.RootCert != "" {
|
|
pool := x509.NewCertPool()
|
|
if !pool.AppendCertsFromPEM([]byte(info.RootCert)) {
|
|
return nil, fmt.Errorf("load mongodb ca cert failed")
|
|
}
|
|
tlsConfig.RootCAs = pool
|
|
}
|
|
|
|
if info.ClientCert != "" && info.ClientKey != "" {
|
|
cert, err := tls.X509KeyPair([]byte(info.ClientCert), []byte(info.ClientKey))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
tlsConfig.Certificates = []tls.Certificate{cert}
|
|
}
|
|
|
|
return tlsConfig, nil
|
|
}
|