From f0edf7b08161e28e0047f901fbab5c7642215d4c Mon Sep 17 00:00:00 2001 From: Keepers Date: Wed, 31 Aug 2022 17:18:15 -0600 Subject: [PATCH] add the event-calendar flag to the cli (#712) ## Description Adds the event-calendar flag to the cli to prepare for selectors including the calendar as the events' "folder" structure. ## Type of change Please check the type of change your PR introduces: - [x] :sunflower: Feature ## Issue(s) #501 ## Test Plan - [ ] :muscle: Manual - [x] :zap: Unit test - [ ] :green_heart: E2E --- src/cli/backup/exchange.go | 62 +++++++++++++++++++++---------- src/cli/backup/exchange_test.go | 63 +++++++++++++++++++++++--------- src/cli/restore/exchange.go | 60 ++++++++++++++++++++---------- src/cli/restore/exchange_test.go | 63 +++++++++++++++++++++++--------- 4 files changed, 175 insertions(+), 73 deletions(-) diff --git a/src/cli/backup/exchange.go b/src/cli/backup/exchange.go index 8cc86acaa..3bf5f6891 100644 --- a/src/cli/backup/exchange.go +++ b/src/cli/backup/exchange.go @@ -1,6 +1,8 @@ package backup import ( + "fmt" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -33,6 +35,7 @@ var ( emailSender string emailSubject string event []string + eventCalendar []string user []string ) @@ -99,13 +102,19 @@ func addExchangeCommands(parent *cobra.Command) *cobra.Command { &emailFolder, "email-folder", nil, - "Select backup details by email folder ID; accepts "+utils.Wildcard+" to select all email folderss") + "Select backup details by email folder ID; accepts "+utils.Wildcard+" to select all email folders") fs.StringSliceVar( &event, "event", nil, "Select backup details by event ID; accepts "+utils.Wildcard+" to select all events", ) + fs.StringSliceVar( + &eventCalendar, + "event-calendar", + nil, + "Select backup details by event calendar ID; accepts "+utils.Wildcard+" to select all events", + ) fs.StringSliceVar( &user, "user", @@ -317,6 +326,7 @@ func detailsExchangeCmd(cmd *cobra.Command, args []string) error { email, emailFolder, event, + eventCalendar, user, backupID, ); err != nil { @@ -348,6 +358,7 @@ func detailsExchangeCmd(cmd *cobra.Command, args []string) error { email, emailFolder, event, + eventCalendar, user) filterExchangeBackupDetailInfoSelectors( sel, @@ -374,19 +385,19 @@ func detailsExchangeCmd(cmd *cobra.Command, args []string) error { // builds the data-selector inclusions for `backup details exchange` func includeExchangeBackupDetailDataSelectors( sel *selectors.ExchangeRestore, - contacts, contactFolders, emails, emailFolders, events, users []string, + contacts, contactFolders, emails, emailFolders, events, eventCalendars, users []string, ) { lc, lcf := len(contacts), len(contactFolders) le, lef := len(emails), len(emailFolders) - lev := len(events) + lev, lec := len(events), len(eventCalendars) lu := len(users) - if lc+lcf+le+lef+lev+lu == 0 { + if lc+lcf+le+lef+lev+lec+lu == 0 { return } // if only users are provided, we only get one selector - if lu > 0 && lc+lcf+le+lef+lev == 0 { + if lu > 0 && lc+lcf+le+lef+lev+lec == 0 { sel.Include(sel.Users(users)) return } @@ -394,7 +405,7 @@ func includeExchangeBackupDetailDataSelectors( // otherwise, add selectors for each type of data includeExchangeContacts(sel, users, contactFolders, contacts) includeExchangeEmails(sel, users, emailFolders, email) - includeExchangeEvents(sel, users, events) + includeExchangeEvents(sel, users, eventCalendars, events) } func includeExchangeContacts(sel *selectors.ExchangeRestore, users, contactFolders, contacts []string) { @@ -402,11 +413,11 @@ func includeExchangeContacts(sel *selectors.ExchangeRestore, users, contactFolde return } - if len(contacts) > 0 { - sel.Include(sel.Contacts(users, contactFolders, contacts)) - } else { - sel.Include(sel.ContactFolders(users, contactFolders)) + if len(contacts) == 0 { + contacts = selectors.Any() } + + sel.Include(sel.Contacts(users, contactFolders, contacts)) } func includeExchangeEmails(sel *selectors.ExchangeRestore, users, emailFolders, emails []string) { @@ -414,18 +425,24 @@ func includeExchangeEmails(sel *selectors.ExchangeRestore, users, emailFolders, return } - if len(emails) > 0 { - sel.Include(sel.Mails(users, emailFolders, emails)) - } else { - sel.Include(sel.MailFolders(users, emailFolders)) + if len(emails) == 0 { + emails = selectors.Any() } + + sel.Include(sel.Mails(users, emailFolders, emails)) } -func includeExchangeEvents(sel *selectors.ExchangeRestore, users, events []string) { - if len(events) == 0 { +func includeExchangeEvents(sel *selectors.ExchangeRestore, users, eventCalendars, events []string) { + if len(eventCalendars) == 0 { return } + if len(events) == 0 { + events = selectors.Any() + } + + fmt.Println("logging eventCalendars so the linter sees it 'used'. Will remove asap", eventCalendars) + sel.Include(sel.Events(users, events)) } @@ -474,7 +491,7 @@ func filterExchangeInfoMailSubject(sel *selectors.ExchangeRestore, subject strin // checks all flags for correctness and interdependencies func validateExchangeBackupDetailFlags( - contacts, contactFolders, emails, emailFolders, events, users []string, + contacts, contactFolders, emails, emailFolders, events, eventCalendars, users []string, backupID string, ) error { if len(backupID) == 0 { @@ -484,9 +501,9 @@ func validateExchangeBackupDetailFlags( lu := len(users) lc, lcf := len(contacts), len(contactFolders) le, lef := len(emails), len(emailFolders) - lev := len(events) + lev, lec := len(events), len(eventCalendars) - if lu+lc+lcf+le+lef+lev == 0 { + if lu+lc+lcf+le+lef+lev+lec == 0 { return nil } @@ -501,7 +518,12 @@ func validateExchangeBackupDetailFlags( if le > 0 && lef == 0 { return errors.New( - "one or more --email-folder ids or the wildcard --email-folder * must be included to specify a --email") + "one or more --email-folder ids or the wildcard --email-folder * must be included to specify an --email") + } + + if lev > 0 && lec == 0 { + return errors.New( + "one or more --event-calendar ids or the wildcard --event-calendar * must be included to specify an --event") } return nil diff --git a/src/cli/backup/exchange_test.go b/src/cli/backup/exchange_test.go index be3a9b0d9..e9d4066ed 100644 --- a/src/cli/backup/exchange_test.go +++ b/src/cli/backup/exchange_test.go @@ -220,10 +220,10 @@ func (suite *ExchangeSuite) TestValidateBackupDetailFlags() { stub := []string{"id-stub"} table := []struct { - name string - contacts, contactFolders, emails, emailFolders, events, users []string - backupID string - expect assert.ErrorAssertionFunc + name string + contacts, contactFolders, emails, emailFolders, events, eventCalendars, users []string + backupID string + expect assert.ErrorAssertionFunc }{ { name: "only backupid", @@ -238,6 +238,7 @@ func (suite *ExchangeSuite) TestValidateBackupDetailFlags() { emails: stub, emailFolders: stub, events: stub, + eventCalendars: stub, users: stub, expect: assert.NoError, }, @@ -252,6 +253,7 @@ func (suite *ExchangeSuite) TestValidateBackupDetailFlags() { emails: stub, emailFolders: stub, events: stub, + eventCalendars: stub, users: stub, expect: assert.Error, }, @@ -263,17 +265,19 @@ func (suite *ExchangeSuite) TestValidateBackupDetailFlags() { emails: stub, emailFolders: stub, events: stub, + eventCalendars: stub, expect: assert.Error, }, { - name: "no contact folders", - backupID: "bid", - contacts: stub, - emails: stub, - emailFolders: stub, - events: stub, - users: stub, - expect: assert.Error, + name: "no contact folders", + backupID: "bid", + contacts: stub, + emails: stub, + emailFolders: stub, + events: stub, + eventCalendars: stub, + users: stub, + expect: assert.Error, }, { name: "no email folders", @@ -282,6 +286,17 @@ func (suite *ExchangeSuite) TestValidateBackupDetailFlags() { contactFolders: stub, emails: stub, events: stub, + eventCalendars: stub, + users: stub, + expect: assert.Error, + }, + { + name: "no event calendars", + backupID: "bid", + contacts: stub, + contactFolders: stub, + emails: stub, + events: stub, users: stub, expect: assert.Error, }, @@ -294,6 +309,7 @@ func (suite *ExchangeSuite) TestValidateBackupDetailFlags() { test.emails, test.emailFolders, test.events, + test.eventCalendars, test.users, test.backupID, )) @@ -306,9 +322,9 @@ func (suite *ExchangeSuite) TestIncludeExchangeBackupDetailDataSelectors() { a := []string{utils.Wildcard} table := []struct { - name string - contacts, contactFolders, emails, emailFolders, events, users []string - expectIncludeLen int + name string + contacts, contactFolders, emails, emailFolders, events, eventCalendars, users []string + expectIncludeLen int }{ { name: "no selectors", @@ -336,6 +352,7 @@ func (suite *ExchangeSuite) TestIncludeExchangeBackupDetailDataSelectors() { emails: a, emailFolders: a, events: a, + eventCalendars: a, users: a, expectIncludeLen: 3, }, @@ -343,8 +360,9 @@ func (suite *ExchangeSuite) TestIncludeExchangeBackupDetailDataSelectors() { name: "any users, any folders", contactFolders: a, emailFolders: a, + eventCalendars: a, users: a, - expectIncludeLen: 2, + expectIncludeLen: 3, }, { name: "single user, single of each data", @@ -353,6 +371,7 @@ func (suite *ExchangeSuite) TestIncludeExchangeBackupDetailDataSelectors() { emails: stub, emailFolders: stub, events: stub, + eventCalendars: stub, users: stub, expectIncludeLen: 3, }, @@ -360,8 +379,9 @@ func (suite *ExchangeSuite) TestIncludeExchangeBackupDetailDataSelectors() { name: "single user, single of each folder", contactFolders: stub, emailFolders: stub, + eventCalendars: stub, users: stub, - expectIncludeLen: 2, + expectIncludeLen: 3, }, { name: "any users, contacts", @@ -394,12 +414,14 @@ func (suite *ExchangeSuite) TestIncludeExchangeBackupDetailDataSelectors() { { name: "any users, events", events: a, + eventCalendars: a, users: a, expectIncludeLen: 1, }, { name: "single user, events", events: stub, + eventCalendars: stub, users: stub, expectIncludeLen: 1, }, @@ -426,6 +448,7 @@ func (suite *ExchangeSuite) TestIncludeExchangeBackupDetailDataSelectors() { emails: a, emailFolders: a, events: a, + eventCalendars: a, users: a, expectIncludeLen: 2, }, @@ -434,6 +457,7 @@ func (suite *ExchangeSuite) TestIncludeExchangeBackupDetailDataSelectors() { emails: stub, emailFolders: stub, events: stub, + eventCalendars: stub, users: stub, expectIncludeLen: 2, }, @@ -442,6 +466,7 @@ func (suite *ExchangeSuite) TestIncludeExchangeBackupDetailDataSelectors() { contacts: a, contactFolders: a, events: a, + eventCalendars: a, users: a, expectIncludeLen: 2, }, @@ -450,12 +475,14 @@ func (suite *ExchangeSuite) TestIncludeExchangeBackupDetailDataSelectors() { contacts: stub, contactFolders: stub, events: stub, + eventCalendars: stub, users: stub, expectIncludeLen: 2, }, { name: "many users, events", events: []string{"foo", "bar"}, + eventCalendars: []string{"baz", "qux"}, users: []string{"fnord", "smarf"}, expectIncludeLen: 1, }, @@ -464,6 +491,7 @@ func (suite *ExchangeSuite) TestIncludeExchangeBackupDetailDataSelectors() { contacts: []string{"foo", "bar"}, contactFolders: []string{"foo", "bar"}, events: []string{"foo", "bar"}, + eventCalendars: []string{"foo", "bar"}, users: []string{"fnord", "smarf"}, expectIncludeLen: 2, }, @@ -478,6 +506,7 @@ func (suite *ExchangeSuite) TestIncludeExchangeBackupDetailDataSelectors() { test.emails, test.emailFolders, test.events, + test.eventCalendars, test.users) assert.Equal(t, test.expectIncludeLen, len(sel.Includes)) }) diff --git a/src/cli/restore/exchange.go b/src/cli/restore/exchange.go index cf9f42722..b8fae05c4 100644 --- a/src/cli/restore/exchange.go +++ b/src/cli/restore/exchange.go @@ -1,6 +1,8 @@ package restore import ( + "fmt" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -25,6 +27,7 @@ var ( emailSender string emailSubject string event []string + eventCalendar []string user []string ) @@ -61,12 +64,18 @@ func addExchangeCommands(parent *cobra.Command) *cobra.Command { "Restore all emails by folder ID; accepts "+utils.Wildcard+" to select all email folders", ) fs.StringSliceVar(&event, "event", nil, "Restore events by ID; accepts "+utils.Wildcard+" to select all events") + fs.StringSliceVar( + &eventCalendar, + "event-calendar", + nil, + "Restore events by calendar ID; accepts "+utils.Wildcard+" to select all event calendars") fs.StringSliceVar(&user, "user", nil, "Restore all data by user ID; accepts "+utils.Wildcard+" to select all users") // TODO: reveal these flags when their production is supported in GC cobra.CheckErr(fs.MarkHidden("contact")) cobra.CheckErr(fs.MarkHidden("contact-folder")) cobra.CheckErr(fs.MarkHidden("event")) + cobra.CheckErr(fs.MarkHidden("event-calendar")) // exchange-info flags fs.StringVar( @@ -117,6 +126,7 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error { email, emailFolder, event, + eventCalendar, user, backupID, ); err != nil { @@ -143,6 +153,7 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error { email, emailFolder, event, + eventCalendar, user) filterExchangeRestoreInfoSelectors( sel, @@ -173,19 +184,19 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error { // builds the data-selector inclusions for `restore exchange` func includeExchangeRestoreDataSelectors( sel *selectors.ExchangeRestore, - contacts, contactFolders, emails, emailFolders, events, users []string, + contacts, contactFolders, emails, emailFolders, events, eventCalendars, users []string, ) { lc, lcf := len(contacts), len(contactFolders) le, lef := len(emails), len(emailFolders) - lev := len(events) + lev, lec := len(events), len(eventCalendars) lu := len(users) - if lc+lcf+le+lef+lev+lu == 0 { + if lc+lcf+le+lef+lev+lec+lu == 0 { return } // if only users are provided, we only get one selector - if lu > 0 && lc+lcf+le+lef+lev == 0 { + if lu > 0 && lc+lcf+le+lef+lev+lec == 0 { sel.Include(sel.Users(users)) return } @@ -193,7 +204,7 @@ func includeExchangeRestoreDataSelectors( // otherwise, add selectors for each type of data includeExchangeContacts(sel, users, contactFolders, contacts) includeExchangeEmails(sel, users, emailFolders, email) - includeExchangeEvents(sel, users, events) + includeExchangeEvents(sel, users, eventCalendars, events) } func includeExchangeContacts(sel *selectors.ExchangeRestore, users, contactFolders, contacts []string) { @@ -201,11 +212,11 @@ func includeExchangeContacts(sel *selectors.ExchangeRestore, users, contactFolde return } - if len(contacts) > 0 { - sel.Include(sel.Contacts(users, contactFolders, contacts)) - } else { - sel.Include(sel.ContactFolders(users, contactFolders)) + if len(contacts) == 0 { + contacts = selectors.Any() } + + sel.Include(sel.Contacts(users, contactFolders, contacts)) } func includeExchangeEmails(sel *selectors.ExchangeRestore, users, emailFolders, emails []string) { @@ -213,18 +224,24 @@ func includeExchangeEmails(sel *selectors.ExchangeRestore, users, emailFolders, return } - if len(emails) > 0 { - sel.Include(sel.Mails(users, emailFolders, emails)) - } else { - sel.Include(sel.MailFolders(users, emailFolders)) + if len(emails) == 0 { + emails = selectors.Any() } + + sel.Include(sel.Mails(users, emailFolders, emails)) } -func includeExchangeEvents(sel *selectors.ExchangeRestore, users, events []string) { - if len(events) == 0 { +func includeExchangeEvents(sel *selectors.ExchangeRestore, users, eventCalendars, events []string) { + if len(eventCalendars) == 0 { return } + if len(events) == 0 { + events = selectors.Any() + } + + fmt.Println("logging eventCalendars so the linter sees it 'used'. Will remove asap", eventCalendars) + sel.Include(sel.Events(users, events)) } @@ -273,7 +290,7 @@ func filterExchangeInfoMailSubject(sel *selectors.ExchangeRestore, subject strin // checks all flags for correctness and interdependencies func validateExchangeRestoreFlags( - contacts, contactFolders, emails, emailFolders, events, users []string, + contacts, contactFolders, emails, emailFolders, events, eventCalendars, users []string, backupID string, ) error { if len(backupID) == 0 { @@ -283,10 +300,10 @@ func validateExchangeRestoreFlags( lu := len(users) lc, lcf := len(contacts), len(contactFolders) le, lef := len(emails), len(emailFolders) - lev := len(events) + lev, lec := len(events), len(eventCalendars) // if only the backupID is populated, that's the same as --all - if lu+lc+lcf+le+lef+lev == 0 { + if lu+lc+lcf+le+lef+lev+lec == 0 { return nil } @@ -301,7 +318,12 @@ func validateExchangeRestoreFlags( if le > 0 && lef == 0 { return errors.New( - "one or more --email-folder ids or the wildcard --email-folder * must be included to specify a --email") + "one or more --email-folder ids or the wildcard --email-folder * must be included to specify an --email") + } + + if lev > 0 && lec == 0 { + return errors.New( + "one or more --event-calendar ids or the wildcard --event-calendar * must be included to specify an --event") } return nil diff --git a/src/cli/restore/exchange_test.go b/src/cli/restore/exchange_test.go index 566e34f07..6ca4f7122 100644 --- a/src/cli/restore/exchange_test.go +++ b/src/cli/restore/exchange_test.go @@ -55,10 +55,10 @@ func (suite *ExchangeSuite) TestValidateExchangeRestoreFlags() { stub := []string{"id-stub"} table := []struct { - name string - contacts, contactFolders, emails, emailFolders, events, users []string - backupID string - expect assert.ErrorAssertionFunc + name string + contacts, contactFolders, emails, emailFolders, events, eventCalendars, users []string + backupID string + expect assert.ErrorAssertionFunc }{ { name: "only backupid", @@ -73,6 +73,7 @@ func (suite *ExchangeSuite) TestValidateExchangeRestoreFlags() { emails: stub, emailFolders: stub, events: stub, + eventCalendars: stub, users: stub, expect: assert.NoError, }, @@ -87,6 +88,7 @@ func (suite *ExchangeSuite) TestValidateExchangeRestoreFlags() { emails: stub, emailFolders: stub, events: stub, + eventCalendars: stub, users: stub, expect: assert.Error, }, @@ -98,17 +100,19 @@ func (suite *ExchangeSuite) TestValidateExchangeRestoreFlags() { emails: stub, emailFolders: stub, events: stub, + eventCalendars: stub, expect: assert.Error, }, { - name: "no contact folders", - backupID: "bid", - contacts: stub, - emails: stub, - emailFolders: stub, - events: stub, - users: stub, - expect: assert.Error, + name: "no contact folders", + backupID: "bid", + contacts: stub, + emails: stub, + emailFolders: stub, + events: stub, + users: stub, + eventCalendars: stub, + expect: assert.Error, }, { name: "no email folders", @@ -117,6 +121,17 @@ func (suite *ExchangeSuite) TestValidateExchangeRestoreFlags() { contactFolders: stub, emails: stub, events: stub, + eventCalendars: stub, + users: stub, + expect: assert.Error, + }, + { + name: "no event calendars", + backupID: "bid", + contacts: stub, + contactFolders: stub, + emails: stub, + events: stub, users: stub, expect: assert.Error, }, @@ -129,6 +144,7 @@ func (suite *ExchangeSuite) TestValidateExchangeRestoreFlags() { test.emails, test.emailFolders, test.events, + test.eventCalendars, test.users, test.backupID, )) @@ -141,9 +157,9 @@ func (suite *ExchangeSuite) TestIncludeExchangeRestoreDataSelectors() { a := []string{utils.Wildcard} table := []struct { - name string - contacts, contactFolders, emails, emailFolders, events, users []string - expectIncludeLen int + name string + contacts, contactFolders, emails, emailFolders, events, eventCalendars, users []string + expectIncludeLen int }{ { name: "no selectors", @@ -171,6 +187,7 @@ func (suite *ExchangeSuite) TestIncludeExchangeRestoreDataSelectors() { emails: a, emailFolders: a, events: a, + eventCalendars: a, users: a, expectIncludeLen: 3, }, @@ -178,8 +195,9 @@ func (suite *ExchangeSuite) TestIncludeExchangeRestoreDataSelectors() { name: "any users, any folders", contactFolders: a, emailFolders: a, + eventCalendars: a, users: a, - expectIncludeLen: 2, + expectIncludeLen: 3, }, { name: "single user, single of each data", @@ -188,6 +206,7 @@ func (suite *ExchangeSuite) TestIncludeExchangeRestoreDataSelectors() { emails: stub, emailFolders: stub, events: stub, + eventCalendars: stub, users: stub, expectIncludeLen: 3, }, @@ -195,8 +214,9 @@ func (suite *ExchangeSuite) TestIncludeExchangeRestoreDataSelectors() { name: "single user, single of each folder", contactFolders: stub, emailFolders: stub, + eventCalendars: stub, users: stub, - expectIncludeLen: 2, + expectIncludeLen: 3, }, { name: "any users, contacts", @@ -229,12 +249,14 @@ func (suite *ExchangeSuite) TestIncludeExchangeRestoreDataSelectors() { { name: "any users, events", events: a, + eventCalendars: a, users: a, expectIncludeLen: 1, }, { name: "single user, events", events: stub, + eventCalendars: stub, users: stub, expectIncludeLen: 1, }, @@ -261,6 +283,7 @@ func (suite *ExchangeSuite) TestIncludeExchangeRestoreDataSelectors() { emails: a, emailFolders: a, events: a, + eventCalendars: a, users: a, expectIncludeLen: 2, }, @@ -269,6 +292,7 @@ func (suite *ExchangeSuite) TestIncludeExchangeRestoreDataSelectors() { emails: stub, emailFolders: stub, events: stub, + eventCalendars: stub, users: stub, expectIncludeLen: 2, }, @@ -277,6 +301,7 @@ func (suite *ExchangeSuite) TestIncludeExchangeRestoreDataSelectors() { contacts: a, contactFolders: a, events: a, + eventCalendars: a, users: a, expectIncludeLen: 2, }, @@ -285,12 +310,14 @@ func (suite *ExchangeSuite) TestIncludeExchangeRestoreDataSelectors() { contacts: stub, contactFolders: stub, events: stub, + eventCalendars: stub, users: stub, expectIncludeLen: 2, }, { name: "many users, events", events: []string{"foo", "bar"}, + eventCalendars: []string{"baz", "qux"}, users: []string{"fnord", "smarf"}, expectIncludeLen: 1, }, @@ -299,6 +326,7 @@ func (suite *ExchangeSuite) TestIncludeExchangeRestoreDataSelectors() { contacts: []string{"foo", "bar"}, contactFolders: []string{"foo", "bar"}, events: []string{"foo", "bar"}, + eventCalendars: []string{"foo", "bar"}, users: []string{"fnord", "smarf"}, expectIncludeLen: 2, }, @@ -313,6 +341,7 @@ func (suite *ExchangeSuite) TestIncludeExchangeRestoreDataSelectors() { test.emails, test.emailFolders, test.events, + test.eventCalendars, test.users) assert.Equal(t, test.expectIncludeLen, len(sel.Includes)) })