From 6d615810cdaf9b5745d8b88687a1e9eb6932db48 Mon Sep 17 00:00:00 2001 From: Danny Date: Sat, 21 Jan 2023 00:50:23 -0500 Subject: [PATCH] CLI: Backup: SharePoint: Pages Enable (#2213) ## Description Adds the functionality to select SharePoint Pages for backup. ## Does this PR need a docs update or release note? SharePoint commands remain hidden in terms of pages. - [x] :clock1: Yes, but in a later PR ## Type of change - [x] :sunflower: Feature ## Issue(s) * closes #2216 * closes #2107 ## Test Plan - [x] :zap: Unit test --- src/cli/backup/sharepoint.go | 53 +++++++++++++++++++++++++------ src/cli/backup/sharepoint_test.go | 17 +++++++--- 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/cli/backup/sharepoint.go b/src/cli/backup/sharepoint.go index d5624380f..4eb62dca0 100644 --- a/src/cli/backup/sharepoint.go +++ b/src/cli/backup/sharepoint.go @@ -27,9 +27,12 @@ import ( // setup and globals // ------------------------------------------------------------------------------------------------ +// sharePoint bucket info from flags var ( libraryItems []string libraryPaths []string + pageFolders []string + page []string site []string weburl []string @@ -38,6 +41,7 @@ var ( const ( dataLibraries = "libraries" + dataPages = "pages" ) const ( @@ -89,11 +93,10 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command { utils.WebURLFN, nil, "Restore data by site webURL; accepts '"+utils.Wildcard+"' to select all sites.") - // TODO: implement fs.StringSliceVar( &sharepointData, utils.DataFN, nil, - "Select one or more types of data to backup: "+dataLibraries+".") + "Select one or more types of data to backup: "+dataLibraries+" or "+dataPages+".") options.AddOperationFlags(c) case listCommand: @@ -128,11 +131,22 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command { fs.StringArrayVar(&site, utils.SiteFN, nil, - "Backup SharePoint data 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, utils.WebURLFN, nil, - "Restore data by site webURL; accepts '"+utils.Wildcard+"' to select all sites.") + "Select backup data by site webURL; accepts '"+utils.Wildcard+"' to select all sites.") + + fs.StringSliceVar( + &pageFolders, + utils.PageFN, nil, + "Select backup data by site ID; accepts '"+utils.Wildcard+"' to select all sites.") + + fs.StringSliceVar( + &page, + utils.PageItemFN, nil, + "Select backup data by file name; accepts '"+utils.Wildcard+"' to select all pages within the site.", + ) // info flags @@ -179,7 +193,7 @@ func createSharePointCmd(cmd *cobra.Command, args []string) error { return nil } - if err := validateSharePointBackupCreateFlags(site, weburl); err != nil { + if err := validateSharePointBackupCreateFlags(site, weburl, sharepointData); err != nil { return err } @@ -200,7 +214,7 @@ func createSharePointCmd(cmd *cobra.Command, args []string) error { return Only(ctx, errors.Wrap(err, "Failed to connect to Microsoft APIs")) } - sel, err := sharePointBackupCreateSelectors(ctx, site, weburl, gc) + sel, err := sharePointBackupCreateSelectors(ctx, site, weburl, sharepointData, gc) if err != nil { return Only(ctx, errors.Wrap(err, "Retrieving up sharepoint sites by ID and WebURL")) } @@ -250,7 +264,7 @@ func createSharePointCmd(cmd *cobra.Command, args []string) error { return nil } -func validateSharePointBackupCreateFlags(sites, weburls []string) error { +func validateSharePointBackupCreateFlags(sites, weburls, data []string) error { if len(sites) == 0 && len(weburls) == 0 { return errors.New( "requires one or more --" + @@ -260,13 +274,21 @@ func validateSharePointBackupCreateFlags(sites, weburls []string) error { ) } + for _, d := range data { + if d != dataLibraries && d != dataPages { + return errors.New( + d + " is an unrecognized data type; either " + dataLibraries + "or " + dataPages, + ) + } + } + return nil } // TODO: users might specify a data type, this only supports AllData(). func sharePointBackupCreateSelectors( ctx context.Context, - sites, weburls []string, + sites, weburls, data []string, gc *connector.GraphConnector, ) (*selectors.SharePointBackup, error) { if len(sites) == 0 && len(weburls) == 0 { @@ -297,7 +319,20 @@ func sharePointBackupCreateSelectors( } sel := selectors.NewSharePointBackup(union) - sel.Include(sel.AllData()) + if len(data) == 0 { + sel.Include(sel.AllData()) + + return sel, nil + } + + for _, d := range data { + switch d { + case dataLibraries: + sel.Include(sel.Libraries(selectors.Any())) + case dataPages: + sel.Include(sel.Pages(selectors.Any())) + } + } return sel, nil } diff --git a/src/cli/backup/sharepoint_test.go b/src/cli/backup/sharepoint_test.go index d568d4cc6..89e40a9f3 100644 --- a/src/cli/backup/sharepoint_test.go +++ b/src/cli/backup/sharepoint_test.go @@ -98,12 +98,13 @@ func (suite *SharePointSuite) TestValidateSharePointBackupCreateFlags() { } for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { - test.expect(t, validateSharePointBackupCreateFlags(test.site, test.weburl)) + test.expect(t, validateSharePointBackupCreateFlags(test.site, test.weburl, nil)) }) } } func (suite *SharePointSuite) TestSharePointBackupCreateSelectors() { + comboString := []string{"id_1", "id_2"} gc := &connector.GraphConnector{ Sites: map[string]string{ "url_1": "id_1", @@ -115,6 +116,7 @@ func (suite *SharePointSuite) TestSharePointBackupCreateSelectors() { name string site []string weburl []string + data []string expect []string expectScopesLen int }{ @@ -163,7 +165,7 @@ func (suite *SharePointSuite) TestSharePointBackupCreateSelectors() { name: "duplicate sites and urls", site: []string{"id_1", "id_2"}, weburl: []string{"url_1", "url_2"}, - expect: []string{"id_1", "id_2"}, + expect: comboString, expectScopesLen: 2, }, { @@ -175,18 +177,25 @@ func (suite *SharePointSuite) TestSharePointBackupCreateSelectors() { }, { name: "unnecessary url wildcard", - site: []string{"id_1", "id_2"}, + site: comboString, weburl: []string{"url_1", utils.Wildcard}, expect: selectors.Any(), expectScopesLen: 2, }, + { + name: "Pages", + site: comboString, + data: []string{dataPages}, + expect: comboString, + expectScopesLen: 1, + }, } for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { ctx, flush := tester.NewContext() defer flush() - sel, err := sharePointBackupCreateSelectors(ctx, test.site, test.weburl, gc) + sel, err := sharePointBackupCreateSelectors(ctx, test.site, test.weburl, test.data, gc) require.NoError(t, err) assert.ElementsMatch(t, test.expect, sel.DiscreteResourceOwners())