@@ -2,7 +2,10 @@ package access
22
33import (
44 "context"
5+ "errors"
56 "fmt"
7+ "net/http"
8+ "strconv"
69
710 "github.com/databricks/databricks-sdk-go/apierr"
811 "github.com/databricks/terraform-provider-databricks/common"
@@ -22,39 +25,89 @@ type Permissions struct {
2225 Permissions []string `json:"permissions"`
2326}
2427
25- func (a PermissionAssignmentAPI ) CreateOrUpdate (principalId int64 , r Permissions ) error {
26- path := fmt .Sprintf ("/preview/permissionassignments/principals/%d" , principalId )
27- return a .client .Put (a .context , path , r )
28+ func (a PermissionAssignmentAPI ) CreateOrUpdate (assignment permissionAssignmentEntity ) (principalInfo , error ) {
29+ if assignment .PrincipalId != 0 {
30+ var resp permissionAssignmentResponseItem
31+ path := fmt .Sprintf ("/api/2.0/preview/permissionassignments/principals/%d" , assignment .PrincipalId )
32+ err := a .client .Do (a .context , http .MethodPut , path , nil , nil ,
33+ Permissions {Permissions : assignment .Permissions }, & resp )
34+ if err == nil && resp .Error != "" {
35+ err = errors .New (resp .Error )
36+ }
37+ return resp .Principal , err
38+ } else {
39+ var principal permissionAssignmentResponse
40+ request := permissionAssignmentRequest {
41+ PermissionAssignments : []permissionAssignmentRequestItem {
42+ {
43+ principalInfo : principalInfo {
44+ ServicePrincipalName : assignment .ServicePrincipalName ,
45+ UserName : assignment .UserName ,
46+ GroupName : assignment .GroupName ,
47+ },
48+ Permissions : assignment .Permissions ,
49+ },
50+ },
51+ }
52+ err := a .client .Post (a .context , "/preview/permissionassignments" , request , & principal )
53+ if err != nil {
54+ return principalInfo {}, err
55+ }
56+ if len (principal .PermissionAssignments ) == 0 {
57+ return principalInfo {}, fmt .Errorf ("no permission assignment found" )
58+ }
59+ if principal .PermissionAssignments [0 ].Error != "" {
60+ return principalInfo {}, errors .New (principal .PermissionAssignments [0 ].Error )
61+ }
62+ return principal .PermissionAssignments [0 ].Principal , nil
63+ }
2864}
2965
3066func (a PermissionAssignmentAPI ) Remove (principalId string ) error {
3167 path := fmt .Sprintf ("/preview/permissionassignments/principals/%s" , principalId )
3268 return a .client .Delete (a .context , path , nil )
3369}
3470
35- type Principal struct {
36- DisplayName string `json:"display_name"`
37- PrincipalID int64 `json:"principal_id"`
71+ type principalInfo struct {
72+ DisplayName string `json:"display_name,omitempty "`
73+ PrincipalID int64 `json:"principal_id,omitempty "`
3874 ServicePrincipalName string `json:"service_principal_name,omitempty"`
3975 UserName string `json:"user_name,omitempty"`
4076 GroupName string `json:"group_name,omitempty"`
4177}
4278
43- type PermissionAssignment struct {
79+ type permissionAssignmentRequestItem struct {
80+ principalInfo
4481 Permissions []string `json:"permissions"`
45- Principal Principal
4682}
4783
48- type PermissionAssignmentList struct {
49- PermissionAssignments []PermissionAssignment `json:"permission_assignments"`
84+ type permissionAssignmentRequest struct {
85+ PermissionAssignments []permissionAssignmentRequestItem `json:"permission_assignments"`
5086}
5187
52- func (l PermissionAssignmentList ) ForPrincipal (principalId int64 ) (res Permissions , err error ) {
88+ type permissionAssignmentResponseItem struct {
89+ Permissions []string `json:"permissions"`
90+ Principal principalInfo
91+ Error string `json:"error,omitempty"`
92+ }
93+
94+ type permissionAssignmentResponse struct {
95+ PermissionAssignments []permissionAssignmentResponseItem `json:"permission_assignments"`
96+ }
97+
98+ func (l permissionAssignmentResponse ) ForPrincipal (principalId int64 ) (res permissionAssignmentEntity , err error ) {
5399 for _ , v := range l .PermissionAssignments {
54100 if v .Principal .PrincipalID != principalId {
55101 continue
56102 }
57- return Permissions {v .Permissions }, nil
103+ return permissionAssignmentEntity {
104+ PrincipalId : v .Principal .PrincipalID ,
105+ ServicePrincipalName : v .Principal .ServicePrincipalName ,
106+ UserName : v .Principal .UserName ,
107+ GroupName : v .Principal .GroupName ,
108+ Permissions : v .Permissions ,
109+ DisplayName : v .Principal .DisplayName ,
110+ }, nil
58111 }
59112 return res , & apierr.APIError {
60113 ErrorCode : "NOT_FOUND" ,
@@ -63,48 +116,63 @@ func (l PermissionAssignmentList) ForPrincipal(principalId int64) (res Permissio
63116 }
64117}
65118
66- func (a PermissionAssignmentAPI ) List () (list PermissionAssignmentList , err error ) {
119+ func (a PermissionAssignmentAPI ) List () (list permissionAssignmentResponse , err error ) {
67120 err = a .client .Get (a .context , "/preview/permissionassignments" , nil , & list )
68121 return
69122}
70123
124+ type permissionAssignmentEntity struct {
125+ PrincipalId int64 `json:"principal_id,omitempty" tf:"computed,force_new"`
126+ ServicePrincipalName string `json:"service_principal_name,omitempty" tf:"computed,force_new"`
127+ UserName string `json:"user_name,omitempty" tf:"computed,force_new"`
128+ GroupName string `json:"group_name,omitempty" tf:"computed,force_new"`
129+ Permissions []string `json:"permissions" tf:"slice_as_set"`
130+ DisplayName string `json:"display_name" tf:"computed"`
131+ }
132+
71133// ResourcePermissionAssignment performs of users to a workspace
72134// from a workspace context, though it requires additional set
73135// data resource for "workspace account scim", whicl will be added later.
74136func ResourcePermissionAssignment () common.Resource {
75- type entity struct {
76- PrincipalId int64 `json:"principal_id"`
77- Permissions []string `json:"permissions" tf:"slice_as_set"`
78- }
79- s := common .StructToSchema (entity {}, common .NoCustomize )
137+ s := common .StructToSchema (permissionAssignmentEntity {}, func (s map [string ]* schema.Schema ) map [string ]* schema.Schema {
138+ fields := []string {"principal_id" , "service_principal_name" , "user_name" , "group_name" }
139+ for _ , field := range fields {
140+ s [field ].ExactlyOneOf = fields
141+ }
142+ common .CustomizeSchemaPath (s , "display_name" ).SetReadOnly ()
143+ return s
144+ })
80145 return common.Resource {
81146 Schema : s ,
82147 Create : func (ctx context.Context , d * schema.ResourceData , c * common.DatabricksClient ) error {
83- var assignment entity
148+ var assignment permissionAssignmentEntity
84149 common .DataToStructPointer (d , s , & assignment )
85150 api := NewPermissionAssignmentAPI (ctx , c )
86- err := api .CreateOrUpdate (assignment . PrincipalId , Permissions { assignment . Permissions } )
151+ principal , err := api .CreateOrUpdate (assignment )
87152 if err != nil {
88153 return err
89154 }
90- d .SetId (fmt . Sprintf ( "%d" , assignment . PrincipalId ))
155+ d .SetId (strconv . FormatInt ( principal . PrincipalID , 10 ))
91156 return nil
92157 },
93158 Read : func (ctx context.Context , d * schema.ResourceData , c * common.DatabricksClient ) error {
94159 list , err := NewPermissionAssignmentAPI (ctx , c ).List ()
95160 if err != nil {
96161 return err
97162 }
98- data := entity {
99- PrincipalId : common .MustInt64 (d .Id ()),
100- }
101- permissions , err := list .ForPrincipal (data .PrincipalId )
163+ data , err := list .ForPrincipal (common .MustInt64 (d .Id ()))
102164 if err != nil {
103165 return err
104166 }
105- data .Permissions = permissions .Permissions
106167 return common .StructToData (data , s , d )
107168 },
169+ Update : func (ctx context.Context , d * schema.ResourceData , c * common.DatabricksClient ) error {
170+ var assignment permissionAssignmentEntity
171+ common .DataToStructPointer (d , s , & assignment )
172+ api := NewPermissionAssignmentAPI (ctx , c )
173+ _ , err := api .CreateOrUpdate (assignment )
174+ return err
175+ },
108176 Delete : func (ctx context.Context , d * schema.ResourceData , c * common.DatabricksClient ) error {
109177 return NewPermissionAssignmentAPI (ctx , c ).Remove (d .Id ())
110178 },
0 commit comments