add a resource getter setter to newServiceHandler
This sets us up to remove the service declaration from the two-step repo creation + init/config, and allows sdk consumers to return to ignoring service until acting on the operation.
This commit is contained in:
parent
ea308055eb
commit
5a50627386
@ -39,7 +39,7 @@ type Controller struct {
|
|||||||
tenant string
|
tenant string
|
||||||
credentials account.M365Config
|
credentials account.M365Config
|
||||||
|
|
||||||
ownerLookup idname.GetResourceIDAndNamer
|
resourceHandler idname.GetResourceIDAndNamer
|
||||||
// maps of resource owner ids to names, and names to ids.
|
// maps of resource owner ids to names, and names to ids.
|
||||||
// not guaranteed to be populated, only here as a post-population
|
// not guaranteed to be populated, only here as a post-population
|
||||||
// reference for processes that choose to populate the values.
|
// reference for processes that choose to populate the values.
|
||||||
@ -83,43 +83,22 @@ func NewController(
|
|||||||
return nil, clues.Wrap(err, "creating api client").WithClues(ctx)
|
return nil, clues.Wrap(err, "creating api client").WithClues(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
var rCli *resourceClient
|
|
||||||
|
|
||||||
// no failure for unknown service.
|
|
||||||
// In that case we create a controller that doesn't attempt to look up any resource
|
|
||||||
// data. This case helps avoid unnecessary service calls when the end user is running
|
|
||||||
// repo init and connect commands via the CLI. All other callers should be expected
|
|
||||||
// to pass in a known service, or else expect downstream failures.
|
|
||||||
if pst != path.UnknownService {
|
|
||||||
rc := resource.UnknownResource
|
|
||||||
|
|
||||||
switch pst {
|
|
||||||
case path.ExchangeService, path.OneDriveService:
|
|
||||||
rc = resource.Users
|
|
||||||
case path.GroupsService:
|
|
||||||
rc = resource.Groups
|
|
||||||
case path.SharePointService:
|
|
||||||
rc = resource.Sites
|
|
||||||
}
|
|
||||||
|
|
||||||
rCli, err = getResourceClient(rc, ac)
|
|
||||||
if err != nil {
|
|
||||||
return nil, clues.Wrap(err, "creating resource client").WithClues(ctx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ctrl := Controller{
|
ctrl := Controller{
|
||||||
AC: ac,
|
AC: ac,
|
||||||
IDNameLookup: idname.NewCache(nil),
|
IDNameLookup: idname.NewCache(nil),
|
||||||
|
|
||||||
credentials: creds,
|
credentials: creds,
|
||||||
ownerLookup: rCli,
|
|
||||||
tenant: acct.ID(),
|
tenant: acct.ID(),
|
||||||
wg: &sync.WaitGroup{},
|
wg: &sync.WaitGroup{},
|
||||||
backupDriveIDNames: idname.NewCache(nil),
|
backupDriveIDNames: idname.NewCache(nil),
|
||||||
backupSiteIDWebURL: idname.NewCache(nil),
|
backupSiteIDWebURL: idname.NewCache(nil),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove in favor of calling setResourceHandler in the newServiceHandler once
|
||||||
|
// all operations types are populated. When we do that, we can also remove pst from
|
||||||
|
// the func params in this call.
|
||||||
|
ctrl.setResourceHandler(pst)
|
||||||
|
|
||||||
return &ctrl, nil
|
return &ctrl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,6 +106,32 @@ func (ctrl *Controller) VerifyAccess(ctx context.Context) error {
|
|||||||
return ctrl.AC.Access().GetToken(ctx)
|
return ctrl.AC.Access().GetToken(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctrl *Controller) setResourceHandler(
|
||||||
|
serviceInOperation path.ServiceType,
|
||||||
|
) {
|
||||||
|
var rh *resourceGetter
|
||||||
|
|
||||||
|
switch serviceInOperation {
|
||||||
|
case path.ExchangeService, path.OneDriveService:
|
||||||
|
rh = &resourceGetter{
|
||||||
|
enum: resource.Users,
|
||||||
|
getter: ctrl.AC.Users(),
|
||||||
|
}
|
||||||
|
case path.GroupsService:
|
||||||
|
rh = &resourceGetter{
|
||||||
|
enum: resource.Sites,
|
||||||
|
getter: ctrl.AC.Sites(),
|
||||||
|
}
|
||||||
|
case path.SharePointService:
|
||||||
|
rh = &resourceGetter{
|
||||||
|
enum: resource.Groups,
|
||||||
|
getter: ctrl.AC.Groups(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrl.resourceHandler = rh
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Processing Status
|
// Processing Status
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -203,20 +208,9 @@ func (ctrl *Controller) CacheItemInfo(dii details.ItemInfo) {
|
|||||||
// Resource Lookup Handling
|
// Resource Lookup Handling
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
func getResourceClient(rc resource.Category, ac api.Client) (*resourceClient, error) {
|
var _ idname.GetResourceIDAndNamer = &resourceGetter{}
|
||||||
switch rc {
|
|
||||||
case resource.Users:
|
|
||||||
return &resourceClient{enum: rc, getter: ac.Users()}, nil
|
|
||||||
case resource.Sites:
|
|
||||||
return &resourceClient{enum: rc, getter: ac.Sites()}, nil
|
|
||||||
case resource.Groups:
|
|
||||||
return &resourceClient{enum: rc, getter: ac.Groups()}, nil
|
|
||||||
default:
|
|
||||||
return nil, clues.New("unrecognized owner resource type").With("resource_enum", rc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type resourceClient struct {
|
type resourceGetter struct {
|
||||||
enum resource.Category
|
enum resource.Category
|
||||||
getter getIDAndNamer
|
getter getIDAndNamer
|
||||||
}
|
}
|
||||||
@ -233,15 +227,13 @@ type getIDAndNamer interface {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ idname.GetResourceIDAndNamer = &resourceClient{}
|
|
||||||
|
|
||||||
// GetResourceIDAndNameFrom looks up the resource's canonical id and display name.
|
// GetResourceIDAndNameFrom looks up the resource's canonical id and display name.
|
||||||
// If the resource is present in the idNameSwapper, then that interface's id and
|
// If the resource is present in the idNameSwapper, then that interface's id and
|
||||||
// name values are returned. As a fallback, the resource calls the discovery
|
// name values are returned. As a fallback, the resource calls the discovery
|
||||||
// api to fetch the user or site using the resource value. This fallback assumes
|
// api to fetch the user or site using the resource value. This fallback assumes
|
||||||
// that the resource is a well formed ID or display name of appropriate design
|
// that the resource is a well formed ID or display name of appropriate design
|
||||||
// (PrincipalName for users, WebURL for sites).
|
// (PrincipalName for users, WebURL for sites).
|
||||||
func (r resourceClient) GetResourceIDAndNameFrom(
|
func (r resourceGetter) GetResourceIDAndNameFrom(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
owner string,
|
owner string,
|
||||||
ins idname.Cacher,
|
ins idname.Cacher,
|
||||||
@ -294,11 +286,11 @@ func (ctrl *Controller) PopulateProtectedResourceIDAndName(
|
|||||||
resourceID string, // input value, can be either id or name
|
resourceID string, // input value, can be either id or name
|
||||||
ins idname.Cacher,
|
ins idname.Cacher,
|
||||||
) (idname.Provider, error) {
|
) (idname.Provider, error) {
|
||||||
if ctrl.ownerLookup == nil {
|
if ctrl.resourceHandler == nil {
|
||||||
return nil, clues.Stack(ErrNoResourceLookup).WithClues(ctx)
|
return nil, clues.Stack(ErrNoResourceLookup).WithClues(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pr, err := ctrl.ownerLookup.GetResourceIDAndNameFrom(ctx, resourceID, ins)
|
pr, err := ctrl.resourceHandler.GetResourceIDAndNameFrom(ctx, resourceID, ins)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, clues.Wrap(err, "identifying resource owner")
|
return nil, clues.Wrap(err, "identifying resource owner")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,18 +57,18 @@ func (suite *ControllerUnitSuite) TestPopulateOwnerIDAndNamesFrom() {
|
|||||||
var (
|
var (
|
||||||
itn = map[string]string{id: name}
|
itn = map[string]string{id: name}
|
||||||
nti = map[string]string{name: id}
|
nti = map[string]string{name: id}
|
||||||
lookup = &resourceClient{
|
lookup = &resourceGetter{
|
||||||
enum: resource.Users,
|
enum: resource.Users,
|
||||||
getter: &mock.IDNameGetter{ID: id, Name: name},
|
getter: &mock.IDNameGetter{ID: id, Name: name},
|
||||||
}
|
}
|
||||||
noLookup = &resourceClient{enum: resource.Users, getter: &mock.IDNameGetter{}}
|
noLookup = &resourceGetter{enum: resource.Users, getter: &mock.IDNameGetter{}}
|
||||||
)
|
)
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
protectedResource string
|
protectedResource string
|
||||||
ins inMock.Cache
|
ins inMock.Cache
|
||||||
rc *resourceClient
|
rc *resourceGetter
|
||||||
expectID string
|
expectID string
|
||||||
expectName string
|
expectName string
|
||||||
expectErr require.ErrorAssertionFunc
|
expectErr require.ErrorAssertionFunc
|
||||||
@ -238,7 +238,7 @@ func (suite *ControllerUnitSuite) TestPopulateOwnerIDAndNamesFrom() {
|
|||||||
ctx, flush := tester.NewContext(t)
|
ctx, flush := tester.NewContext(t)
|
||||||
defer flush()
|
defer flush()
|
||||||
|
|
||||||
ctrl := &Controller{ownerLookup: test.rc}
|
ctrl := &Controller{resourceHandler: test.rc}
|
||||||
|
|
||||||
resource, err := ctrl.PopulateProtectedResourceIDAndName(ctx, test.protectedResource, test.ins)
|
resource, err := ctrl.PopulateProtectedResourceIDAndName(ctx, test.protectedResource, test.ins)
|
||||||
test.expectErr(t, err, clues.ToCore(err))
|
test.expectErr(t, err, clues.ToCore(err))
|
||||||
|
|||||||
@ -17,6 +17,8 @@ func (ctrl *Controller) NewServiceHandler(
|
|||||||
opts control.Options,
|
opts control.Options,
|
||||||
service path.ServiceType,
|
service path.ServiceType,
|
||||||
) (inject.ServiceHandler, error) {
|
) (inject.ServiceHandler, error) {
|
||||||
|
ctrl.setResourceHandler(service)
|
||||||
|
|
||||||
switch service {
|
switch service {
|
||||||
case path.OneDriveService:
|
case path.OneDriveService:
|
||||||
return onedrive.NewOneDriveHandler(opts), nil
|
return onedrive.NewOneDriveHandler(opts), nil
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user