Skip to content

Commit a59abf1

Browse files
authored
[Internal] refactored databricks_mws_permission_assignment to Go SDK (#3831)
## Changes - refactored `databricks_mws_permission_assignment` to Go SDK - added `TestUcAccAssignGroupToWorkspace` to flaky tests ## Tests <!-- How is this tested? Please see the checklist below and also describe any other relevant tests --> - [x] `make test` run locally - [x] covered with integration tests in `internal/acceptance` - [ ] relevant acceptance tests are passing - [x] using Go SDK
1 parent 4409a63 commit a59abf1

File tree

5 files changed

+114
-116
lines changed

5 files changed

+114
-116
lines changed

common/util.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ func MustInt64(s string) int64 {
4949
return n
5050
}
5151

52+
// GetInt64 returns the data for the given key and cast it to int64
53+
func GetInt64(d *schema.ResourceData, key string) int64 {
54+
return int64(d.Get(key).(int))
55+
}
56+
5257
// Reads the file content from a given path
5358
func ReadFileContent(source string) ([]byte, error) {
5459
log.Printf("[INFO] Reading %s", source)

mws/resource_mws_permission_assignment.go

Lines changed: 38 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -2,131 +2,90 @@ package mws
22

33
import (
44
"context"
5-
"errors"
65
"fmt"
76

87
"github.com/databricks/databricks-sdk-go/apierr"
8+
"github.com/databricks/databricks-sdk-go/service/iam"
99
"github.com/databricks/terraform-provider-databricks/common"
1010
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1111
)
1212

13-
func NewPermissionAssignmentAPI(ctx context.Context, m any) PermissionAssignmentAPI {
14-
return PermissionAssignmentAPI{m.(*common.DatabricksClient), ctx}
15-
}
16-
17-
type PermissionAssignmentAPI struct {
18-
client *common.DatabricksClient
19-
context context.Context
20-
}
21-
22-
type Permissions struct {
23-
Permissions []string `json:"permissions"`
24-
}
25-
26-
func (a PermissionAssignmentAPI) CreateOrUpdate(workspaceId, principalId int64, r Permissions) error {
27-
if a.client.Config.AccountID == "" {
28-
return errors.New("must have `account_id` on provider")
29-
}
30-
path := fmt.Sprintf(
31-
"/accounts/%s/workspaces/%d/permissionassignments/principals/%d",
32-
a.client.Config.AccountID, workspaceId, principalId)
33-
return a.client.Put(a.context, path, r)
34-
}
35-
36-
func (a PermissionAssignmentAPI) Remove(workspaceId, principalId string) error {
37-
if a.client.Config.AccountID == "" {
38-
return errors.New("must have `account_id` on provider")
39-
}
40-
path := fmt.Sprintf(
41-
"/accounts/%s/workspaces/%s/permissionassignments/principals/%s",
42-
a.client.Config.AccountID, workspaceId, principalId)
43-
return a.client.Delete(a.context, path, nil)
44-
}
45-
46-
type Principal struct {
47-
DisplayName string `json:"display_name"`
48-
PrincipalID int64 `json:"principal_id"`
49-
ServicePrincipalName string `json:"service_principal_name,omitempty"`
50-
UserName string `json:"user_name,omitempty"`
51-
GroupName string `json:"group_name,omitempty"`
52-
}
53-
54-
type PermissionAssignment struct {
55-
Permissions []string `json:"permissions"`
56-
Principal Principal
57-
}
58-
59-
type PermissionAssignmentList struct {
60-
PermissionAssignments []PermissionAssignment `json:"permission_assignments"`
61-
}
62-
63-
func (l PermissionAssignmentList) ForPrincipal(principalId int64) (res Permissions, err error) {
64-
for _, v := range l.PermissionAssignments {
65-
if v.Principal.PrincipalID != principalId {
13+
func getPermissionsByPrincipal(list iam.PermissionAssignments, principalId int64) (res iam.UpdateWorkspaceAssignments, err error) {
14+
for _, v := range list.PermissionAssignments {
15+
if v.Principal.PrincipalId != principalId {
6616
continue
6717
}
68-
return Permissions{v.Permissions}, nil
18+
return iam.UpdateWorkspaceAssignments{Permissions: v.Permissions}, nil
6919
}
7020
return res, apierr.NotFound(fmt.Sprintf("%d not found", principalId))
7121
}
7222

73-
func (a PermissionAssignmentAPI) List(workspaceId int64) (list PermissionAssignmentList, err error) {
74-
if a.client.Config.AccountID == "" {
75-
return list, errors.New("must have `account_id` on provider")
76-
}
77-
path := fmt.Sprintf("/accounts/%s/workspaces/%d/permissionassignments",
78-
a.client.Config.AccountID, workspaceId)
79-
err = a.client.Get(a.context, path, nil, &list)
80-
return
81-
}
82-
8323
func ResourceMwsPermissionAssignment() common.Resource {
84-
type entity struct {
85-
WorkspaceId int64 `json:"workspace_id"`
86-
PrincipalId int64 `json:"principal_id"`
87-
Permissions []string `json:"permissions" tf:"slice_as_set"`
88-
}
89-
s := common.StructToSchema(entity{},
90-
common.NoCustomize)
24+
s := common.StructToSchema(iam.UpdateWorkspaceAssignments{},
25+
func(m map[string]*schema.Schema) map[string]*schema.Schema {
26+
common.CustomizeSchemaPath(m).AddNewField("workspace_id", &schema.Schema{
27+
Type: schema.TypeInt,
28+
Required: true,
29+
}).AddNewField("principal_id", &schema.Schema{
30+
Type: schema.TypeInt,
31+
Required: true,
32+
})
33+
common.CustomizeSchemaPath(m, "permissions").SetRequired().SetSliceSet()
34+
return m
35+
})
9136
pair := common.NewPairID("workspace_id", "principal_id").Schema(
9237
func(m map[string]*schema.Schema) map[string]*schema.Schema {
9338
return s
9439
})
9540
return common.Resource{
9641
Schema: s,
9742
Create: func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error {
98-
var assignment entity
43+
acc, err := c.AccountClient()
44+
if err != nil {
45+
return err
46+
}
47+
var assignment iam.UpdateWorkspaceAssignments
9948
common.DataToStructPointer(d, s, &assignment)
100-
api := NewPermissionAssignmentAPI(ctx, c)
101-
err := api.CreateOrUpdate(assignment.WorkspaceId, assignment.PrincipalId,
102-
Permissions{assignment.Permissions})
49+
assignment.PrincipalId = common.GetInt64(d, "principal_id")
50+
assignment.WorkspaceId = common.GetInt64(d, "workspace_id")
51+
_, err = acc.WorkspaceAssignment.Update(ctx, assignment)
10352
if err != nil {
10453
return err
10554
}
10655
pair.Pack(d)
10756
return nil
10857
},
10958
Read: func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error {
59+
acc, err := c.AccountClient()
60+
if err != nil {
61+
return err
62+
}
11063
workspaceId, principalId, err := pair.Unpack(d)
11164
if err != nil {
11265
return fmt.Errorf("parse id: %w", err)
11366
}
114-
list, err := NewPermissionAssignmentAPI(ctx, c).List(common.MustInt64(workspaceId))
67+
list, err := acc.WorkspaceAssignment.ListByWorkspaceId(ctx, common.MustInt64(workspaceId))
11568
if err != nil {
11669
return err
11770
}
118-
permissions, err := list.ForPrincipal(common.MustInt64(principalId))
71+
permissions, err := getPermissionsByPrincipal(*list, common.MustInt64(principalId))
11972
if err != nil {
12073
return err
12174
}
75+
d.Set("workspace_id", common.MustInt64(workspaceId))
76+
d.Set("principal_id", common.MustInt64(principalId))
12277
return common.StructToData(permissions, s, d)
12378
},
12479
Delete: func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error {
80+
acc, err := c.AccountClient()
81+
if err != nil {
82+
return err
83+
}
12584
workspaceId, principalId, err := pair.Unpack(d)
12685
if err != nil {
12786
return fmt.Errorf("parse id: %w", err)
12887
}
129-
return NewPermissionAssignmentAPI(ctx, c).Remove(workspaceId, principalId)
88+
return acc.WorkspaceAssignment.DeleteByWorkspaceIdAndPrincipalId(ctx, common.MustInt64(workspaceId), common.MustInt64(principalId))
13089
},
13190
}
13291
}

mws/resource_mws_permission_assignment_test.go

Lines changed: 67 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,36 @@ package mws
33
import (
44
"testing"
55

6+
"github.com/databricks/databricks-sdk-go/experimental/mocks"
7+
"github.com/databricks/databricks-sdk-go/service/iam"
68
"github.com/databricks/terraform-provider-databricks/qa"
9+
"github.com/stretchr/testify/mock"
710
)
811

912
func TestPermissionAssignmentCreate(t *testing.T) {
1013
qa.ResourceFixture{
11-
Fixtures: []qa.HTTPFixture{
12-
{
13-
Method: "PUT",
14-
Resource: "/api/2.0/accounts/abc/workspaces/123/permissionassignments/principals/345",
15-
ExpectedRequest: Permissions{
16-
Permissions: []string{"USER"},
14+
MockAccountClientFunc: func(m *mocks.MockAccountClient) {
15+
e := m.GetMockWorkspaceAssignmentAPI().EXPECT()
16+
e.Update(mock.Anything, iam.UpdateWorkspaceAssignments{
17+
Permissions: []iam.WorkspacePermission{iam.WorkspacePermissionUser},
18+
PrincipalId: 345,
19+
WorkspaceId: 123,
20+
}).Return(&iam.PermissionAssignment{
21+
Permissions: []iam.WorkspacePermission{iam.WorkspacePermissionUser},
22+
Principal: &iam.PrincipalOutput{
23+
PrincipalId: 345,
1724
},
18-
},
19-
{
20-
Method: "GET",
21-
Resource: "/api/2.0/accounts/abc/workspaces/123/permissionassignments",
22-
Response: PermissionAssignmentList{
23-
PermissionAssignments: []PermissionAssignment{
24-
{
25-
Permissions: []string{"USER"},
26-
Principal: Principal{
27-
PrincipalID: 345,
28-
},
25+
}, nil)
26+
e.ListByWorkspaceId(mock.Anything, int64(123)).Return(&iam.PermissionAssignments{
27+
PermissionAssignments: []iam.PermissionAssignment{
28+
{
29+
Permissions: []iam.WorkspacePermission{iam.WorkspacePermissionUser},
30+
Principal: &iam.PrincipalOutput{
31+
PrincipalId: 345,
2932
},
3033
},
3134
},
32-
},
35+
}, nil)
3336
},
3437
Resource: ResourceMwsPermissionAssignment(),
3538
Create: true,
@@ -42,23 +45,53 @@ func TestPermissionAssignmentCreate(t *testing.T) {
4245
}.ApplyNoError(t)
4346
}
4447

48+
func TestPermissionAssignmentRead(t *testing.T) {
49+
qa.ResourceFixture{
50+
MockAccountClientFunc: func(m *mocks.MockAccountClient) {
51+
e := m.GetMockWorkspaceAssignmentAPI().EXPECT()
52+
e.ListByWorkspaceId(mock.Anything, int64(123)).Return(&iam.PermissionAssignments{
53+
PermissionAssignments: []iam.PermissionAssignment{
54+
{
55+
Permissions: []iam.WorkspacePermission{iam.WorkspacePermissionUser},
56+
Principal: &iam.PrincipalOutput{
57+
PrincipalId: 345,
58+
},
59+
},
60+
{
61+
Permissions: []iam.WorkspacePermission{iam.WorkspacePermissionUser},
62+
Principal: &iam.PrincipalOutput{
63+
PrincipalId: 456,
64+
},
65+
},
66+
},
67+
}, nil)
68+
},
69+
Resource: ResourceMwsPermissionAssignment(),
70+
Read: true,
71+
New: true,
72+
AccountID: "abc",
73+
ID: "123|456",
74+
}.ApplyAndExpectData(t, map[string]any{
75+
"workspace_id": 123,
76+
"principal_id": 456,
77+
"permissions": []string{"USER"},
78+
})
79+
}
80+
4581
func TestPermissionAssignmentReadNotFound(t *testing.T) {
4682
qa.ResourceFixture{
47-
Fixtures: []qa.HTTPFixture{
48-
{
49-
Method: "GET",
50-
Resource: "/api/2.0/accounts/abc/workspaces/123/permissionassignments",
51-
Response: PermissionAssignmentList{
52-
PermissionAssignments: []PermissionAssignment{
53-
{
54-
Permissions: []string{"USER"},
55-
Principal: Principal{
56-
PrincipalID: 345,
57-
},
83+
MockAccountClientFunc: func(m *mocks.MockAccountClient) {
84+
e := m.GetMockWorkspaceAssignmentAPI().EXPECT()
85+
e.ListByWorkspaceId(mock.Anything, int64(123)).Return(&iam.PermissionAssignments{
86+
PermissionAssignments: []iam.PermissionAssignment{
87+
{
88+
Permissions: []iam.WorkspacePermission{iam.WorkspacePermissionUser},
89+
Principal: &iam.PrincipalOutput{
90+
PrincipalId: 345,
5891
},
5992
},
6093
},
61-
},
94+
}, nil)
6295
},
6396
Resource: ResourceMwsPermissionAssignment(),
6497
Read: true,
@@ -70,11 +103,9 @@ func TestPermissionAssignmentReadNotFound(t *testing.T) {
70103

71104
func TestPermissionAssignmentDelete(t *testing.T) {
72105
qa.ResourceFixture{
73-
Fixtures: []qa.HTTPFixture{
74-
{
75-
Method: "DELETE",
76-
Resource: "/api/2.0/accounts/abc/workspaces/123/permissionassignments/principals/456",
77-
},
106+
MockAccountClientFunc: func(m *mocks.MockAccountClient) {
107+
e := m.GetMockWorkspaceAssignmentAPI().EXPECT()
108+
e.DeleteByWorkspaceIdAndPrincipalId(mock.Anything, int64(123), int64(456)).Return(nil)
78109
},
79110
Resource: ResourceMwsPermissionAssignment(),
80111
Delete: true,
@@ -86,7 +117,7 @@ func TestPermissionAssignmentDelete(t *testing.T) {
86117
func TestPermissionAssignmentFuzz_NoAccountID(t *testing.T) {
87118
qa.ResourceCornerCases(t, ResourceMwsPermissionAssignment(),
88119
qa.CornerCaseID("123|456"),
89-
qa.CornerCaseExpectError("must have `account_id` on provider"))
120+
qa.CornerCaseExpectError("invalid Databricks Account configuration"))
90121
}
91122

92123
func TestPermissionAssignmentFuzz_InvalidID(t *testing.T) {

qa/testing.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ func ResourceCornerCases(t *testing.T, resource common.Resource, cc ...CornerCas
458458
}
459459
HTTPFixturesApply(t, HTTPFailures, func(ctx context.Context, client *common.DatabricksClient) {
460460
validData := r.TestResourceData()
461-
client.Config.AccountID = config["account_id"]
461+
client.Config.WithTesting().AccountID = config["account_id"]
462462
for n, v := range m {
463463
if v == nil {
464464
continue

test-config.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ ignored_tests:
1212
- package: github.com/databricks/terraform-provider-databricks/internal/acceptance
1313
test_name: TestMwsAccServicePrincipalResourceOnAws
1414
comment: Failures due to read-after-write inconsistency. Tracked in https://databricks.atlassian.net/browse/ES-1100061
15+
- package: github.com/databricks/terraform-provider-databricks/internal/acceptance
16+
test_name: TestUcAccAssignGroupToWorkspace
17+
comment: Failures due to read-after-write inconsistency. Tracked in https://databricks.atlassian.net/browse/ES-1100061

0 commit comments

Comments
 (0)