rename libraries -> libraryFolder (#2774)
The selector moniker "libraries" is incorrect. It should refer to the library folder, since it only matches on directory structures within a given drive. The 'library' is analogous to the drive itself, and will need a separate selector of its own. --- #### Does this PR need a docs update or release note? - [x] ⛔ No #### Type of change - [x] 🐛 Bugfix #### Issue(s) * #2757 #### Test Plan - [x] ⚡ Unit test - [x] 💚 E2E
This commit is contained in:
parent
120eb0d256
commit
635e4f6bc4
@ -55,11 +55,6 @@ corso backup details onedrive --backup 1234abcd-12ab-cd34-56de-1234abcd \
|
|||||||
--user alice@example.com --file-created-before 2015-01-01T00:00:00`
|
--user alice@example.com --file-created-before 2015-01-01T00:00:00`
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
folderPaths []string
|
|
||||||
fileNames []string
|
|
||||||
)
|
|
||||||
|
|
||||||
// called by backup.go to map subcommands to provider-specific handling.
|
// called by backup.go to map subcommands to provider-specific handling.
|
||||||
func addOneDriveCommands(cmd *cobra.Command) *cobra.Command {
|
func addOneDriveCommands(cmd *cobra.Command) *cobra.Command {
|
||||||
var (
|
var (
|
||||||
@ -103,14 +98,14 @@ func addOneDriveCommands(cmd *cobra.Command) *cobra.Command {
|
|||||||
// onedrive hierarchy flags
|
// onedrive hierarchy flags
|
||||||
|
|
||||||
fs.StringSliceVar(
|
fs.StringSliceVar(
|
||||||
&folderPaths,
|
&utils.FolderPaths,
|
||||||
utils.FolderFN, nil,
|
utils.FolderFN, nil,
|
||||||
"Select backup details by OneDrive folder; defaults to root.")
|
"Select backup details by OneDrive folder; defaults to root.")
|
||||||
|
|
||||||
fs.StringSliceVar(
|
fs.StringSliceVar(
|
||||||
&fileNames,
|
&utils.FileNames,
|
||||||
utils.FileFN, nil,
|
utils.FileFN, nil,
|
||||||
"Select backup details by file name or ID.")
|
"Select backup details by file name.")
|
||||||
|
|
||||||
// onedrive info flags
|
// onedrive info flags
|
||||||
|
|
||||||
@ -263,8 +258,8 @@ func detailsOneDriveCmd(cmd *cobra.Command, args []string) error {
|
|||||||
ctx := cmd.Context()
|
ctx := cmd.Context()
|
||||||
opts := utils.OneDriveOpts{
|
opts := utils.OneDriveOpts{
|
||||||
Users: user,
|
Users: user,
|
||||||
Names: fileNames,
|
FileNames: utils.FileNames,
|
||||||
Paths: folderPaths,
|
FolderPaths: utils.FolderPaths,
|
||||||
FileCreatedAfter: utils.FileCreatedAfter,
|
FileCreatedAfter: utils.FileCreatedAfter,
|
||||||
FileCreatedBefore: utils.FileCreatedBefore,
|
FileCreatedBefore: utils.FileCreatedBefore,
|
||||||
FileModifiedAfter: utils.FileModifiedAfter,
|
FileModifiedAfter: utils.FileModifiedAfter,
|
||||||
|
|||||||
@ -26,12 +26,8 @@ import (
|
|||||||
|
|
||||||
// sharePoint bucket info from flags
|
// sharePoint bucket info from flags
|
||||||
var (
|
var (
|
||||||
libraryItems []string
|
|
||||||
libraryPaths []string
|
|
||||||
pageFolders []string
|
pageFolders []string
|
||||||
page []string
|
page []string
|
||||||
site []string
|
|
||||||
weburl []string
|
|
||||||
|
|
||||||
sharepointData []string
|
sharepointData []string
|
||||||
)
|
)
|
||||||
@ -43,34 +39,29 @@ const (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
sharePointServiceCommand = "sharepoint"
|
sharePointServiceCommand = "sharepoint"
|
||||||
sharePointServiceCommandCreateUseSuffix = "--site <siteId> | '" + utils.Wildcard + "'"
|
sharePointServiceCommandCreateUseSuffix = "--web-url <siteURL> | '" + utils.Wildcard + "'"
|
||||||
sharePointServiceCommandDeleteUseSuffix = "--backup <backupId>"
|
sharePointServiceCommandDeleteUseSuffix = "--backup <backupId>"
|
||||||
sharePointServiceCommandDetailsUseSuffix = "--backup <backupId>"
|
sharePointServiceCommandDetailsUseSuffix = "--backup <backupId>"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
sharePointServiceCommandCreateExamples = `# Backup SharePoint data for <site>
|
sharePointServiceCommandCreateExamples = `# Backup SharePoint data for a Site
|
||||||
corso backup create sharepoint --site <site_id>
|
corso backup create sharepoint --web-url <siteURL>
|
||||||
|
|
||||||
# Backup SharePoint for Alice and Bob
|
# Backup SharePoint for two sites: HR and Team
|
||||||
corso backup create sharepoint --site <site_id_1>,<site_id_2>
|
corso backup create sharepoint --site https://example.com/hr,https://example.com/team
|
||||||
|
|
||||||
# TODO: Site IDs may contain commas. We'll need to warn the site about escaping them.
|
# Backup all SharePoint data for all Sites
|
||||||
|
corso backup create sharepoint --web-url '*'`
|
||||||
# Backup all SharePoint data for all sites
|
|
||||||
corso backup create sharepoint --site '*'`
|
|
||||||
|
|
||||||
sharePointServiceCommandDeleteExamples = `# Delete SharePoint backup with ID 1234abcd-12ab-cd34-56de-1234abcd
|
sharePointServiceCommandDeleteExamples = `# Delete SharePoint backup with ID 1234abcd-12ab-cd34-56de-1234abcd
|
||||||
corso backup delete sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd`
|
corso backup delete sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd`
|
||||||
|
|
||||||
sharePointServiceCommandDetailsExamples = `# Explore <site>'s files from backup 1234abcd-12ab-cd34-56de-1234abcd
|
sharePointServiceCommandDetailsExamples = `# Explore a site's files from backup 1234abcd-12ab-cd34-56de-1234abcd
|
||||||
|
|
||||||
|
corso backup details sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd --web-url https://example.com
|
||||||
|
|
||||||
corso backup details sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd --site <site_id>
|
|
||||||
<<<<<<< HEAD
|
|
||||||
# Explore site's files created before end of 2015 from a specific backup
|
|
||||||
=======
|
|
||||||
# Find all site files that were created before a certain date.
|
# Find all site files that were created before a certain date.
|
||||||
>>>>>>> main
|
|
||||||
corso backup details sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd \
|
corso backup details sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd \
|
||||||
--web-url https://example.com --file-created-before 2015-01-01T00:00:00
|
--web-url https://example.com --file-created-before 2015-01-01T00:00:00
|
||||||
`
|
`
|
||||||
@ -90,11 +81,13 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command {
|
|||||||
c.Use = c.Use + " " + sharePointServiceCommandCreateUseSuffix
|
c.Use = c.Use + " " + sharePointServiceCommandCreateUseSuffix
|
||||||
c.Example = sharePointServiceCommandCreateExamples
|
c.Example = sharePointServiceCommandCreateExamples
|
||||||
|
|
||||||
fs.StringArrayVar(&site,
|
fs.StringArrayVar(
|
||||||
|
&utils.Site,
|
||||||
utils.SiteFN, nil,
|
utils.SiteFN, nil,
|
||||||
"Backup SharePoint data by site ID; accepts '"+utils.Wildcard+"' to select all sites.")
|
"Backup SharePoint data by site ID; accepts '"+utils.Wildcard+"' to select all sites.")
|
||||||
|
|
||||||
fs.StringSliceVar(&weburl,
|
fs.StringSliceVar(
|
||||||
|
&utils.WebURL,
|
||||||
utils.WebURLFN, nil,
|
utils.WebURLFN, nil,
|
||||||
"Restore data by site web URL; accepts '"+utils.Wildcard+"' to select all sites.")
|
"Restore data by site web URL; accepts '"+utils.Wildcard+"' to select all sites.")
|
||||||
|
|
||||||
@ -126,21 +119,28 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command {
|
|||||||
|
|
||||||
// sharepoint hierarchy flags
|
// sharepoint hierarchy flags
|
||||||
|
|
||||||
fs.StringSliceVar(
|
fs.StringVar(
|
||||||
&libraryPaths,
|
&utils.Library,
|
||||||
utils.LibraryFN, nil,
|
utils.LibraryFN, "",
|
||||||
"Select backup details by Library name.")
|
"Select backup details within a library. Defaults includes all libraries.")
|
||||||
|
|
||||||
fs.StringSliceVar(
|
fs.StringSliceVar(
|
||||||
&libraryItems,
|
&utils.FolderPaths,
|
||||||
utils.LibraryItemFN, nil,
|
utils.FolderFN, nil,
|
||||||
"Select backup details by library item name or ID.")
|
"Select backup details by folder; defaults to root.")
|
||||||
|
|
||||||
fs.StringArrayVar(&site,
|
fs.StringSliceVar(
|
||||||
|
&utils.FileNames,
|
||||||
|
utils.FileFN, nil,
|
||||||
|
"Select backup details by file name.")
|
||||||
|
|
||||||
|
fs.StringArrayVar(
|
||||||
|
&utils.Site,
|
||||||
utils.SiteFN, nil,
|
utils.SiteFN, nil,
|
||||||
"Select backup details by site ID; accepts '"+utils.Wildcard+"' to select all sites.")
|
"Select backup details by site ID; accepts '"+utils.Wildcard+"' to select all sites.")
|
||||||
|
|
||||||
fs.StringSliceVar(&weburl,
|
fs.StringSliceVar(
|
||||||
|
&utils.WebURL,
|
||||||
utils.WebURLFN, nil,
|
utils.WebURLFN, nil,
|
||||||
"Select backup data by site webURL; accepts '"+utils.Wildcard+"' to select all sites.")
|
"Select backup data by site webURL; accepts '"+utils.Wildcard+"' to select all sites.")
|
||||||
|
|
||||||
@ -152,29 +152,28 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command {
|
|||||||
fs.StringSliceVar(
|
fs.StringSliceVar(
|
||||||
&page,
|
&page,
|
||||||
utils.PagesFN, nil,
|
utils.PagesFN, nil,
|
||||||
"Select backup data by file name; accepts '"+utils.Wildcard+"' to select all pages within the site.",
|
"Select backup data by file name; accepts '"+utils.Wildcard+"' to select all pages within the site.")
|
||||||
)
|
|
||||||
|
|
||||||
// sharepoint info flags
|
// sharepoint info flags
|
||||||
|
|
||||||
fs.StringVar(
|
fs.StringVar(
|
||||||
&utils.FileCreatedAfter,
|
&utils.FileCreatedAfter,
|
||||||
utils.FileCreatedAfterFN, "",
|
utils.FileCreatedAfterFN, "",
|
||||||
"Select backup details for items created after this datetime.")
|
"Select backup details created after this datetime.")
|
||||||
|
|
||||||
fs.StringVar(
|
fs.StringVar(
|
||||||
&utils.FileCreatedBefore,
|
&utils.FileCreatedBefore,
|
||||||
utils.FileCreatedBeforeFN, "",
|
utils.FileCreatedBeforeFN, "",
|
||||||
"Select backup details for files created before this datetime.")
|
"Select backup details created before this datetime.")
|
||||||
|
|
||||||
fs.StringVar(
|
fs.StringVar(
|
||||||
&utils.FileModifiedAfter,
|
&utils.FileModifiedAfter,
|
||||||
utils.FileModifiedAfterFN, "",
|
utils.FileModifiedAfterFN, "",
|
||||||
"Select backup details for files modified after this datetime.")
|
"Select backup details modified after this datetime.")
|
||||||
fs.StringVar(
|
fs.StringVar(
|
||||||
&utils.FileModifiedBefore,
|
&utils.FileModifiedBefore,
|
||||||
utils.FileModifiedBeforeFN, "",
|
utils.FileModifiedBeforeFN, "",
|
||||||
"Select backup details for files modified before this datetime.")
|
"Select backup details modified before this datetime.")
|
||||||
|
|
||||||
case deleteCommand:
|
case deleteCommand:
|
||||||
c, fs = utils.AddCommand(cmd, sharePointDeleteCmd(), utils.MarkPreReleaseCommand())
|
c, fs = utils.AddCommand(cmd, sharePointDeleteCmd(), utils.MarkPreReleaseCommand())
|
||||||
@ -214,7 +213,7 @@ func createSharePointCmd(cmd *cobra.Command, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := validateSharePointBackupCreateFlags(site, weburl, sharepointData); err != nil {
|
if err := validateSharePointBackupCreateFlags(utils.Site, utils.WebURL, sharepointData); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,7 +232,7 @@ func createSharePointCmd(cmd *cobra.Command, args []string) error {
|
|||||||
return Only(ctx, errors.Wrap(err, "Failed to connect to Microsoft APIs"))
|
return Only(ctx, errors.Wrap(err, "Failed to connect to Microsoft APIs"))
|
||||||
}
|
}
|
||||||
|
|
||||||
sel, err := sharePointBackupCreateSelectors(ctx, site, weburl, sharepointData, gc)
|
sel, err := sharePointBackupCreateSelectors(ctx, utils.Site, utils.WebURL, sharepointData, gc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Only(ctx, errors.Wrap(err, "Retrieving up sharepoint sites by ID and Web URL"))
|
return Only(ctx, errors.Wrap(err, "Retrieving up sharepoint sites by ID and Web URL"))
|
||||||
}
|
}
|
||||||
@ -319,13 +318,13 @@ func includeAllSitesWithCategories(categories []string) *selectors.SharePointBac
|
|||||||
func addCategories(sel *selectors.SharePointBackup, cats []string) *selectors.SharePointBackup {
|
func addCategories(sel *selectors.SharePointBackup, cats []string) *selectors.SharePointBackup {
|
||||||
// Issue #2631: Libraries are the only supported feature for SharePoint at this time.
|
// Issue #2631: Libraries are the only supported feature for SharePoint at this time.
|
||||||
if len(cats) == 0 {
|
if len(cats) == 0 {
|
||||||
sel.Include(sel.Libraries(selectors.Any()))
|
sel.Include(sel.LibraryFolders(selectors.Any()))
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range cats {
|
for _, d := range cats {
|
||||||
switch d {
|
switch d {
|
||||||
case dataLibraries:
|
case dataLibraries:
|
||||||
sel.Include(sel.Libraries(selectors.Any()))
|
sel.Include(sel.LibraryFolders(selectors.Any()))
|
||||||
case dataPages:
|
case dataPages:
|
||||||
sel.Include(sel.Pages(selectors.Any()))
|
sel.Include(sel.Pages(selectors.Any()))
|
||||||
}
|
}
|
||||||
@ -396,10 +395,11 @@ func detailsSharePointCmd(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
ctx := cmd.Context()
|
ctx := cmd.Context()
|
||||||
opts := utils.SharePointOpts{
|
opts := utils.SharePointOpts{
|
||||||
LibraryItems: libraryItems,
|
FolderPaths: utils.FolderPaths,
|
||||||
LibraryPaths: libraryPaths,
|
FileNames: utils.FileNames,
|
||||||
Sites: site,
|
Library: utils.Library,
|
||||||
WebURLs: weburl,
|
Sites: utils.Site,
|
||||||
|
WebURLs: utils.WebURL,
|
||||||
FileCreatedAfter: fileCreatedAfter,
|
FileCreatedAfter: fileCreatedAfter,
|
||||||
FileCreatedBefore: fileCreatedBefore,
|
FileCreatedBefore: fileCreatedBefore,
|
||||||
FileModifiedAfter: fileModifiedAfter,
|
FileModifiedAfter: fileModifiedAfter,
|
||||||
|
|||||||
@ -161,7 +161,7 @@ func (suite *BackupDeleteSharePointE2ESuite) SetupSuite() {
|
|||||||
|
|
||||||
// some tests require an existing backup
|
// some tests require an existing backup
|
||||||
sel := selectors.NewSharePointBackup(sites)
|
sel := selectors.NewSharePointBackup(sites)
|
||||||
sel.Include(sel.Libraries(selectors.Any()))
|
sel.Include(sel.LibraryFolders(selectors.Any()))
|
||||||
|
|
||||||
suite.backupOp, err = suite.repo.NewBackup(ctx, sel.Selector)
|
suite.backupOp, err = suite.repo.NewBackup(ctx, sel.Selector)
|
||||||
require.NoError(t, suite.backupOp.Run(ctx))
|
require.NoError(t, suite.backupOp.Run(ctx))
|
||||||
|
|||||||
@ -133,8 +133,8 @@ func restoreOneDriveCmd(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
opts := utils.OneDriveOpts{
|
opts := utils.OneDriveOpts{
|
||||||
Users: user,
|
Users: user,
|
||||||
Names: fileNames,
|
FileNames: fileNames,
|
||||||
Paths: folderPaths,
|
FolderPaths: folderPaths,
|
||||||
FileCreatedAfter: utils.FileCreatedAfter,
|
FileCreatedAfter: utils.FileCreatedAfter,
|
||||||
FileCreatedBefore: utils.FileCreatedBefore,
|
FileCreatedBefore: utils.FileCreatedBefore,
|
||||||
FileModifiedAfter: utils.FileModifiedAfter,
|
FileModifiedAfter: utils.FileModifiedAfter,
|
||||||
|
|||||||
@ -20,10 +20,6 @@ var (
|
|||||||
listPaths []string
|
listPaths []string
|
||||||
pageFolders []string
|
pageFolders []string
|
||||||
pages []string
|
pages []string
|
||||||
libraryItems []string
|
|
||||||
libraryPaths []string
|
|
||||||
site []string
|
|
||||||
weburl []string
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// called by restore.go to map subcommands to provider-specific handling.
|
// called by restore.go to map subcommands to provider-specific handling.
|
||||||
@ -43,30 +39,38 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command {
|
|||||||
// More generic (ex: --site) and more frequently used flags take precedence.
|
// More generic (ex: --site) and more frequently used flags take precedence.
|
||||||
fs.SortFlags = false
|
fs.SortFlags = false
|
||||||
|
|
||||||
fs.StringVar(&backupID,
|
fs.StringVar(
|
||||||
|
&backupID,
|
||||||
utils.BackupFN, "",
|
utils.BackupFN, "",
|
||||||
"ID of the backup to restore. (required)")
|
"ID of the backup to restore. (required)")
|
||||||
cobra.CheckErr(c.MarkFlagRequired(utils.BackupFN))
|
cobra.CheckErr(c.MarkFlagRequired(utils.BackupFN))
|
||||||
|
|
||||||
fs.StringSliceVar(&site,
|
fs.StringSliceVar(
|
||||||
|
&utils.Site,
|
||||||
utils.SiteFN, nil,
|
utils.SiteFN, nil,
|
||||||
"Restore data by site ID; accepts '"+utils.Wildcard+"' to select all sites.")
|
"Restore data by site ID; accepts '"+utils.Wildcard+"' to select all sites.")
|
||||||
|
|
||||||
fs.StringSliceVar(&weburl,
|
fs.StringSliceVar(
|
||||||
|
&utils.WebURL,
|
||||||
utils.WebURLFN, nil,
|
utils.WebURLFN, nil,
|
||||||
"Restore data by site webURL; accepts '"+utils.Wildcard+"' to select all sites.")
|
"Restore data by site webURL; accepts '"+utils.Wildcard+"' to select all sites.")
|
||||||
|
|
||||||
// sharepoint hierarchy (path/name) flags
|
// sharepoint hierarchy (path/name) flags
|
||||||
|
|
||||||
fs.StringSliceVar(
|
fs.StringVar(
|
||||||
&libraryPaths,
|
&utils.Library,
|
||||||
utils.LibraryFN, nil,
|
utils.LibraryFN, "",
|
||||||
"Restore library items by SharePoint library")
|
"Restore files within a library. Default includes all libraries.")
|
||||||
|
|
||||||
fs.StringSliceVar(
|
fs.StringSliceVar(
|
||||||
&libraryItems,
|
&utils.FolderPaths,
|
||||||
utils.LibraryItemFN, nil,
|
utils.FolderFN, nil,
|
||||||
"Restore library items by file name or ID")
|
"Restore files by folder; defaults to root.")
|
||||||
|
|
||||||
|
fs.StringSliceVar(
|
||||||
|
&utils.FileNames,
|
||||||
|
utils.FileFN, nil,
|
||||||
|
"Restore files by name.")
|
||||||
|
|
||||||
fs.StringSliceVar(
|
fs.StringSliceVar(
|
||||||
&listPaths,
|
&listPaths,
|
||||||
@ -81,21 +85,33 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command {
|
|||||||
fs.StringSliceVar(
|
fs.StringSliceVar(
|
||||||
&pageFolders,
|
&pageFolders,
|
||||||
utils.PageFolderFN, nil,
|
utils.PageFolderFN, nil,
|
||||||
"Restore Site pages by page folder name",
|
"Restore Site pages by page folder name")
|
||||||
)
|
|
||||||
|
|
||||||
fs.StringSliceVar(
|
fs.StringSliceVar(
|
||||||
&pages,
|
&pages,
|
||||||
utils.PagesFN, nil,
|
utils.PagesFN, nil,
|
||||||
"Restore site pages by file name(s)",
|
"Restore site pages by file name(s)")
|
||||||
)
|
|
||||||
|
|
||||||
// sharepoint info flags
|
// sharepoint info flags
|
||||||
|
|
||||||
// fs.StringVar(
|
fs.StringVar(
|
||||||
// &fileCreatedAfter,
|
&utils.FileCreatedAfter,
|
||||||
// utils.FileCreatedAfterFN, "",
|
utils.FileCreatedAfterFN, "",
|
||||||
// "Restore files created after this datetime")
|
"Restore files created after this datetime.")
|
||||||
|
|
||||||
|
fs.StringVar(
|
||||||
|
&utils.FileCreatedBefore,
|
||||||
|
utils.FileCreatedBeforeFN, "",
|
||||||
|
"Restore files created before this datetime.")
|
||||||
|
|
||||||
|
fs.StringVar(
|
||||||
|
&utils.FileModifiedAfter,
|
||||||
|
utils.FileModifiedAfterFN, "",
|
||||||
|
"Restore files modified after this datetime.")
|
||||||
|
fs.StringVar(
|
||||||
|
&utils.FileModifiedBefore,
|
||||||
|
utils.FileModifiedBeforeFN, "",
|
||||||
|
"Restore files modified before this datetime.")
|
||||||
|
|
||||||
// others
|
// others
|
||||||
options.AddOperationFlags(c)
|
options.AddOperationFlags(c)
|
||||||
@ -112,13 +128,13 @@ const (
|
|||||||
sharePointServiceCommandRestoreExamples = `# Restore file with ID 98765abcdef
|
sharePointServiceCommandRestoreExamples = `# Restore file with ID 98765abcdef
|
||||||
corso restore sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd --file 98765abcdef
|
corso restore sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd --file 98765abcdef
|
||||||
|
|
||||||
# Restore <site>'s file named "ServerRenderTemplate.xsl in "Display Templates/Style Sheets" from a specific backup
|
# Restore a Site's file named "ServerRenderTemplate.xsl in "Display Templates/Style Sheets" from a specific backup
|
||||||
corso restore sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd \
|
corso restore sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd \
|
||||||
--site <siteID> --file "ServerRenderTemplate.xsl" --folder "Display Templates/Style Sheets"
|
--web-url https://example.com --file "ServerRenderTemplate.xsl" --folder "Display Templates/Style Sheets"
|
||||||
|
|
||||||
# Restore all files from <site> that were created before 2020 when captured in a specific backup
|
# Restore all files from a Site that were created before 2020 when captured in a specific backup
|
||||||
corso restore sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd
|
corso restore sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd
|
||||||
--site <siteID> --folder "Display Templates/Style Sheets" --file-created-before 2020-01-01T00:00:00`
|
--web-url https://example.com --folder "Display Templates/Style Sheets" --file-created-before 2020-01-01T00:00:00`
|
||||||
)
|
)
|
||||||
|
|
||||||
// `corso restore sharepoint [<flag>...]`
|
// `corso restore sharepoint [<flag>...]`
|
||||||
@ -141,14 +157,15 @@ func restoreSharePointCmd(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
opts := utils.SharePointOpts{
|
opts := utils.SharePointOpts{
|
||||||
LibraryItems: libraryItems,
|
FileNames: utils.FileNames,
|
||||||
LibraryPaths: libraryPaths,
|
FolderPaths: utils.FolderPaths,
|
||||||
|
Library: utils.Library,
|
||||||
ListItems: listItems,
|
ListItems: listItems,
|
||||||
ListPaths: listPaths,
|
ListPaths: listPaths,
|
||||||
PageFolders: pageFolders,
|
PageFolders: pageFolders,
|
||||||
Pages: pages,
|
Pages: pages,
|
||||||
Sites: site,
|
Sites: utils.Site,
|
||||||
WebURLs: weburl,
|
WebURLs: utils.WebURL,
|
||||||
FileCreatedAfter: utils.FileCreatedAfter,
|
FileCreatedAfter: utils.FileCreatedAfter,
|
||||||
FileCreatedBefore: utils.FileCreatedBefore,
|
FileCreatedBefore: utils.FileCreatedBefore,
|
||||||
FileModifiedAfter: utils.FileModifiedAfter,
|
FileModifiedAfter: utils.FileModifiedAfter,
|
||||||
|
|||||||
@ -10,18 +10,37 @@ import (
|
|||||||
"github.com/alcionai/corso/src/pkg/path"
|
"github.com/alcionai/corso/src/pkg/path"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ==============================================
|
// common flag vars
|
||||||
// Folder Object flags
|
|
||||||
// These options are flags for indicating
|
|
||||||
// that a time-based filter should be used for
|
|
||||||
// within returning objects for details.
|
|
||||||
// Used by: OneDrive, SharePoint
|
|
||||||
// ================================================
|
|
||||||
var (
|
var (
|
||||||
|
FolderPaths []string
|
||||||
|
FileNames []string
|
||||||
|
|
||||||
FileCreatedAfter string
|
FileCreatedAfter string
|
||||||
FileCreatedBefore string
|
FileCreatedBefore string
|
||||||
FileModifiedAfter string
|
FileModifiedAfter string
|
||||||
FileModifiedBefore string
|
FileModifiedBefore string
|
||||||
|
|
||||||
|
Library string
|
||||||
|
Site []string
|
||||||
|
WebURL []string
|
||||||
|
)
|
||||||
|
|
||||||
|
// common flag names
|
||||||
|
const (
|
||||||
|
BackupFN = "backup"
|
||||||
|
DataFN = "data"
|
||||||
|
LibraryFN = "library"
|
||||||
|
SiteFN = "site"
|
||||||
|
UserFN = "user"
|
||||||
|
WebURLFN = "web-url"
|
||||||
|
|
||||||
|
FileFN = "file"
|
||||||
|
FolderFN = "folder"
|
||||||
|
|
||||||
|
FileCreatedAfterFN = "file-created-after"
|
||||||
|
FileCreatedBeforeFN = "file-created-before"
|
||||||
|
FileModifiedAfterFN = "file-modified-after"
|
||||||
|
FileModifiedBeforeFN = "file-modified-before"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PopulatedFlags map[string]struct{}
|
type PopulatedFlags map[string]struct{}
|
||||||
|
|||||||
@ -6,17 +6,10 @@ import (
|
|||||||
"github.com/alcionai/corso/src/pkg/selectors"
|
"github.com/alcionai/corso/src/pkg/selectors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
FileFN = "file"
|
|
||||||
FolderFN = "folder"
|
|
||||||
NamesFN = "name"
|
|
||||||
PathsFN = "path"
|
|
||||||
)
|
|
||||||
|
|
||||||
type OneDriveOpts struct {
|
type OneDriveOpts struct {
|
||||||
Users []string
|
Users []string
|
||||||
Names []string
|
FileNames []string
|
||||||
Paths []string
|
FolderPaths []string
|
||||||
FileCreatedAfter string
|
FileCreatedAfter string
|
||||||
FileCreatedBefore string
|
FileCreatedBefore string
|
||||||
FileModifiedAfter string
|
FileModifiedAfter string
|
||||||
@ -74,7 +67,7 @@ func IncludeOneDriveRestoreDataSelectors(opts OneDriveOpts) *selectors.OneDriveR
|
|||||||
|
|
||||||
sel := selectors.NewOneDriveRestore(users)
|
sel := selectors.NewOneDriveRestore(users)
|
||||||
|
|
||||||
lp, ln := len(opts.Paths), len(opts.Names)
|
lp, ln := len(opts.FolderPaths), len(opts.FileNames)
|
||||||
|
|
||||||
// only use the inclusion if either a path or item name
|
// only use the inclusion if either a path or item name
|
||||||
// is specified
|
// is specified
|
||||||
@ -83,20 +76,20 @@ func IncludeOneDriveRestoreDataSelectors(opts OneDriveOpts) *selectors.OneDriveR
|
|||||||
return sel
|
return sel
|
||||||
}
|
}
|
||||||
|
|
||||||
opts.Paths = trimFolderSlash(opts.Paths)
|
opts.FolderPaths = trimFolderSlash(opts.FolderPaths)
|
||||||
|
|
||||||
if ln == 0 {
|
if ln == 0 {
|
||||||
opts.Names = selectors.Any()
|
opts.FileNames = selectors.Any()
|
||||||
}
|
}
|
||||||
|
|
||||||
containsFolders, prefixFolders := splitFoldersIntoContainsAndPrefix(opts.Paths)
|
containsFolders, prefixFolders := splitFoldersIntoContainsAndPrefix(opts.FolderPaths)
|
||||||
|
|
||||||
if len(containsFolders) > 0 {
|
if len(containsFolders) > 0 {
|
||||||
sel.Include(sel.Items(containsFolders, opts.Names))
|
sel.Include(sel.Items(containsFolders, opts.FileNames))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(prefixFolders) > 0 {
|
if len(prefixFolders) > 0 {
|
||||||
sel.Include(sel.Items(prefixFolders, opts.Names, selectors.PrefixMatch()))
|
sel.Include(sel.Items(prefixFolders, opts.FileNames, selectors.PrefixMatch()))
|
||||||
}
|
}
|
||||||
|
|
||||||
return sel
|
return sel
|
||||||
|
|||||||
@ -37,8 +37,8 @@ func (suite *OneDriveUtilsSuite) TestIncludeOneDriveRestoreDataSelectors() {
|
|||||||
name: "no inputs",
|
name: "no inputs",
|
||||||
opts: utils.OneDriveOpts{
|
opts: utils.OneDriveOpts{
|
||||||
Users: empty,
|
Users: empty,
|
||||||
Paths: empty,
|
FileNames: empty,
|
||||||
Names: empty,
|
FolderPaths: empty,
|
||||||
},
|
},
|
||||||
expectIncludeLen: 1,
|
expectIncludeLen: 1,
|
||||||
},
|
},
|
||||||
@ -46,8 +46,8 @@ func (suite *OneDriveUtilsSuite) TestIncludeOneDriveRestoreDataSelectors() {
|
|||||||
name: "single inputs",
|
name: "single inputs",
|
||||||
opts: utils.OneDriveOpts{
|
opts: utils.OneDriveOpts{
|
||||||
Users: single,
|
Users: single,
|
||||||
Paths: single,
|
FileNames: single,
|
||||||
Names: single,
|
FolderPaths: single,
|
||||||
},
|
},
|
||||||
expectIncludeLen: 1,
|
expectIncludeLen: 1,
|
||||||
},
|
},
|
||||||
@ -55,8 +55,8 @@ func (suite *OneDriveUtilsSuite) TestIncludeOneDriveRestoreDataSelectors() {
|
|||||||
name: "multi inputs",
|
name: "multi inputs",
|
||||||
opts: utils.OneDriveOpts{
|
opts: utils.OneDriveOpts{
|
||||||
Users: multi,
|
Users: multi,
|
||||||
Paths: multi,
|
FileNames: multi,
|
||||||
Names: multi,
|
FolderPaths: multi,
|
||||||
},
|
},
|
||||||
expectIncludeLen: 1,
|
expectIncludeLen: 1,
|
||||||
},
|
},
|
||||||
@ -64,8 +64,8 @@ func (suite *OneDriveUtilsSuite) TestIncludeOneDriveRestoreDataSelectors() {
|
|||||||
name: "folder contains",
|
name: "folder contains",
|
||||||
opts: utils.OneDriveOpts{
|
opts: utils.OneDriveOpts{
|
||||||
Users: empty,
|
Users: empty,
|
||||||
Paths: containsOnly,
|
FileNames: empty,
|
||||||
Names: empty,
|
FolderPaths: containsOnly,
|
||||||
},
|
},
|
||||||
expectIncludeLen: 1,
|
expectIncludeLen: 1,
|
||||||
},
|
},
|
||||||
@ -73,8 +73,8 @@ func (suite *OneDriveUtilsSuite) TestIncludeOneDriveRestoreDataSelectors() {
|
|||||||
name: "folder prefixes",
|
name: "folder prefixes",
|
||||||
opts: utils.OneDriveOpts{
|
opts: utils.OneDriveOpts{
|
||||||
Users: empty,
|
Users: empty,
|
||||||
Paths: prefixOnly,
|
FileNames: empty,
|
||||||
Names: empty,
|
FolderPaths: prefixOnly,
|
||||||
},
|
},
|
||||||
expectIncludeLen: 1,
|
expectIncludeLen: 1,
|
||||||
},
|
},
|
||||||
@ -82,8 +82,8 @@ func (suite *OneDriveUtilsSuite) TestIncludeOneDriveRestoreDataSelectors() {
|
|||||||
name: "folder prefixes and contains",
|
name: "folder prefixes and contains",
|
||||||
opts: utils.OneDriveOpts{
|
opts: utils.OneDriveOpts{
|
||||||
Users: empty,
|
Users: empty,
|
||||||
Paths: containsAndPrefix,
|
FileNames: empty,
|
||||||
Names: empty,
|
FolderPaths: containsAndPrefix,
|
||||||
},
|
},
|
||||||
expectIncludeLen: 2,
|
expectIncludeLen: 2,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -8,18 +8,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LibraryItemFN = "library-item"
|
|
||||||
LibraryFN = "library"
|
|
||||||
ListItemFN = "list-item"
|
ListItemFN = "list-item"
|
||||||
ListFN = "list"
|
ListFN = "list"
|
||||||
PageFolderFN = "page-folders"
|
PageFolderFN = "page-folders"
|
||||||
PagesFN = "pages"
|
PagesFN = "pages"
|
||||||
WebURLFN = "web-url"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SharePointOpts struct {
|
type SharePointOpts struct {
|
||||||
LibraryItems []string
|
FileNames []string // for libraries, to duplicate onedrive interface
|
||||||
LibraryPaths []string
|
FolderPaths []string // for libraries, to duplicate onedrive interface
|
||||||
|
Library string
|
||||||
ListItems []string
|
ListItems []string
|
||||||
ListPaths []string
|
ListPaths []string
|
||||||
PageFolders []string
|
PageFolders []string
|
||||||
@ -79,7 +77,7 @@ func AddSharePointFilter(
|
|||||||
func IncludeSharePointRestoreDataSelectors(opts SharePointOpts) *selectors.SharePointRestore {
|
func IncludeSharePointRestoreDataSelectors(opts SharePointOpts) *selectors.SharePointRestore {
|
||||||
sites := opts.Sites
|
sites := opts.Sites
|
||||||
|
|
||||||
lp, li := len(opts.LibraryPaths), len(opts.LibraryItems)
|
lfp, lfn := len(opts.FolderPaths), len(opts.FileNames)
|
||||||
ls, lwu := len(opts.Sites), len(opts.WebURLs)
|
ls, lwu := len(opts.Sites), len(opts.WebURLs)
|
||||||
slp, sli := len(opts.ListPaths), len(opts.ListItems)
|
slp, sli := len(opts.ListPaths), len(opts.ListItems)
|
||||||
pf, pi := len(opts.PageFolders), len(opts.Pages)
|
pf, pi := len(opts.PageFolders), len(opts.Pages)
|
||||||
@ -90,25 +88,25 @@ func IncludeSharePointRestoreDataSelectors(opts SharePointOpts) *selectors.Share
|
|||||||
|
|
||||||
sel := selectors.NewSharePointRestore(sites)
|
sel := selectors.NewSharePointRestore(sites)
|
||||||
|
|
||||||
if lp+li+lwu+slp+sli+pf+pi == 0 {
|
if lfp+lfn+lwu+slp+sli+pf+pi == 0 {
|
||||||
sel.Include(sel.AllData())
|
sel.Include(sel.AllData())
|
||||||
return sel
|
return sel
|
||||||
}
|
}
|
||||||
|
|
||||||
if lp+li > 0 {
|
if lfp+lfn > 0 {
|
||||||
if li == 0 {
|
if lfn == 0 {
|
||||||
opts.LibraryItems = selectors.Any()
|
opts.FileNames = selectors.Any()
|
||||||
}
|
}
|
||||||
|
|
||||||
opts.LibraryPaths = trimFolderSlash(opts.LibraryPaths)
|
opts.FolderPaths = trimFolderSlash(opts.FolderPaths)
|
||||||
containsFolders, prefixFolders := splitFoldersIntoContainsAndPrefix(opts.LibraryPaths)
|
containsFolders, prefixFolders := splitFoldersIntoContainsAndPrefix(opts.FolderPaths)
|
||||||
|
|
||||||
if len(containsFolders) > 0 {
|
if len(containsFolders) > 0 {
|
||||||
sel.Include(sel.LibraryItems(containsFolders, opts.LibraryItems))
|
sel.Include(sel.LibraryItems(containsFolders, opts.FileNames))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(prefixFolders) > 0 {
|
if len(prefixFolders) > 0 {
|
||||||
sel.Include(sel.LibraryItems(prefixFolders, opts.LibraryItems, selectors.PrefixMatch()))
|
sel.Include(sel.LibraryItems(prefixFolders, opts.FileNames, selectors.PrefixMatch()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,6 +165,7 @@ func FilterSharePointRestoreInfoSelectors(
|
|||||||
sel *selectors.SharePointRestore,
|
sel *selectors.SharePointRestore,
|
||||||
opts SharePointOpts,
|
opts SharePointOpts,
|
||||||
) {
|
) {
|
||||||
|
AddSharePointFilter(sel, opts.Library, sel.Library)
|
||||||
AddSharePointFilter(sel, opts.FileCreatedAfter, sel.CreatedAfter)
|
AddSharePointFilter(sel, opts.FileCreatedAfter, sel.CreatedAfter)
|
||||||
AddSharePointFilter(sel, opts.FileCreatedBefore, sel.CreatedBefore)
|
AddSharePointFilter(sel, opts.FileCreatedBefore, sel.CreatedBefore)
|
||||||
AddSharePointFilter(sel, opts.FileModifiedAfter, sel.ModifiedAfter)
|
AddSharePointFilter(sel, opts.FileModifiedAfter, sel.ModifiedAfter)
|
||||||
|
|||||||
@ -43,8 +43,8 @@ func (suite *SharePointUtilsSuite) TestIncludeSharePointRestoreDataSelectors() {
|
|||||||
{
|
{
|
||||||
name: "single inputs",
|
name: "single inputs",
|
||||||
opts: utils.SharePointOpts{
|
opts: utils.SharePointOpts{
|
||||||
LibraryItems: single,
|
FileNames: single,
|
||||||
LibraryPaths: single,
|
FolderPaths: single,
|
||||||
Sites: single,
|
Sites: single,
|
||||||
WebURLs: single,
|
WebURLs: single,
|
||||||
},
|
},
|
||||||
@ -53,8 +53,8 @@ func (suite *SharePointUtilsSuite) TestIncludeSharePointRestoreDataSelectors() {
|
|||||||
{
|
{
|
||||||
name: "single extended",
|
name: "single extended",
|
||||||
opts: utils.SharePointOpts{
|
opts: utils.SharePointOpts{
|
||||||
LibraryItems: single,
|
FileNames: single,
|
||||||
LibraryPaths: single,
|
FolderPaths: single,
|
||||||
ListItems: single,
|
ListItems: single,
|
||||||
ListPaths: single,
|
ListPaths: single,
|
||||||
Sites: single,
|
Sites: single,
|
||||||
@ -65,38 +65,38 @@ func (suite *SharePointUtilsSuite) TestIncludeSharePointRestoreDataSelectors() {
|
|||||||
{
|
{
|
||||||
name: "multi inputs",
|
name: "multi inputs",
|
||||||
opts: utils.SharePointOpts{
|
opts: utils.SharePointOpts{
|
||||||
LibraryItems: multi,
|
FileNames: multi,
|
||||||
LibraryPaths: multi,
|
FolderPaths: multi,
|
||||||
Sites: multi,
|
Sites: multi,
|
||||||
WebURLs: multi,
|
WebURLs: multi,
|
||||||
},
|
},
|
||||||
expectIncludeLen: 4,
|
expectIncludeLen: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "library contains",
|
name: "library folder contains",
|
||||||
opts: utils.SharePointOpts{
|
opts: utils.SharePointOpts{
|
||||||
LibraryItems: empty,
|
FileNames: empty,
|
||||||
LibraryPaths: containsOnly,
|
FolderPaths: containsOnly,
|
||||||
Sites: empty,
|
Sites: empty,
|
||||||
WebURLs: empty,
|
WebURLs: empty,
|
||||||
},
|
},
|
||||||
expectIncludeLen: 1,
|
expectIncludeLen: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "library prefixes",
|
name: "library folder prefixes",
|
||||||
opts: utils.SharePointOpts{
|
opts: utils.SharePointOpts{
|
||||||
LibraryItems: empty,
|
FileNames: empty,
|
||||||
LibraryPaths: prefixOnly,
|
FolderPaths: prefixOnly,
|
||||||
Sites: empty,
|
Sites: empty,
|
||||||
WebURLs: empty,
|
WebURLs: empty,
|
||||||
},
|
},
|
||||||
expectIncludeLen: 1,
|
expectIncludeLen: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "library prefixes and contains",
|
name: "library folder prefixes and contains",
|
||||||
opts: utils.SharePointOpts{
|
opts: utils.SharePointOpts{
|
||||||
LibraryItems: empty,
|
FileNames: empty,
|
||||||
LibraryPaths: containsAndPrefix,
|
FolderPaths: containsAndPrefix,
|
||||||
Sites: empty,
|
Sites: empty,
|
||||||
WebURLs: empty,
|
WebURLs: empty,
|
||||||
},
|
},
|
||||||
@ -105,8 +105,8 @@ func (suite *SharePointUtilsSuite) TestIncludeSharePointRestoreDataSelectors() {
|
|||||||
{
|
{
|
||||||
name: "list contains",
|
name: "list contains",
|
||||||
opts: utils.SharePointOpts{
|
opts: utils.SharePointOpts{
|
||||||
LibraryItems: empty,
|
FileNames: empty,
|
||||||
LibraryPaths: empty,
|
FolderPaths: empty,
|
||||||
ListItems: empty,
|
ListItems: empty,
|
||||||
ListPaths: containsOnly,
|
ListPaths: containsOnly,
|
||||||
Sites: empty,
|
Sites: empty,
|
||||||
@ -131,28 +131,28 @@ func (suite *SharePointUtilsSuite) TestIncludeSharePointRestoreDataSelectors() {
|
|||||||
{
|
{
|
||||||
name: "weburl contains",
|
name: "weburl contains",
|
||||||
opts: utils.SharePointOpts{
|
opts: utils.SharePointOpts{
|
||||||
LibraryItems: empty,
|
FileNames: empty,
|
||||||
LibraryPaths: empty,
|
FolderPaths: empty,
|
||||||
Sites: empty,
|
Sites: empty,
|
||||||
WebURLs: containsOnly,
|
WebURLs: containsOnly,
|
||||||
},
|
},
|
||||||
expectIncludeLen: 3,
|
expectIncludeLen: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "library suffixes",
|
name: "library folder suffixes",
|
||||||
opts: utils.SharePointOpts{
|
opts: utils.SharePointOpts{
|
||||||
LibraryItems: empty,
|
FileNames: empty,
|
||||||
LibraryPaths: empty,
|
FolderPaths: empty,
|
||||||
Sites: empty,
|
Sites: empty,
|
||||||
WebURLs: prefixOnly, // prefix pattern matches suffix pattern
|
WebURLs: prefixOnly, // prefix pattern matches suffix pattern
|
||||||
},
|
},
|
||||||
expectIncludeLen: 3,
|
expectIncludeLen: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "library suffixes and contains",
|
name: "library folder suffixes and contains",
|
||||||
opts: utils.SharePointOpts{
|
opts: utils.SharePointOpts{
|
||||||
LibraryItems: empty,
|
FileNames: empty,
|
||||||
LibraryPaths: empty,
|
FolderPaths: empty,
|
||||||
Sites: empty,
|
Sites: empty,
|
||||||
WebURLs: containsAndPrefix, // prefix pattern matches suffix pattern
|
WebURLs: containsAndPrefix, // prefix pattern matches suffix pattern
|
||||||
},
|
},
|
||||||
@ -173,10 +173,10 @@ func (suite *SharePointUtilsSuite) TestIncludeSharePointRestoreDataSelectors() {
|
|||||||
expectIncludeLen: 1,
|
expectIncludeLen: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Page & Library",
|
name: "Page & library Files",
|
||||||
opts: utils.SharePointOpts{
|
opts: utils.SharePointOpts{
|
||||||
PageFolders: single,
|
PageFolders: single,
|
||||||
LibraryItems: multi,
|
FileNames: multi,
|
||||||
},
|
},
|
||||||
expectIncludeLen: 2,
|
expectIncludeLen: 2,
|
||||||
},
|
},
|
||||||
|
|||||||
20
src/cli/utils/testdata/opts.go
vendored
20
src/cli/utils/testdata/opts.go
vendored
@ -350,28 +350,28 @@ var (
|
|||||||
Name: "AllFiles",
|
Name: "AllFiles",
|
||||||
Expected: testdata.OneDriveItems,
|
Expected: testdata.OneDriveItems,
|
||||||
Opts: utils.OneDriveOpts{
|
Opts: utils.OneDriveOpts{
|
||||||
Paths: selectors.Any(),
|
FolderPaths: selectors.Any(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "FolderPrefixMatch",
|
Name: "FolderPrefixMatch",
|
||||||
Expected: testdata.OneDriveItems,
|
Expected: testdata.OneDriveItems,
|
||||||
Opts: utils.OneDriveOpts{
|
Opts: utils.OneDriveOpts{
|
||||||
Paths: []string{testdata.OneDriveFolderFolder},
|
FolderPaths: []string{testdata.OneDriveFolderFolder},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "FolderPrefixMatchTrailingSlash",
|
Name: "FolderPrefixMatchTrailingSlash",
|
||||||
Expected: testdata.OneDriveItems,
|
Expected: testdata.OneDriveItems,
|
||||||
Opts: utils.OneDriveOpts{
|
Opts: utils.OneDriveOpts{
|
||||||
Paths: []string{testdata.OneDriveFolderFolder + "/"},
|
FolderPaths: []string{testdata.OneDriveFolderFolder + "/"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "FolderPrefixMatchTrailingSlash",
|
Name: "FolderPrefixMatchTrailingSlash",
|
||||||
Expected: testdata.OneDriveItems,
|
Expected: testdata.OneDriveItems,
|
||||||
Opts: utils.OneDriveOpts{
|
Opts: utils.OneDriveOpts{
|
||||||
Paths: []string{testdata.OneDriveFolderFolder + "/"},
|
FolderPaths: []string{testdata.OneDriveFolderFolder + "/"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -381,7 +381,7 @@ var (
|
|||||||
testdata.OneDriveItems[1],
|
testdata.OneDriveItems[1],
|
||||||
},
|
},
|
||||||
Opts: utils.OneDriveOpts{
|
Opts: utils.OneDriveOpts{
|
||||||
Names: []string{
|
FileNames: []string{
|
||||||
testdata.OneDriveItems[0].ShortRef,
|
testdata.OneDriveItems[0].ShortRef,
|
||||||
testdata.OneDriveItems[1].ShortRef,
|
testdata.OneDriveItems[1].ShortRef,
|
||||||
},
|
},
|
||||||
@ -438,28 +438,28 @@ var (
|
|||||||
Name: "AllLibraryItems",
|
Name: "AllLibraryItems",
|
||||||
Expected: testdata.SharePointLibraryItems,
|
Expected: testdata.SharePointLibraryItems,
|
||||||
Opts: utils.SharePointOpts{
|
Opts: utils.SharePointOpts{
|
||||||
LibraryPaths: selectors.Any(),
|
FolderPaths: selectors.Any(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "FolderPrefixMatch",
|
Name: "FolderPrefixMatch",
|
||||||
Expected: testdata.SharePointLibraryItems,
|
Expected: testdata.SharePointLibraryItems,
|
||||||
Opts: utils.SharePointOpts{
|
Opts: utils.SharePointOpts{
|
||||||
LibraryPaths: []string{testdata.SharePointLibraryFolder},
|
FolderPaths: []string{testdata.SharePointLibraryFolder},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "FolderPrefixMatchTrailingSlash",
|
Name: "FolderPrefixMatchTrailingSlash",
|
||||||
Expected: testdata.SharePointLibraryItems,
|
Expected: testdata.SharePointLibraryItems,
|
||||||
Opts: utils.SharePointOpts{
|
Opts: utils.SharePointOpts{
|
||||||
LibraryPaths: []string{testdata.SharePointLibraryFolder + "/"},
|
FolderPaths: []string{testdata.SharePointLibraryFolder + "/"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "FolderPrefixMatchTrailingSlash",
|
Name: "FolderPrefixMatchTrailingSlash",
|
||||||
Expected: testdata.SharePointLibraryItems,
|
Expected: testdata.SharePointLibraryItems,
|
||||||
Opts: utils.SharePointOpts{
|
Opts: utils.SharePointOpts{
|
||||||
LibraryPaths: []string{testdata.SharePointLibraryFolder + "/"},
|
FolderPaths: []string{testdata.SharePointLibraryFolder + "/"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -469,7 +469,7 @@ var (
|
|||||||
testdata.SharePointLibraryItems[1],
|
testdata.SharePointLibraryItems[1],
|
||||||
},
|
},
|
||||||
Opts: utils.SharePointOpts{
|
Opts: utils.SharePointOpts{
|
||||||
LibraryItems: []string{
|
FileNames: []string{
|
||||||
testdata.SharePointLibraryItems[0].ShortRef,
|
testdata.SharePointLibraryItems[0].ShortRef,
|
||||||
testdata.SharePointLibraryItems[1].ShortRef,
|
testdata.SharePointLibraryItems[1].ShortRef,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,18 +17,6 @@ import (
|
|||||||
"github.com/alcionai/corso/src/pkg/storage"
|
"github.com/alcionai/corso/src/pkg/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
// common flag names
|
|
||||||
const (
|
|
||||||
BackupFN = "backup"
|
|
||||||
DataFN = "data"
|
|
||||||
SiteFN = "site"
|
|
||||||
UserFN = "user"
|
|
||||||
FileCreatedAfterFN = "file-created-after"
|
|
||||||
FileCreatedBeforeFN = "file-created-before"
|
|
||||||
FileModifiedAfterFN = "file-modified-after"
|
|
||||||
FileModifiedBeforeFN = "file-modified-before"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Wildcard = "*"
|
Wildcard = "*"
|
||||||
)
|
)
|
||||||
|
|||||||
@ -168,7 +168,7 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestDataCollections_invali
|
|||||||
name: "Invalid sharepoint backup site",
|
name: "Invalid sharepoint backup site",
|
||||||
getSelector: func(t *testing.T) selectors.Selector {
|
getSelector: func(t *testing.T) selectors.Selector {
|
||||||
sel := selectors.NewSharePointBackup(owners)
|
sel := selectors.NewSharePointBackup(owners)
|
||||||
sel.Include(sel.Libraries(selectors.Any()))
|
sel.Include(sel.LibraryFolders(selectors.Any()))
|
||||||
return sel.Selector
|
return sel.Selector
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -194,7 +194,7 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestDataCollections_invali
|
|||||||
name: "missing sharepoint backup site",
|
name: "missing sharepoint backup site",
|
||||||
getSelector: func(t *testing.T) selectors.Selector {
|
getSelector: func(t *testing.T) selectors.Selector {
|
||||||
sel := selectors.NewSharePointBackup(owners)
|
sel := selectors.NewSharePointBackup(owners)
|
||||||
sel.Include(sel.Libraries(selectors.Any()))
|
sel.Include(sel.LibraryFolders(selectors.Any()))
|
||||||
sel.DiscreteOwner = ""
|
sel.DiscreteOwner = ""
|
||||||
return sel.Selector
|
return sel.Selector
|
||||||
},
|
},
|
||||||
@ -237,7 +237,7 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestSharePointDataCollecti
|
|||||||
name: "Libraries",
|
name: "Libraries",
|
||||||
getSelector: func() selectors.Selector {
|
getSelector: func() selectors.Selector {
|
||||||
sel := selectors.NewSharePointBackup(selSites)
|
sel := selectors.NewSharePointBackup(selSites)
|
||||||
sel.Include(sel.Libraries(selectors.Any()))
|
sel.Include(sel.LibraryFolders(selectors.Any()))
|
||||||
return sel.Selector
|
return sel.Selector
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -334,7 +334,7 @@ func (suite *ConnectorCreateSharePointCollectionIntegrationSuite) TestCreateShar
|
|||||||
)
|
)
|
||||||
|
|
||||||
sel := selectors.NewSharePointBackup(siteIDs)
|
sel := selectors.NewSharePointBackup(siteIDs)
|
||||||
sel.Include(sel.Libraries([]string{"foo"}, selectors.PrefixMatch()))
|
sel.Include(sel.LibraryFolders([]string{"foo"}, selectors.PrefixMatch()))
|
||||||
|
|
||||||
cols, excludes, err := gc.DataCollections(
|
cols, excludes, err := gc.DataCollections(
|
||||||
ctx,
|
ctx,
|
||||||
|
|||||||
@ -194,7 +194,7 @@ func downloadItem(ctx context.Context, hc *http.Client, item models.DriveItemabl
|
|||||||
// doesn't have its size value updated as a side effect of creation,
|
// doesn't have its size value updated as a side effect of creation,
|
||||||
// and kiota drops any SetSize update.
|
// and kiota drops any SetSize update.
|
||||||
func oneDriveItemInfo(di models.DriveItemable, itemSize int64) *details.OneDriveInfo {
|
func oneDriveItemInfo(di models.DriveItemable, itemSize int64) *details.OneDriveInfo {
|
||||||
var email, parent string
|
var email, driveName, driveID string
|
||||||
|
|
||||||
if di.GetCreatedBy() != nil && di.GetCreatedBy().GetUser() != nil {
|
if di.GetCreatedBy() != nil && di.GetCreatedBy().GetUser() != nil {
|
||||||
// User is sometimes not available when created via some
|
// User is sometimes not available when created via some
|
||||||
@ -205,19 +205,20 @@ func oneDriveItemInfo(di models.DriveItemable, itemSize int64) *details.OneDrive
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if di.GetParentReference() != nil && di.GetParentReference().GetName() != nil {
|
if di.GetParentReference() != nil {
|
||||||
// EndPoint is not always populated from external apps
|
driveID = ptr.Val(di.GetParentReference().GetDriveId())
|
||||||
parent = *di.GetParentReference().GetName()
|
driveName = strings.TrimSpace(ptr.Val(di.GetParentReference().GetName()))
|
||||||
}
|
}
|
||||||
|
|
||||||
return &details.OneDriveInfo{
|
return &details.OneDriveInfo{
|
||||||
ItemType: details.OneDriveItem,
|
|
||||||
ItemName: ptr.Val(di.GetName()),
|
|
||||||
Created: ptr.Val(di.GetCreatedDateTime()),
|
Created: ptr.Val(di.GetCreatedDateTime()),
|
||||||
|
DriveID: driveID,
|
||||||
|
DriveName: driveName,
|
||||||
|
ItemName: ptr.Val(di.GetName()),
|
||||||
|
ItemType: details.OneDriveItem,
|
||||||
Modified: ptr.Val(di.GetLastModifiedDateTime()),
|
Modified: ptr.Val(di.GetLastModifiedDateTime()),
|
||||||
DriveName: parent,
|
|
||||||
Size: itemSize,
|
|
||||||
Owner: email,
|
Owner: email,
|
||||||
|
Size: itemSize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,10 +312,7 @@ func filterUserPermissions(ctx context.Context, perms []models.Permissionable) [
|
|||||||
// and kiota drops any SetSize update.
|
// and kiota drops any SetSize update.
|
||||||
// TODO: Update drive name during Issue #2071
|
// TODO: Update drive name during Issue #2071
|
||||||
func sharePointItemInfo(di models.DriveItemable, itemSize int64) *details.SharePointInfo {
|
func sharePointItemInfo(di models.DriveItemable, itemSize int64) *details.SharePointInfo {
|
||||||
var (
|
var id, driveName, driveID, weburl string
|
||||||
id, parentID, displayName, url string
|
|
||||||
reference = di.GetParentReference()
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO: we rely on this info for details/restore lookups,
|
// TODO: we rely on this info for details/restore lookups,
|
||||||
// so if it's nil we have an issue, and will need an alternative
|
// so if it's nil we have an issue, and will need an alternative
|
||||||
@ -323,16 +321,16 @@ func sharePointItemInfo(di models.DriveItemable, itemSize int64) *details.ShareP
|
|||||||
gsi := di.GetSharepointIds()
|
gsi := di.GetSharepointIds()
|
||||||
if gsi != nil {
|
if gsi != nil {
|
||||||
id = ptr.Val(gsi.GetSiteId())
|
id = ptr.Val(gsi.GetSiteId())
|
||||||
url = ptr.Val(gsi.GetSiteUrl())
|
weburl = ptr.Val(gsi.GetSiteUrl())
|
||||||
|
|
||||||
if len(url) == 0 {
|
if len(weburl) == 0 {
|
||||||
url = constructWebURL(di.GetAdditionalData())
|
weburl = constructWebURL(di.GetAdditionalData())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if reference != nil {
|
if di.GetParentReference() != nil {
|
||||||
parentID = ptr.Val(reference.GetDriveId())
|
driveID = ptr.Val(di.GetParentReference().GetDriveId())
|
||||||
displayName = strings.TrimSpace(ptr.Val(reference.GetName()))
|
driveName = strings.TrimSpace(ptr.Val(di.GetParentReference().GetName()))
|
||||||
}
|
}
|
||||||
|
|
||||||
return &details.SharePointInfo{
|
return &details.SharePointInfo{
|
||||||
@ -340,11 +338,11 @@ func sharePointItemInfo(di models.DriveItemable, itemSize int64) *details.ShareP
|
|||||||
ItemName: ptr.Val(di.GetName()),
|
ItemName: ptr.Val(di.GetName()),
|
||||||
Created: ptr.Val(di.GetCreatedDateTime()),
|
Created: ptr.Val(di.GetCreatedDateTime()),
|
||||||
Modified: ptr.Val(di.GetLastModifiedDateTime()),
|
Modified: ptr.Val(di.GetLastModifiedDateTime()),
|
||||||
DriveName: parentID,
|
DriveID: driveID,
|
||||||
DisplayName: displayName,
|
DriveName: driveName,
|
||||||
Size: itemSize,
|
Size: itemSize,
|
||||||
Owner: id,
|
Owner: id,
|
||||||
WebURL: url,
|
WebURL: weburl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -261,9 +261,9 @@ type folderMatcher struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fm folderMatcher) IsAny() bool {
|
func (fm folderMatcher) IsAny() bool {
|
||||||
return fm.scope.IsAny(selectors.SharePointLibrary)
|
return fm.scope.IsAny(selectors.SharePointLibraryFolder)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fm folderMatcher) Matches(dir string) bool {
|
func (fm folderMatcher) Matches(dir string) bool {
|
||||||
return fm.scope.Matches(selectors.SharePointLibrary, dir)
|
return fm.scope.Matches(selectors.SharePointLibraryFolder, dir)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,11 +29,11 @@ type testFolderMatcher struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fm testFolderMatcher) IsAny() bool {
|
func (fm testFolderMatcher) IsAny() bool {
|
||||||
return fm.scope.IsAny(selectors.SharePointLibrary)
|
return fm.scope.IsAny(selectors.SharePointLibraryFolder)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fm testFolderMatcher) Matches(path string) bool {
|
func (fm testFolderMatcher) Matches(path string) bool {
|
||||||
return fm.scope.Matches(selectors.SharePointLibrary, path)
|
return fm.scope.Matches(selectors.SharePointLibraryFolder, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -49,7 +49,7 @@ func TestSharePointLibrariesUnitSuite(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *SharePointLibrariesUnitSuite) TestUpdateCollections() {
|
func (suite *SharePointLibrariesUnitSuite) TestUpdateCollections() {
|
||||||
anyFolder := (&selectors.SharePointBackup{}).Libraries(selectors.Any())[0]
|
anyFolder := (&selectors.SharePointBackup{}).LibraryFolders(selectors.Any())[0]
|
||||||
|
|
||||||
const (
|
const (
|
||||||
tenant = "tenant"
|
tenant = "tenant"
|
||||||
|
|||||||
@ -1101,7 +1101,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_sharePoint() {
|
|||||||
sel = selectors.NewSharePointBackup([]string{suite.site})
|
sel = selectors.NewSharePointBackup([]string{suite.site})
|
||||||
)
|
)
|
||||||
|
|
||||||
sel.Include(sel.Libraries(selectors.Any()))
|
sel.Include(sel.LibraryFolders(selectors.Any()))
|
||||||
|
|
||||||
bo, _, kw, _, closer := prepNewTestBackupOp(t, ctx, mb, sel.Selector, control.Toggles{})
|
bo, _, kw, _, closer := prepNewTestBackupOp(t, ctx, mb, sel.Selector, control.Toggles{})
|
||||||
defer closer()
|
defer closer()
|
||||||
|
|||||||
@ -219,9 +219,7 @@ func (suite *RestoreOpIntegrationSuite) SetupSuite() {
|
|||||||
sites := []string{siteID}
|
sites := []string{siteID}
|
||||||
csel := selectors.NewSharePointBackup(sites)
|
csel := selectors.NewSharePointBackup(sites)
|
||||||
csel.DiscreteOwner = siteID
|
csel.DiscreteOwner = siteID
|
||||||
csel.Include(
|
csel.Include(csel.LibraryFolders(selectors.Any()))
|
||||||
csel.Libraries(selectors.Any()),
|
|
||||||
)
|
|
||||||
|
|
||||||
bo, err = NewBackupOperation(
|
bo, err = NewBackupOperation(
|
||||||
ctx,
|
ctx,
|
||||||
|
|||||||
@ -600,9 +600,9 @@ func (i ExchangeInfo) Values() []string {
|
|||||||
// SharePointInfo describes a sharepoint item
|
// SharePointInfo describes a sharepoint item
|
||||||
type SharePointInfo struct {
|
type SharePointInfo struct {
|
||||||
Created time.Time `json:"created,omitempty"`
|
Created time.Time `json:"created,omitempty"`
|
||||||
ItemName string `json:"itemName,omitempty"`
|
|
||||||
DriveName string `json:"driveName,omitempty"`
|
DriveName string `json:"driveName,omitempty"`
|
||||||
DisplayName string `json:"displayName,omitempty"`
|
DriveID string `json:"driveID,omitempty"`
|
||||||
|
ItemName string `json:"itemName,omitempty"`
|
||||||
ItemType ItemType `json:"itemType,omitempty"`
|
ItemType ItemType `json:"itemType,omitempty"`
|
||||||
Modified time.Time `josn:"modified,omitempty"`
|
Modified time.Time `josn:"modified,omitempty"`
|
||||||
Owner string `json:"owner,omitempty"`
|
Owner string `json:"owner,omitempty"`
|
||||||
@ -614,7 +614,7 @@ type SharePointInfo struct {
|
|||||||
// Headers returns the human-readable names of properties in a SharePointInfo
|
// Headers returns the human-readable names of properties in a SharePointInfo
|
||||||
// for printing out to a terminal in a columnar display.
|
// for printing out to a terminal in a columnar display.
|
||||||
func (i SharePointInfo) Headers() []string {
|
func (i SharePointInfo) Headers() []string {
|
||||||
return []string{"ItemName", "Drive", "ParentPath", "Size", "WebURL", "Created", "Modified"}
|
return []string{"ItemName", "Library", "ParentPath", "Size", "WebURL", "Created", "Modified"}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Values returns the values matching the Headers list for printing
|
// Values returns the values matching the Headers list for printing
|
||||||
@ -622,7 +622,7 @@ func (i SharePointInfo) Headers() []string {
|
|||||||
func (i SharePointInfo) Values() []string {
|
func (i SharePointInfo) Values() []string {
|
||||||
return []string{
|
return []string{
|
||||||
i.ItemName,
|
i.ItemName,
|
||||||
i.DisplayName,
|
i.DriveName,
|
||||||
i.ParentPath,
|
i.ParentPath,
|
||||||
humanize.Bytes(uint64(i.Size)),
|
humanize.Bytes(uint64(i.Size)),
|
||||||
i.WebURL,
|
i.WebURL,
|
||||||
@ -645,10 +645,11 @@ func (i *SharePointInfo) UpdateParentPath(newPath path.Path) error {
|
|||||||
// OneDriveInfo describes a oneDrive item
|
// OneDriveInfo describes a oneDrive item
|
||||||
type OneDriveInfo struct {
|
type OneDriveInfo struct {
|
||||||
Created time.Time `json:"created,omitempty"`
|
Created time.Time `json:"created,omitempty"`
|
||||||
ItemName string `json:"itemName,omitempty"`
|
DriveID string `json:"driveID,omitempty"`
|
||||||
DriveName string `json:"driveName,omitempty"`
|
DriveName string `json:"driveName,omitempty"`
|
||||||
ItemType ItemType `json:"itemType,omitempty"`
|
|
||||||
IsMeta bool `json:"isMeta,omitempty"`
|
IsMeta bool `json:"isMeta,omitempty"`
|
||||||
|
ItemName string `json:"itemName,omitempty"`
|
||||||
|
ItemType ItemType `json:"itemType,omitempty"`
|
||||||
Modified time.Time `json:"modified,omitempty"`
|
Modified time.Time `json:"modified,omitempty"`
|
||||||
Owner string `json:"owner,omitempty"`
|
Owner string `json:"owner,omitempty"`
|
||||||
ParentPath string `json:"parentPath"`
|
ParentPath string `json:"parentPath"`
|
||||||
|
|||||||
@ -117,17 +117,17 @@ func (suite *DetailsUnitSuite) TestDetailsEntry_HeadersValues() {
|
|||||||
ParentPath: "parentPath",
|
ParentPath: "parentPath",
|
||||||
Size: 1000,
|
Size: 1000,
|
||||||
WebURL: "https://not.a.real/url",
|
WebURL: "https://not.a.real/url",
|
||||||
DisplayName: "aDrive",
|
DriveName: "aLibrary",
|
||||||
Created: now,
|
Created: now,
|
||||||
Modified: now,
|
Modified: now,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectHs: []string{"ID", "ItemName", "Drive", "ParentPath", "Size", "WebURL", "Created", "Modified"},
|
expectHs: []string{"ID", "ItemName", "Library", "ParentPath", "Size", "WebURL", "Created", "Modified"},
|
||||||
expectVs: []string{
|
expectVs: []string{
|
||||||
"deadbeef",
|
"deadbeef",
|
||||||
"itemName",
|
"itemName",
|
||||||
"aDrive",
|
"aLibrary",
|
||||||
"parentPath",
|
"parentPath",
|
||||||
"1.0 kB",
|
"1.0 kB",
|
||||||
"https://not.a.real/url",
|
"https://not.a.real/url",
|
||||||
|
|||||||
@ -346,7 +346,7 @@ func (suite *SelectorSuite) TestPathCategories_includes() {
|
|||||||
isErr: assert.NoError,
|
isErr: assert.NoError,
|
||||||
getSelector: func(t *testing.T) *Selector {
|
getSelector: func(t *testing.T) *Selector {
|
||||||
sel := NewSharePointBackup(users)
|
sel := NewSharePointBackup(users)
|
||||||
sel.Include(sel.Libraries([]string{"A directory"}, SuffixMatch()))
|
sel.Include(sel.LibraryFolders([]string{"A directory"}, SuffixMatch()))
|
||||||
|
|
||||||
return &sel.Selector
|
return &sel.Selector
|
||||||
},
|
},
|
||||||
|
|||||||
@ -225,7 +225,7 @@ func (s *sharePoint) AllData() []SharePointScope {
|
|||||||
|
|
||||||
scopes = append(
|
scopes = append(
|
||||||
scopes,
|
scopes,
|
||||||
makeScope[SharePointScope](SharePointLibrary, Any()),
|
makeScope[SharePointScope](SharePointLibraryFolder, Any()),
|
||||||
makeScope[SharePointScope](SharePointList, Any()),
|
makeScope[SharePointScope](SharePointList, Any()),
|
||||||
makeScope[SharePointScope](SharePointPageFolder, Any()),
|
makeScope[SharePointScope](SharePointPageFolder, Any()),
|
||||||
)
|
)
|
||||||
@ -265,11 +265,28 @@ func (s *sharePoint) ListItems(lists, items []string, opts ...option) []SharePoi
|
|||||||
return scopes
|
return scopes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Libraries produces one or more SharePoint library scopes.
|
// Library produces one or more SharePoint library scopes, where the library
|
||||||
|
// matches upon a given drive by ID or Name. In order to ensure library selection
|
||||||
|
// this should always be embedded within the Filter() set; include(Library()) will
|
||||||
|
// select all items in the library without further filtering.
|
||||||
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
||||||
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
||||||
// If any slice is empty, it defaults to [selectors.None]
|
// If any slice is empty, it defaults to [selectors.None]
|
||||||
func (s *sharePoint) Libraries(libraries []string, opts ...option) []SharePointScope {
|
func (s *sharePoint) Library(library string) []SharePointScope {
|
||||||
|
return []SharePointScope{
|
||||||
|
makeFilterScope[SharePointScope](
|
||||||
|
SharePointLibraryItem,
|
||||||
|
SharePointFilterLibraryDrive,
|
||||||
|
[]string{library},
|
||||||
|
wrapFilter(filters.Equal)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LibraryFolders produces one or more SharePoint libraryFolder scopes.
|
||||||
|
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
||||||
|
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
||||||
|
// If any slice is empty, it defaults to [selectors.None]
|
||||||
|
func (s *sharePoint) LibraryFolders(libraryFolders []string, opts ...option) []SharePointScope {
|
||||||
var (
|
var (
|
||||||
scopes = []SharePointScope{}
|
scopes = []SharePointScope{}
|
||||||
os = append([]option{pathComparator()}, opts...)
|
os = append([]option{pathComparator()}, opts...)
|
||||||
@ -277,7 +294,7 @@ func (s *sharePoint) Libraries(libraries []string, opts ...option) []SharePointS
|
|||||||
|
|
||||||
scopes = append(
|
scopes = append(
|
||||||
scopes,
|
scopes,
|
||||||
makeScope[SharePointScope](SharePointLibrary, libraries, os...),
|
makeScope[SharePointScope](SharePointLibraryFolder, libraryFolders, os...),
|
||||||
)
|
)
|
||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
@ -294,7 +311,7 @@ func (s *sharePoint) LibraryItems(libraries, items []string, opts ...option) []S
|
|||||||
scopes = append(
|
scopes = append(
|
||||||
scopes,
|
scopes,
|
||||||
makeScope[SharePointScope](SharePointLibraryItem, items).
|
makeScope[SharePointScope](SharePointLibraryItem, items).
|
||||||
set(SharePointLibrary, libraries, opts...),
|
set(SharePointLibraryFolder, libraries, opts...),
|
||||||
)
|
)
|
||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
@ -394,7 +411,7 @@ const (
|
|||||||
SharePointSite sharePointCategory = "SharePointSite"
|
SharePointSite sharePointCategory = "SharePointSite"
|
||||||
SharePointList sharePointCategory = "SharePointList"
|
SharePointList sharePointCategory = "SharePointList"
|
||||||
SharePointListItem sharePointCategory = "SharePointListItem"
|
SharePointListItem sharePointCategory = "SharePointListItem"
|
||||||
SharePointLibrary sharePointCategory = "SharePointLibrary"
|
SharePointLibraryFolder sharePointCategory = "SharePointLibraryFolder"
|
||||||
SharePointLibraryItem sharePointCategory = "SharePointLibraryItem"
|
SharePointLibraryItem sharePointCategory = "SharePointLibraryItem"
|
||||||
SharePointPageFolder sharePointCategory = "SharePointPageFolder"
|
SharePointPageFolder sharePointCategory = "SharePointPageFolder"
|
||||||
SharePointPage sharePointCategory = "SharePointPage"
|
SharePointPage sharePointCategory = "SharePointPage"
|
||||||
@ -404,12 +421,15 @@ const (
|
|||||||
SiteFilterCreatedBefore sharePointCategory = "FileFilterCreatedBefore"
|
SiteFilterCreatedBefore sharePointCategory = "FileFilterCreatedBefore"
|
||||||
SiteFilterModifiedAfter sharePointCategory = "FileFilterModifiedAfter"
|
SiteFilterModifiedAfter sharePointCategory = "FileFilterModifiedAfter"
|
||||||
SiteFilterModifiedBefore sharePointCategory = "FileFilterModifiedBefore"
|
SiteFilterModifiedBefore sharePointCategory = "FileFilterModifiedBefore"
|
||||||
|
|
||||||
|
// library drive selection
|
||||||
|
SharePointFilterLibraryDrive sharePointCategory = "SharePointFilterLibraryDrive"
|
||||||
)
|
)
|
||||||
|
|
||||||
// sharePointLeafProperties describes common metadata of the leaf categories
|
// sharePointLeafProperties describes common metadata of the leaf categories
|
||||||
var sharePointLeafProperties = map[categorizer]leafProperty{
|
var sharePointLeafProperties = map[categorizer]leafProperty{
|
||||||
SharePointLibraryItem: {
|
SharePointLibraryItem: {
|
||||||
pathKeys: []categorizer{SharePointLibrary, SharePointLibraryItem},
|
pathKeys: []categorizer{SharePointLibraryFolder, SharePointLibraryItem},
|
||||||
pathType: path.LibrariesCategory,
|
pathType: path.LibrariesCategory,
|
||||||
},
|
},
|
||||||
SharePointListItem: {
|
SharePointListItem: {
|
||||||
@ -437,7 +457,7 @@ func (c sharePointCategory) String() string {
|
|||||||
// Ex: ServiceUser.leafCat() => ServiceUser
|
// Ex: ServiceUser.leafCat() => ServiceUser
|
||||||
func (c sharePointCategory) leafCat() categorizer {
|
func (c sharePointCategory) leafCat() categorizer {
|
||||||
switch c {
|
switch c {
|
||||||
case SharePointLibrary, SharePointLibraryItem,
|
case SharePointLibraryFolder, SharePointLibraryItem, SharePointFilterLibraryDrive,
|
||||||
SiteFilterCreatedAfter, SiteFilterCreatedBefore,
|
SiteFilterCreatedAfter, SiteFilterCreatedBefore,
|
||||||
SiteFilterModifiedAfter, SiteFilterModifiedBefore:
|
SiteFilterModifiedAfter, SiteFilterModifiedBefore:
|
||||||
return SharePointLibraryItem
|
return SharePointLibraryItem
|
||||||
@ -480,8 +500,8 @@ func (c sharePointCategory) pathValues(repo path.Path, ent details.DetailsEntry)
|
|||||||
var folderCat, itemCat categorizer
|
var folderCat, itemCat categorizer
|
||||||
|
|
||||||
switch c {
|
switch c {
|
||||||
case SharePointLibrary, SharePointLibraryItem:
|
case SharePointLibraryFolder, SharePointLibraryItem:
|
||||||
folderCat, itemCat = SharePointLibrary, SharePointLibraryItem
|
folderCat, itemCat = SharePointLibraryFolder, SharePointLibraryItem
|
||||||
case SharePointList, SharePointListItem:
|
case SharePointList, SharePointListItem:
|
||||||
folderCat, itemCat = SharePointList, SharePointListItem
|
folderCat, itemCat = SharePointList, SharePointListItem
|
||||||
case SharePointPage, SharePointPageFolder:
|
case SharePointPage, SharePointPageFolder:
|
||||||
@ -572,7 +592,7 @@ func (s SharePointScope) set(cat sharePointCategory, v []string, opts ...option)
|
|||||||
os := []option{}
|
os := []option{}
|
||||||
|
|
||||||
switch cat {
|
switch cat {
|
||||||
case SharePointLibrary, SharePointList, SharePointPage:
|
case SharePointLibraryFolder, SharePointList, SharePointPage:
|
||||||
os = append(os, pathComparator())
|
os = append(os, pathComparator())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,13 +603,13 @@ func (s SharePointScope) set(cat sharePointCategory, v []string, opts ...option)
|
|||||||
func (s SharePointScope) setDefaults() {
|
func (s SharePointScope) setDefaults() {
|
||||||
switch s.Category() {
|
switch s.Category() {
|
||||||
case SharePointSite:
|
case SharePointSite:
|
||||||
s[SharePointLibrary.String()] = passAny
|
s[SharePointLibraryFolder.String()] = passAny
|
||||||
s[SharePointLibraryItem.String()] = passAny
|
s[SharePointLibraryItem.String()] = passAny
|
||||||
s[SharePointList.String()] = passAny
|
s[SharePointList.String()] = passAny
|
||||||
s[SharePointListItem.String()] = passAny
|
s[SharePointListItem.String()] = passAny
|
||||||
s[SharePointPageFolder.String()] = passAny
|
s[SharePointPageFolder.String()] = passAny
|
||||||
s[SharePointPage.String()] = passAny
|
s[SharePointPage.String()] = passAny
|
||||||
case SharePointLibrary:
|
case SharePointLibraryFolder:
|
||||||
s[SharePointLibraryItem.String()] = passAny
|
s[SharePointLibraryItem.String()] = passAny
|
||||||
case SharePointList:
|
case SharePointList:
|
||||||
s[SharePointListItem.String()] = passAny
|
s[SharePointListItem.String()] = passAny
|
||||||
@ -647,6 +667,18 @@ func (s SharePointScope) matchesInfo(dii details.ItemInfo) bool {
|
|||||||
i = common.FormatTime(info.Created)
|
i = common.FormatTime(info.Created)
|
||||||
case SiteFilterModifiedAfter, SiteFilterModifiedBefore:
|
case SiteFilterModifiedAfter, SiteFilterModifiedBefore:
|
||||||
i = common.FormatTime(info.Modified)
|
i = common.FormatTime(info.Modified)
|
||||||
|
case SharePointFilterLibraryDrive:
|
||||||
|
ds := []string{}
|
||||||
|
|
||||||
|
if len(info.DriveName) > 0 {
|
||||||
|
ds = append(ds, info.DriveName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(info.DriveID) > 0 {
|
||||||
|
ds = append(ds, info.DriveID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return matchesAny(s, SharePointFilterLibraryDrive, ds)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.Matches(filterCat, i)
|
return s.Matches(filterCat, i)
|
||||||
|
|||||||
@ -80,7 +80,7 @@ func (suite *SharePointSelectorSuite) TestSharePointSelector_AllData() {
|
|||||||
spsc,
|
spsc,
|
||||||
map[categorizer]string{
|
map[categorizer]string{
|
||||||
SharePointLibraryItem: AnyTgt,
|
SharePointLibraryItem: AnyTgt,
|
||||||
SharePointLibrary: AnyTgt,
|
SharePointLibraryFolder: AnyTgt,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
case SharePointListItem:
|
case SharePointListItem:
|
||||||
@ -289,7 +289,7 @@ func (suite *SharePointSelectorSuite) TestSharePointRestore_Reduce() {
|
|||||||
deets: deets,
|
deets: deets,
|
||||||
makeSelector: func() *SharePointRestore {
|
makeSelector: func() *SharePointRestore {
|
||||||
odr := NewSharePointRestore([]string{"sid"})
|
odr := NewSharePointRestore([]string{"sid"})
|
||||||
odr.Include(odr.Libraries([]string{"folderA/folderB", pairAC}))
|
odr.Include(odr.LibraryFolders([]string{"folderA/folderB", pairAC}))
|
||||||
return odr
|
return odr
|
||||||
},
|
},
|
||||||
expect: arr(item, item2),
|
expect: arr(item, item2),
|
||||||
@ -330,7 +330,7 @@ func (suite *SharePointSelectorSuite) TestSharePointCategory_PathValues() {
|
|||||||
name: "SharePoint Libraries",
|
name: "SharePoint Libraries",
|
||||||
sc: SharePointLibraryItem,
|
sc: SharePointLibraryItem,
|
||||||
expected: map[categorizer][]string{
|
expected: map[categorizer][]string{
|
||||||
SharePointLibrary: {"dir1/dir2"},
|
SharePointLibraryFolder: {"dir1/dir2"},
|
||||||
SharePointLibraryItem: {"item", "short"},
|
SharePointLibraryItem: {"item", "short"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -370,7 +370,7 @@ func (suite *SharePointSelectorSuite) TestSharePointCategory_PathValues() {
|
|||||||
|
|
||||||
func (suite *SharePointSelectorSuite) TestSharePointScope_MatchesInfo() {
|
func (suite *SharePointSelectorSuite) TestSharePointScope_MatchesInfo() {
|
||||||
var (
|
var (
|
||||||
ods = NewSharePointRestore(Any())
|
sel = NewSharePointRestore(Any())
|
||||||
host = "www.website.com"
|
host = "www.website.com"
|
||||||
pth = "/foo"
|
pth = "/foo"
|
||||||
url = host + pth
|
url = host + pth
|
||||||
@ -386,29 +386,33 @@ func (suite *SharePointSelectorSuite) TestSharePointScope_MatchesInfo() {
|
|||||||
scope []SharePointScope
|
scope []SharePointScope
|
||||||
expect assert.BoolAssertionFunc
|
expect assert.BoolAssertionFunc
|
||||||
}{
|
}{
|
||||||
{"host match", host, ods.WebURL([]string{host}), assert.True},
|
{"host match", host, sel.WebURL([]string{host}), assert.True},
|
||||||
{"url match", url, ods.WebURL([]string{url}), assert.True},
|
{"url match", url, sel.WebURL([]string{url}), assert.True},
|
||||||
{"url contains host", url, ods.WebURL([]string{host}), assert.True},
|
{"url contains host", url, sel.WebURL([]string{host}), assert.True},
|
||||||
{"host suffixes host", host, ods.WebURL([]string{host}, SuffixMatch()), assert.True},
|
{"host suffixes host", host, sel.WebURL([]string{host}, SuffixMatch()), assert.True},
|
||||||
{"url does not suffix host", url, ods.WebURL([]string{host}, SuffixMatch()), assert.False},
|
{"url does not suffix host", url, sel.WebURL([]string{host}, SuffixMatch()), assert.False},
|
||||||
{"url contains path", url, ods.WebURL([]string{pth}), assert.True},
|
{"url contains path", url, sel.WebURL([]string{pth}), assert.True},
|
||||||
{"url has path suffix", url, ods.WebURL([]string{pth}, SuffixMatch()), assert.True},
|
{"url has path suffix", url, sel.WebURL([]string{pth}, SuffixMatch()), assert.True},
|
||||||
{"host does not contain substring", host, ods.WebURL([]string{"website"}), assert.False},
|
{"host does not contain substring", host, sel.WebURL([]string{"website"}), assert.False},
|
||||||
{"url does not suffix substring", url, ods.WebURL([]string{"oo"}), assert.False},
|
{"url does not suffix substring", url, sel.WebURL([]string{"oo"}), assert.False},
|
||||||
{"host mismatch", host, ods.WebURL([]string{"www.google.com"}), assert.False},
|
{"host mismatch", host, sel.WebURL([]string{"www.google.com"}), assert.False},
|
||||||
{"file create after the epoch", host, ods.CreatedAfter(common.FormatTime(epoch)), assert.True},
|
{"file create after the epoch", host, sel.CreatedAfter(common.FormatTime(epoch)), assert.True},
|
||||||
{"file create after now", host, ods.CreatedAfter(common.FormatTime(now)), assert.False},
|
{"file create after now", host, sel.CreatedAfter(common.FormatTime(now)), assert.False},
|
||||||
{"file create after later", url, ods.CreatedAfter(common.FormatTime(future)), assert.False},
|
{"file create after later", url, sel.CreatedAfter(common.FormatTime(future)), assert.False},
|
||||||
{"file create before future", host, ods.CreatedBefore(common.FormatTime(future)), assert.True},
|
{"file create before future", host, sel.CreatedBefore(common.FormatTime(future)), assert.True},
|
||||||
{"file create before now", host, ods.CreatedBefore(common.FormatTime(now)), assert.False},
|
{"file create before now", host, sel.CreatedBefore(common.FormatTime(now)), assert.False},
|
||||||
{"file create before modification", host, ods.CreatedBefore(common.FormatTime(modification)), assert.True},
|
{"file create before modification", host, sel.CreatedBefore(common.FormatTime(modification)), assert.True},
|
||||||
{"file create before epoch", host, ods.CreatedBefore(common.FormatTime(now)), assert.False},
|
{"file create before epoch", host, sel.CreatedBefore(common.FormatTime(now)), assert.False},
|
||||||
{"file modified after the epoch", host, ods.ModifiedAfter(common.FormatTime(epoch)), assert.True},
|
{"file modified after the epoch", host, sel.ModifiedAfter(common.FormatTime(epoch)), assert.True},
|
||||||
{"file modified after now", host, ods.ModifiedAfter(common.FormatTime(now)), assert.True},
|
{"file modified after now", host, sel.ModifiedAfter(common.FormatTime(now)), assert.True},
|
||||||
{"file modified after later", host, ods.ModifiedAfter(common.FormatTime(future)), assert.False},
|
{"file modified after later", host, sel.ModifiedAfter(common.FormatTime(future)), assert.False},
|
||||||
{"file modified before future", host, ods.ModifiedBefore(common.FormatTime(future)), assert.True},
|
{"file modified before future", host, sel.ModifiedBefore(common.FormatTime(future)), assert.True},
|
||||||
{"file modified before now", host, ods.ModifiedBefore(common.FormatTime(now)), assert.False},
|
{"file modified before now", host, sel.ModifiedBefore(common.FormatTime(now)), assert.False},
|
||||||
{"file modified before epoch", host, ods.ModifiedBefore(common.FormatTime(now)), assert.False},
|
{"file modified before epoch", host, sel.ModifiedBefore(common.FormatTime(now)), assert.False},
|
||||||
|
{"in library", host, sel.Library("included-library"), assert.True},
|
||||||
|
{"not in library", host, sel.Library("not-included-library"), assert.False},
|
||||||
|
{"library id", host, sel.Library("1234"), assert.True},
|
||||||
|
{"not library id", host, sel.Library("abcd"), assert.False},
|
||||||
}
|
}
|
||||||
for _, test := range table {
|
for _, test := range table {
|
||||||
suite.Run(test.name, func() {
|
suite.Run(test.name, func() {
|
||||||
@ -420,6 +424,8 @@ func (suite *SharePointSelectorSuite) TestSharePointScope_MatchesInfo() {
|
|||||||
WebURL: test.infoURL,
|
WebURL: test.infoURL,
|
||||||
Created: now,
|
Created: now,
|
||||||
Modified: modification,
|
Modified: modification,
|
||||||
|
DriveName: "included-library",
|
||||||
|
DriveID: "1234",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,7 +445,7 @@ func (suite *SharePointSelectorSuite) TestCategory_PathType() {
|
|||||||
{SharePointCategoryUnknown, path.UnknownCategory},
|
{SharePointCategoryUnknown, path.UnknownCategory},
|
||||||
{SharePointWebURL, path.UnknownCategory},
|
{SharePointWebURL, path.UnknownCategory},
|
||||||
{SharePointSite, path.UnknownCategory},
|
{SharePointSite, path.UnknownCategory},
|
||||||
{SharePointLibrary, path.LibrariesCategory},
|
{SharePointLibraryFolder, path.LibrariesCategory},
|
||||||
{SharePointLibraryItem, path.LibrariesCategory},
|
{SharePointLibraryItem, path.LibrariesCategory},
|
||||||
{SharePointList, path.ListsCategory},
|
{SharePointList, path.ListsCategory},
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user