hand resource down to drive controller (#4436)
hands the backup resource into the drive collection for the handler to use to record as the siteID --- #### Does this PR need a docs update or release note? - [x] ⛔ No #### Type of change - [x] 🐛 Bugfix #### Issue(s) * #3988 #### Test Plan - [x] 💪 Manual - [x] ⚡ Unit test - [x] 💚 E2E
This commit is contained in:
parent
02db885c1e
commit
c88b5764a9
@ -120,7 +120,7 @@ func generateAndRestoreItems(
|
||||
|
||||
func getControllerAndVerifyResourceOwner(
|
||||
ctx context.Context,
|
||||
resourceOwner string,
|
||||
protectedResource string,
|
||||
pst path.ServiceType,
|
||||
) (
|
||||
*m365.Controller,
|
||||
@ -150,12 +150,12 @@ func getControllerAndVerifyResourceOwner(
|
||||
return nil, account.Account{}, nil, clues.Wrap(err, "connecting to graph api")
|
||||
}
|
||||
|
||||
id, _, err := ctrl.PopulateProtectedResourceIDAndName(ctx, resourceOwner, nil)
|
||||
pr, err := ctrl.PopulateProtectedResourceIDAndName(ctx, protectedResource, nil)
|
||||
if err != nil {
|
||||
return nil, account.Account{}, nil, clues.Wrap(err, "verifying user")
|
||||
}
|
||||
|
||||
return ctrl, acct, ctrl.IDNameLookup.ProviderForID(id), nil
|
||||
return ctrl, acct, pr, nil
|
||||
}
|
||||
|
||||
type item struct {
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
package idname
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/alcionai/clues"
|
||||
"golang.org/x/exp/maps"
|
||||
)
|
||||
|
||||
@ -21,7 +24,18 @@ type Provider interface {
|
||||
Name() string
|
||||
}
|
||||
|
||||
var _ Provider = &is{}
|
||||
type GetResourceIDAndNamer interface {
|
||||
GetResourceIDAndNameFrom(
|
||||
ctx context.Context,
|
||||
owner string,
|
||||
cacher Cacher,
|
||||
) (Provider, error)
|
||||
}
|
||||
|
||||
var (
|
||||
_ Provider = &is{}
|
||||
_ clues.Concealer = &is{}
|
||||
)
|
||||
|
||||
type is struct {
|
||||
id string
|
||||
@ -35,6 +49,24 @@ func NewProvider(id, name string) *is {
|
||||
func (is is) ID() string { return is.id }
|
||||
func (is is) Name() string { return is.name }
|
||||
|
||||
const isStringTmpl = "{id:%s, name:%s}"
|
||||
|
||||
func (is is) PlainString() string {
|
||||
return fmt.Sprintf(isStringTmpl, clues.Hide(is.id), clues.Hide(is.name))
|
||||
}
|
||||
|
||||
func (is is) Conceal() string {
|
||||
return fmt.Sprintf(isStringTmpl, clues.Hide(is.id), clues.Hide(is.name))
|
||||
}
|
||||
|
||||
func (is is) String() string {
|
||||
return is.Conceal()
|
||||
}
|
||||
|
||||
func (is is) Format(fs fmt.State, _ rune) {
|
||||
fmt.Fprint(fs, is.Conceal())
|
||||
}
|
||||
|
||||
type Cacher interface {
|
||||
IDOf(name string) (string, bool)
|
||||
NameOf(id string) (string, bool)
|
||||
|
||||
@ -380,18 +380,18 @@ func (suite *SPCollectionIntgSuite) TestCreateSharePointCollection_Libraries() {
|
||||
siteIDs = []string{siteID}
|
||||
)
|
||||
|
||||
id, name, err := ctrl.PopulateProtectedResourceIDAndName(ctx, siteID, nil)
|
||||
site, err := ctrl.PopulateProtectedResourceIDAndName(ctx, siteID, nil)
|
||||
require.NoError(t, err, clues.ToCore(err))
|
||||
|
||||
sel := selectors.NewSharePointBackup(siteIDs)
|
||||
sel.Include(sel.LibraryFolders([]string{"foo"}, selectors.PrefixMatch()))
|
||||
|
||||
sel.SetDiscreteOwnerIDName(id, name)
|
||||
sel.SetDiscreteOwnerIDName(site.ID(), site.Name())
|
||||
|
||||
bpc := inject.BackupProducerConfig{
|
||||
LastBackupVersion: version.NoBackup,
|
||||
Options: control.DefaultOptions(),
|
||||
ProtectedResource: inMock.NewProvider(id, name),
|
||||
ProtectedResource: site,
|
||||
Selector: sel.Selector,
|
||||
}
|
||||
|
||||
@ -430,18 +430,18 @@ func (suite *SPCollectionIntgSuite) TestCreateSharePointCollection_Lists() {
|
||||
siteIDs = []string{siteID}
|
||||
)
|
||||
|
||||
id, name, err := ctrl.PopulateProtectedResourceIDAndName(ctx, siteID, nil)
|
||||
site, err := ctrl.PopulateProtectedResourceIDAndName(ctx, siteID, nil)
|
||||
require.NoError(t, err, clues.ToCore(err))
|
||||
|
||||
sel := selectors.NewSharePointBackup(siteIDs)
|
||||
sel.Include(sel.Lists(selectors.Any()))
|
||||
|
||||
sel.SetDiscreteOwnerIDName(id, name)
|
||||
sel.SetDiscreteOwnerIDName(site.ID(), site.Name())
|
||||
|
||||
bpc := inject.BackupProducerConfig{
|
||||
LastBackupVersion: version.NoBackup,
|
||||
Options: control.DefaultOptions(),
|
||||
ProtectedResource: inMock.NewProvider(id, name),
|
||||
ProtectedResource: site,
|
||||
Selector: sel.Selector,
|
||||
}
|
||||
|
||||
@ -516,18 +516,18 @@ func (suite *GroupsCollectionIntgSuite) TestCreateGroupsCollection_SharePoint()
|
||||
groupIDs = []string{groupID}
|
||||
)
|
||||
|
||||
id, name, err := ctrl.PopulateProtectedResourceIDAndName(ctx, groupID, nil)
|
||||
group, err := ctrl.PopulateProtectedResourceIDAndName(ctx, groupID, nil)
|
||||
require.NoError(t, err, clues.ToCore(err))
|
||||
|
||||
sel := selectors.NewGroupsBackup(groupIDs)
|
||||
sel.Include(sel.LibraryFolders([]string{"test"}, selectors.PrefixMatch()))
|
||||
|
||||
sel.SetDiscreteOwnerIDName(id, name)
|
||||
sel.SetDiscreteOwnerIDName(group.ID(), group.Name())
|
||||
|
||||
bpc := inject.BackupProducerConfig{
|
||||
LastBackupVersion: version.NoBackup,
|
||||
Options: control.DefaultOptions(),
|
||||
ProtectedResource: inMock.NewProvider(id, name),
|
||||
ProtectedResource: group,
|
||||
Selector: sel.Selector,
|
||||
}
|
||||
|
||||
@ -590,13 +590,13 @@ func (suite *GroupsCollectionIntgSuite) TestCreateGroupsCollection_SharePoint_In
|
||||
groupIDs = []string{groupID}
|
||||
)
|
||||
|
||||
id, name, err := ctrl.PopulateProtectedResourceIDAndName(ctx, groupID, nil)
|
||||
group, err := ctrl.PopulateProtectedResourceIDAndName(ctx, groupID, nil)
|
||||
require.NoError(t, err, clues.ToCore(err))
|
||||
|
||||
sel := selectors.NewGroupsBackup(groupIDs)
|
||||
sel.Include(sel.LibraryFolders([]string{"test"}, selectors.PrefixMatch()))
|
||||
|
||||
sel.SetDiscreteOwnerIDName(id, name)
|
||||
sel.SetDiscreteOwnerIDName(group.ID(), group.Name())
|
||||
|
||||
site, err := suite.connector.AC.Groups().GetRootSite(ctx, groupID)
|
||||
require.NoError(t, err, clues.ToCore(err))
|
||||
@ -626,7 +626,7 @@ func (suite *GroupsCollectionIntgSuite) TestCreateGroupsCollection_SharePoint_In
|
||||
bpc := inject.BackupProducerConfig{
|
||||
LastBackupVersion: version.NoBackup,
|
||||
Options: control.DefaultOptions(),
|
||||
ProtectedResource: inMock.NewProvider(id, name),
|
||||
ProtectedResource: group,
|
||||
Selector: sel.Selector,
|
||||
MetadataCollections: mmc,
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||
"github.com/spatialcurrent/go-lazy/pkg/lazy"
|
||||
|
||||
"github.com/alcionai/corso/src/internal/common/idname"
|
||||
"github.com/alcionai/corso/src/internal/common/ptr"
|
||||
"github.com/alcionai/corso/src/internal/data"
|
||||
"github.com/alcionai/corso/src/internal/m365/collection/drive/metadata"
|
||||
@ -39,6 +40,9 @@ var _ data.BackupCollection = &Collection{}
|
||||
type Collection struct {
|
||||
handler BackupHandler
|
||||
|
||||
// the protected resource represented in this collection.
|
||||
protectedResource idname.Provider
|
||||
|
||||
// data is used to share data streams with the collection consumer
|
||||
data chan data.Item
|
||||
// folderPath indicates what level in the hierarchy this collection
|
||||
@ -98,6 +102,7 @@ func pathToLocation(p path.Path) (*path.Builder, error) {
|
||||
// NewCollection creates a Collection
|
||||
func NewCollection(
|
||||
handler BackupHandler,
|
||||
resource idname.Provider,
|
||||
currPath path.Path,
|
||||
prevPath path.Path,
|
||||
driveID string,
|
||||
@ -123,6 +128,7 @@ func NewCollection(
|
||||
|
||||
c := newColl(
|
||||
handler,
|
||||
resource,
|
||||
currPath,
|
||||
prevPath,
|
||||
driveID,
|
||||
@ -140,6 +146,7 @@ func NewCollection(
|
||||
|
||||
func newColl(
|
||||
handler BackupHandler,
|
||||
resource idname.Provider,
|
||||
currPath path.Path,
|
||||
prevPath path.Path,
|
||||
driveID string,
|
||||
@ -151,6 +158,7 @@ func newColl(
|
||||
) *Collection {
|
||||
c := &Collection{
|
||||
handler: handler,
|
||||
protectedResource: resource,
|
||||
folderPath: currPath,
|
||||
prevPath: prevPath,
|
||||
driveItems: map[string]models.DriveItemable{},
|
||||
@ -551,7 +559,12 @@ func (oc *Collection) streamDriveItem(
|
||||
return
|
||||
}
|
||||
|
||||
itemInfo = oc.handler.AugmentItemInfo(itemInfo, item, itemSize, parentPath)
|
||||
itemInfo = oc.handler.AugmentItemInfo(
|
||||
itemInfo,
|
||||
oc.protectedResource,
|
||||
item,
|
||||
itemSize,
|
||||
parentPath)
|
||||
|
||||
ctx = clues.Add(ctx, "item_info", itemInfo)
|
||||
|
||||
|
||||
@ -207,6 +207,7 @@ func (suite *CollectionUnitSuite) TestCollection() {
|
||||
|
||||
coll, err := NewCollection(
|
||||
mbh,
|
||||
mbh.ProtectedResource,
|
||||
folderPath,
|
||||
nil,
|
||||
"drive-id",
|
||||
@ -328,6 +329,7 @@ func (suite *CollectionUnitSuite) TestCollectionReadError() {
|
||||
|
||||
coll, err := NewCollection(
|
||||
mbh,
|
||||
mbh.ProtectedResource,
|
||||
folderPath,
|
||||
nil,
|
||||
"fakeDriveID",
|
||||
@ -405,6 +407,7 @@ func (suite *CollectionUnitSuite) TestCollectionReadUnauthorizedErrorRetry() {
|
||||
|
||||
coll, err := NewCollection(
|
||||
mbh,
|
||||
mbh.ProtectedResource,
|
||||
folderPath,
|
||||
nil,
|
||||
"fakeDriveID",
|
||||
@ -460,6 +463,7 @@ func (suite *CollectionUnitSuite) TestCollectionPermissionBackupLatestModTime()
|
||||
|
||||
coll, err := NewCollection(
|
||||
mbh,
|
||||
mbh.ProtectedResource,
|
||||
folderPath,
|
||||
nil,
|
||||
"drive-id",
|
||||
@ -971,6 +975,7 @@ func (suite *CollectionUnitSuite) TestItemExtensions() {
|
||||
|
||||
coll, err := NewCollection(
|
||||
mbh,
|
||||
mbh.ProtectedResource,
|
||||
folderPath,
|
||||
nil,
|
||||
driveID,
|
||||
|
||||
@ -11,6 +11,7 @@ import (
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
"github.com/alcionai/corso/src/internal/common/idname"
|
||||
"github.com/alcionai/corso/src/internal/common/prefixmatcher"
|
||||
"github.com/alcionai/corso/src/internal/common/ptr"
|
||||
"github.com/alcionai/corso/src/internal/data"
|
||||
@ -49,7 +50,7 @@ type Collections struct {
|
||||
handler BackupHandler
|
||||
|
||||
tenantID string
|
||||
resourceOwner string
|
||||
protectedResource idname.Provider
|
||||
|
||||
statusUpdater support.StatusUpdater
|
||||
|
||||
@ -69,14 +70,14 @@ type Collections struct {
|
||||
func NewCollections(
|
||||
bh BackupHandler,
|
||||
tenantID string,
|
||||
resourceOwner string,
|
||||
protectedResource idname.Provider,
|
||||
statusUpdater support.StatusUpdater,
|
||||
ctrlOpts control.Options,
|
||||
) *Collections {
|
||||
return &Collections{
|
||||
handler: bh,
|
||||
tenantID: tenantID,
|
||||
resourceOwner: resourceOwner,
|
||||
protectedResource: protectedResource,
|
||||
CollectionMap: map[string]map[string]*Collection{},
|
||||
statusUpdater: statusUpdater,
|
||||
ctrl: ctrlOpts,
|
||||
@ -246,7 +247,7 @@ func (c *Collections) Get(
|
||||
defer close(progressBar)
|
||||
|
||||
// Enumerate drives for the specified resourceOwner
|
||||
pager := c.handler.NewDrivePager(c.resourceOwner, nil)
|
||||
pager := c.handler.NewDrivePager(c.protectedResource.ID(), nil)
|
||||
|
||||
drives, err := api.GetAllDrives(ctx, pager)
|
||||
if err != nil {
|
||||
@ -384,6 +385,7 @@ func (c *Collections) Get(
|
||||
|
||||
col, err := NewCollection(
|
||||
c.handler,
|
||||
c.protectedResource,
|
||||
nil, // delete the folder
|
||||
prevPath,
|
||||
driveID,
|
||||
@ -420,6 +422,7 @@ func (c *Collections) Get(
|
||||
|
||||
coll, err := NewCollection(
|
||||
c.handler,
|
||||
c.protectedResource,
|
||||
nil, // delete the drive
|
||||
prevDrivePath,
|
||||
driveID,
|
||||
@ -605,6 +608,7 @@ func (c *Collections) handleDelete(
|
||||
|
||||
col, err := NewCollection(
|
||||
c.handler,
|
||||
c.protectedResource,
|
||||
nil, // deletes the collection
|
||||
prevPath,
|
||||
driveID,
|
||||
@ -789,6 +793,7 @@ func (c *Collections) UpdateCollections(
|
||||
|
||||
col, err := NewCollection(
|
||||
c.handler,
|
||||
c.protectedResource,
|
||||
collectionPath,
|
||||
prevPath,
|
||||
driveID,
|
||||
|
||||
@ -14,6 +14,7 @@ import (
|
||||
"github.com/stretchr/testify/suite"
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
"github.com/alcionai/corso/src/internal/common/idname"
|
||||
"github.com/alcionai/corso/src/internal/common/prefixmatcher"
|
||||
pmMock "github.com/alcionai/corso/src/internal/common/prefixmatcher/mock"
|
||||
"github.com/alcionai/corso/src/internal/data"
|
||||
@ -747,7 +748,7 @@ func (suite *OneDriveCollectionsUnitSuite) TestUpdateCollections() {
|
||||
c := NewCollections(
|
||||
&itemBackupHandler{api.Drives{}, user, tt.scope},
|
||||
tenant,
|
||||
user,
|
||||
idname.NewProvider(user, user),
|
||||
nil,
|
||||
control.Options{ToggleFeatures: control.Toggles{}})
|
||||
|
||||
@ -2274,7 +2275,7 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
|
||||
c := NewCollections(
|
||||
mbh,
|
||||
tenant,
|
||||
user,
|
||||
idname.NewProvider(user, user),
|
||||
func(*support.ControllerOperationStatus) {},
|
||||
control.Options{ToggleFeatures: control.Toggles{}})
|
||||
|
||||
@ -2648,7 +2649,7 @@ func (suite *OneDriveCollectionsUnitSuite) TestAddURLCacheToDriveCollections() {
|
||||
c := NewCollections(
|
||||
mbh,
|
||||
"test-tenant",
|
||||
"test-user",
|
||||
idname.NewProvider("test-user", "test-user"),
|
||||
nil,
|
||||
control.Options{ToggleFeatures: control.Toggles{}})
|
||||
|
||||
@ -2660,6 +2661,7 @@ func (suite *OneDriveCollectionsUnitSuite) TestAddURLCacheToDriveCollections() {
|
||||
for i := 0; i < collCount; i++ {
|
||||
coll, err := NewCollection(
|
||||
&itemBackupHandler{api.Drives{}, "test-user", anyFolder},
|
||||
idname.NewProvider("", ""),
|
||||
nil,
|
||||
nil,
|
||||
driveID,
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||
|
||||
"github.com/alcionai/corso/src/internal/common/idname"
|
||||
"github.com/alcionai/corso/src/internal/common/ptr"
|
||||
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||
"github.com/alcionai/corso/src/pkg/path"
|
||||
@ -12,12 +13,13 @@ import (
|
||||
|
||||
func augmentItemInfo(
|
||||
dii details.ItemInfo,
|
||||
resource idname.Provider,
|
||||
service path.ServiceType,
|
||||
item models.DriveItemable,
|
||||
size int64,
|
||||
parentPath *path.Builder,
|
||||
) details.ItemInfo {
|
||||
var driveName, siteID, driveID, weburl, creatorEmail string
|
||||
var driveName, driveID, creatorEmail string
|
||||
|
||||
// TODO: we rely on this info for details/restore lookups,
|
||||
// so if it's nil we have an issue, and will need an alternative
|
||||
@ -38,19 +40,6 @@ func augmentItemInfo(
|
||||
}
|
||||
}
|
||||
|
||||
if service == path.SharePointService ||
|
||||
service == path.GroupsService {
|
||||
gsi := item.GetSharepointIds()
|
||||
if gsi != nil {
|
||||
siteID = ptr.Val(gsi.GetSiteId())
|
||||
weburl = ptr.Val(gsi.GetSiteUrl())
|
||||
|
||||
if len(weburl) == 0 {
|
||||
weburl = constructWebURL(item.GetAdditionalData())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if item.GetParentReference() != nil {
|
||||
driveID = ptr.Val(item.GetParentReference().GetDriveId())
|
||||
driveName = strings.TrimSpace(ptr.Val(item.GetParentReference().GetName()))
|
||||
@ -84,9 +73,9 @@ func augmentItemInfo(
|
||||
Modified: ptr.Val(item.GetLastModifiedDateTime()),
|
||||
Owner: creatorEmail,
|
||||
ParentPath: pps,
|
||||
SiteID: siteID,
|
||||
SiteID: resource.ID(),
|
||||
Size: size,
|
||||
WebURL: weburl,
|
||||
WebURL: resource.Name(),
|
||||
}
|
||||
|
||||
case path.GroupsService:
|
||||
@ -99,9 +88,9 @@ func augmentItemInfo(
|
||||
Modified: ptr.Val(item.GetLastModifiedDateTime()),
|
||||
Owner: creatorEmail,
|
||||
ParentPath: pps,
|
||||
SiteID: siteID,
|
||||
SiteID: resource.ID(),
|
||||
Size: size,
|
||||
WebURL: weburl,
|
||||
WebURL: resource.Name(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/drives"
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||
|
||||
"github.com/alcionai/corso/src/internal/common/idname"
|
||||
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||
"github.com/alcionai/corso/src/pkg/control"
|
||||
"github.com/alcionai/corso/src/pkg/path"
|
||||
@ -20,6 +21,7 @@ type ItemInfoAugmenter interface {
|
||||
// and kiota drops any SetSize update.
|
||||
AugmentItemInfo(
|
||||
dii details.ItemInfo,
|
||||
resource idname.Provider,
|
||||
item models.DriveItemable,
|
||||
size int64,
|
||||
parentPath *path.Builder,
|
||||
|
||||
@ -11,6 +11,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/alcionai/corso/src/internal/common/idname"
|
||||
"github.com/alcionai/corso/src/internal/common/prefixmatcher"
|
||||
"github.com/alcionai/corso/src/internal/m365/graph"
|
||||
"github.com/alcionai/corso/src/internal/tester"
|
||||
@ -267,7 +268,7 @@ func (suite *OneDriveIntgSuite) TestOneDriveNewCollections() {
|
||||
colls := NewCollections(
|
||||
&itemBackupHandler{suite.ac.Drives(), test.user, scope},
|
||||
creds.AzureTenantID,
|
||||
test.user,
|
||||
idname.NewProvider(test.user, test.user),
|
||||
service.updateStatus,
|
||||
control.Options{
|
||||
ToggleFeatures: control.Toggles{},
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/drives"
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||
|
||||
"github.com/alcionai/corso/src/internal/common/idname"
|
||||
odConsts "github.com/alcionai/corso/src/internal/m365/service/onedrive/consts"
|
||||
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||
"github.com/alcionai/corso/src/pkg/control"
|
||||
@ -96,11 +97,12 @@ func (h itemBackupHandler) NewItemPager(
|
||||
|
||||
func (h itemBackupHandler) AugmentItemInfo(
|
||||
dii details.ItemInfo,
|
||||
resource idname.Provider,
|
||||
item models.DriveItemable,
|
||||
size int64,
|
||||
parentPath *path.Builder,
|
||||
) details.ItemInfo {
|
||||
return augmentItemInfo(dii, path.OneDriveService, item, size, parentPath)
|
||||
return augmentItemInfo(dii, resource, path.OneDriveService, item, size, parentPath)
|
||||
}
|
||||
|
||||
func (h itemBackupHandler) FormatDisplayPath(
|
||||
@ -173,11 +175,12 @@ func (h itemRestoreHandler) NewDrivePager(
|
||||
// and kiota drops any SetSize update.
|
||||
func (h itemRestoreHandler) AugmentItemInfo(
|
||||
dii details.ItemInfo,
|
||||
resource idname.Provider,
|
||||
item models.DriveItemable,
|
||||
size int64,
|
||||
parentPath *path.Builder,
|
||||
) details.ItemInfo {
|
||||
return augmentItemInfo(dii, path.OneDriveService, item, size, parentPath)
|
||||
return augmentItemInfo(dii, resource, path.OneDriveService, item, size, parentPath)
|
||||
}
|
||||
|
||||
func (h itemRestoreHandler) DeleteItem(
|
||||
|
||||
@ -3,13 +3,12 @@ package drive
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/alcionai/clues"
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/drives"
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||
|
||||
"github.com/alcionai/corso/src/internal/common/ptr"
|
||||
"github.com/alcionai/corso/src/internal/common/idname"
|
||||
odConsts "github.com/alcionai/corso/src/internal/m365/service/onedrive/consts"
|
||||
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||
"github.com/alcionai/corso/src/pkg/control"
|
||||
@ -101,44 +100,12 @@ func (h libraryBackupHandler) NewItemPager(
|
||||
|
||||
func (h libraryBackupHandler) AugmentItemInfo(
|
||||
dii details.ItemInfo,
|
||||
resource idname.Provider,
|
||||
item models.DriveItemable,
|
||||
size int64,
|
||||
parentPath *path.Builder,
|
||||
) details.ItemInfo {
|
||||
return augmentItemInfo(dii, h.service, item, size, parentPath)
|
||||
}
|
||||
|
||||
// constructWebURL is a helper function for recreating the webURL
|
||||
// for the originating SharePoint site. Uses the additionalData map
|
||||
// from a models.DriveItemable that possesses a downloadURL within the map.
|
||||
// Returns "" if the map is nil or key is not present.
|
||||
func constructWebURL(adtl map[string]any) string {
|
||||
var (
|
||||
desiredKey = "@microsoft.graph.downloadUrl"
|
||||
sep = `/_layouts`
|
||||
url string
|
||||
)
|
||||
|
||||
if adtl == nil {
|
||||
return url
|
||||
}
|
||||
|
||||
r := adtl[desiredKey]
|
||||
point, ok := r.(*string)
|
||||
|
||||
if !ok {
|
||||
return url
|
||||
}
|
||||
|
||||
value := ptr.Val(point)
|
||||
if len(value) == 0 {
|
||||
return url
|
||||
}
|
||||
|
||||
temp := strings.Split(value, sep)
|
||||
url = temp[0]
|
||||
|
||||
return url
|
||||
return augmentItemInfo(dii, resource, h.service, item, size, parentPath)
|
||||
}
|
||||
|
||||
func (h libraryBackupHandler) FormatDisplayPath(
|
||||
@ -208,11 +175,12 @@ func (h libraryRestoreHandler) NewDrivePager(
|
||||
|
||||
func (h libraryRestoreHandler) AugmentItemInfo(
|
||||
dii details.ItemInfo,
|
||||
resource idname.Provider,
|
||||
item models.DriveItemable,
|
||||
size int64,
|
||||
parentPath *path.Builder,
|
||||
) details.ItemInfo {
|
||||
return augmentItemInfo(dii, h.service, item, size, parentPath)
|
||||
return augmentItemInfo(dii, resource, h.service, item, size, parentPath)
|
||||
}
|
||||
|
||||
func (h libraryRestoreHandler) DeleteItem(
|
||||
|
||||
@ -271,7 +271,7 @@ func restoreItem(
|
||||
itemInfo, err := restoreV0File(
|
||||
ctx,
|
||||
rh,
|
||||
rcc.RestoreConfig,
|
||||
rcc,
|
||||
drivePath,
|
||||
fibn,
|
||||
restoreFolderID,
|
||||
@ -377,7 +377,7 @@ func restoreItem(
|
||||
func restoreV0File(
|
||||
ctx context.Context,
|
||||
rh RestoreHandler,
|
||||
restoreCfg control.RestoreConfig,
|
||||
rcc inject.RestoreConsumerConfig,
|
||||
drivePath *path.DrivePath,
|
||||
fibn data.FetchItemByNamer,
|
||||
restoreFolderID string,
|
||||
@ -388,7 +388,7 @@ func restoreV0File(
|
||||
) (details.ItemInfo, error) {
|
||||
_, itemInfo, err := restoreFile(
|
||||
ctx,
|
||||
restoreCfg,
|
||||
rcc,
|
||||
rh,
|
||||
fibn,
|
||||
itemData.ID(),
|
||||
@ -423,7 +423,7 @@ func restoreV1File(
|
||||
|
||||
itemID, itemInfo, err := restoreFile(
|
||||
ctx,
|
||||
rcc.RestoreConfig,
|
||||
rcc,
|
||||
rh,
|
||||
fibn,
|
||||
trimmedName,
|
||||
@ -509,7 +509,7 @@ func restoreV6File(
|
||||
|
||||
itemID, itemInfo, err := restoreFile(
|
||||
ctx,
|
||||
rcc.RestoreConfig,
|
||||
rcc,
|
||||
rh,
|
||||
fibn,
|
||||
meta.FileName,
|
||||
@ -711,7 +711,7 @@ type itemRestorer interface {
|
||||
// restoreFile will create a new item in the specified `parentFolderID` and upload the data.Item
|
||||
func restoreFile(
|
||||
ctx context.Context,
|
||||
restoreCfg control.RestoreConfig,
|
||||
rcc inject.RestoreConsumerConfig,
|
||||
ir itemRestorer,
|
||||
fibn data.FetchItemByNamer,
|
||||
name string,
|
||||
@ -743,7 +743,7 @@ func restoreFile(
|
||||
log := logger.Ctx(ctx).With("collision_key", clues.Hide(collisionKey))
|
||||
log.Debug("item collision")
|
||||
|
||||
if restoreCfg.OnCollision == control.Skip {
|
||||
if rcc.RestoreConfig.OnCollision == control.Skip {
|
||||
ctr.Inc(count.CollisionSkip)
|
||||
log.Debug("skipping item with collision")
|
||||
|
||||
@ -751,7 +751,7 @@ func restoreFile(
|
||||
}
|
||||
|
||||
collision = dci
|
||||
shouldDeleteOriginal = restoreCfg.OnCollision == control.Replace && !dci.IsFolder
|
||||
shouldDeleteOriginal = rcc.RestoreConfig.OnCollision == control.Replace && !dci.IsFolder
|
||||
}
|
||||
|
||||
// drive items do not support PUT requests on the drive item data, so
|
||||
@ -850,7 +850,12 @@ func restoreFile(
|
||||
|
||||
defer closeProgressBar()
|
||||
|
||||
dii := ir.AugmentItemInfo(details.ItemInfo{}, newItem, written, nil)
|
||||
dii := ir.AugmentItemInfo(
|
||||
details.ItemInfo{},
|
||||
rcc.ProtectedResource,
|
||||
newItem,
|
||||
written,
|
||||
nil)
|
||||
|
||||
if shouldDeleteOriginal {
|
||||
ctr.Inc(count.CollisionReplace)
|
||||
|
||||
@ -38,7 +38,7 @@ func CollectLibraries(
|
||||
colls = drive.NewCollections(
|
||||
bh,
|
||||
tenantID,
|
||||
bpc.ProtectedResource.ID(),
|
||||
bpc.ProtectedResource,
|
||||
su,
|
||||
bpc.Options)
|
||||
)
|
||||
|
||||
@ -36,7 +36,7 @@ type Controller struct {
|
||||
tenant string
|
||||
credentials account.M365Config
|
||||
|
||||
ownerLookup getOwnerIDAndNamer
|
||||
ownerLookup idname.GetResourceIDAndNamer
|
||||
// maps of resource owner ids to names, and names to ids.
|
||||
// not guaranteed to be populated, only here as a post-population
|
||||
// reference for processes that choose to populate the values.
|
||||
@ -229,38 +229,24 @@ type getIDAndNamer interface {
|
||||
)
|
||||
}
|
||||
|
||||
var _ getOwnerIDAndNamer = &resourceClient{}
|
||||
var _ idname.GetResourceIDAndNamer = &resourceClient{}
|
||||
|
||||
type getOwnerIDAndNamer interface {
|
||||
getOwnerIDAndNameFrom(
|
||||
ctx context.Context,
|
||||
discovery api.Client,
|
||||
owner string,
|
||||
ins idname.Cacher,
|
||||
) (
|
||||
ownerID string,
|
||||
ownerName string,
|
||||
err error,
|
||||
)
|
||||
}
|
||||
|
||||
// getOwnerIDAndNameFrom looks up the owner's canonical id and display name.
|
||||
// If the owner is present in the idNameSwapper, then that interface's id and
|
||||
// GetResourceIDAndNameFrom looks up the resource's canonical id and display name.
|
||||
// If the resource is present in the idNameSwapper, then that interface's id and
|
||||
// name values are returned. As a fallback, the resource calls the discovery
|
||||
// api to fetch the user or site using the owner value. This fallback assumes
|
||||
// that the owner is a well formed ID or display name of appropriate design
|
||||
// api to fetch the user or site using the resource value. This fallback assumes
|
||||
// that the resource is a well formed ID or display name of appropriate design
|
||||
// (PrincipalName for users, WebURL for sites).
|
||||
func (r resourceClient) getOwnerIDAndNameFrom(
|
||||
func (r resourceClient) GetResourceIDAndNameFrom(
|
||||
ctx context.Context,
|
||||
discovery api.Client,
|
||||
owner string,
|
||||
ins idname.Cacher,
|
||||
) (string, string, error) {
|
||||
) (idname.Provider, error) {
|
||||
if ins != nil {
|
||||
if n, ok := ins.NameOf(owner); ok {
|
||||
return owner, n, nil
|
||||
return idname.NewProvider(owner, n), nil
|
||||
} else if i, ok := ins.IDOf(owner); ok {
|
||||
return i, owner, nil
|
||||
return idname.NewProvider(i, owner), nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -274,17 +260,17 @@ func (r resourceClient) getOwnerIDAndNameFrom(
|
||||
id, name, err = r.getter.GetIDAndName(ctx, owner, api.CallConfig{})
|
||||
if err != nil {
|
||||
if graph.IsErrUserNotFound(err) {
|
||||
return "", "", clues.Stack(graph.ErrResourceOwnerNotFound, err)
|
||||
return nil, clues.Stack(graph.ErrResourceOwnerNotFound, err)
|
||||
}
|
||||
|
||||
return "", "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(id) == 0 || len(name) == 0 {
|
||||
return "", "", clues.Stack(graph.ErrResourceOwnerNotFound)
|
||||
return nil, clues.Stack(graph.ErrResourceOwnerNotFound)
|
||||
}
|
||||
|
||||
return id, name, nil
|
||||
return idname.NewProvider(id, name), nil
|
||||
}
|
||||
|
||||
// PopulateProtectedResourceIDAndName takes the provided owner identifier and produces
|
||||
@ -297,15 +283,15 @@ func (r resourceClient) getOwnerIDAndNameFrom(
|
||||
// data gets stored inside the controller instance for later re-use.
|
||||
func (ctrl *Controller) PopulateProtectedResourceIDAndName(
|
||||
ctx context.Context,
|
||||
owner string, // input value, can be either id or name
|
||||
resourceID string, // input value, can be either id or name
|
||||
ins idname.Cacher,
|
||||
) (string, string, error) {
|
||||
id, name, err := ctrl.ownerLookup.getOwnerIDAndNameFrom(ctx, ctrl.AC, owner, ins)
|
||||
) (idname.Provider, error) {
|
||||
pr, err := ctrl.ownerLookup.GetResourceIDAndNameFrom(ctx, resourceID, ins)
|
||||
if err != nil {
|
||||
return "", "", clues.Wrap(err, "identifying resource owner")
|
||||
return nil, clues.Wrap(err, "identifying resource owner")
|
||||
}
|
||||
|
||||
ctrl.IDNameLookup = idname.NewCache(map[string]string{id: name})
|
||||
ctrl.IDNameLookup = idname.NewCache(map[string]string{pr.ID(): pr.Name()})
|
||||
|
||||
return id, name, nil
|
||||
return pr, nil
|
||||
}
|
||||
|
||||
@ -66,113 +66,125 @@ func (suite *ControllerUnitSuite) TestPopulateOwnerIDAndNamesFrom() {
|
||||
|
||||
table := []struct {
|
||||
name string
|
||||
owner string
|
||||
protectedResource string
|
||||
ins inMock.Cache
|
||||
rc *resourceClient
|
||||
expectID string
|
||||
expectName string
|
||||
expectErr require.ErrorAssertionFunc
|
||||
expectNil require.ValueAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "nil ins",
|
||||
owner: id,
|
||||
protectedResource: id,
|
||||
rc: lookup,
|
||||
expectID: id,
|
||||
expectName: name,
|
||||
expectErr: require.NoError,
|
||||
expectNil: require.NotNil,
|
||||
},
|
||||
{
|
||||
name: "nil ins no lookup",
|
||||
owner: id,
|
||||
protectedResource: id,
|
||||
rc: noLookup,
|
||||
expectID: "",
|
||||
expectName: "",
|
||||
expectErr: require.Error,
|
||||
expectNil: require.Nil,
|
||||
},
|
||||
{
|
||||
name: "only id map with owner id",
|
||||
owner: id,
|
||||
protectedResource: id,
|
||||
ins: inMock.NewCache(itn, nil),
|
||||
rc: noLookup,
|
||||
expectID: id,
|
||||
expectName: name,
|
||||
expectErr: require.NoError,
|
||||
expectNil: require.NotNil,
|
||||
},
|
||||
{
|
||||
name: "only name map with owner id",
|
||||
owner: id,
|
||||
protectedResource: id,
|
||||
ins: inMock.NewCache(nil, nti),
|
||||
rc: noLookup,
|
||||
expectID: "",
|
||||
expectName: "",
|
||||
expectErr: require.Error,
|
||||
expectNil: require.Nil,
|
||||
},
|
||||
{
|
||||
name: "only name map with owner id and lookup",
|
||||
owner: id,
|
||||
protectedResource: id,
|
||||
ins: inMock.NewCache(nil, nti),
|
||||
rc: lookup,
|
||||
expectID: id,
|
||||
expectName: name,
|
||||
expectErr: require.NoError,
|
||||
expectNil: require.NotNil,
|
||||
},
|
||||
{
|
||||
name: "only id map with owner name",
|
||||
owner: name,
|
||||
protectedResource: name,
|
||||
ins: inMock.NewCache(itn, nil),
|
||||
rc: lookup,
|
||||
expectID: id,
|
||||
expectName: name,
|
||||
expectErr: require.NoError,
|
||||
expectNil: require.NotNil,
|
||||
},
|
||||
{
|
||||
name: "only name map with owner name",
|
||||
owner: name,
|
||||
protectedResource: name,
|
||||
ins: inMock.NewCache(nil, nti),
|
||||
rc: noLookup,
|
||||
expectID: id,
|
||||
expectName: name,
|
||||
expectErr: require.NoError,
|
||||
expectNil: require.NotNil,
|
||||
},
|
||||
{
|
||||
name: "only id map with owner name",
|
||||
owner: name,
|
||||
protectedResource: name,
|
||||
ins: inMock.NewCache(itn, nil),
|
||||
rc: noLookup,
|
||||
expectID: "",
|
||||
expectName: "",
|
||||
expectErr: require.Error,
|
||||
expectNil: require.Nil,
|
||||
},
|
||||
{
|
||||
name: "only id map with owner name and lookup",
|
||||
owner: name,
|
||||
protectedResource: name,
|
||||
ins: inMock.NewCache(itn, nil),
|
||||
rc: lookup,
|
||||
expectID: id,
|
||||
expectName: name,
|
||||
expectErr: require.NoError,
|
||||
expectNil: require.NotNil,
|
||||
},
|
||||
{
|
||||
name: "both maps with owner id",
|
||||
owner: id,
|
||||
protectedResource: id,
|
||||
ins: inMock.NewCache(itn, nti),
|
||||
rc: noLookup,
|
||||
expectID: id,
|
||||
expectName: name,
|
||||
expectErr: require.NoError,
|
||||
expectNil: require.NotNil,
|
||||
},
|
||||
{
|
||||
name: "both maps with owner name",
|
||||
owner: name,
|
||||
protectedResource: name,
|
||||
ins: inMock.NewCache(itn, nti),
|
||||
rc: noLookup,
|
||||
expectID: id,
|
||||
expectName: name,
|
||||
expectErr: require.NoError,
|
||||
expectNil: require.NotNil,
|
||||
},
|
||||
{
|
||||
name: "non-matching maps with owner id",
|
||||
owner: id,
|
||||
protectedResource: id,
|
||||
ins: inMock.NewCache(
|
||||
map[string]string{"foo": "bar"},
|
||||
map[string]string{"fnords": "smarf"}),
|
||||
@ -180,10 +192,11 @@ func (suite *ControllerUnitSuite) TestPopulateOwnerIDAndNamesFrom() {
|
||||
expectID: "",
|
||||
expectName: "",
|
||||
expectErr: require.Error,
|
||||
expectNil: require.Nil,
|
||||
},
|
||||
{
|
||||
name: "non-matching with owner name",
|
||||
owner: name,
|
||||
protectedResource: name,
|
||||
ins: inMock.NewCache(
|
||||
map[string]string{"foo": "bar"},
|
||||
map[string]string{"fnords": "smarf"}),
|
||||
@ -191,10 +204,11 @@ func (suite *ControllerUnitSuite) TestPopulateOwnerIDAndNamesFrom() {
|
||||
expectID: "",
|
||||
expectName: "",
|
||||
expectErr: require.Error,
|
||||
expectNil: require.Nil,
|
||||
},
|
||||
{
|
||||
name: "non-matching maps with owner id and lookup",
|
||||
owner: id,
|
||||
protectedResource: id,
|
||||
ins: inMock.NewCache(
|
||||
map[string]string{"foo": "bar"},
|
||||
map[string]string{"fnords": "smarf"}),
|
||||
@ -202,10 +216,11 @@ func (suite *ControllerUnitSuite) TestPopulateOwnerIDAndNamesFrom() {
|
||||
expectID: id,
|
||||
expectName: name,
|
||||
expectErr: require.NoError,
|
||||
expectNil: require.NotNil,
|
||||
},
|
||||
{
|
||||
name: "non-matching with owner name and lookup",
|
||||
owner: name,
|
||||
protectedResource: name,
|
||||
ins: inMock.NewCache(
|
||||
map[string]string{"foo": "bar"},
|
||||
map[string]string{"fnords": "smarf"}),
|
||||
@ -213,6 +228,7 @@ func (suite *ControllerUnitSuite) TestPopulateOwnerIDAndNamesFrom() {
|
||||
expectID: id,
|
||||
expectName: name,
|
||||
expectErr: require.NoError,
|
||||
expectNil: require.NotNil,
|
||||
},
|
||||
}
|
||||
for _, test := range table {
|
||||
@ -224,10 +240,16 @@ func (suite *ControllerUnitSuite) TestPopulateOwnerIDAndNamesFrom() {
|
||||
|
||||
ctrl := &Controller{ownerLookup: test.rc}
|
||||
|
||||
rID, rName, err := ctrl.PopulateProtectedResourceIDAndName(ctx, test.owner, test.ins)
|
||||
resource, err := ctrl.PopulateProtectedResourceIDAndName(ctx, test.protectedResource, test.ins)
|
||||
test.expectErr(t, err, clues.ToCore(err))
|
||||
assert.Equal(t, test.expectID, rID, "id")
|
||||
assert.Equal(t, test.expectName, rName, "name")
|
||||
test.expectNil(t, resource)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equal(t, test.expectID, resource.ID(), "id")
|
||||
assert.Equal(t, test.expectName, resource.Name(), "name")
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1362,15 +1384,15 @@ func (suite *ControllerIntegrationSuite) TestBackup_CreatesPrefixCollections() {
|
||||
start = time.Now()
|
||||
)
|
||||
|
||||
id, name, err := backupCtrl.PopulateProtectedResourceIDAndName(ctx, backupSel.DiscreteOwner, nil)
|
||||
resource, err := backupCtrl.PopulateProtectedResourceIDAndName(ctx, backupSel.DiscreteOwner, nil)
|
||||
require.NoError(t, err, clues.ToCore(err))
|
||||
|
||||
backupSel.SetDiscreteOwnerIDName(id, name)
|
||||
backupSel.SetDiscreteOwnerIDName(resource.ID(), resource.Name())
|
||||
|
||||
bpc := inject.BackupProducerConfig{
|
||||
LastBackupVersion: version.NoBackup,
|
||||
Options: control.DefaultOptions(),
|
||||
ProtectedResource: inMock.NewProvider(id, name),
|
||||
ProtectedResource: resource,
|
||||
Selector: backupSel,
|
||||
}
|
||||
|
||||
|
||||
@ -99,8 +99,7 @@ func (ctrl Controller) PopulateProtectedResourceIDAndName(
|
||||
ctx context.Context,
|
||||
protectedResource string, // input value, can be either id or name
|
||||
ins idname.Cacher,
|
||||
) (string, string, error) {
|
||||
return ctrl.ProtectedResourceID,
|
||||
ctrl.ProtectedResourceName,
|
||||
) (idname.Provider, error) {
|
||||
return idname.NewProvider(ctrl.ProtectedResourceID, ctrl.ProtectedResourceName),
|
||||
ctrl.ProtectedResourceErr
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ func ProduceBackupCollections(
|
||||
}
|
||||
|
||||
for _, s := range sites {
|
||||
pr := idname.NewProvider(ptr.Val(s.GetId()), ptr.Val(s.GetName()))
|
||||
pr := idname.NewProvider(ptr.Val(s.GetId()), ptr.Val(s.GetWebUrl()))
|
||||
sbpc := inject.BackupProducerConfig{
|
||||
LastBackupVersion: bpc.LastBackupVersion,
|
||||
Options: bpc.Options,
|
||||
|
||||
@ -51,7 +51,7 @@ func ProduceBackupCollections(
|
||||
nc := drive.NewCollections(
|
||||
drive.NewItemBackupHandler(ac.Drives(), bpc.ProtectedResource.ID(), scope),
|
||||
tenant,
|
||||
bpc.ProtectedResource.ID(),
|
||||
bpc.ProtectedResource,
|
||||
su,
|
||||
bpc.Options)
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/drives"
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||
|
||||
"github.com/alcionai/corso/src/internal/common/idname"
|
||||
odConsts "github.com/alcionai/corso/src/internal/m365/service/onedrive/consts"
|
||||
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||
"github.com/alcionai/corso/src/pkg/control"
|
||||
@ -34,7 +35,7 @@ type BackupHandler struct {
|
||||
CanonPathFn canonPather
|
||||
CanonPathErr error
|
||||
|
||||
ResourceOwner string
|
||||
ProtectedResource idname.Provider
|
||||
Service path.ServiceType
|
||||
Category path.CategoryType
|
||||
|
||||
@ -60,7 +61,7 @@ func DefaultOneDriveBH(resourceOwner string) *BackupHandler {
|
||||
PathPrefixFn: defaultOneDrivePathPrefixer,
|
||||
MetadataPathPrefixFn: defaultOneDriveMetadataPathPrefixer,
|
||||
CanonPathFn: defaultOneDriveCanonPather,
|
||||
ResourceOwner: resourceOwner,
|
||||
ProtectedResource: idname.NewProvider(resourceOwner, resourceOwner),
|
||||
Service: path.OneDriveService,
|
||||
Category: path.FilesCategory,
|
||||
LocationIDFn: defaultOneDriveLocationIDer,
|
||||
@ -80,7 +81,7 @@ func DefaultSharePointBH(resourceOwner string) *BackupHandler {
|
||||
PathPrefixFn: defaultSharePointPathPrefixer,
|
||||
MetadataPathPrefixFn: defaultSharePointMetadataPathPrefixer,
|
||||
CanonPathFn: defaultSharePointCanonPather,
|
||||
ResourceOwner: resourceOwner,
|
||||
ProtectedResource: idname.NewProvider(resourceOwner, resourceOwner),
|
||||
Service: path.SharePointService,
|
||||
Category: path.LibrariesCategory,
|
||||
LocationIDFn: defaultSharePointLocationIDer,
|
||||
@ -90,7 +91,7 @@ func DefaultSharePointBH(resourceOwner string) *BackupHandler {
|
||||
}
|
||||
|
||||
func (h BackupHandler) PathPrefix(tID, driveID string) (path.Path, error) {
|
||||
pp, err := h.PathPrefixFn(tID, h.ResourceOwner, driveID)
|
||||
pp, err := h.PathPrefixFn(tID, h.ProtectedResource.ID(), driveID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -99,7 +100,7 @@ func (h BackupHandler) PathPrefix(tID, driveID string) (path.Path, error) {
|
||||
}
|
||||
|
||||
func (h BackupHandler) MetadataPathPrefix(tID string) (path.Path, error) {
|
||||
pp, err := h.MetadataPathPrefixFn(tID, h.ResourceOwner)
|
||||
pp, err := h.MetadataPathPrefixFn(tID, h.ProtectedResource.ID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -108,7 +109,7 @@ func (h BackupHandler) MetadataPathPrefix(tID string) (path.Path, error) {
|
||||
}
|
||||
|
||||
func (h BackupHandler) CanonicalPath(pb *path.Builder, tID string) (path.Path, error) {
|
||||
cp, err := h.CanonPathFn(pb, tID, h.ResourceOwner)
|
||||
cp, err := h.CanonPathFn(pb, tID, h.ProtectedResource.ID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -136,7 +137,13 @@ func (h BackupHandler) NewLocationIDer(driveID string, elems ...string) details.
|
||||
return h.LocationIDFn(driveID, elems...)
|
||||
}
|
||||
|
||||
func (h BackupHandler) AugmentItemInfo(details.ItemInfo, models.DriveItemable, int64, *path.Builder) details.ItemInfo {
|
||||
func (h BackupHandler) AugmentItemInfo(
|
||||
details.ItemInfo,
|
||||
idname.Provider,
|
||||
models.DriveItemable,
|
||||
int64,
|
||||
*path.Builder,
|
||||
) details.ItemInfo {
|
||||
return h.ItemInfo
|
||||
}
|
||||
|
||||
@ -308,6 +315,7 @@ func (h RestoreHandler) NewDrivePager(string, []string) api.Pager[models.Driveab
|
||||
|
||||
func (h *RestoreHandler) AugmentItemInfo(
|
||||
details.ItemInfo,
|
||||
idname.Provider,
|
||||
models.DriveItemable,
|
||||
int64,
|
||||
*path.Builder,
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/alcionai/corso/src/internal/common/idname"
|
||||
"github.com/alcionai/corso/src/internal/m365/collection/drive"
|
||||
odConsts "github.com/alcionai/corso/src/internal/m365/service/onedrive/consts"
|
||||
"github.com/alcionai/corso/src/internal/tester"
|
||||
@ -103,7 +104,7 @@ func (suite *LibrariesBackupUnitSuite) TestUpdateCollections() {
|
||||
c := drive.NewCollections(
|
||||
drive.NewLibraryBackupHandler(api.Drives{}, siteID, test.scope, path.SharePointService),
|
||||
tenantID,
|
||||
siteID,
|
||||
idname.NewProvider(siteID, siteID),
|
||||
nil,
|
||||
control.DefaultOptions())
|
||||
|
||||
|
||||
@ -34,7 +34,7 @@ func ControllerWithSelector(
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
id, name, err := ctrl.PopulateProtectedResourceIDAndName(ctx, sel.DiscreteOwner, ins)
|
||||
resource, err := ctrl.PopulateProtectedResourceIDAndName(ctx, sel.DiscreteOwner, ins)
|
||||
if !assert.NoError(t, err, clues.ToCore(err)) {
|
||||
if onFail != nil {
|
||||
onFail()
|
||||
@ -43,7 +43,7 @@ func ControllerWithSelector(
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
sel = sel.SetDiscreteOwnerIDName(id, name)
|
||||
sel = sel.SetDiscreteOwnerIDName(resource.ID(), resource.Name())
|
||||
|
||||
return ctrl, sel
|
||||
}
|
||||
|
||||
@ -109,10 +109,7 @@ type (
|
||||
ctx context.Context,
|
||||
owner string, // input value, can be either id or name
|
||||
ins idname.Cacher,
|
||||
) (
|
||||
id, name string,
|
||||
err error,
|
||||
)
|
||||
) (idname.Provider, error)
|
||||
}
|
||||
|
||||
RepoMaintenancer interface {
|
||||
|
||||
@ -362,12 +362,12 @@ func chooseRestoreResource(
|
||||
return orig, nil
|
||||
}
|
||||
|
||||
id, name, err := pprian.PopulateProtectedResourceIDAndName(
|
||||
resource, err := pprian.PopulateProtectedResourceIDAndName(
|
||||
ctx,
|
||||
restoreCfg.ProtectedResource,
|
||||
nil)
|
||||
|
||||
return idname.NewProvider(id, name), clues.Stack(err).OrNil()
|
||||
return resource, clues.Stack(err).OrNil()
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@ -550,7 +550,7 @@ func ControllerWithSelector(
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
id, name, err := ctrl.PopulateProtectedResourceIDAndName(ctx, sel.DiscreteOwner, ins)
|
||||
resource, err := ctrl.PopulateProtectedResourceIDAndName(ctx, sel.DiscreteOwner, ins)
|
||||
if !assert.NoError(t, err, clues.ToCore(err)) {
|
||||
if onFail != nil {
|
||||
onFail(t, ctx)
|
||||
@ -559,7 +559,7 @@ func ControllerWithSelector(
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
sel = sel.SetDiscreteOwnerIDName(id, name)
|
||||
sel = sel.SetDiscreteOwnerIDName(resource.ID(), resource.Name())
|
||||
|
||||
return ctrl, sel
|
||||
}
|
||||
|
||||
@ -76,13 +76,13 @@ func (r repository) NewBackupWithLookup(
|
||||
return operations.BackupOperation{}, clues.Wrap(err, "connecting to m365")
|
||||
}
|
||||
|
||||
ownerID, ownerName, err := r.Provider.PopulateProtectedResourceIDAndName(ctx, sel.DiscreteOwner, ins)
|
||||
resource, err := r.Provider.PopulateProtectedResourceIDAndName(ctx, sel.DiscreteOwner, ins)
|
||||
if err != nil {
|
||||
return operations.BackupOperation{}, clues.Wrap(err, "resolving resource owner details")
|
||||
}
|
||||
|
||||
// TODO: retrieve display name from gc
|
||||
sel = sel.SetDiscreteOwnerIDName(ownerID, ownerName)
|
||||
sel = sel.SetDiscreteOwnerIDName(resource.ID(), resource.Name())
|
||||
|
||||
return operations.NewBackupOperation(
|
||||
ctx,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user