GC: Backup:Event Feature to incorporate event ids for all calendars (#808)

Feature enhancement to include all Calendars in the event `restore-all` feature.
This commit is contained in:
Danny 2022-09-12 08:17:04 -04:00 committed by GitHub
parent 964a2fc39e
commit 432f984e61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 48 deletions

View File

@ -77,12 +77,12 @@ func loadService(t *testing.T) *exchangeService {
// functions are valid for current versioning of msgraph-go-sdk // functions are valid for current versioning of msgraph-go-sdk
func (suite *ExchangeIteratorSuite) TestIterativeFunctions() { func (suite *ExchangeIteratorSuite) TestIterativeFunctions() {
var ( var (
ctx = context.Background() ctx = context.Background()
t = suite.T() t = suite.T()
mailScope, contactScope selectors.ExchangeScope mailScope, contactScope, eventScope selectors.ExchangeScope
userID = tester.M365UserID(t) userID = tester.M365UserID(t)
sel = selectors.NewExchangeBackup() sel = selectors.NewExchangeBackup()
service = loadService(t) service = loadService(t)
) )
sel.Include(sel.Users([]string{userID})) sel.Include(sel.Users([]string{userID}))
@ -100,6 +100,10 @@ func (suite *ExchangeIteratorSuite) TestIterativeFunctions() {
if scope.IncludesCategory(selectors.ExchangeMail) { if scope.IncludesCategory(selectors.ExchangeMail) {
mailScope = scope mailScope = scope
} }
if scope.IncludesCategory(selectors.ExchangeEvent) {
eventScope = scope
}
} }
tests := []struct { tests := []struct {
@ -126,6 +130,12 @@ func (suite *ExchangeIteratorSuite) TestIterativeFunctions() {
iterativeFunction: IterateSelectAllDescendablesForCollections, iterativeFunction: IterateSelectAllDescendablesForCollections,
scope: contactScope, scope: contactScope,
transformer: models.CreateContactFromDiscriminatorValue, transformer: models.CreateContactFromDiscriminatorValue,
}, {
name: "Events Iterative Check",
queryFunction: GetAllCalendarNamesForUser,
iterativeFunction: IterateSelectAllEventsFromCalendars,
scope: eventScope,
transformer: models.CreateCalendarCollectionResponseFromDiscriminatorValue,
}, { }, {
name: "Folder Iterative Check", name: "Folder Iterative Check",
queryFunction: GetAllFolderNamesForUser, queryFunction: GetAllFolderNamesForUser,

View File

@ -281,9 +281,9 @@ func SetupExchangeCollectionVars(scope selectors.ExchangeScope) (
} }
if scope.IncludesCategory(selectors.ExchangeEvent) { if scope.IncludesCategory(selectors.ExchangeEvent) {
return models.CreateEventCollectionResponseFromDiscriminatorValue, return models.CreateCalendarCollectionResponseFromDiscriminatorValue,
GetAllEventsForUser, GetAllCalendarNamesForUser,
IterateSelectAllEventsForCollections, IterateSelectAllEventsFromCalendars,
nil nil
} }

View File

@ -2,7 +2,6 @@ package exchange
import ( import (
"context" "context"
"fmt"
"strings" "strings"
"github.com/microsoftgraph/msgraph-sdk-go/models" "github.com/microsoftgraph/msgraph-sdk-go/models"
@ -203,79 +202,88 @@ func IterateSelectAllDescendablesForCollections(
// utility function for iterating through events // utility function for iterating through events
// and storing events in collections based on // and storing events in collections based on
// the calendarID which originates from M365. // the calendarID which originates from M365.
func IterateSelectAllEventsForCollections( func IterateSelectAllEventsFromCalendars(
ctx context.Context, ctx context.Context,
qp graph.QueryParams, qp graph.QueryParams,
errs error, errs error,
collections map[string]*Collection, collections map[string]*Collection,
statusUpdater support.StatusUpdater, statusUpdater support.StatusUpdater,
) func(any) bool { ) func(any) bool {
return func(eventItem any) bool { return func(pageItem any) bool {
event, ok := eventItem.(models.Eventable) if pageItem == nil {
return true
}
shell, ok := pageItem.(models.Calendarable)
if !ok { if !ok {
errs = support.WrapAndAppend( errs = support.WrapAndAppend(
qp.User, qp.User,
errors.New("event iteration failure"), errors.New("calendar event"),
errs, errs)
)
return true return true
} }
adtl := event.GetAdditionalData() service, err := createService(qp.Credentials, qp.FailFast)
value, ok := adtl["calendar@odata.associationLink"]
if !ok {
errs = support.WrapAndAppend(
qp.User,
fmt.Errorf("%s: does not support calendar look up", *event.GetId()),
errs,
)
return true
}
link, ok := value.(*string)
if !ok || link == nil {
errs = support.WrapAndAppend(
qp.User,
fmt.Errorf("%s: unable to obtain calendar event data", *event.GetId()),
errs,
)
return true
}
// calendars and events are not easily correlated
// helper function retrieves calendarID from url
directory, err := parseCalendarIDFromEvent(*link)
if err != nil { if err != nil {
errs = support.WrapAndAppend( errs = support.WrapAndAppend(
qp.User, qp.User,
errors.Wrap(err, *event.GetId()), errors.Wrap(err, "unable to create service during IterateSelectAllEventsFromCalendars"),
errs, errs,
) )
return true return true
} }
if _, ok := collections[directory]; !ok { eventResponseable, err := service.Client().
UsersById(qp.User).
CalendarsById(*shell.GetId()).
Events().Get()
if err != nil {
errs = support.WrapAndAppend(
qp.User,
err,
errs,
)
}
directory := shell.GetName()
owner := shell.GetOwner()
// Conditional Guard Checks
if eventResponseable == nil ||
directory == nil ||
owner == nil {
return true
}
eventables := eventResponseable.GetValue()
// Clause is true when Calendar has does not have any events
if eventables == nil {
return true
}
if _, ok := collections[*directory]; !ok {
service, err := createService(qp.Credentials, qp.FailFast) service, err := createService(qp.Credentials, qp.FailFast)
if err != nil { if err != nil {
errs = support.WrapAndAppend(qp.User, err, errs) errs = support.WrapAndAppend(qp.User, err, errs)
return true return true
} }
edc := NewCollection( edc := NewCollection(
qp.User, qp.User,
[]string{qp.Credentials.TenantID, qp.User, path.EventsCategory.String(), directory}, []string{qp.Credentials.TenantID, qp.User, path.EventsCategory.String(), *directory},
events, events,
service, service,
statusUpdater, statusUpdater,
) )
collections[directory] = &edc collections[*directory] = &edc
} }
collections[directory].AddJob(*event.GetId()) for _, event := range eventables {
collections[*directory].AddJob(*event.GetId())
}
return true return true
} }

View File

@ -55,7 +55,7 @@ func GetAllFolderNamesForUser(gs graph.Service, user string) (absser.Parsable, e
} }
func GetAllCalendarNamesForUser(gs graph.Service, user string) (absser.Parsable, error) { func GetAllCalendarNamesForUser(gs graph.Service, user string) (absser.Parsable, error) {
options, err := optionsForCalendars([]string{"name"}) options, err := optionsForCalendars([]string{"name", "owner"})
if err != nil { if err != nil {
return nil, err return nil, err
} }