Skip to content

Commit 9e1eb13

Browse files
Add caching of scim/me API to databricks_current_user data source and databricks_permissions resource. (#2170)
* Cache scim/me API * add mutext to protect cached user * naming fix * defer mu.unlock and remove unused code * cache ws client * inline method and rename
1 parent eb4fe2a commit 9e1eb13

File tree

4 files changed

+59
-10
lines changed

4 files changed

+59
-10
lines changed

common/client.go

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,35 @@ import (
66
"log"
77
"net/http"
88
"strings"
9+
"sync"
910

1011
"github.com/databricks/databricks-sdk-go"
1112
"github.com/databricks/databricks-sdk-go/client"
1213
"github.com/databricks/databricks-sdk-go/config"
14+
"github.com/databricks/databricks-sdk-go/service/scim"
1315
"github.com/golang-jwt/jwt/v4"
1416
)
1517

18+
type cachedMe struct {
19+
internalImpl scim.CurrentUserService
20+
cachedUser *scim.User
21+
mu sync.Mutex
22+
}
23+
24+
func (a *cachedMe) Me(ctx context.Context) (*scim.User, error) {
25+
a.mu.Lock()
26+
defer a.mu.Unlock()
27+
if a.cachedUser != nil {
28+
return a.cachedUser, nil
29+
}
30+
user, err := a.internalImpl.Me(ctx)
31+
if err != nil {
32+
return user, err
33+
}
34+
a.cachedUser = user
35+
return user, err
36+
}
37+
1638
// DatabricksClient holds properties needed for authentication and HTTP client setup
1739
// fields with `name` struct tags become Terraform provider attributes. `env` struct tag
1840
// can hold one or more coma-separated env variable names to find value, if not specified
@@ -21,11 +43,27 @@ type DatabricksClient struct {
2143
*client.DatabricksClient
2244

2345
// callback used to create API1.2 call wrapper, which simplifies unit tessting
24-
commandFactory func(context.Context, *DatabricksClient) CommandExecutor
46+
commandFactory func(context.Context, *DatabricksClient) CommandExecutor
47+
cachedWorkspaceClient *databricks.WorkspaceClient
48+
mu sync.Mutex
2549
}
2650

2751
func (c *DatabricksClient) WorkspaceClient() (*databricks.WorkspaceClient, error) {
28-
return databricks.NewWorkspaceClient((*databricks.Config)(c.DatabricksClient.Config))
52+
c.mu.Lock()
53+
defer c.mu.Unlock()
54+
if c.cachedWorkspaceClient != nil {
55+
return c.cachedWorkspaceClient, nil
56+
}
57+
w, err := databricks.NewWorkspaceClient((*databricks.Config)(c.DatabricksClient.Config))
58+
if err != nil {
59+
return nil, err
60+
}
61+
internalImpl := w.CurrentUser.Impl()
62+
w.CurrentUser.WithImpl(&cachedMe{
63+
internalImpl: internalImpl,
64+
})
65+
c.cachedWorkspaceClient = w
66+
return w, nil
2967
}
3068

3169
// Get on path

exporter/context.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,11 @@ func (ic *importContext) Run() error {
157157
} else if !info.IsDir() {
158158
return fmt.Errorf("the path %s is not a directory", ic.Directory)
159159
}
160-
usersAPI := scim.NewUsersAPI(ic.Context, ic.Client)
161-
me, err := usersAPI.Me()
160+
w, err := ic.Client.WorkspaceClient()
161+
if err != nil {
162+
return err
163+
}
164+
me, err := w.CurrentUser.Me(ic.Context)
162165
if err != nil {
163166
return err
164167
}

internal/acceptance/secret_scope_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"testing"
77

88
"github.com/databricks/terraform-provider-databricks/qa"
9-
"github.com/databricks/terraform-provider-databricks/scim"
109
"github.com/databricks/terraform-provider-databricks/secrets"
1110

1211
"github.com/databricks/terraform-provider-databricks/common"
@@ -33,8 +32,10 @@ func TestAccSecretScopeResource(t *testing.T) {
3332
acls, err := secretACLAPI.List(id)
3433
require.NoError(t, err)
3534

36-
usersAPI := scim.NewUsersAPI(ctx, client)
37-
me, err := usersAPI.Me()
35+
w, err := client.WorkspaceClient()
36+
require.NoError(t, err)
37+
38+
me, err := w.CurrentUser.Me(ctx)
3839
require.NoError(t, err)
3940
assert.Equal(t, 1, len(acls))
4041
assert.Equal(t, me.UserName, acls[0].Principal)

permissions/resource_permissions.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"github.com/databricks/terraform-provider-databricks/common"
1414
"github.com/databricks/terraform-provider-databricks/jobs"
1515
"github.com/databricks/terraform-provider-databricks/pipelines"
16-
"github.com/databricks/terraform-provider-databricks/scim"
1716

1817
"github.com/hashicorp/go-cty/cty"
1918
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -141,7 +140,11 @@ func (a PermissionsAPI) ensureCurrentUserCanManageObject(objectID string, object
141140
if !a.shouldExplicitlyGrantCallingUserManagePermissions(objectID) {
142141
return objectACL, nil
143142
}
144-
me, err := scim.NewUsersAPI(a.context, a.client).Me()
143+
w, err := a.client.WorkspaceClient()
144+
if err != nil {
145+
return objectACL, err
146+
}
147+
me, err := w.CurrentUser.Me(a.context)
145148
if err != nil {
146149
return objectACL, err
147150
}
@@ -184,7 +187,11 @@ func (a PermissionsAPI) Update(objectID string, objectACL AccessControlChangeLis
184187
}
185188
}
186189
if owners == 0 {
187-
me, err := scim.NewUsersAPI(a.context, a.client).Me()
190+
w, err := a.client.WorkspaceClient()
191+
if err != nil {
192+
return err
193+
}
194+
me, err := w.CurrentUser.Me(a.context)
188195
if err != nil {
189196
return err
190197
}

0 commit comments

Comments
 (0)