Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
Signed-off-by: Anisur Rahman <[email protected]>
  • Loading branch information
anisurrahman75 committed Aug 23, 2024
1 parent 80912d1 commit 59e7950
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 41 deletions.
43 changes: 18 additions & 25 deletions pkg/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,12 @@ func (opt *mongoOptions) backupMongoDB(targetRef api_v1beta1.TargetRef) (*restic
}
}

var tlsEnable bool
if appBinding.Spec.ClientConfig.CABundle != nil {
tlsEnable = true
}

if tlsEnable {
if tlsSecret == nil {
return nil, errors.Wrap(err, "spec.tlsSecret needs to be set in appbinding for TLS secured database.")
}
Expand All @@ -346,8 +351,8 @@ func (opt *mongoOptions) backupMongoDB(targetRef api_v1beta1.TargetRef) (*restic
}
dumpCreds = []interface{}{
"--ssl",
"--sslCAFile", filepath.Join(opt.setupOptions.ScratchDir, MongoTLSCertFileName),
"--sslPEMKeyFile", filepath.Join(opt.setupOptions.ScratchDir, MongoClientPemFileName),
fmt.Sprintf("--sslCAFile=%s", filepath.Join(opt.setupOptions.ScratchDir, MongoTLSCertFileName)),
fmt.Sprintf("--sslPEMKeyFile=%s", filepath.Join(opt.setupOptions.ScratchDir, MongoClientPemFileName)),
}

// get certificate secret to get client certificate
Expand All @@ -374,9 +379,9 @@ func (opt *mongoOptions) backupMongoDB(targetRef api_v1beta1.TargetRef) (*restic
return nil, errors.Wrap(err, "unable to get user from ssl.")
}
userAuth := []interface{}{
"-u", user,
"--authenticationMechanism", "MONGODB-X509",
"--authenticationDatabase", "$external",
fmt.Sprintf("--username=%s", user),
"--authenticationMechanism=MONGODB-X509",
"--authenticationDatabase=$external",
}
mongoCreds = append(mongoCreds, userAuth...)
dumpCreds = append(dumpCreds, userAuth...)
Expand All @@ -400,7 +405,7 @@ func (opt *mongoOptions) backupMongoDB(targetRef api_v1beta1.TargetRef) (*restic
BackupPaths: opt.defaultBackupOptions.BackupPaths,
}

uri := opt.buildMongoURI(mongoDSN, port, isStandalone, isSrv)
uri := opt.buildMongoURI(mongoDSN, port, isStandalone, isSrv, tlsEnable)

// setup pipe command
backupCmd := restic.Command{
Expand All @@ -410,6 +415,13 @@ func (opt *mongoOptions) backupMongoDB(targetRef api_v1beta1.TargetRef) (*restic
"--archive",
},
}

if tlsEnable {
backupCmd.Args = append(backupCmd.Args,
fmt.Sprintf("--sslCAFile=%s", getOptionValue(dumpCreds, "--sslCAFile")),
fmt.Sprintf("--sslPEMKeyFile=%s", getOptionValue(dumpCreds, "--sslPEMKeyFile")))
}

userArgs := strings.Fields(opt.mongoArgs)

if !isStandalone {
Expand Down Expand Up @@ -571,25 +583,6 @@ func cleanup() {
}
}

func (opt *mongoOptions) buildMongoURI(mongoDSN string, port int32, isStandalone, isSrv bool) string {
userName := getOptionValue(dumpCreds, "--username")
password := getOptionValue(dumpCreds, "--password")
authDbName := getOptionValue(dumpCreds, "--authenticationDatabase")

prefix := "mongodb"
portStr := fmt.Sprintf(":%d", port)
if isSrv {
prefix += "+srv"
portStr = ""
}
if !isStandalone {
portStr = ""
}

return fmt.Sprintf("%s://%s:%s@%s%s/%s?authSource=%s",
prefix, userName, password, mongoDSN, portStr, authDbName, authDbName)
}

func getOptionValue(args []interface{}, option string) string {
for _, arg := range args {
strArg, ok := arg.(string)
Expand Down
55 changes: 39 additions & 16 deletions pkg/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,23 @@ func (opt *mongoOptions) restoreMongoDB(targetRef api_v1beta1.TargetRef) (*resti
return nil, err
}

port, err := appBinding.Port()
if err != nil {
return nil, err
var isSrv bool
port := int32(27017)
if appBinding.Spec.ClientConfig.URL != nil {
isSrv, err = isSrvConnection(*appBinding.Spec.ClientConfig.URL)
if err != nil {
return nil, err
}
}

// Checked for Altlas and DigitalOcean srv format connection string don't give port.
// mongodump --uri format not support port.

if !isSrv {
port, err = appBinding.Port()
if err != nil {
return nil, err
}
}

// unmarshal parameter is the field has value
Expand Down Expand Up @@ -249,8 +263,12 @@ func (opt *mongoOptions) restoreMongoDB(targetRef api_v1beta1.TargetRef) (*resti
return nil, err
}
}

var tlsEnable bool
if appBinding.Spec.ClientConfig.CABundle != nil {
tlsEnable = true
}

if tlsEnable {
if err := os.WriteFile(filepath.Join(opt.setupOptions.ScratchDir, MongoTLSCertFileName), appBinding.Spec.ClientConfig.CABundle, os.ModePerm); err != nil {
return nil, errors.Wrap(err, "failed to write key for CA certificate")
}
Expand All @@ -261,8 +279,8 @@ func (opt *mongoOptions) restoreMongoDB(targetRef api_v1beta1.TargetRef) (*resti
}
dumpCreds = []interface{}{
"--ssl",
"--sslCAFile", filepath.Join(opt.setupOptions.ScratchDir, MongoTLSCertFileName),
"--sslPEMKeyFile", filepath.Join(opt.setupOptions.ScratchDir, MongoClientPemFileName),
fmt.Sprintf("--sslCAFile=%s", filepath.Join(opt.setupOptions.ScratchDir, MongoTLSCertFileName)),
fmt.Sprintf("--sslPEMKeyFile=%s", filepath.Join(opt.setupOptions.ScratchDir, MongoClientPemFileName)),
}

// get certificate secret to get client certificate
Expand All @@ -289,9 +307,9 @@ func (opt *mongoOptions) restoreMongoDB(targetRef api_v1beta1.TargetRef) (*resti
return nil, errors.Wrap(err, "unable to get user from ssl.")
}
userAuth := []interface{}{
"-u", user,
"--authenticationMechanism", "MONGODB-X509",
"--authenticationDatabase", "$external",
fmt.Sprintf("--username=%s", user),
"--authenticationMechanism=MONGODB-X509",
"--authenticationDatabase=$external",
}
mongoCreds = append(mongoCreds, userAuth...)
dumpCreds = append(dumpCreds, userAuth...)
Expand All @@ -300,7 +318,7 @@ func (opt *mongoOptions) restoreMongoDB(targetRef api_v1beta1.TargetRef) (*resti
userAuth := []interface{}{
fmt.Sprintf("--username=%s", authSecret.Data[MongoUserKey]),
fmt.Sprintf("--password=%s", authSecret.Data[MongoPasswordKey]),
"--authenticationDatabase", opt.authenticationDatabase,
fmt.Sprintf("--authenticationDatabase=%s", opt.authenticationDatabase),
}
mongoCreds = append(mongoCreds, userAuth...)
dumpCreds = append(dumpCreds, userAuth...)
Expand All @@ -314,19 +332,24 @@ func (opt *mongoOptions) restoreMongoDB(targetRef api_v1beta1.TargetRef) (*resti
FileName: opt.defaultDumpOptions.FileName,
Snapshot: opt.getSnapshotForHost(hostKey, restoreSession.Spec.Target.Rules),
}

uri := opt.buildMongoURI(mongoDSN, port, isStandalone, isSrv, tlsEnable)
// setup pipe command
restoreCmd := restic.Command{
Name: MongoRestoreCMD,
Args: append([]interface{}{
"--host", mongoDSN,
Args: []interface{}{
"--uri", fmt.Sprintf("\"%s\"", uri),
"--archive",
}, dumpCreds...),
},
}
if tlsEnable {
restoreCmd.Args = append(restoreCmd.Args,
fmt.Sprintf("--sslCAFile=%s", getOptionValue(dumpCreds, "--sslCAFile")),
fmt.Sprintf("--sslPEMKeyFile=%s", getOptionValue(dumpCreds, "--sslPEMKeyFile")))
}

userArgs := strings.Fields(opt.mongoArgs)
if isStandalone {
restoreCmd.Args = append(restoreCmd.Args, fmt.Sprintf("--port=%d", port))
} else {
if !isStandalone {
// - port is already added in mongoDSN with replicasetName/host:port format.
// - oplog is enabled automatically for replicasets.
// Don't use --oplogReplay if user specify any of these arguments through opt.mongoArgs
Expand Down
24 changes: 24 additions & 0 deletions pkg/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,27 @@ func isSrvConnection(connectionString string) (bool, error) {
// Check if the scheme is "mongodb+srv"
return parsedURL.Scheme == "mongodb+srv", nil
}

func (opt *mongoOptions) buildMongoURI(mongoDSN string, port int32, isStandalone, isSrv, tlsEnable bool) string {
prefix := "mongodb"
portStr := fmt.Sprintf(":%d", port)
if isSrv {
prefix += "+srv"
portStr = ""
}
if !isStandalone {
portStr = ""
}

authDbName := getOptionValue(dumpCreds, "--authenticationDatabase")
userName := getOptionValue(dumpCreds, "--username")
if !tlsEnable {
password := getOptionValue(dumpCreds, "--password")
return fmt.Sprintf("%s://%s:%s@%s%s/dbnew?authSource=%s",
prefix, userName, password, mongoDSN, portStr, authDbName)
}

authMechanism := getOptionValue(dumpCreds, "--authenticationMechanism")
return fmt.Sprintf("%s://%s@%s%s/dbnew?authSource=%s&authMechanism=%s&ssl=true",
prefix, userName, mongoDSN, portStr, authDbName, authMechanism)
}

0 comments on commit 59e7950

Please sign in to comment.