github.com/chnsz/golangsdk@v0.0.0-20240506093406-85a3fbfa605b/openstack/identity/v3/roles/requests.go (about) 1 package roles 2 3 import ( 4 "github.com/chnsz/golangsdk" 5 "github.com/chnsz/golangsdk/pagination" 6 ) 7 8 // ListOptsBuilder allows extensions to add additional parameters to 9 // the List request 10 type ListOptsBuilder interface { 11 ToRoleListQuery() (string, error) 12 } 13 14 // ListOpts provides options to filter the List results. 15 type ListOpts struct { 16 // DomainID filters the response by a domain ID. 17 // If this parameter is specified, only custom policies of the account will be returned. 18 // If not specified, all system permissions (including system-defined policies and roles) will be returned. 19 DomainID string `q:"domain_id"` 20 21 // Name filters the response by role name. 22 Name string `q:"name"` 23 24 DisplayName string `q:"display_name"` 25 26 // This parameter is valid only when domain_id is left blank. 27 // policy: system-defined policy; role: system-defined role 28 PermissionType string `q:"permission_type"` 29 30 // The number of pages of data for paging query, the minimum value is 1. 31 // Need to exist at the same time as "PerPage" parameter. When the "DomainID" parameter is passed in to query the 32 // custom policies, it can be used together. 33 Page int `q:"page"` 34 35 // The number of data per page in paging query, the value range is from 1 to 300, the default value is 300. 36 // It needs to exist at the same time as "Page" parameter. When the "Page" and "PerPage" parameters are not passed, 37 // a maximum of 300 permissions are returned per page. 38 PerPage int `q:"per_page"` 39 40 // Display mode of the permission. The options include domain, project, and all. 41 Type string `q:"type"` 42 43 // Service catalog, which corresponds to the catalog field in policies. 44 Catalog string `q:"catalog"` 45 } 46 47 // ToRoleListQuery formats a ListOpts into a query string. 48 func (opts ListOpts) ToRoleListQuery() (string, error) { 49 q, err := golangsdk.BuildQueryString(opts) 50 return q.String(), err 51 } 52 53 // List enumerates the roles to which the current token has access. 54 // 55 // Deprecated: AllPages will not work due to the links.next field is always null in API response. 56 // please use ListWithPages instead. 57 func List(client *golangsdk.ServiceClient, opts ListOptsBuilder) pagination.Pager { 58 url := listURL(client) 59 if opts != nil { 60 query, err := opts.ToRoleListQuery() 61 if err != nil { 62 return pagination.Pager{Err: err} 63 } 64 url += query 65 } 66 67 return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { 68 return RolePage{pagination.LinkedPageBase{PageResult: r}} 69 }) 70 } 71 72 // ListWithPages is a method to query role pages via page size and page number. 73 func ListWithPages(client *golangsdk.ServiceClient, opts ListOpts) pagination.Pager { 74 url := listURL(client) 75 if opts.PerPage == 0 { 76 opts.PerPage = 300 77 } 78 if opts.Page == 0 { 79 opts.Page = 1 80 } 81 82 query, err := opts.ToRoleListQuery() 83 if err != nil { 84 return pagination.Pager{Err: err} 85 } 86 url += query 87 88 return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { 89 return RoleOffsetPage{pagination.OffsetPageBase{PageResult: r}} 90 }) 91 } 92 93 // Get retrieves details on a single role, by ID. 94 func Get(client *golangsdk.ServiceClient, id string) (r GetResult) { 95 _, r.Err = client.Get(getURL(client, id), &r.Body, nil) 96 return 97 } 98 99 // CreateOptsBuilder allows extensions to add additional parameters to 100 // the Create request. 101 type CreateOptsBuilder interface { 102 ToRoleCreateMap() (map[string]interface{}, error) 103 } 104 105 // CreateOpts provides options used to create a role. 106 type CreateOpts struct { 107 // Name is the name of the new role. 108 Name string `json:"name" required:"true"` 109 110 // DomainID is the ID of the domain the role belongs to. 111 DomainID string `json:"domain_id,omitempty"` 112 113 // Extra is free-form extra key/value pairs to describe the role. 114 Extra map[string]interface{} `json:"-"` 115 } 116 117 // ToRoleCreateMap formats a CreateOpts into a create request. 118 func (opts CreateOpts) ToRoleCreateMap() (map[string]interface{}, error) { 119 b, err := golangsdk.BuildRequestBody(opts, "role") 120 if err != nil { 121 return nil, err 122 } 123 124 if opts.Extra != nil { 125 if v, ok := b["role"].(map[string]interface{}); ok { 126 for key, value := range opts.Extra { 127 v[key] = value 128 } 129 } 130 } 131 132 return b, nil 133 } 134 135 // Create creates a new Role. 136 func Create(client *golangsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { 137 b, err := opts.ToRoleCreateMap() 138 if err != nil { 139 r.Err = err 140 return 141 } 142 _, r.Err = client.Post(createURL(client), &b, &r.Body, &golangsdk.RequestOpts{ 143 OkCodes: []int{201}, 144 }) 145 return 146 } 147 148 // UpdateOptsBuilder allows extensions to add additional parameters to 149 // the Update request. 150 type UpdateOptsBuilder interface { 151 ToRoleUpdateMap() (map[string]interface{}, error) 152 } 153 154 // UpdateOpts provides options for updating a role. 155 type UpdateOpts struct { 156 // Name is the name of the new role. 157 Name string `json:"name,omitempty"` 158 159 // Extra is free-form extra key/value pairs to describe the role. 160 Extra map[string]interface{} `json:"-"` 161 } 162 163 // ToRoleUpdateMap formats a UpdateOpts into an update request. 164 func (opts UpdateOpts) ToRoleUpdateMap() (map[string]interface{}, error) { 165 b, err := golangsdk.BuildRequestBody(opts, "role") 166 if err != nil { 167 return nil, err 168 } 169 170 if opts.Extra != nil { 171 if v, ok := b["role"].(map[string]interface{}); ok { 172 for key, value := range opts.Extra { 173 v[key] = value 174 } 175 } 176 } 177 178 return b, nil 179 } 180 181 // Update updates an existing Role. 182 func Update(client *golangsdk.ServiceClient, roleID string, opts UpdateOptsBuilder) (r UpdateResult) { 183 b, err := opts.ToRoleUpdateMap() 184 if err != nil { 185 r.Err = err 186 return 187 } 188 _, r.Err = client.Patch(updateURL(client, roleID), &b, &r.Body, &golangsdk.RequestOpts{ 189 OkCodes: []int{200}, 190 }) 191 return 192 } 193 194 // Delete deletes a role. 195 func Delete(client *golangsdk.ServiceClient, roleID string) (r DeleteResult) { 196 _, r.Err = client.Delete(deleteURL(client, roleID), nil) 197 return 198 } 199 200 // ListAssignmentsOptsBuilder allows extensions to add additional parameters to 201 // the ListAssignments request. 202 type ListAssignmentsOptsBuilder interface { 203 extractAssignment() (string, string, string, string, error) 204 } 205 206 // ListAssignmentsOpts allows you to query the ListAssignments method. 207 // Specify one of or a combination of GroupId, RoleId, ScopeDomainId, 208 // ScopeProjectId, and/or UserId to search for roles assigned to corresponding 209 // entities. 210 type ListAssignmentsOpts struct { 211 // GroupID is the group ID to query. 212 GroupID string `q:"group.id"` 213 214 // ScopeDomainID filters the results by the given domain ID. 215 ScopeDomainID string `q:"scope.domain.id"` 216 217 // ScopeProjectID filters the results by the given Project ID. 218 ScopeProjectID string `q:"scope.project.id"` 219 220 // UserID filterst he results by the given User ID. 221 UserID string `q:"user.id"` 222 } 223 224 // ToRolesListAssignmentsQuery formats a ListAssignmentsOpts into a query string. 225 func (opts ListAssignmentsOpts) extractAssignment() (string, string, string, string, error) { 226 // Get corresponding URL 227 var targetID string 228 var targetType string 229 if opts.ScopeProjectID != "" { 230 targetID = opts.ScopeProjectID 231 targetType = "projects" 232 } else { 233 targetID = opts.ScopeDomainID 234 targetType = "domains" 235 } 236 237 var actorID string 238 var actorType string 239 if opts.UserID != "" { 240 actorID = opts.UserID 241 actorType = "users" 242 } else { 243 actorID = opts.GroupID 244 actorType = "groups" 245 } 246 247 return targetType, targetID, actorType, actorID, nil 248 } 249 250 // ListAssignments enumerates the roles assigned to a specified resource. 251 func ListAssignments(client *golangsdk.ServiceClient, opts ListAssignmentsOptsBuilder) pagination.Pager { 252 targetType, targetID, actorType, actorID, _ := opts.extractAssignment() 253 254 url := listAssignmentsURL(client, targetType, targetID, actorType, actorID) 255 return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { 256 return RoleAssignmentPage{pagination.LinkedPageBase{PageResult: r}} 257 }) 258 } 259 260 // AssignOpts provides options to assign a role 261 type AssignOpts struct { 262 // UserID is the ID of a user to assign a role 263 // Note: exactly one of UserID or GroupID must be provided 264 UserID string `xor:"GroupID"` 265 266 // GroupID is the ID of a group to assign a role 267 // Note: exactly one of UserID or GroupID must be provided 268 GroupID string `xor:"UserID"` 269 270 // ProjectID is the ID of a project to assign a role on 271 // Note: exactly one of ProjectID or DomainID must be provided 272 ProjectID string `xor:"DomainID"` 273 274 // DomainID is the ID of a domain to assign a role on 275 // Note: exactly one of ProjectID or DomainID must be provided 276 DomainID string `xor:"ProjectID"` 277 } 278 279 // UnassignOpts provides options to unassign a role 280 type UnassignOpts struct { 281 // UserID is the ID of a user to unassign a role 282 // Note: exactly one of UserID or GroupID must be provided 283 UserID string `xor:"GroupID"` 284 285 // GroupID is the ID of a group to unassign a role 286 // Note: exactly one of UserID or GroupID must be provided 287 GroupID string `xor:"UserID"` 288 289 // ProjectID is the ID of a project to unassign a role on 290 // Note: exactly one of ProjectID or DomainID must be provided 291 ProjectID string `xor:"DomainID"` 292 293 // DomainID is the ID of a domain to unassign a role on 294 // Note: exactly one of ProjectID or DomainID must be provided 295 DomainID string `xor:"ProjectID"` 296 } 297 298 // Assign is the operation responsible for assigning a role 299 // to a user/group on a project/domain. 300 func Assign(client *golangsdk.ServiceClient, roleID string, opts AssignOpts) (r AssignmentResult) { 301 // Check xor conditions 302 _, err := golangsdk.BuildRequestBody(opts, "") 303 if err != nil { 304 r.Err = err 305 return 306 } 307 308 // Get corresponding URL 309 var targetID string 310 var targetType string 311 if opts.ProjectID != "" { 312 targetID = opts.ProjectID 313 targetType = "projects" 314 } else { 315 targetID = opts.DomainID 316 targetType = "domains" 317 } 318 319 var actorID string 320 var actorType string 321 if opts.UserID != "" { 322 actorID = opts.UserID 323 actorType = "users" 324 } else { 325 actorID = opts.GroupID 326 actorType = "groups" 327 } 328 329 _, r.Err = client.Put(assignURL(client, targetType, targetID, actorType, actorID, roleID), nil, nil, &golangsdk.RequestOpts{ 330 OkCodes: []int{204}, 331 }) 332 return 333 } 334 335 // Unassign is the operation responsible for unassigning a role 336 // from a user/group on a project/domain. 337 func Unassign(client *golangsdk.ServiceClient, roleID string, opts UnassignOpts) (r UnassignmentResult) { 338 // Check xor conditions 339 _, err := golangsdk.BuildRequestBody(opts, "") 340 if err != nil { 341 r.Err = err 342 return 343 } 344 345 // Get corresponding URL 346 var targetID string 347 var targetType string 348 if opts.ProjectID != "" { 349 targetID = opts.ProjectID 350 targetType = "projects" 351 } else { 352 targetID = opts.DomainID 353 targetType = "domains" 354 } 355 356 var actorID string 357 var actorType string 358 if opts.UserID != "" { 359 actorID = opts.UserID 360 actorType = "users" 361 } else { 362 actorID = opts.GroupID 363 actorType = "groups" 364 } 365 366 _, r.Err = client.Delete(assignURL(client, targetType, targetID, actorType, actorID, roleID), &golangsdk.RequestOpts{ 367 OkCodes: []int{204}, 368 }) 369 return 370 } 371 372 // AssignAllResources is the operation responsible for granting a user group permissions for all resources, 373 // including those in enterprise projects, region-specific projects, and global services. 374 func AssignAllResources(client *golangsdk.ServiceClient, domainID, groupID, roleID string) (r AssignmentResult) { 375 _, r.Err = client.Put(assignInheritedURL(client, domainID, groupID, roleID), nil, nil, &golangsdk.RequestOpts{ 376 OkCodes: []int{204}, 377 }) 378 return 379 } 380 381 // UnassignAllResources is the operation responsible for unassigning a user group permissions for all resources. 382 func UnassignAllResources(client *golangsdk.ServiceClient, domainID, groupID, roleID string) (r AssignmentResult) { 383 _, r.Err = client.Delete(assignInheritedURL(client, domainID, groupID, roleID), &golangsdk.RequestOpts{ 384 OkCodes: []int{204}, 385 }) 386 return 387 } 388 389 // CheckAllResourcesPermission is provided for the administrator to check whether a user group has specified permissions for all resources. 390 func CheckAllResourcesPermission(client *golangsdk.ServiceClient, domainID, groupID, roleID string) (r CheckResult) { 391 _, r.Err = client.Head(assignInheritedURL(client, domainID, groupID, roleID), &golangsdk.RequestOpts{ 392 OkCodes: []int{204}, 393 }) 394 return 395 }