diff --git a/src/cli/backup/exchange.go b/src/cli/backup/exchange.go index 558f800b6..9045d611e 100644 --- a/src/cli/backup/exchange.go +++ b/src/cli/backup/exchange.go @@ -136,6 +136,8 @@ func addExchangeCommands(cmd *cobra.Command) *cobra.Command { c.Use = c.Use + " " + exchangeServiceCommandDetailsUseSuffix c.Example = exchangeServiceCommandDetailsExamples + options.AddSkipReduceFlag(c) + // Flags addition ordering should follow the order we want them to appear in help and docs: // More generic (ex: --user) and more frequently used flags take precedence. fs.StringVar(&backupID, @@ -212,7 +214,6 @@ func addExchangeCommands(cmd *cobra.Command) *cobra.Command { &contactFolder, utils.ContactFolderFN, nil, "Select backup details for contacts within a folder; accepts '"+utils.Wildcard+"' to select all contact folders.") - fs.StringVar( &contactName, utils.ContactNameFN, "", @@ -434,7 +435,8 @@ func exchangeDetailsCmd() *cobra.Command { } } -// lists the history of backup operations +// lists all items in the backup, running the results first through +// selector reduction as a filtering step. func detailsExchangeCmd(cmd *cobra.Command, args []string) error { if utils.HasNoFlagsAndShownHelp(cmd) { return nil @@ -468,14 +470,16 @@ func detailsExchangeCmd(cmd *cobra.Command, args []string) error { return Only(ctx, err) } - r, err := repository.Connect(ctx, acct, s, options.Control()) + ctrlOpts := options.Control() + + r, err := repository.Connect(ctx, acct, s, ctrlOpts) if err != nil { return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) } defer utils.CloseRepo(ctx, r) - ds, err := runDetailsExchangeCmd(ctx, r, backupID, opts) + ds, err := runDetailsExchangeCmd(ctx, r, backupID, opts, ctrlOpts.SkipReduce) if err != nil { return Only(ctx, err) } @@ -498,6 +502,7 @@ func runDetailsExchangeCmd( r repository.BackupGetter, backupID string, opts utils.ExchangeOpts, + skipReduce bool, ) (*details.Details, error) { if err := utils.ValidateExchangeRestoreFlags(backupID, opts); err != nil { return nil, err @@ -513,10 +518,13 @@ func runDetailsExchangeCmd( return nil, errors.Wrap(errs.Failure(), "Failed to get backup details in the repository") } - sel := utils.IncludeExchangeRestoreDataSelectors(opts) - utils.FilterExchangeRestoreInfoSelectors(sel, opts) + if !skipReduce { + sel := utils.IncludeExchangeRestoreDataSelectors(opts) + utils.FilterExchangeRestoreInfoSelectors(sel, opts) + d = sel.Reduce(ctx, d, errs) + } - return sel.Reduce(ctx, d, errs), nil + return d, nil } // ------------------------------------------------------------------------------------------------ diff --git a/src/cli/backup/exchange_test.go b/src/cli/backup/exchange_test.go index 16e11c30d..514e897bf 100644 --- a/src/cli/backup/exchange_test.go +++ b/src/cli/backup/exchange_test.go @@ -231,7 +231,8 @@ func (suite *ExchangeSuite) TestExchangeBackupDetailsSelectors() { ctx, test.BackupGetter, "backup-ID", - test.Opts) + test.Opts, + false) assert.NoError(t, err, "failure") assert.ElementsMatch(t, test.Expected, output.Entries) }) @@ -250,7 +251,8 @@ func (suite *ExchangeSuite) TestExchangeBackupDetailsSelectorsBadFormats() { ctx, test.BackupGetter, "backup-ID", - test.Opts) + test.Opts, + false) assert.Error(t, err, "failure") assert.Empty(t, output) }) diff --git a/src/cli/backup/onedrive.go b/src/cli/backup/onedrive.go index f3fabd63f..a6bd1cb4a 100644 --- a/src/cli/backup/onedrive.go +++ b/src/cli/backup/onedrive.go @@ -103,6 +103,8 @@ func addOneDriveCommands(cmd *cobra.Command) *cobra.Command { c.Use = c.Use + " " + oneDriveServiceCommandDetailsUseSuffix c.Example = oneDriveServiceCommandDetailsExamples + options.AddSkipReduceFlag(c) + fs.StringVar(&backupID, utils.BackupFN, "", "ID of the backup to explore. (required)") @@ -348,7 +350,9 @@ func detailsOneDriveCmd(cmd *cobra.Command, args []string) error { return Only(ctx, err) } - r, err := repository.Connect(ctx, acct, s, options.Control()) + ctrlOpts := options.Control() + + r, err := repository.Connect(ctx, acct, s, ctrlOpts) if err != nil { return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) } @@ -367,7 +371,7 @@ func detailsOneDriveCmd(cmd *cobra.Command, args []string) error { Populated: utils.GetPopulatedFlags(cmd), } - ds, err := runDetailsOneDriveCmd(ctx, r, backupID, opts) + ds, err := runDetailsOneDriveCmd(ctx, r, backupID, opts, ctrlOpts.SkipReduce) if err != nil { return Only(ctx, err) } @@ -390,6 +394,7 @@ func runDetailsOneDriveCmd( r repository.BackupGetter, backupID string, opts utils.OneDriveOpts, + skipReduce bool, ) (*details.Details, error) { if err := utils.ValidateOneDriveRestoreFlags(backupID, opts); err != nil { return nil, err @@ -405,10 +410,13 @@ func runDetailsOneDriveCmd( return nil, errors.Wrap(errs.Failure(), "Failed to get backup details in the repository") } - sel := utils.IncludeOneDriveRestoreDataSelectors(opts) - utils.FilterOneDriveRestoreInfoSelectors(sel, opts) + if !skipReduce { + sel := utils.IncludeOneDriveRestoreDataSelectors(opts) + utils.FilterOneDriveRestoreInfoSelectors(sel, opts) + d = sel.Reduce(ctx, d, errs) + } - return sel.Reduce(ctx, d, errs), nil + return d, nil } // `corso backup delete onedrive [...]` diff --git a/src/cli/backup/onedrive_test.go b/src/cli/backup/onedrive_test.go index a876497c9..d45314955 100644 --- a/src/cli/backup/onedrive_test.go +++ b/src/cli/backup/onedrive_test.go @@ -102,7 +102,8 @@ func (suite *OneDriveSuite) TestOneDriveBackupDetailsSelectors() { ctx, test.BackupGetter, "backup-ID", - test.Opts) + test.Opts, + false) assert.NoError(t, err) assert.ElementsMatch(t, test.Expected, output.Entries) }) @@ -121,7 +122,8 @@ func (suite *OneDriveSuite) TestOneDriveBackupDetailsSelectorsBadFormats() { ctx, test.BackupGetter, "backup-ID", - test.Opts) + test.Opts, + false) assert.Error(t, err) assert.Empty(t, output) }) diff --git a/src/cli/backup/sharepoint.go b/src/cli/backup/sharepoint.go index 00239d8b1..e3b4ef6d7 100644 --- a/src/cli/backup/sharepoint.go +++ b/src/cli/backup/sharepoint.go @@ -114,6 +114,8 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command { c.Use = c.Use + " " + sharePointServiceCommandDetailsUseSuffix c.Example = sharePointServiceCommandDetailsExamples + options.AddSkipReduceFlag(c) + fs.StringVar(&backupID, utils.BackupFN, "", "ID of the backup to retrieve.") @@ -479,7 +481,9 @@ func detailsSharePointCmd(cmd *cobra.Command, args []string) error { return Only(ctx, err) } - r, err := repository.Connect(ctx, acct, s, options.Control()) + ctrlOpts := options.Control() + + r, err := repository.Connect(ctx, acct, s, ctrlOpts) if err != nil { return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) } @@ -495,7 +499,7 @@ func detailsSharePointCmd(cmd *cobra.Command, args []string) error { Populated: utils.GetPopulatedFlags(cmd), } - ds, err := runDetailsSharePointCmd(ctx, r, backupID, opts) + ds, err := runDetailsSharePointCmd(ctx, r, backupID, opts, ctrlOpts.SkipReduce) if err != nil { return Only(ctx, err) } @@ -518,6 +522,7 @@ func runDetailsSharePointCmd( r repository.BackupGetter, backupID string, opts utils.SharePointOpts, + skipReduce bool, ) (*details.Details, error) { if err := utils.ValidateSharePointRestoreFlags(backupID, opts); err != nil { return nil, err @@ -533,8 +538,11 @@ func runDetailsSharePointCmd( return nil, errors.Wrap(errs.Failure(), "Failed to get backup details in the repository") } - sel := utils.IncludeSharePointRestoreDataSelectors(opts) - utils.FilterSharePointRestoreInfoSelectors(sel, opts) + if !skipReduce { + sel := utils.IncludeSharePointRestoreDataSelectors(opts) + utils.FilterSharePointRestoreInfoSelectors(sel, opts) + d = sel.Reduce(ctx, d, errs) + } - return sel.Reduce(ctx, d, errs), nil + return d, nil } diff --git a/src/cli/backup/sharepoint_test.go b/src/cli/backup/sharepoint_test.go index e8e046fc0..705ee8e2f 100644 --- a/src/cli/backup/sharepoint_test.go +++ b/src/cli/backup/sharepoint_test.go @@ -219,7 +219,8 @@ func (suite *SharePointSuite) TestSharePointBackupDetailsSelectors() { ctx, test.BackupGetter, "backup-ID", - test.Opts) + test.Opts, + false) assert.NoError(t, err) assert.ElementsMatch(t, test.Expected, output.Entries) }) @@ -238,7 +239,8 @@ func (suite *SharePointSuite) TestSharePointBackupDetailsSelectorsBadFormats() { ctx, test.BackupGetter, "backup-ID", - test.Opts) + test.Opts, + false) assert.Error(t, err) assert.Empty(t, output) }) diff --git a/src/cli/options/options.go b/src/cli/options/options.go index 2b423836c..2aeb53ea8 100644 --- a/src/cli/options/options.go +++ b/src/cli/options/options.go @@ -14,6 +14,7 @@ func Control() control.Options { opt.FailFast = fastFail opt.DisableMetrics = noStats opt.RestorePermissions = restorePermissions + opt.SkipReduce = skipReduce opt.ToggleFeatures.DisableIncrementals = disableIncrementals opt.ToggleFeatures.EnablePermissionsBackup = enablePermissionsBackup @@ -28,6 +29,7 @@ var ( fastFail bool noStats bool restorePermissions bool + skipReduce bool ) // AddOperationFlags adds command-local operation flags @@ -52,6 +54,14 @@ func AddRestorePermissionsFlag(cmd *cobra.Command) { cobra.CheckErr(fs.MarkHidden("restore-permissions")) } +// AddSkipReduceFlag adds a hidden flag that allows callers to skip the selector +// reduction step. Currently only intended for details commands, not restore. +func AddSkipReduceFlag(cmd *cobra.Command) { + fs := cmd.Flags() + fs.BoolVar(&skipReduce, "skip-reduce", false, "Skip the selector reduce filtering") + cobra.CheckErr(fs.MarkHidden("skip-reduce")) +} + // --------------------------------------------------------------------------- // Feature Flags // --------------------------------------------------------------------------- diff --git a/src/pkg/control/options.go b/src/pkg/control/options.go index 7348e8fa6..aecaef46e 100644 --- a/src/pkg/control/options.go +++ b/src/pkg/control/options.go @@ -10,6 +10,7 @@ type Options struct { DisableMetrics bool `json:"disableMetrics"` FailFast bool `json:"failFast"` RestorePermissions bool `json:"restorePermissions"` + SkipReduce bool `json:"skipReduce"` ToggleFeatures Toggles `json:"ToggleFeatures"` }