diff --git a/src/cli/backup/exchange.go b/src/cli/backup/exchange.go index e5bcecf96..b0eac0bdf 100644 --- a/src/cli/backup/exchange.go +++ b/src/cli/backup/exchange.go @@ -88,6 +88,7 @@ func addExchangeCommands(cmd *cobra.Command) *cobra.Command { options.AddFetchParallelismFlag(c) options.AddFailFastFlag(c) options.AddDisableIncrementalsFlag(c) + options.AddEnableImmutableIDFlag(c) case listCommand: c, fs = utils.AddCommand(cmd, exchangeListCmd()) diff --git a/src/cli/options/options.go b/src/cli/options/options.go index 153da734f..626ad2115 100644 --- a/src/cli/options/options.go +++ b/src/cli/options/options.go @@ -18,6 +18,7 @@ func Control() control.Options { opt.RestorePermissions = restorePermissionsFV opt.SkipReduce = skipReduceFV opt.ToggleFeatures.DisableIncrementals = disableIncrementalsFV + opt.ToggleFeatures.ExchangeImmutableIDs = enableImmutableID opt.ItemFetchParallelism = fetchParallelismFV return opt @@ -34,6 +35,7 @@ const ( RestorePermissionsFN = "restore-permissions" SkipReduceFN = "skip-reduce" DisableIncrementalsFN = "disable-incrementals" + EnableImmutableIDFN = "enable-immutable-id" ) var ( @@ -101,3 +103,17 @@ func AddDisableIncrementalsFlag(cmd *cobra.Command) { "Disable incremental data retrieval in backups.") cobra.CheckErr(fs.MarkHidden(DisableIncrementalsFN)) } + +var enableImmutableID bool + +// Adds the hidden '--enable-immutable-id' cli flag which, when set, enables +// immutable IDs for Exchange +func AddEnableImmutableIDFlag(cmd *cobra.Command) { + fs := cmd.Flags() + fs.BoolVar( + &enableImmutableID, + EnableImmutableIDFN, + false, + "Enable exchange immutable ID.") + cobra.CheckErr(fs.MarkHidden(EnableImmutableIDFN)) +} diff --git a/src/internal/connector/graph/errors.go b/src/internal/connector/graph/errors.go index b175457eb..f3f47da4b 100644 --- a/src/internal/connector/graph/errors.go +++ b/src/internal/connector/graph/errors.go @@ -34,6 +34,7 @@ const ( errCodeMalwareDetected = "malwareDetected" errCodeSyncFolderNotFound = "ErrorSyncFolderNotFound" errCodeSyncStateNotFound = "SyncStateNotFound" + errCodeSyncStateInvalid = "SyncStateInvalid" errCodeResourceNotFound = "ResourceNotFound" errCodeRequestResourceNotFound = "Request_ResourceNotFound" errCodeMailboxNotEnabledForRESTAPI = "MailboxNotEnabledForRESTAPI" @@ -93,7 +94,7 @@ func IsErrDeletedInFlight(err error) bool { } func IsErrInvalidDelta(err error) bool { - return hasErrorCode(err, errCodeSyncStateNotFound, errCodeResyncRequired) || + return hasErrorCode(err, errCodeSyncStateNotFound, errCodeResyncRequired, errCodeSyncStateInvalid) || errors.Is(err, ErrInvalidDelta) } diff --git a/src/internal/connector/graph/errors_test.go b/src/internal/connector/graph/errors_test.go index f6f5788da..56b2fba1f 100644 --- a/src/internal/connector/graph/errors_test.go +++ b/src/internal/connector/graph/errors_test.go @@ -137,6 +137,11 @@ func (suite *GraphErrorsUnitSuite) TestIsErrInvalidDelta() { err: odErr(errCodeResyncRequired), expect: assert.True, }, + { + name: "sync state invalid oDataErr", + err: odErr(errCodeSyncStateInvalid), + expect: assert.True, + }, // next two tests are to make sure the checks are case insensitive { name: "resync-required oDataErr camelcase",