Handle SyncStateInvalid error when ImmutableIDs are enabled after initial backup (#3176)

Handles the `SyncStateInvalid` error if a delta URL constructed without the immutable ID header is used.

This will fallback to full backup similar to how we handle other sync errors for delta queries.

Also adds a hidden flag so we can test this using the CLI.

*Note*: Enabling immutable IDs for exchange is not yet supported

---

#### Does this PR need a docs update or release note?

- [ ]  Yes, it's included
- [ ] 🕐 Yes, but in a later PR
- [x]  No

#### Type of change

<!--- Please check the type of change your PR introduces: --->
- [ ] 🌻 Feature
- [x] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Supportability/Tests
- [ ] 💻 CI/Deployment
- [ ] 🧹 Tech Debt/Cleanup

#### Issue(s)

<!-- Can reference multiple issues. Use one of the following "magic words" - "closes, fixes" to auto-close the Github issue. -->
* #<issue>

#### Test Plan

<!-- How will this be tested prior to merging.-->
- [ ] 💪 Manual
- [x]  Unit test
- [ ] 💚 E2E
This commit is contained in:
Vaibhav Kamra 2023-04-19 16:52:08 -07:00 committed by GitHub
parent 306db14339
commit 2050a953fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 1 deletions

View File

@ -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())

View File

@ -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))
}

View File

@ -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)
}

View File

@ -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",