cetnralize restoreConfig (#3563)
centralizes all restore configuration management within a restoreConfig struct. This struct is owned by the control package, which allows it to be utilized by both CLI and SDK consumers. --- #### Does this PR need a docs update or release note? - [x] ⛔ No #### Type of change - [x] 🧹 Tech Debt/Cleanup #### Issue(s) * #3562 #### Test Plan - [x] ⚡ Unit test - [x] 💚 E2E
This commit is contained in:
parent
de589a4571
commit
960e8b79a0
@ -96,13 +96,13 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
defer utils.CloseRepo(ctx, r)
|
defer utils.CloseRepo(ctx, r)
|
||||||
|
|
||||||
dest := control.DefaultRestoreDestination(dttm.HumanReadable)
|
restoreCfg := control.DefaultRestoreConfig(dttm.HumanReadable)
|
||||||
Infof(ctx, "Restoring to folder %s", dest.ContainerName)
|
Infof(ctx, "Restoring to folder %s", restoreCfg.Location)
|
||||||
|
|
||||||
sel := utils.IncludeExchangeRestoreDataSelectors(opts)
|
sel := utils.IncludeExchangeRestoreDataSelectors(opts)
|
||||||
utils.FilterExchangeRestoreInfoSelectors(sel, opts)
|
utils.FilterExchangeRestoreInfoSelectors(sel, opts)
|
||||||
|
|
||||||
ro, err := r.NewRestore(ctx, utils.BackupIDFV, sel.Selector, dest)
|
ro, err := r.NewRestore(ctx, utils.BackupIDFV, sel.Selector, restoreCfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Only(ctx, clues.Wrap(err, "Failed to initialize Exchange restore"))
|
return Only(ctx, clues.Wrap(err, "Failed to initialize Exchange restore"))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -97,13 +97,13 @@ func restoreOneDriveCmd(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
defer utils.CloseRepo(ctx, r)
|
defer utils.CloseRepo(ctx, r)
|
||||||
|
|
||||||
dest := control.DefaultRestoreDestination(dttm.HumanReadableDriveItem)
|
restoreCfg := control.DefaultRestoreConfig(dttm.HumanReadableDriveItem)
|
||||||
Infof(ctx, "Restoring to folder %s", dest.ContainerName)
|
Infof(ctx, "Restoring to folder %s", restoreCfg.Location)
|
||||||
|
|
||||||
sel := utils.IncludeOneDriveRestoreDataSelectors(opts)
|
sel := utils.IncludeOneDriveRestoreDataSelectors(opts)
|
||||||
utils.FilterOneDriveRestoreInfoSelectors(sel, opts)
|
utils.FilterOneDriveRestoreInfoSelectors(sel, opts)
|
||||||
|
|
||||||
ro, err := r.NewRestore(ctx, utils.BackupIDFV, sel.Selector, dest)
|
ro, err := r.NewRestore(ctx, utils.BackupIDFV, sel.Selector, restoreCfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Only(ctx, clues.Wrap(err, "Failed to initialize OneDrive restore"))
|
return Only(ctx, clues.Wrap(err, "Failed to initialize OneDrive restore"))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -102,13 +102,13 @@ func restoreSharePointCmd(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
defer utils.CloseRepo(ctx, r)
|
defer utils.CloseRepo(ctx, r)
|
||||||
|
|
||||||
dest := control.DefaultRestoreDestination(dttm.HumanReadableDriveItem)
|
restoreCfg := control.DefaultRestoreConfig(dttm.HumanReadableDriveItem)
|
||||||
Infof(ctx, "Restoring to folder %s", dest.ContainerName)
|
Infof(ctx, "Restoring to folder %s", restoreCfg.Location)
|
||||||
|
|
||||||
sel := utils.IncludeSharePointRestoreDataSelectors(ctx, opts)
|
sel := utils.IncludeSharePointRestoreDataSelectors(ctx, opts)
|
||||||
utils.FilterSharePointRestoreInfoSelectors(sel, opts)
|
utils.FilterSharePointRestoreInfoSelectors(sel, opts)
|
||||||
|
|
||||||
ro, err := r.NewRestore(ctx, utils.BackupIDFV, sel.Selector, dest)
|
ro, err := r.NewRestore(ctx, utils.BackupIDFV, sel.Selector, restoreCfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Only(ctx, clues.Wrap(err, "Failed to initialize SharePoint restore"))
|
return Only(ctx, clues.Wrap(err, "Failed to initialize SharePoint restore"))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -83,9 +83,9 @@ func generateAndRestoreItems(
|
|||||||
items: items,
|
items: items,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
dest := control.DefaultRestoreDestination(dttm.SafeForTesting)
|
dest := control.DefaultRestoreConfig(dttm.SafeForTesting)
|
||||||
dest.ContainerName = destFldr
|
dest.Location = destFldr
|
||||||
print.Infof(ctx, "Restoring to folder %s", dest.ContainerName)
|
print.Infof(ctx, "Restoring to folder %s", dest.Location)
|
||||||
|
|
||||||
dataColls, err := buildCollections(
|
dataColls, err := buildCollections(
|
||||||
service,
|
service,
|
||||||
@ -163,7 +163,7 @@ type collection struct {
|
|||||||
func buildCollections(
|
func buildCollections(
|
||||||
service path.ServiceType,
|
service path.ServiceType,
|
||||||
tenant, user string,
|
tenant, user string,
|
||||||
dest control.RestoreDestination,
|
dest control.RestoreConfig,
|
||||||
colls []collection,
|
colls []collection,
|
||||||
) ([]data.RestoreCollection, error) {
|
) ([]data.RestoreCollection, error) {
|
||||||
collections := make([]data.RestoreCollection, 0, len(colls))
|
collections := make([]data.RestoreCollection, 0, len(colls))
|
||||||
@ -224,9 +224,9 @@ func generateAndRestoreDriveItems(
|
|||||||
ctx, flush := tester.NewContext(nil)
|
ctx, flush := tester.NewContext(nil)
|
||||||
defer flush()
|
defer flush()
|
||||||
|
|
||||||
dest := control.DefaultRestoreDestination(dttm.SafeForTesting)
|
dest := control.DefaultRestoreConfig(dttm.SafeForTesting)
|
||||||
dest.ContainerName = destFldr
|
dest.Location = destFldr
|
||||||
print.Infof(ctx, "Restoring to folder %s", dest.ContainerName)
|
print.Infof(ctx, "Restoring to folder %s", dest.Location)
|
||||||
|
|
||||||
var driveID string
|
var driveID string
|
||||||
|
|
||||||
@ -394,7 +394,7 @@ func generateAndRestoreDriveItems(
|
|||||||
Service: service,
|
Service: service,
|
||||||
Tenant: tenantID,
|
Tenant: tenantID,
|
||||||
ResourceOwners: []string{resourceOwner},
|
ResourceOwners: []string{resourceOwner},
|
||||||
Dest: tester.DefaultTestRestoreDestination(""),
|
RestoreCfg: tester.DefaultTestRestoreConfig(""),
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, collections, _, err := connector.GetCollectionsAndExpected(
|
_, _, collections, _, err := connector.GetCollectionsAndExpected(
|
||||||
|
|||||||
@ -233,7 +233,7 @@ func (gc *GraphConnector) ConsumeRestoreCollections(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
backupVersion int,
|
backupVersion int,
|
||||||
sels selectors.Selector,
|
sels selectors.Selector,
|
||||||
dest control.RestoreDestination,
|
restoreCfg control.RestoreConfig,
|
||||||
opts control.Options,
|
opts control.Options,
|
||||||
dcs []data.RestoreCollection,
|
dcs []data.RestoreCollection,
|
||||||
errs *fault.Bus,
|
errs *fault.Bus,
|
||||||
@ -251,13 +251,13 @@ func (gc *GraphConnector) ConsumeRestoreCollections(
|
|||||||
|
|
||||||
switch sels.Service {
|
switch sels.Service {
|
||||||
case selectors.ServiceExchange:
|
case selectors.ServiceExchange:
|
||||||
status, err = exchange.RestoreCollections(ctx, gc.AC, dest, dcs, deets, errs)
|
status, err = exchange.RestoreCollections(ctx, gc.AC, restoreCfg, dcs, deets, errs)
|
||||||
case selectors.ServiceOneDrive:
|
case selectors.ServiceOneDrive:
|
||||||
status, err = onedrive.RestoreCollections(
|
status, err = onedrive.RestoreCollections(
|
||||||
ctx,
|
ctx,
|
||||||
onedrive.NewRestoreHandler(gc.AC),
|
onedrive.NewRestoreHandler(gc.AC),
|
||||||
backupVersion,
|
backupVersion,
|
||||||
dest,
|
restoreCfg,
|
||||||
opts,
|
opts,
|
||||||
dcs,
|
dcs,
|
||||||
deets,
|
deets,
|
||||||
@ -267,7 +267,7 @@ func (gc *GraphConnector) ConsumeRestoreCollections(
|
|||||||
ctx,
|
ctx,
|
||||||
backupVersion,
|
backupVersion,
|
||||||
gc.AC,
|
gc.AC,
|
||||||
dest,
|
restoreCfg,
|
||||||
opts,
|
opts,
|
||||||
dcs,
|
dcs,
|
||||||
deets,
|
deets,
|
||||||
|
|||||||
@ -51,7 +51,7 @@ func (suite *ContactsRestoreIntgSuite) TestCreateContainerDestination() {
|
|||||||
path.EmailCategory,
|
path.EmailCategory,
|
||||||
suite.creds.AzureTenantID,
|
suite.creds.AzureTenantID,
|
||||||
suite.userID,
|
suite.userID,
|
||||||
tester.DefaultTestRestoreDestination("").ContainerName,
|
tester.DefaultTestRestoreConfig("").Location,
|
||||||
[]string{"Hufflepuff"},
|
[]string{"Hufflepuff"},
|
||||||
[]string{"Ravenclaw"})
|
[]string{"Ravenclaw"})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,7 +51,7 @@ func (suite *EventsRestoreIntgSuite) TestCreateContainerDestination() {
|
|||||||
path.EmailCategory,
|
path.EmailCategory,
|
||||||
suite.creds.AzureTenantID,
|
suite.creds.AzureTenantID,
|
||||||
suite.userID,
|
suite.userID,
|
||||||
tester.DefaultTestRestoreDestination("").ContainerName,
|
tester.DefaultTestRestoreConfig("").Location,
|
||||||
[]string{"Durmstrang"},
|
[]string{"Durmstrang"},
|
||||||
[]string{"Beauxbatons"})
|
[]string{"Beauxbatons"})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,7 +51,7 @@ func (suite *MailRestoreIntgSuite) TestCreateContainerDestination() {
|
|||||||
path.EmailCategory,
|
path.EmailCategory,
|
||||||
suite.creds.AzureTenantID,
|
suite.creds.AzureTenantID,
|
||||||
suite.userID,
|
suite.userID,
|
||||||
tester.DefaultTestRestoreDestination("").ContainerName,
|
tester.DefaultTestRestoreConfig("").Location,
|
||||||
[]string{"Griffindor", "Croix"},
|
[]string{"Griffindor", "Croix"},
|
||||||
[]string{"Griffindor", "Felicius"})
|
[]string{"Griffindor", "Felicius"})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,7 +54,7 @@ func (suite *RestoreIntgSuite) TestRestoreContact() {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
userID = tester.M365UserID(t)
|
userID = tester.M365UserID(t)
|
||||||
folderName = tester.DefaultTestRestoreDestination("contact").ContainerName
|
folderName = tester.DefaultTestRestoreConfig("contact").Location
|
||||||
handler = newContactRestoreHandler(suite.ac)
|
handler = newContactRestoreHandler(suite.ac)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ func (suite *RestoreIntgSuite) TestRestoreEvent() {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
userID = tester.M365UserID(t)
|
userID = tester.M365UserID(t)
|
||||||
subject = tester.DefaultTestRestoreDestination("event").ContainerName
|
subject = tester.DefaultTestRestoreConfig("event").Location
|
||||||
handler = newEventRestoreHandler(suite.ac)
|
handler = newEventRestoreHandler(suite.ac)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ func (suite *RestoreIntgSuite) TestRestoreExchangeObject() {
|
|||||||
bytes: exchMock.MessageBytes("Restore Exchange Object"),
|
bytes: exchMock.MessageBytes("Restore Exchange Object"),
|
||||||
category: path.EmailCategory,
|
category: path.EmailCategory,
|
||||||
destination: func(t *testing.T, ctx context.Context) string {
|
destination: func(t *testing.T, ctx context.Context) string {
|
||||||
folderName := tester.DefaultTestRestoreDestination("mailobj").ContainerName
|
folderName := tester.DefaultTestRestoreConfig("mailobj").Location
|
||||||
folder, err := handlers[path.EmailCategory].
|
folder, err := handlers[path.EmailCategory].
|
||||||
CreateContainer(ctx, userID, folderName, "")
|
CreateContainer(ctx, userID, folderName, "")
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
@ -167,7 +167,7 @@ func (suite *RestoreIntgSuite) TestRestoreExchangeObject() {
|
|||||||
bytes: exchMock.MessageWithDirectAttachment("Restore 1 Attachment"),
|
bytes: exchMock.MessageWithDirectAttachment("Restore 1 Attachment"),
|
||||||
category: path.EmailCategory,
|
category: path.EmailCategory,
|
||||||
destination: func(t *testing.T, ctx context.Context) string {
|
destination: func(t *testing.T, ctx context.Context) string {
|
||||||
folderName := tester.DefaultTestRestoreDestination("mailwattch").ContainerName
|
folderName := tester.DefaultTestRestoreConfig("mailwattch").Location
|
||||||
folder, err := handlers[path.EmailCategory].
|
folder, err := handlers[path.EmailCategory].
|
||||||
CreateContainer(ctx, userID, folderName, "")
|
CreateContainer(ctx, userID, folderName, "")
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
@ -180,7 +180,7 @@ func (suite *RestoreIntgSuite) TestRestoreExchangeObject() {
|
|||||||
bytes: exchMock.MessageWithItemAttachmentEvent("Event Item Attachment"),
|
bytes: exchMock.MessageWithItemAttachmentEvent("Event Item Attachment"),
|
||||||
category: path.EmailCategory,
|
category: path.EmailCategory,
|
||||||
destination: func(t *testing.T, ctx context.Context) string {
|
destination: func(t *testing.T, ctx context.Context) string {
|
||||||
folderName := tester.DefaultTestRestoreDestination("eventwattch").ContainerName
|
folderName := tester.DefaultTestRestoreConfig("eventwattch").Location
|
||||||
folder, err := handlers[path.EmailCategory].
|
folder, err := handlers[path.EmailCategory].
|
||||||
CreateContainer(ctx, userID, folderName, "")
|
CreateContainer(ctx, userID, folderName, "")
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
@ -193,7 +193,7 @@ func (suite *RestoreIntgSuite) TestRestoreExchangeObject() {
|
|||||||
bytes: exchMock.MessageWithItemAttachmentMail("Mail Item Attachment"),
|
bytes: exchMock.MessageWithItemAttachmentMail("Mail Item Attachment"),
|
||||||
category: path.EmailCategory,
|
category: path.EmailCategory,
|
||||||
destination: func(t *testing.T, ctx context.Context) string {
|
destination: func(t *testing.T, ctx context.Context) string {
|
||||||
folderName := tester.DefaultTestRestoreDestination("mailitemattch").ContainerName
|
folderName := tester.DefaultTestRestoreConfig("mailitemattch").Location
|
||||||
folder, err := handlers[path.EmailCategory].
|
folder, err := handlers[path.EmailCategory].
|
||||||
CreateContainer(ctx, userID, folderName, "")
|
CreateContainer(ctx, userID, folderName, "")
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
@ -209,7 +209,7 @@ func (suite *RestoreIntgSuite) TestRestoreExchangeObject() {
|
|||||||
),
|
),
|
||||||
category: path.EmailCategory,
|
category: path.EmailCategory,
|
||||||
destination: func(t *testing.T, ctx context.Context) string {
|
destination: func(t *testing.T, ctx context.Context) string {
|
||||||
folderName := tester.DefaultTestRestoreDestination("mailbasicattch").ContainerName
|
folderName := tester.DefaultTestRestoreConfig("mailbasicattch").Location
|
||||||
folder, err := handlers[path.EmailCategory].
|
folder, err := handlers[path.EmailCategory].
|
||||||
CreateContainer(ctx, userID, folderName, "")
|
CreateContainer(ctx, userID, folderName, "")
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
@ -225,7 +225,7 @@ func (suite *RestoreIntgSuite) TestRestoreExchangeObject() {
|
|||||||
),
|
),
|
||||||
category: path.EmailCategory,
|
category: path.EmailCategory,
|
||||||
destination: func(t *testing.T, ctx context.Context) string {
|
destination: func(t *testing.T, ctx context.Context) string {
|
||||||
folderName := tester.DefaultTestRestoreDestination("mailnestattch").ContainerName
|
folderName := tester.DefaultTestRestoreConfig("mailnestattch").Location
|
||||||
folder, err := handlers[path.EmailCategory].
|
folder, err := handlers[path.EmailCategory].
|
||||||
CreateContainer(ctx, userID, folderName, "")
|
CreateContainer(ctx, userID, folderName, "")
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
@ -241,7 +241,7 @@ func (suite *RestoreIntgSuite) TestRestoreExchangeObject() {
|
|||||||
),
|
),
|
||||||
category: path.EmailCategory,
|
category: path.EmailCategory,
|
||||||
destination: func(t *testing.T, ctx context.Context) string {
|
destination: func(t *testing.T, ctx context.Context) string {
|
||||||
folderName := tester.DefaultTestRestoreDestination("mailcontactattch").ContainerName
|
folderName := tester.DefaultTestRestoreConfig("mailcontactattch").Location
|
||||||
folder, err := handlers[path.EmailCategory].
|
folder, err := handlers[path.EmailCategory].
|
||||||
CreateContainer(ctx, userID, folderName, "")
|
CreateContainer(ctx, userID, folderName, "")
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
@ -254,7 +254,7 @@ func (suite *RestoreIntgSuite) TestRestoreExchangeObject() {
|
|||||||
bytes: exchMock.MessageWithNestedItemAttachmentEvent("Nested Item Attachment"),
|
bytes: exchMock.MessageWithNestedItemAttachmentEvent("Nested Item Attachment"),
|
||||||
category: path.EmailCategory,
|
category: path.EmailCategory,
|
||||||
destination: func(t *testing.T, ctx context.Context) string {
|
destination: func(t *testing.T, ctx context.Context) string {
|
||||||
folderName := tester.DefaultTestRestoreDestination("nestedattch").ContainerName
|
folderName := tester.DefaultTestRestoreConfig("nestedattch").Location
|
||||||
folder, err := handlers[path.EmailCategory].
|
folder, err := handlers[path.EmailCategory].
|
||||||
CreateContainer(ctx, userID, folderName, "")
|
CreateContainer(ctx, userID, folderName, "")
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
@ -267,7 +267,7 @@ func (suite *RestoreIntgSuite) TestRestoreExchangeObject() {
|
|||||||
bytes: exchMock.MessageWithLargeAttachment("Restore Large Attachment"),
|
bytes: exchMock.MessageWithLargeAttachment("Restore Large Attachment"),
|
||||||
category: path.EmailCategory,
|
category: path.EmailCategory,
|
||||||
destination: func(t *testing.T, ctx context.Context) string {
|
destination: func(t *testing.T, ctx context.Context) string {
|
||||||
folderName := tester.DefaultTestRestoreDestination("maillargeattch").ContainerName
|
folderName := tester.DefaultTestRestoreConfig("maillargeattch").Location
|
||||||
folder, err := handlers[path.EmailCategory].
|
folder, err := handlers[path.EmailCategory].
|
||||||
CreateContainer(ctx, userID, folderName, "")
|
CreateContainer(ctx, userID, folderName, "")
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
@ -280,7 +280,7 @@ func (suite *RestoreIntgSuite) TestRestoreExchangeObject() {
|
|||||||
bytes: exchMock.MessageWithTwoAttachments("Restore 2 Attachments"),
|
bytes: exchMock.MessageWithTwoAttachments("Restore 2 Attachments"),
|
||||||
category: path.EmailCategory,
|
category: path.EmailCategory,
|
||||||
destination: func(t *testing.T, ctx context.Context) string {
|
destination: func(t *testing.T, ctx context.Context) string {
|
||||||
folderName := tester.DefaultTestRestoreDestination("mailtwoattch").ContainerName
|
folderName := tester.DefaultTestRestoreConfig("mailtwoattch").Location
|
||||||
folder, err := handlers[path.EmailCategory].
|
folder, err := handlers[path.EmailCategory].
|
||||||
CreateContainer(ctx, userID, folderName, "")
|
CreateContainer(ctx, userID, folderName, "")
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
@ -293,7 +293,7 @@ func (suite *RestoreIntgSuite) TestRestoreExchangeObject() {
|
|||||||
bytes: exchMock.MessageWithOneDriveAttachment("Restore Reference(OneDrive) Attachment"),
|
bytes: exchMock.MessageWithOneDriveAttachment("Restore Reference(OneDrive) Attachment"),
|
||||||
category: path.EmailCategory,
|
category: path.EmailCategory,
|
||||||
destination: func(t *testing.T, ctx context.Context) string {
|
destination: func(t *testing.T, ctx context.Context) string {
|
||||||
folderName := tester.DefaultTestRestoreDestination("mailrefattch").ContainerName
|
folderName := tester.DefaultTestRestoreConfig("mailrefattch").Location
|
||||||
folder, err := handlers[path.EmailCategory].
|
folder, err := handlers[path.EmailCategory].
|
||||||
CreateContainer(ctx, userID, folderName, "")
|
CreateContainer(ctx, userID, folderName, "")
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
@ -306,7 +306,7 @@ func (suite *RestoreIntgSuite) TestRestoreExchangeObject() {
|
|||||||
bytes: exchMock.ContactBytes("Test_Omega"),
|
bytes: exchMock.ContactBytes("Test_Omega"),
|
||||||
category: path.ContactsCategory,
|
category: path.ContactsCategory,
|
||||||
destination: func(t *testing.T, ctx context.Context) string {
|
destination: func(t *testing.T, ctx context.Context) string {
|
||||||
folderName := tester.DefaultTestRestoreDestination("contact").ContainerName
|
folderName := tester.DefaultTestRestoreConfig("contact").Location
|
||||||
folder, err := handlers[path.ContactsCategory].
|
folder, err := handlers[path.ContactsCategory].
|
||||||
CreateContainer(ctx, userID, folderName, "")
|
CreateContainer(ctx, userID, folderName, "")
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
@ -319,7 +319,7 @@ func (suite *RestoreIntgSuite) TestRestoreExchangeObject() {
|
|||||||
bytes: exchMock.EventBytes("Restored Event Object"),
|
bytes: exchMock.EventBytes("Restored Event Object"),
|
||||||
category: path.EventsCategory,
|
category: path.EventsCategory,
|
||||||
destination: func(t *testing.T, ctx context.Context) string {
|
destination: func(t *testing.T, ctx context.Context) string {
|
||||||
folderName := tester.DefaultTestRestoreDestination("event").ContainerName
|
folderName := tester.DefaultTestRestoreConfig("event").Location
|
||||||
calendar, err := handlers[path.EventsCategory].
|
calendar, err := handlers[path.EventsCategory].
|
||||||
CreateContainer(ctx, userID, folderName, "")
|
CreateContainer(ctx, userID, folderName, "")
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
@ -332,7 +332,7 @@ func (suite *RestoreIntgSuite) TestRestoreExchangeObject() {
|
|||||||
bytes: exchMock.EventWithAttachment("Restored Event Attachment"),
|
bytes: exchMock.EventWithAttachment("Restored Event Attachment"),
|
||||||
category: path.EventsCategory,
|
category: path.EventsCategory,
|
||||||
destination: func(t *testing.T, ctx context.Context) string {
|
destination: func(t *testing.T, ctx context.Context) string {
|
||||||
folderName := tester.DefaultTestRestoreDestination("eventobj").ContainerName
|
folderName := tester.DefaultTestRestoreConfig("eventobj").Location
|
||||||
calendar, err := handlers[path.EventsCategory].
|
calendar, err := handlers[path.EventsCategory].
|
||||||
CreateContainer(ctx, userID, folderName, "")
|
CreateContainer(ctx, userID, folderName, "")
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
|
|||||||
@ -190,7 +190,7 @@ func (suite *ServiceIteratorsSuite) TestFilterContainersAndFillCollections() {
|
|||||||
getter mockGetter
|
getter mockGetter
|
||||||
resolver graph.ContainerResolver
|
resolver graph.ContainerResolver
|
||||||
scope selectors.ExchangeScope
|
scope selectors.ExchangeScope
|
||||||
failFast control.FailureBehavior
|
failFast control.FailurePolicy
|
||||||
expectErr assert.ErrorAssertionFunc
|
expectErr assert.ErrorAssertionFunc
|
||||||
expectNewColls int
|
expectNewColls int
|
||||||
expectMetadataColls int
|
expectMetadataColls int
|
||||||
|
|||||||
@ -27,7 +27,7 @@ import (
|
|||||||
func RestoreCollections(
|
func RestoreCollections(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
ac api.Client,
|
ac api.Client,
|
||||||
dest control.RestoreDestination,
|
restoreCfg control.RestoreConfig,
|
||||||
dcs []data.RestoreCollection,
|
dcs []data.RestoreCollection,
|
||||||
deets *details.Builder,
|
deets *details.Builder,
|
||||||
errs *fault.Bus,
|
errs *fault.Bus,
|
||||||
@ -76,7 +76,7 @@ func RestoreCollections(
|
|||||||
containerID, gcr, err := createDestination(
|
containerID, gcr, err := createDestination(
|
||||||
ictx,
|
ictx,
|
||||||
handler,
|
handler,
|
||||||
handler.formatRestoreDestination(dest.ContainerName, dc.FullPath()),
|
handler.formatRestoreDestination(restoreCfg.Location, dc.FullPath()),
|
||||||
userID,
|
userID,
|
||||||
directoryCache[category],
|
directoryCache[category],
|
||||||
isNewCache,
|
isNewCache,
|
||||||
@ -116,7 +116,7 @@ func RestoreCollections(
|
|||||||
support.Restore,
|
support.Restore,
|
||||||
len(dcs),
|
len(dcs),
|
||||||
metrics,
|
metrics,
|
||||||
dest.ContainerName)
|
restoreCfg.Location)
|
||||||
|
|
||||||
return status, el.Failure()
|
return status, el.Failure()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -936,7 +936,7 @@ func checkCollections(
|
|||||||
category = returned.FullPath().Category()
|
category = returned.FullPath().Category()
|
||||||
expectedColData = expected[returned.FullPath().String()]
|
expectedColData = expected[returned.FullPath().String()]
|
||||||
folders = returned.FullPath().Elements()
|
folders = returned.FullPath().Elements()
|
||||||
rootDir = folders[len(folders)-1] == config.Dest.ContainerName
|
rootDir = folders[len(folders)-1] == config.RestoreCfg.Location
|
||||||
)
|
)
|
||||||
|
|
||||||
// Need to iterate through all items even if we don't expect to find a match
|
// Need to iterate through all items even if we don't expect to find a match
|
||||||
|
|||||||
@ -339,7 +339,7 @@ func GetCollectionsAndExpected(
|
|||||||
config.Service,
|
config.Service,
|
||||||
config.Tenant,
|
config.Tenant,
|
||||||
owner,
|
owner,
|
||||||
config.Dest,
|
config.RestoreCfg,
|
||||||
testCollections,
|
testCollections,
|
||||||
backupVersion,
|
backupVersion,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -293,8 +293,8 @@ func (suite *GraphConnectorIntegrationSuite) TestRestoreFailsBadService() {
|
|||||||
defer flush()
|
defer flush()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
dest = tester.DefaultTestRestoreDestination("")
|
restoreCfg = tester.DefaultTestRestoreConfig("")
|
||||||
sel = selectors.Selector{
|
sel = selectors.Selector{
|
||||||
Service: selectors.ServiceUnknown,
|
Service: selectors.ServiceUnknown,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -303,7 +303,7 @@ func (suite *GraphConnectorIntegrationSuite) TestRestoreFailsBadService() {
|
|||||||
ctx,
|
ctx,
|
||||||
version.Backup,
|
version.Backup,
|
||||||
sel,
|
sel,
|
||||||
dest,
|
restoreCfg,
|
||||||
control.Options{
|
control.Options{
|
||||||
RestorePermissions: true,
|
RestorePermissions: true,
|
||||||
ToggleFeatures: control.Toggles{},
|
ToggleFeatures: control.Toggles{},
|
||||||
@ -320,7 +320,7 @@ func (suite *GraphConnectorIntegrationSuite) TestRestoreFailsBadService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *GraphConnectorIntegrationSuite) TestEmptyCollections() {
|
func (suite *GraphConnectorIntegrationSuite) TestEmptyCollections() {
|
||||||
dest := tester.DefaultTestRestoreDestination("")
|
restoreCfg := tester.DefaultTestRestoreConfig("")
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
col []data.RestoreCollection
|
col []data.RestoreCollection
|
||||||
@ -381,7 +381,7 @@ func (suite *GraphConnectorIntegrationSuite) TestEmptyCollections() {
|
|||||||
ctx,
|
ctx,
|
||||||
version.Backup,
|
version.Backup,
|
||||||
test.sel,
|
test.sel,
|
||||||
dest,
|
restoreCfg,
|
||||||
control.Options{
|
control.Options{
|
||||||
RestorePermissions: true,
|
RestorePermissions: true,
|
||||||
ToggleFeatures: control.Toggles{},
|
ToggleFeatures: control.Toggles{},
|
||||||
@ -413,7 +413,7 @@ func runRestore(
|
|||||||
) {
|
) {
|
||||||
t.Logf(
|
t.Logf(
|
||||||
"Restoring collections to %s for resourceOwners(s) %v\n",
|
"Restoring collections to %s for resourceOwners(s) %v\n",
|
||||||
config.Dest.ContainerName,
|
config.RestoreCfg.Location,
|
||||||
config.ResourceOwners)
|
config.ResourceOwners)
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
@ -424,7 +424,7 @@ func runRestore(
|
|||||||
ctx,
|
ctx,
|
||||||
backupVersion,
|
backupVersion,
|
||||||
restoreSel,
|
restoreSel,
|
||||||
config.Dest,
|
config.RestoreCfg,
|
||||||
config.Opts,
|
config.Opts,
|
||||||
collections,
|
collections,
|
||||||
fault.New(true))
|
fault.New(true))
|
||||||
@ -472,7 +472,7 @@ func runBackupAndCompare(
|
|||||||
for _, ro := range config.ResourceOwners {
|
for _, ro := range config.ResourceOwners {
|
||||||
expectedDests = append(expectedDests, destAndCats{
|
expectedDests = append(expectedDests, destAndCats{
|
||||||
resourceOwner: ro,
|
resourceOwner: ro,
|
||||||
dest: config.Dest.ContainerName,
|
dest: config.RestoreCfg.Location,
|
||||||
cats: cats,
|
cats: cats,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -536,7 +536,7 @@ func runRestoreBackupTest(
|
|||||||
Service: test.service,
|
Service: test.service,
|
||||||
Tenant: tenant,
|
Tenant: tenant,
|
||||||
ResourceOwners: resourceOwners,
|
ResourceOwners: resourceOwners,
|
||||||
Dest: tester.DefaultTestRestoreDestination(""),
|
RestoreCfg: tester.DefaultTestRestoreConfig(""),
|
||||||
}
|
}
|
||||||
|
|
||||||
totalItems, totalKopiaItems, collections, expectedData, err := GetCollectionsAndExpected(
|
totalItems, totalKopiaItems, collections, expectedData, err := GetCollectionsAndExpected(
|
||||||
@ -581,7 +581,7 @@ func runRestoreTestWithVersion(
|
|||||||
Service: test.service,
|
Service: test.service,
|
||||||
Tenant: tenant,
|
Tenant: tenant,
|
||||||
ResourceOwners: resourceOwners,
|
ResourceOwners: resourceOwners,
|
||||||
Dest: tester.DefaultTestRestoreDestination(""),
|
RestoreCfg: tester.DefaultTestRestoreConfig(""),
|
||||||
}
|
}
|
||||||
|
|
||||||
totalItems, _, collections, _, err := GetCollectionsAndExpected(
|
totalItems, _, collections, _, err := GetCollectionsAndExpected(
|
||||||
@ -618,7 +618,7 @@ func runRestoreBackupTestVersions(
|
|||||||
Service: test.service,
|
Service: test.service,
|
||||||
Tenant: tenant,
|
Tenant: tenant,
|
||||||
ResourceOwners: resourceOwners,
|
ResourceOwners: resourceOwners,
|
||||||
Dest: tester.DefaultTestRestoreDestination(""),
|
RestoreCfg: tester.DefaultTestRestoreConfig(""),
|
||||||
}
|
}
|
||||||
|
|
||||||
totalItems, _, collections, _, err := GetCollectionsAndExpected(
|
totalItems, _, collections, _, err := GetCollectionsAndExpected(
|
||||||
@ -993,11 +993,11 @@ func (suite *GraphConnectorIntegrationSuite) TestMultiFolderBackupDifferentNames
|
|||||||
allExpectedData := map[string]map[string][]byte{}
|
allExpectedData := map[string]map[string][]byte{}
|
||||||
|
|
||||||
for i, collection := range test.collections {
|
for i, collection := range test.collections {
|
||||||
// Get a dest per collection so they're independent.
|
// Get a restoreCfg per collection so they're independent.
|
||||||
dest := tester.DefaultTestRestoreDestination("")
|
restoreCfg := tester.DefaultTestRestoreConfig("")
|
||||||
expectedDests = append(expectedDests, destAndCats{
|
expectedDests = append(expectedDests, destAndCats{
|
||||||
resourceOwner: suite.user,
|
resourceOwner: suite.user,
|
||||||
dest: dest.ContainerName,
|
dest: restoreCfg.Location,
|
||||||
cats: map[path.CategoryType]struct{}{
|
cats: map[path.CategoryType]struct{}{
|
||||||
collection.Category: {},
|
collection.Category: {},
|
||||||
},
|
},
|
||||||
@ -1007,7 +1007,7 @@ func (suite *GraphConnectorIntegrationSuite) TestMultiFolderBackupDifferentNames
|
|||||||
test.service,
|
test.service,
|
||||||
suite.connector.tenant,
|
suite.connector.tenant,
|
||||||
suite.user,
|
suite.user,
|
||||||
dest,
|
restoreCfg,
|
||||||
[]ColInfo{collection},
|
[]ColInfo{collection},
|
||||||
version.Backup,
|
version.Backup,
|
||||||
)
|
)
|
||||||
@ -1023,7 +1023,7 @@ func (suite *GraphConnectorIntegrationSuite) TestMultiFolderBackupDifferentNames
|
|||||||
"Restoring %v/%v collections to %s\n",
|
"Restoring %v/%v collections to %s\n",
|
||||||
i+1,
|
i+1,
|
||||||
len(test.collections),
|
len(test.collections),
|
||||||
dest.ContainerName,
|
restoreCfg.Location,
|
||||||
)
|
)
|
||||||
|
|
||||||
restoreGC := loadConnector(ctx, t, test.resource)
|
restoreGC := loadConnector(ctx, t, test.resource)
|
||||||
@ -1031,7 +1031,7 @@ func (suite *GraphConnectorIntegrationSuite) TestMultiFolderBackupDifferentNames
|
|||||||
ctx,
|
ctx,
|
||||||
version.Backup,
|
version.Backup,
|
||||||
restoreSel,
|
restoreSel,
|
||||||
dest,
|
restoreCfg,
|
||||||
control.Options{
|
control.Options{
|
||||||
RestorePermissions: true,
|
RestorePermissions: true,
|
||||||
ToggleFeatures: control.Toggles{},
|
ToggleFeatures: control.Toggles{},
|
||||||
@ -1081,7 +1081,7 @@ func (suite *GraphConnectorIntegrationSuite) TestMultiFolderBackupDifferentNames
|
|||||||
ci := ConfigInfo{
|
ci := ConfigInfo{
|
||||||
Opts: control.Options{RestorePermissions: true},
|
Opts: control.Options{RestorePermissions: true},
|
||||||
// Alright to be empty, needed for OneDrive.
|
// Alright to be empty, needed for OneDrive.
|
||||||
Dest: control.RestoreDestination{},
|
RestoreCfg: control.RestoreConfig{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pull the data prior to waiting for the status as otherwise it will
|
// Pull the data prior to waiting for the status as otherwise it will
|
||||||
|
|||||||
@ -43,7 +43,7 @@ type ConfigInfo struct {
|
|||||||
Service path.ServiceType
|
Service path.ServiceType
|
||||||
Tenant string
|
Tenant string
|
||||||
ResourceOwners []string
|
ResourceOwners []string
|
||||||
Dest control.RestoreDestination
|
RestoreCfg control.RestoreConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustToDataLayerPath(
|
func mustToDataLayerPath(
|
||||||
@ -66,15 +66,15 @@ func mustToDataLayerPath(
|
|||||||
// combination of the location the data was recently restored to and where the
|
// combination of the location the data was recently restored to and where the
|
||||||
// data was originally in the hierarchy.
|
// data was originally in the hierarchy.
|
||||||
func backupOutputPathFromRestore(
|
func backupOutputPathFromRestore(
|
||||||
restoreDest control.RestoreDestination,
|
restoreCfg control.RestoreConfig,
|
||||||
inputPath path.Path,
|
inputPath path.Path,
|
||||||
) (path.Path, error) {
|
) (path.Path, error) {
|
||||||
base := []string{restoreDest.ContainerName}
|
base := []string{restoreCfg.Location}
|
||||||
|
|
||||||
// OneDrive has leading information like the drive ID.
|
// OneDrive has leading information like the drive ID.
|
||||||
if inputPath.Service() == path.OneDriveService || inputPath.Service() == path.SharePointService {
|
if inputPath.Service() == path.OneDriveService || inputPath.Service() == path.SharePointService {
|
||||||
folders := inputPath.Folders()
|
folders := inputPath.Folders()
|
||||||
base = append(append([]string{}, folders[:3]...), restoreDest.ContainerName)
|
base = append(append([]string{}, folders[:3]...), restoreCfg.Location)
|
||||||
|
|
||||||
if len(folders) > 3 {
|
if len(folders) > 3 {
|
||||||
base = append(base, folders[3:]...)
|
base = append(base, folders[3:]...)
|
||||||
@ -117,7 +117,7 @@ func (rc mockRestoreCollection) FetchItemByName(
|
|||||||
func collectionsForInfo(
|
func collectionsForInfo(
|
||||||
service path.ServiceType,
|
service path.ServiceType,
|
||||||
tenant, user string,
|
tenant, user string,
|
||||||
dest control.RestoreDestination,
|
restoreCfg control.RestoreConfig,
|
||||||
allInfo []ColInfo,
|
allInfo []ColInfo,
|
||||||
backupVersion int,
|
backupVersion int,
|
||||||
) (int, int, []data.RestoreCollection, map[string]map[string][]byte, error) {
|
) (int, int, []data.RestoreCollection, map[string]map[string][]byte, error) {
|
||||||
@ -142,7 +142,7 @@ func collectionsForInfo(
|
|||||||
|
|
||||||
mc := exchMock.NewCollection(pth, pth, len(info.Items))
|
mc := exchMock.NewCollection(pth, pth, len(info.Items))
|
||||||
|
|
||||||
baseDestPath, err := backupOutputPathFromRestore(dest, pth)
|
baseDestPath, err := backupOutputPathFromRestore(restoreCfg, pth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return totalItems, kopiaEntries, collections, expectedData, err
|
return totalItems, kopiaEntries, collections, expectedData, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,7 +60,7 @@ func (gc GraphConnector) ConsumeRestoreCollections(
|
|||||||
_ context.Context,
|
_ context.Context,
|
||||||
_ int,
|
_ int,
|
||||||
_ selectors.Selector,
|
_ selectors.Selector,
|
||||||
_ control.RestoreDestination,
|
_ control.RestoreConfig,
|
||||||
_ control.Options,
|
_ control.Options,
|
||||||
_ []data.RestoreCollection,
|
_ []data.RestoreCollection,
|
||||||
_ *fault.Bus,
|
_ *fault.Bus,
|
||||||
|
|||||||
@ -155,7 +155,7 @@ func (suite *ItemIntegrationSuite) TestItemWriter() {
|
|||||||
root, err := suite.service.ac.Drives().GetRootFolder(ctx, test.driveID)
|
root, err := suite.service.ac.Drives().GetRootFolder(ctx, test.driveID)
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
|
|
||||||
newFolderName := tester.DefaultTestRestoreDestination("folder").ContainerName
|
newFolderName := tester.DefaultTestRestoreConfig("folder").Location
|
||||||
t.Logf("creating folder %s", newFolderName)
|
t.Logf("creating folder %s", newFolderName)
|
||||||
|
|
||||||
newFolder, err := rh.PostItemInContainer(
|
newFolder, err := rh.PostItemInContainer(
|
||||||
|
|||||||
@ -64,7 +64,7 @@ func RestoreCollections(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
rh RestoreHandler,
|
rh RestoreHandler,
|
||||||
backupVersion int,
|
backupVersion int,
|
||||||
dest control.RestoreDestination,
|
restoreCfg control.RestoreConfig,
|
||||||
opts control.Options,
|
opts control.Options,
|
||||||
dcs []data.RestoreCollection,
|
dcs []data.RestoreCollection,
|
||||||
deets *details.Builder,
|
deets *details.Builder,
|
||||||
@ -79,7 +79,7 @@ func RestoreCollections(
|
|||||||
ctx = clues.Add(
|
ctx = clues.Add(
|
||||||
ctx,
|
ctx,
|
||||||
"backup_version", backupVersion,
|
"backup_version", backupVersion,
|
||||||
"destination", dest.ContainerName)
|
"restore_location", restoreCfg.Location)
|
||||||
|
|
||||||
// Reorder collections so that the parents directories are created
|
// Reorder collections so that the parents directories are created
|
||||||
// before the child directories; a requirement for permissions.
|
// before the child directories; a requirement for permissions.
|
||||||
@ -97,7 +97,7 @@ func RestoreCollections(
|
|||||||
ictx = clues.Add(
|
ictx = clues.Add(
|
||||||
ctx,
|
ctx,
|
||||||
"category", dc.FullPath().Category(),
|
"category", dc.FullPath().Category(),
|
||||||
"destination", clues.Hide(dest.ContainerName),
|
"destination", clues.Hide(restoreCfg.Location),
|
||||||
"resource_owner", clues.Hide(dc.FullPath().ResourceOwner()),
|
"resource_owner", clues.Hide(dc.FullPath().ResourceOwner()),
|
||||||
"full_path", dc.FullPath())
|
"full_path", dc.FullPath())
|
||||||
)
|
)
|
||||||
@ -108,7 +108,7 @@ func RestoreCollections(
|
|||||||
backupVersion,
|
backupVersion,
|
||||||
dc,
|
dc,
|
||||||
caches,
|
caches,
|
||||||
dest.ContainerName,
|
restoreCfg.Location,
|
||||||
deets,
|
deets,
|
||||||
opts.RestorePermissions,
|
opts.RestorePermissions,
|
||||||
errs)
|
errs)
|
||||||
@ -128,7 +128,7 @@ func RestoreCollections(
|
|||||||
support.Restore,
|
support.Restore,
|
||||||
len(dcs),
|
len(dcs),
|
||||||
restoreMetrics,
|
restoreMetrics,
|
||||||
dest.ContainerName)
|
restoreCfg.Location)
|
||||||
|
|
||||||
return status, el.Failure()
|
return status, el.Failure()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -63,7 +63,7 @@ func (suite *URLCacheIntegrationSuite) TestURLCacheBasic() {
|
|||||||
t = suite.T()
|
t = suite.T()
|
||||||
ac = suite.ac.Drives()
|
ac = suite.ac.Drives()
|
||||||
driveID = suite.driveID
|
driveID = suite.driveID
|
||||||
newFolderName = tester.DefaultTestRestoreDestination("folder").ContainerName
|
newFolderName = tester.DefaultTestRestoreConfig("folder").Location
|
||||||
driveItemPager = suite.ac.Drives().NewItemPager(driveID, "", api.DriveItemSelectDefault())
|
driveItemPager = suite.ac.Drives().NewItemPager(driveID, "", api.DriveItemSelectDefault())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -92,7 +92,7 @@ func (suite *SharePointPageSuite) TestRestoreSinglePage() {
|
|||||||
ctx, flush := tester.NewContext(t)
|
ctx, flush := tester.NewContext(t)
|
||||||
defer flush()
|
defer flush()
|
||||||
|
|
||||||
destName := tester.DefaultTestRestoreDestination("").ContainerName
|
destName := tester.DefaultTestRestoreConfig("").Location
|
||||||
testName := "MockPage"
|
testName := "MockPage"
|
||||||
|
|
||||||
// Create Test Page
|
// Create Test Page
|
||||||
|
|||||||
@ -208,7 +208,7 @@ func (suite *SharePointCollectionSuite) TestListCollection_Restore() {
|
|||||||
info: sharePointListInfo(listing, int64(len(byteArray))),
|
info: sharePointListInfo(listing, int64(len(byteArray))),
|
||||||
}
|
}
|
||||||
|
|
||||||
destName := tester.DefaultTestRestoreDestination("").ContainerName
|
destName := tester.DefaultTestRestoreConfig("").Location
|
||||||
|
|
||||||
deets, err := restoreListItem(ctx, service, listData, suite.siteID, destName)
|
deets, err := restoreListItem(ctx, service, listData, suite.siteID, destName)
|
||||||
assert.NoError(t, err, clues.ToCore(err))
|
assert.NoError(t, err, clues.ToCore(err))
|
||||||
|
|||||||
@ -43,7 +43,7 @@ func RestoreCollections(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
backupVersion int,
|
backupVersion int,
|
||||||
ac api.Client,
|
ac api.Client,
|
||||||
dest control.RestoreDestination,
|
restoreCfg control.RestoreConfig,
|
||||||
opts control.Options,
|
opts control.Options,
|
||||||
dcs []data.RestoreCollection,
|
dcs []data.RestoreCollection,
|
||||||
deets *details.Builder,
|
deets *details.Builder,
|
||||||
@ -71,7 +71,7 @@ func RestoreCollections(
|
|||||||
metrics support.CollectionMetrics
|
metrics support.CollectionMetrics
|
||||||
ictx = clues.Add(ctx,
|
ictx = clues.Add(ctx,
|
||||||
"category", category,
|
"category", category,
|
||||||
"destination", clues.Hide(dest.ContainerName),
|
"restore_location", restoreCfg.Location,
|
||||||
"resource_owner", clues.Hide(dc.FullPath().ResourceOwner()),
|
"resource_owner", clues.Hide(dc.FullPath().ResourceOwner()),
|
||||||
"full_path", dc.FullPath())
|
"full_path", dc.FullPath())
|
||||||
)
|
)
|
||||||
@ -84,7 +84,7 @@ func RestoreCollections(
|
|||||||
backupVersion,
|
backupVersion,
|
||||||
dc,
|
dc,
|
||||||
caches,
|
caches,
|
||||||
dest.ContainerName,
|
restoreCfg.Location,
|
||||||
deets,
|
deets,
|
||||||
opts.RestorePermissions,
|
opts.RestorePermissions,
|
||||||
errs)
|
errs)
|
||||||
@ -94,7 +94,7 @@ func RestoreCollections(
|
|||||||
ictx,
|
ictx,
|
||||||
ac.Stable,
|
ac.Stable,
|
||||||
dc,
|
dc,
|
||||||
dest.ContainerName,
|
restoreCfg.Location,
|
||||||
deets,
|
deets,
|
||||||
errs)
|
errs)
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ func RestoreCollections(
|
|||||||
ictx,
|
ictx,
|
||||||
ac.Stable,
|
ac.Stable,
|
||||||
dc,
|
dc,
|
||||||
dest.ContainerName,
|
restoreCfg.Location,
|
||||||
deets,
|
deets,
|
||||||
errs)
|
errs)
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ func RestoreCollections(
|
|||||||
support.Restore,
|
support.Restore,
|
||||||
len(dcs),
|
len(dcs),
|
||||||
restoreMetrics,
|
restoreMetrics,
|
||||||
dest.ContainerName)
|
restoreCfg.Location)
|
||||||
|
|
||||||
return status, el.Failure()
|
return status, el.Failure()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -381,14 +381,14 @@ func generateContainerOfItems(
|
|||||||
items: items,
|
items: items,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
dest := control.DefaultRestoreDestination(dttm.SafeForTesting)
|
restoreCfg := control.DefaultRestoreConfig(dttm.SafeForTesting)
|
||||||
dest.ContainerName = destFldr
|
restoreCfg.Location = destFldr
|
||||||
|
|
||||||
dataColls := buildCollections(
|
dataColls := buildCollections(
|
||||||
t,
|
t,
|
||||||
service,
|
service,
|
||||||
tenantID, resourceOwner,
|
tenantID, resourceOwner,
|
||||||
dest,
|
restoreCfg,
|
||||||
collections)
|
collections)
|
||||||
|
|
||||||
opts := control.Defaults()
|
opts := control.Defaults()
|
||||||
@ -398,7 +398,7 @@ func generateContainerOfItems(
|
|||||||
ctx,
|
ctx,
|
||||||
backupVersion,
|
backupVersion,
|
||||||
sel,
|
sel,
|
||||||
dest,
|
restoreCfg,
|
||||||
opts,
|
opts,
|
||||||
dataColls,
|
dataColls,
|
||||||
fault.New(true))
|
fault.New(true))
|
||||||
@ -443,7 +443,7 @@ func buildCollections(
|
|||||||
t *testing.T,
|
t *testing.T,
|
||||||
service path.ServiceType,
|
service path.ServiceType,
|
||||||
tenant, user string,
|
tenant, user string,
|
||||||
dest control.RestoreDestination,
|
restoreCfg control.RestoreConfig,
|
||||||
colls []incrementalCollection,
|
colls []incrementalCollection,
|
||||||
) []data.RestoreCollection {
|
) []data.RestoreCollection {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|||||||
@ -37,7 +37,7 @@ type (
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
backupVersion int,
|
backupVersion int,
|
||||||
selector selectors.Selector,
|
selector selectors.Selector,
|
||||||
dest control.RestoreDestination,
|
restoreCfg control.RestoreConfig,
|
||||||
opts control.Options,
|
opts control.Options,
|
||||||
dcs []data.RestoreCollection,
|
dcs []data.RestoreCollection,
|
||||||
errs *fault.Bus,
|
errs *fault.Bus,
|
||||||
|
|||||||
@ -35,11 +35,11 @@ import (
|
|||||||
type RestoreOperation struct {
|
type RestoreOperation struct {
|
||||||
operation
|
operation
|
||||||
|
|
||||||
BackupID model.StableID `json:"backupID"`
|
BackupID model.StableID
|
||||||
Destination control.RestoreDestination `json:"destination"`
|
Results RestoreResults
|
||||||
Results RestoreResults `json:"results"`
|
Selectors selectors.Selector
|
||||||
Selectors selectors.Selector `json:"selectors"`
|
RestoreCfg control.RestoreConfig
|
||||||
Version string `json:"version"`
|
Version string
|
||||||
|
|
||||||
acct account.Account
|
acct account.Account
|
||||||
rc inject.RestoreConsumer
|
rc inject.RestoreConsumer
|
||||||
@ -61,17 +61,17 @@ func NewRestoreOperation(
|
|||||||
acct account.Account,
|
acct account.Account,
|
||||||
backupID model.StableID,
|
backupID model.StableID,
|
||||||
sel selectors.Selector,
|
sel selectors.Selector,
|
||||||
dest control.RestoreDestination,
|
restoreCfg control.RestoreConfig,
|
||||||
bus events.Eventer,
|
bus events.Eventer,
|
||||||
) (RestoreOperation, error) {
|
) (RestoreOperation, error) {
|
||||||
op := RestoreOperation{
|
op := RestoreOperation{
|
||||||
operation: newOperation(opts, bus, kw, sw),
|
operation: newOperation(opts, bus, kw, sw),
|
||||||
acct: acct,
|
acct: acct,
|
||||||
BackupID: backupID,
|
BackupID: backupID,
|
||||||
Destination: dest,
|
RestoreCfg: restoreCfg,
|
||||||
Selectors: sel,
|
Selectors: sel,
|
||||||
Version: "v0",
|
Version: "v0",
|
||||||
rc: rc,
|
rc: rc,
|
||||||
}
|
}
|
||||||
if err := op.validate(); err != nil {
|
if err := op.validate(); err != nil {
|
||||||
return RestoreOperation{}, err
|
return RestoreOperation{}, err
|
||||||
@ -138,7 +138,7 @@ func (op *RestoreOperation) Run(ctx context.Context) (restoreDetails *details.De
|
|||||||
"tenant_id", clues.Hide(op.acct.ID()),
|
"tenant_id", clues.Hide(op.acct.ID()),
|
||||||
"backup_id", op.BackupID,
|
"backup_id", op.BackupID,
|
||||||
"service", op.Selectors.Service,
|
"service", op.Selectors.Service,
|
||||||
"destination_container", clues.Hide(op.Destination.ContainerName))
|
"destination_container", clues.Hide(op.RestoreCfg.Location))
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
op.bus.Event(
|
op.bus.Event(
|
||||||
@ -257,7 +257,7 @@ func (op *RestoreOperation) do(
|
|||||||
op.rc,
|
op.rc,
|
||||||
bup.Version,
|
bup.Version,
|
||||||
op.Selectors,
|
op.Selectors,
|
||||||
op.Destination,
|
op.RestoreCfg,
|
||||||
op.Options,
|
op.Options,
|
||||||
dcs,
|
dcs,
|
||||||
op.Errors)
|
op.Errors)
|
||||||
@ -314,7 +314,7 @@ func consumeRestoreCollections(
|
|||||||
rc inject.RestoreConsumer,
|
rc inject.RestoreConsumer,
|
||||||
backupVersion int,
|
backupVersion int,
|
||||||
sel selectors.Selector,
|
sel selectors.Selector,
|
||||||
dest control.RestoreDestination,
|
restoreCfg control.RestoreConfig,
|
||||||
opts control.Options,
|
opts control.Options,
|
||||||
dcs []data.RestoreCollection,
|
dcs []data.RestoreCollection,
|
||||||
errs *fault.Bus,
|
errs *fault.Bus,
|
||||||
@ -329,7 +329,7 @@ func consumeRestoreCollections(
|
|||||||
ctx,
|
ctx,
|
||||||
backupVersion,
|
backupVersion,
|
||||||
sel,
|
sel,
|
||||||
dest,
|
restoreCfg,
|
||||||
opts,
|
opts,
|
||||||
dcs,
|
dcs,
|
||||||
errs)
|
errs)
|
||||||
|
|||||||
@ -46,11 +46,11 @@ func TestRestoreOpSuite(t *testing.T) {
|
|||||||
|
|
||||||
func (suite *RestoreOpSuite) TestRestoreOperation_PersistResults() {
|
func (suite *RestoreOpSuite) TestRestoreOperation_PersistResults() {
|
||||||
var (
|
var (
|
||||||
kw = &kopia.Wrapper{}
|
kw = &kopia.Wrapper{}
|
||||||
sw = &store.Wrapper{}
|
sw = &store.Wrapper{}
|
||||||
gc = &mock.GraphConnector{}
|
gc = &mock.GraphConnector{}
|
||||||
now = time.Now()
|
now = time.Now()
|
||||||
dest = tester.DefaultTestRestoreDestination("")
|
restoreCfg = tester.DefaultTestRestoreConfig("")
|
||||||
)
|
)
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
@ -113,7 +113,7 @@ func (suite *RestoreOpSuite) TestRestoreOperation_PersistResults() {
|
|||||||
account.Account{},
|
account.Account{},
|
||||||
"foo",
|
"foo",
|
||||||
selectors.Selector{DiscreteOwner: "test"},
|
selectors.Selector{DiscreteOwner: "test"},
|
||||||
dest,
|
restoreCfg,
|
||||||
evmock.NewBus())
|
evmock.NewBus())
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
|
|
||||||
@ -215,11 +215,11 @@ func (suite *RestoreOpIntegrationSuite) TearDownSuite() {
|
|||||||
|
|
||||||
func (suite *RestoreOpIntegrationSuite) TestNewRestoreOperation() {
|
func (suite *RestoreOpIntegrationSuite) TestNewRestoreOperation() {
|
||||||
var (
|
var (
|
||||||
kw = &kopia.Wrapper{}
|
kw = &kopia.Wrapper{}
|
||||||
sw = &store.Wrapper{}
|
sw = &store.Wrapper{}
|
||||||
gc = &mock.GraphConnector{}
|
gc = &mock.GraphConnector{}
|
||||||
dest = tester.DefaultTestRestoreDestination("")
|
restoreCfg = tester.DefaultTestRestoreConfig("")
|
||||||
opts = control.Defaults()
|
opts = control.Defaults()
|
||||||
)
|
)
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
@ -251,7 +251,7 @@ func (suite *RestoreOpIntegrationSuite) TestNewRestoreOperation() {
|
|||||||
tester.NewM365Account(t),
|
tester.NewM365Account(t),
|
||||||
"backup-id",
|
"backup-id",
|
||||||
selectors.Selector{DiscreteOwner: "test"},
|
selectors.Selector{DiscreteOwner: "test"},
|
||||||
dest,
|
restoreCfg,
|
||||||
evmock.NewBus())
|
evmock.NewBus())
|
||||||
test.errCheck(t, err, clues.ToCore(err))
|
test.errCheck(t, err, clues.ToCore(err))
|
||||||
})
|
})
|
||||||
@ -370,14 +370,14 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run() {
|
|||||||
tables := []struct {
|
tables := []struct {
|
||||||
name string
|
name string
|
||||||
owner string
|
owner string
|
||||||
dest control.RestoreDestination
|
restoreCfg control.RestoreConfig
|
||||||
getSelector func(t *testing.T, owners []string) selectors.Selector
|
getSelector func(t *testing.T, owners []string) selectors.Selector
|
||||||
setup func(t *testing.T, kw *kopia.Wrapper, sw *store.Wrapper, acct account.Account, owner string) bupResults
|
setup func(t *testing.T, kw *kopia.Wrapper, sw *store.Wrapper, acct account.Account, owner string) bupResults
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Exchange_Restore",
|
name: "Exchange_Restore",
|
||||||
owner: tester.M365UserID(suite.T()),
|
owner: tester.M365UserID(suite.T()),
|
||||||
dest: tester.DefaultTestRestoreDestination(""),
|
restoreCfg: tester.DefaultTestRestoreConfig(""),
|
||||||
getSelector: func(t *testing.T, owners []string) selectors.Selector {
|
getSelector: func(t *testing.T, owners []string) selectors.Selector {
|
||||||
rsel := selectors.NewExchangeRestore(owners)
|
rsel := selectors.NewExchangeRestore(owners)
|
||||||
rsel.Include(rsel.AllData())
|
rsel.Include(rsel.AllData())
|
||||||
@ -387,9 +387,9 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run() {
|
|||||||
setup: setupExchangeBackup,
|
setup: setupExchangeBackup,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "SharePoint_Restore",
|
name: "SharePoint_Restore",
|
||||||
owner: tester.M365SiteID(suite.T()),
|
owner: tester.M365SiteID(suite.T()),
|
||||||
dest: control.DefaultRestoreDestination(dttm.SafeForTesting),
|
restoreCfg: control.DefaultRestoreConfig(dttm.SafeForTesting),
|
||||||
getSelector: func(t *testing.T, owners []string) selectors.Selector {
|
getSelector: func(t *testing.T, owners []string) selectors.Selector {
|
||||||
rsel := selectors.NewSharePointRestore(owners)
|
rsel := selectors.NewSharePointRestore(owners)
|
||||||
rsel.Include(rsel.AllData())
|
rsel.Include(rsel.AllData())
|
||||||
@ -423,7 +423,7 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run() {
|
|||||||
tester.NewM365Account(t),
|
tester.NewM365Account(t),
|
||||||
bup.backupID,
|
bup.backupID,
|
||||||
test.getSelector(t, bup.selectorResourceOwners),
|
test.getSelector(t, bup.selectorResourceOwners),
|
||||||
test.dest,
|
test.restoreCfg,
|
||||||
mb)
|
mb)
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
|
|
||||||
@ -453,8 +453,8 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run_errorNoBackup() {
|
|||||||
defer flush()
|
defer flush()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
dest = tester.DefaultTestRestoreDestination("")
|
restoreCfg = tester.DefaultTestRestoreConfig("")
|
||||||
mb = evmock.NewBus()
|
mb = evmock.NewBus()
|
||||||
)
|
)
|
||||||
|
|
||||||
rsel := selectors.NewExchangeRestore(selectors.None())
|
rsel := selectors.NewExchangeRestore(selectors.None())
|
||||||
@ -475,7 +475,7 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run_errorNoBackup() {
|
|||||||
tester.NewM365Account(t),
|
tester.NewM365Account(t),
|
||||||
"backupID",
|
"backupID",
|
||||||
rsel.Selector,
|
rsel.Selector,
|
||||||
dest,
|
restoreCfg,
|
||||||
mb)
|
mb)
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
|
|
||||||
|
|||||||
@ -9,10 +9,10 @@ import (
|
|||||||
|
|
||||||
const RestoreFolderPrefix = "Corso_Test"
|
const RestoreFolderPrefix = "Corso_Test"
|
||||||
|
|
||||||
func DefaultTestRestoreDestination(namespace string) control.RestoreDestination {
|
func DefaultTestRestoreConfig(namespace string) control.RestoreConfig {
|
||||||
var (
|
var (
|
||||||
dest = control.DefaultRestoreDestination(dttm.SafeForTesting)
|
restoreCfg = control.DefaultRestoreConfig(dttm.SafeForTesting)
|
||||||
sft = dttm.FormatNow(dttm.SafeForTesting)
|
sft = dttm.FormatNow(dttm.SafeForTesting)
|
||||||
)
|
)
|
||||||
|
|
||||||
parts := []string{RestoreFolderPrefix, namespace, sft}
|
parts := []string{RestoreFolderPrefix, namespace, sft}
|
||||||
@ -20,7 +20,7 @@ func DefaultTestRestoreDestination(namespace string) control.RestoreDestination
|
|||||||
parts = []string{RestoreFolderPrefix, sft}
|
parts = []string{RestoreFolderPrefix, sft}
|
||||||
}
|
}
|
||||||
|
|
||||||
dest.ContainerName = strings.Join(parts, "_")
|
restoreCfg.Location = strings.Join(parts, "_")
|
||||||
|
|
||||||
return dest
|
return restoreCfg
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,26 +0,0 @@
|
|||||||
// Code generated by "stringer -type=CollisionPolicy"; DO NOT EDIT.
|
|
||||||
|
|
||||||
package control
|
|
||||||
|
|
||||||
import "strconv"
|
|
||||||
|
|
||||||
func _() {
|
|
||||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
|
||||||
// Re-run the stringer command to generate them again.
|
|
||||||
var x [1]struct{}
|
|
||||||
_ = x[Unknown-0]
|
|
||||||
_ = x[Copy-1]
|
|
||||||
_ = x[Skip-2]
|
|
||||||
_ = x[Replace-3]
|
|
||||||
}
|
|
||||||
|
|
||||||
const _CollisionPolicy_name = "UnknownCopySkipReplace"
|
|
||||||
|
|
||||||
var _CollisionPolicy_index = [...]uint8{0, 7, 11, 15, 22}
|
|
||||||
|
|
||||||
func (i CollisionPolicy) String() string {
|
|
||||||
if i < 0 || i >= CollisionPolicy(len(_CollisionPolicy_index)-1) {
|
|
||||||
return "CollisionPolicy(" + strconv.FormatInt(int64(i), 10) + ")"
|
|
||||||
}
|
|
||||||
return _CollisionPolicy_name[_CollisionPolicy_index[i]:_CollisionPolicy_index[i+1]]
|
|
||||||
}
|
|
||||||
@ -7,9 +7,8 @@ import (
|
|||||||
|
|
||||||
// Options holds the optional configurations for a process
|
// Options holds the optional configurations for a process
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Collision CollisionPolicy `json:"-"`
|
|
||||||
DisableMetrics bool `json:"disableMetrics"`
|
DisableMetrics bool `json:"disableMetrics"`
|
||||||
FailureHandling FailureBehavior `json:"failureHandling"`
|
FailureHandling FailurePolicy `json:"failureHandling"`
|
||||||
RestorePermissions bool `json:"restorePermissions"`
|
RestorePermissions bool `json:"restorePermissions"`
|
||||||
SkipReduce bool `json:"skipReduce"`
|
SkipReduce bool `json:"skipReduce"`
|
||||||
ToggleFeatures Toggles `json:"toggleFeatures"`
|
ToggleFeatures Toggles `json:"toggleFeatures"`
|
||||||
@ -17,8 +16,6 @@ type Options struct {
|
|||||||
Repo repository.Options `json:"repo"`
|
Repo repository.Options `json:"repo"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FailureBehavior string
|
|
||||||
|
|
||||||
type Parallelism struct {
|
type Parallelism struct {
|
||||||
// sets the collection buffer size before blocking.
|
// sets the collection buffer size before blocking.
|
||||||
CollectionBuffer int
|
CollectionBuffer int
|
||||||
@ -26,13 +23,15 @@ type Parallelism struct {
|
|||||||
ItemFetch int
|
ItemFetch int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FailurePolicy string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// fails and exits the run immediately
|
// fails and exits the run immediately
|
||||||
FailFast FailureBehavior = "fail-fast"
|
FailFast FailurePolicy = "fail-fast"
|
||||||
// recovers whenever possible, reports non-zero recoveries as a failure
|
// recovers whenever possible, reports non-zero recoveries as a failure
|
||||||
FailAfterRecovery FailureBehavior = "fail-after-recovery"
|
FailAfterRecovery FailurePolicy = "fail-after-recovery"
|
||||||
// recovers whenever possible, does not report recovery as failure
|
// recovers whenever possible, does not report recovery as failure
|
||||||
BestEffort FailureBehavior = "best-effort"
|
BestEffort FailurePolicy = "best-effort"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Defaults provides an Options with the default values set.
|
// Defaults provides an Options with the default values set.
|
||||||
@ -48,44 +47,50 @@ func Defaults() Options {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Restore Item Collision Policy
|
// Restore Configuration
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// CollisionPolicy describes how the datalayer behaves in case of a collision.
|
|
||||||
type CollisionPolicy int
|
|
||||||
|
|
||||||
//go:generate stringer -type=CollisionPolicy
|
|
||||||
const (
|
|
||||||
Unknown CollisionPolicy = iota
|
|
||||||
Copy
|
|
||||||
Skip
|
|
||||||
Replace
|
|
||||||
)
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// Restore Destination
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultRestoreLocation = "Corso_Restore_"
|
defaultRestoreLocation = "Corso_Restore_"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RestoreDestination is a POD that contains an override of the resource owner
|
// CollisionPolicy describes how the datalayer behaves in case of a collision.
|
||||||
// to restore data under and the name of the root of the restored container
|
type CollisionPolicy string
|
||||||
// hierarchy.
|
|
||||||
type RestoreDestination struct {
|
const (
|
||||||
// ResourceOwnerOverride overrides the default resource owner to restore to.
|
Unknown CollisionPolicy = ""
|
||||||
// If it is not populated items should be restored under the previous resource
|
Skip CollisionPolicy = "skip"
|
||||||
// owner of the item.
|
Copy CollisionPolicy = "copy"
|
||||||
ResourceOwnerOverride string
|
Replace CollisionPolicy = "replace"
|
||||||
// ContainerName is the name of the root of the restored container hierarchy.
|
)
|
||||||
// This field must be populated for a restore.
|
|
||||||
ContainerName string
|
// RestoreConfig contains
|
||||||
|
type RestoreConfig struct {
|
||||||
|
// Defines the per-item collision handling policy.
|
||||||
|
// Defaults to Skip.
|
||||||
|
OnCollision CollisionPolicy
|
||||||
|
|
||||||
|
// ProtectedResource specifies which resource the data will be restored to.
|
||||||
|
// If empty, restores to the same resource that was backed up.
|
||||||
|
// Defaults to empty.
|
||||||
|
ProtectedResource string
|
||||||
|
|
||||||
|
// Location specifies the container into which the data will be restored.
|
||||||
|
// Only accepts container names, does not accept IDs.
|
||||||
|
// If empty or "/", data will get restored in place, beginning at the root.
|
||||||
|
// Defaults to "Corso_Restore_<current_dttm>"
|
||||||
|
Location string
|
||||||
|
|
||||||
|
// Drive specifies the drive into which the data will be restored.
|
||||||
|
// If empty, data is restored to the same drive that was backed up.
|
||||||
|
// Defaults to empty.
|
||||||
|
Drive string
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultRestoreDestination(timeFormat dttm.TimeFormat) RestoreDestination {
|
func DefaultRestoreConfig(timeFormat dttm.TimeFormat) RestoreConfig {
|
||||||
return RestoreDestination{
|
return RestoreConfig{
|
||||||
ContainerName: defaultRestoreLocation + dttm.FormatNow(timeFormat),
|
OnCollision: Skip,
|
||||||
|
Location: defaultRestoreLocation + dttm.FormatNow(timeFormat),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -151,9 +151,9 @@ func runRestoreLoadTest(
|
|||||||
t.Skip("restore load test is toggled off")
|
t.Skip("restore load test is toggled off")
|
||||||
}
|
}
|
||||||
|
|
||||||
dest := tester.DefaultTestRestoreDestination("")
|
restoreCfg := tester.DefaultTestRestoreConfig("")
|
||||||
|
|
||||||
rst, err := r.NewRestore(ctx, backupID, restSel, dest)
|
rst, err := r.NewRestore(ctx, backupID, restSel, restoreCfg)
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
|
|
||||||
doRestoreLoadTest(t, ctx, rst, service, bup.Results.ItemsWritten, usersUnderTest)
|
doRestoreLoadTest(t, ctx, rst, service, bup.Results.ItemsWritten, usersUnderTest)
|
||||||
|
|||||||
@ -69,7 +69,7 @@ type Repository interface {
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
backupID string,
|
backupID string,
|
||||||
sel selectors.Selector,
|
sel selectors.Selector,
|
||||||
dest control.RestoreDestination,
|
restoreCfg control.RestoreConfig,
|
||||||
) (operations.RestoreOperation, error)
|
) (operations.RestoreOperation, error)
|
||||||
NewMaintenance(
|
NewMaintenance(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
@ -336,7 +336,7 @@ func (r repository) NewRestore(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
backupID string,
|
backupID string,
|
||||||
sel selectors.Selector,
|
sel selectors.Selector,
|
||||||
dest control.RestoreDestination,
|
restoreCfg control.RestoreConfig,
|
||||||
) (operations.RestoreOperation, error) {
|
) (operations.RestoreOperation, error) {
|
||||||
gc, err := connectToM365(ctx, sel, r.Account)
|
gc, err := connectToM365(ctx, sel, r.Account)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -352,7 +352,7 @@ func (r repository) NewRestore(
|
|||||||
r.Account,
|
r.Account,
|
||||||
model.StableID(backupID),
|
model.StableID(backupID),
|
||||||
sel,
|
sel,
|
||||||
dest,
|
restoreCfg,
|
||||||
r.Bus)
|
r.Bus)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -242,7 +242,7 @@ func (suite *RepositoryIntegrationSuite) TestNewRestore() {
|
|||||||
defer flush()
|
defer flush()
|
||||||
|
|
||||||
acct := tester.NewM365Account(t)
|
acct := tester.NewM365Account(t)
|
||||||
dest := tester.DefaultTestRestoreDestination("")
|
restoreCfg := tester.DefaultTestRestoreConfig("")
|
||||||
|
|
||||||
// need to initialize the repository before we can test connecting to it.
|
// need to initialize the repository before we can test connecting to it.
|
||||||
st := tester.NewPrefixedS3Storage(t)
|
st := tester.NewPrefixedS3Storage(t)
|
||||||
@ -250,7 +250,7 @@ func (suite *RepositoryIntegrationSuite) TestNewRestore() {
|
|||||||
r, err := repository.Initialize(ctx, acct, st, control.Defaults())
|
r, err := repository.Initialize(ctx, acct, st, control.Defaults())
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
|
|
||||||
ro, err := r.NewRestore(ctx, "backup-id", selectors.Selector{DiscreteOwner: "test"}, dest)
|
ro, err := r.NewRestore(ctx, "backup-id", selectors.Selector{DiscreteOwner: "test"}, restoreCfg)
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
require.NotNil(t, ro)
|
require.NotNil(t, ro)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user