From d2810a49c4299bd0d7e7eb2ebbdc4ee0deea5c60 Mon Sep 17 00:00:00 2001 From: lgtm <1gtm@users.noreply.github.com> Date: Tue, 3 Oct 2023 23:44:14 -0700 Subject: [PATCH] Add support for restoring specific snapshot (#1927) (#1956) /cherry-pick Signed-off-by: hmsayem --- pkg/restore.go | 27 +++++++++++++++++++++------ pkg/utils.go | 9 +++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/pkg/restore.go b/pkg/restore.go index d9f0c7f3f..db27d0a8d 100644 --- a/pkg/restore.go +++ b/pkg/restore.go @@ -226,14 +226,14 @@ func (opt *mongoOptions) restoreMongoDB(targetRef api_v1beta1.TargetRef) (*resti // So, for stand-alone MongoDB and MongoDB ReplicaSet, we don't have to do anything. // We only need to update totalHosts field for sharded MongoDB + restoreSession, err := opt.stashClient.StashV1beta1().RestoreSessions(opt.namespace).Get(context.TODO(), opt.restoreSessionName, metav1.GetOptions{}) + if err != nil { + return nil, err + } opt.totalHosts = 1 // For sharded MongoDB, parameter.ConfigServer will not be empty if parameters.ConfigServer != "" { opt.totalHosts = len(parameters.ReplicaSets) + 1 // for each shard there will be one key in parameters.ReplicaSet - restoreSession, err := opt.stashClient.StashV1beta1().RestoreSessions(opt.namespace).Get(context.TODO(), opt.restoreSessionName, metav1.GetOptions{}) - if err != nil { - return nil, err - } _, err = stash_cs_util.UpdateRestoreSessionStatus( context.TODO(), opt.stashClient.StashV1beta1(), @@ -311,9 +311,8 @@ func (opt *mongoOptions) restoreMongoDB(targetRef api_v1beta1.TargetRef) (*resti Host: hostKey, SourceHost: hostKey, FileName: opt.defaultDumpOptions.FileName, - Snapshot: opt.defaultDumpOptions.Snapshot, + Snapshot: opt.getSnapshotForHost(hostKey, restoreSession.Spec.Target.Rules), } - // setup pipe command restoreCmd := restic.Command{ Name: MongoRestoreCMD, @@ -426,3 +425,19 @@ func (opt *mongoOptions) getHostRestoreStats(err error) []api_v1beta1.HostRestor return restoreStats } + +func (opt *mongoOptions) getSnapshotForHost(hostname string, rules []api_v1beta1.Rule) string { + var hostSnapshot string + for _, rule := range rules { + if len(rule.TargetHosts) == 0 || containsString(rule.TargetHosts, hostname) { + hostSnapshot = rule.Snapshots[0] + // if rule has empty targetHost then check further rules to see if any other rule with non-empty targetHost matches + if len(rule.TargetHosts) == 0 { + continue + } else { + return hostSnapshot + } + } + } + return hostSnapshot +} diff --git a/pkg/utils.go b/pkg/utils.go index c28de5cf1..347b81234 100644 --- a/pkg/utils.go +++ b/pkg/utils.go @@ -94,3 +94,12 @@ func containsArg(args []string, checklist sets.String) bool { } return false } + +func containsString(a []string, e string) bool { + for _, s := range a { + if s == e { + return true + } + } + return false +}