github.com/vmware/go-vcloud-director/v2@v2.24.0/govcd/global_role.go (about) 1 /* 2 * Copyright 2021 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. 3 */ 4 5 package govcd 6 7 import ( 8 "fmt" 9 "net/url" 10 11 "github.com/vmware/go-vcloud-director/v2/types/v56" 12 ) 13 14 type GlobalRole struct { 15 GlobalRole *types.GlobalRole 16 client *Client 17 } 18 19 // GetAllGlobalRoles retrieves all global roles. Query parameters can be supplied to perform additional filtering 20 // Only System administrator can handle global roles 21 func (client *Client) GetAllGlobalRoles(queryParameters url.Values) ([]*GlobalRole, error) { 22 if !client.IsSysAdmin { 23 return nil, fmt.Errorf("only system administrator can handle global roles") 24 } 25 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles 26 minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint) 27 if err != nil { 28 return nil, err 29 } 30 31 urlRef, err := client.OpenApiBuildEndpoint(endpoint) 32 if err != nil { 33 return nil, err 34 } 35 36 typeResponses := []*types.GlobalRole{{}} 37 err = client.OpenApiGetAllItems(minimumApiVersion, urlRef, queryParameters, &typeResponses, nil) 38 if err != nil { 39 return nil, err 40 } 41 42 // Wrap all typeResponses into GlobalRole types with client 43 returnGlobalRoles := make([]*GlobalRole, len(typeResponses)) 44 for sliceIndex := range typeResponses { 45 returnGlobalRoles[sliceIndex] = &GlobalRole{ 46 GlobalRole: typeResponses[sliceIndex], 47 client: client, 48 } 49 } 50 51 return returnGlobalRoles, nil 52 } 53 54 // GetGlobalRoleByName retrieves a global role by given name 55 func (client *Client) GetGlobalRoleByName(name string) (*GlobalRole, error) { 56 queryParams := url.Values{} 57 queryParams.Add("filter", "name=="+name) 58 globalRoles, err := client.GetAllGlobalRoles(queryParams) 59 if err != nil { 60 return nil, err 61 } 62 if len(globalRoles) == 0 { 63 return nil, ErrorEntityNotFound 64 } 65 if len(globalRoles) > 1 { 66 return nil, fmt.Errorf("more than one global role found with name '%s'", name) 67 } 68 return globalRoles[0], nil 69 } 70 71 // GetGlobalRoleById retrieves global role by given ID 72 func (client *Client) GetGlobalRoleById(id string) (*GlobalRole, error) { 73 if !client.IsSysAdmin { 74 return nil, fmt.Errorf("only system administrator can handle global roles") 75 } 76 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles 77 minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint) 78 if err != nil { 79 return nil, err 80 } 81 82 if id == "" { 83 return nil, fmt.Errorf("empty GlobalRole id") 84 } 85 86 urlRef, err := client.OpenApiBuildEndpoint(endpoint, id) 87 if err != nil { 88 return nil, err 89 } 90 91 globalRole := &GlobalRole{ 92 GlobalRole: &types.GlobalRole{}, 93 client: client, 94 } 95 96 err = client.OpenApiGetItem(minimumApiVersion, urlRef, nil, globalRole.GlobalRole, nil) 97 if err != nil { 98 return nil, err 99 } 100 101 return globalRole, nil 102 } 103 104 // CreateGlobalRole creates a new global role as a system administrator 105 func (client *Client) CreateGlobalRole(newGlobalRole *types.GlobalRole) (*GlobalRole, error) { 106 if !client.IsSysAdmin { 107 return nil, fmt.Errorf("only system administrator can handle global roles") 108 } 109 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles 110 minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint) 111 if err != nil { 112 return nil, err 113 } 114 115 urlRef, err := client.OpenApiBuildEndpoint(endpoint) 116 if err != nil { 117 return nil, err 118 } 119 120 if newGlobalRole.BundleKey == "" { 121 newGlobalRole.BundleKey = types.VcloudUndefinedKey 122 } 123 if newGlobalRole.PublishAll == nil { 124 newGlobalRole.PublishAll = addrOf(false) 125 } 126 returnGlobalRole := &GlobalRole{ 127 GlobalRole: &types.GlobalRole{}, 128 client: client, 129 } 130 131 err = client.OpenApiPostItem(minimumApiVersion, urlRef, nil, newGlobalRole, returnGlobalRole.GlobalRole, nil) 132 if err != nil { 133 return nil, fmt.Errorf("error creating global role: %s", err) 134 } 135 136 return returnGlobalRole, nil 137 } 138 139 // Update updates existing global role 140 func (globalRole *GlobalRole) Update() (*GlobalRole, error) { 141 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles 142 minimumApiVersion, err := globalRole.client.checkOpenApiEndpointCompatibility(endpoint) 143 if err != nil { 144 return nil, err 145 } 146 147 if globalRole.GlobalRole.Id == "" { 148 return nil, fmt.Errorf("cannot update role without id") 149 } 150 151 urlRef, err := globalRole.client.OpenApiBuildEndpoint(endpoint, globalRole.GlobalRole.Id) 152 if err != nil { 153 return nil, err 154 } 155 156 returnGlobalRole := &GlobalRole{ 157 GlobalRole: &types.GlobalRole{}, 158 client: globalRole.client, 159 } 160 161 err = globalRole.client.OpenApiPutItem(minimumApiVersion, urlRef, nil, globalRole.GlobalRole, returnGlobalRole.GlobalRole, nil) 162 if err != nil { 163 return nil, fmt.Errorf("error updating global role: %s", err) 164 } 165 166 return returnGlobalRole, nil 167 } 168 169 // Delete deletes global role 170 func (globalRole *GlobalRole) Delete() error { 171 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles 172 minimumApiVersion, err := globalRole.client.checkOpenApiEndpointCompatibility(endpoint) 173 if err != nil { 174 return err 175 } 176 177 if globalRole.GlobalRole.Id == "" { 178 return fmt.Errorf("cannot delete global role without id") 179 } 180 181 urlRef, err := globalRole.client.OpenApiBuildEndpoint(endpoint, globalRole.GlobalRole.Id) 182 if err != nil { 183 return err 184 } 185 186 err = globalRole.client.OpenApiDeleteItem(minimumApiVersion, urlRef, nil, nil) 187 188 if err != nil { 189 return fmt.Errorf("error deleting global role: %s", err) 190 } 191 192 return nil 193 } 194 195 // getContainerTenants retrieves all tenants associated with a given rights container (Global Role, Rights Bundle). 196 // Query parameters can be supplied to perform additional filtering 197 func getContainerTenants(client *Client, rightsContainerId, endpoint string, queryParameters url.Values) ([]types.OpenApiReference, error) { 198 minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint) 199 if err != nil { 200 return nil, err 201 } 202 203 urlRef, err := client.OpenApiBuildEndpoint(endpoint + rightsContainerId + "/tenants") 204 if err != nil { 205 return nil, err 206 } 207 208 typeResponses := types.OpenApiItems{ 209 Values: []types.OpenApiReference{}, 210 } 211 212 err = client.OpenApiGetAllItems(minimumApiVersion, urlRef, queryParameters, &typeResponses.Values, nil) 213 if err != nil { 214 return nil, err 215 } 216 217 return typeResponses.Values, nil 218 } 219 220 // publishContainerToTenants is a generic function that publishes or unpublishes a rights collection (Global Role, or Rights bundle) to tenants 221 // containerType is an informative string (one of "GlobalRole", "RightsBundle") 222 // name and id are the name and ID of the collection 223 // endpoint is the API endpoint used as a basis for the POST operation 224 // tenants is a collection of tenants (ID+name) to be added 225 // publishType can be one of "add", "remove", "replace" 226 func publishContainerToTenants(client *Client, containerType, name, id, endpoint string, tenants []types.OpenApiReference, publishType string) error { 227 minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint) 228 if err != nil { 229 return err 230 } 231 232 if id == "" { 233 return fmt.Errorf("cannot update %s without id", containerType) 234 } 235 if name == "" { 236 return fmt.Errorf("empty name given for %s %s", containerType, id) 237 } 238 239 var operation string 240 241 var action func(apiVersion string, urlRef *url.URL, params url.Values, payload, outType interface{}, additionalHeader map[string]string) error 242 243 switch publishType { 244 case "add": 245 operation = "/tenants/publish" 246 action = client.OpenApiPostItem 247 case "replace": 248 operation = "/tenants" 249 action = client.OpenApiPutItem 250 case "remove": 251 operation = "/tenants/unpublish" 252 action = client.OpenApiPostItem 253 } 254 255 urlRef, err := client.OpenApiBuildEndpoint(endpoint, id, operation) 256 if err != nil { 257 return err 258 } 259 260 var input types.OpenApiItems 261 262 for _, tenant := range tenants { 263 input.Values = append(input.Values, types.OpenApiReference{ 264 Name: tenant.Name, 265 ID: tenant.ID, 266 }) 267 } 268 var pages types.OpenApiPages 269 270 err = action(minimumApiVersion, urlRef, nil, &input, &pages, nil) 271 272 if err != nil { 273 return fmt.Errorf("error publishing %s %s to tenants: %s", containerType, name, err) 274 } 275 276 return nil 277 } 278 279 // publishContainerToAllTenants is a generic function that publishes or unpublishes a rights collection ( Global Role, or Rights bundle) to all tenants 280 // containerType is an informative string (one of "GlobalRole", "RightsBundle") 281 // name and id are the name and ID of the collection 282 // endpoint is the API endpoint used as a basis for the POST operation 283 // If "publish" is false, it will revert the operation 284 func publishContainerToAllTenants(client *Client, containerType, name, id, endpoint string, publish bool) error { 285 minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint) 286 if err != nil { 287 return err 288 } 289 290 if id == "" { 291 return fmt.Errorf("cannot update %s without id", containerType) 292 } 293 if name == "" { 294 return fmt.Errorf("empty name given for %s %s", containerType, id) 295 } 296 297 operation := "/tenants/publishAll" 298 if !publish { 299 operation = "/tenants/unpublishAll" 300 } 301 urlRef, err := client.OpenApiBuildEndpoint(endpoint, id, operation) 302 if err != nil { 303 return err 304 } 305 306 var pages types.OpenApiPages 307 308 err = client.OpenApiPostItem(minimumApiVersion, urlRef, nil, &pages, &pages, nil) 309 310 if err != nil { 311 return fmt.Errorf("error publishing %s %s to tenants: %s", containerType, name, err) 312 } 313 314 return nil 315 } 316 317 // AddRights adds a collection of rights to a global role 318 func (globalRole *GlobalRole) AddRights(newRights []types.OpenApiReference) error { 319 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles 320 return addRightsToRole(globalRole.client, "GlobalRole", globalRole.GlobalRole.Name, globalRole.GlobalRole.Id, endpoint, newRights, nil) 321 } 322 323 // UpdateRights replaces existing rights with the given collection of rights 324 func (globalRole *GlobalRole) UpdateRights(newRights []types.OpenApiReference) error { 325 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles 326 return updateRightsInRole(globalRole.client, "GlobalRole", globalRole.GlobalRole.Name, globalRole.GlobalRole.Id, endpoint, newRights, nil) 327 } 328 329 // RemoveRights removes specific rights from a global role 330 func (globalRole *GlobalRole) RemoveRights(removeRights []types.OpenApiReference) error { 331 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles 332 return removeRightsFromRole(globalRole.client, "GlobalRole", globalRole.GlobalRole.Name, globalRole.GlobalRole.Id, endpoint, removeRights, nil) 333 } 334 335 // RemoveAllRights removes all rights from a global role 336 func (globalRole *GlobalRole) RemoveAllRights() error { 337 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles 338 return removeAllRightsFromRole(globalRole.client, "GlobalRole", globalRole.GlobalRole.Name, globalRole.GlobalRole.Id, endpoint, nil) 339 } 340 341 // GetRights retrieves all rights belonging to a given Global Role. Query parameters can be supplied to perform additional 342 // filtering 343 func (globalRole *GlobalRole) GetRights(queryParameters url.Values) ([]*types.Right, error) { 344 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles 345 return getRights(globalRole.client, globalRole.GlobalRole.Id, endpoint, queryParameters, nil) 346 } 347 348 // GetTenants retrieves all tenants associated to a given Global Role. Query parameters can be supplied to perform additional 349 // filtering 350 func (globalRole *GlobalRole) GetTenants(queryParameters url.Values) ([]types.OpenApiReference, error) { 351 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles 352 return getContainerTenants(globalRole.client, globalRole.GlobalRole.Id, endpoint, queryParameters) 353 } 354 355 // PublishTenants publishes a global role to one or more tenants, adding to tenants that may already been there 356 func (globalRole *GlobalRole) PublishTenants(tenants []types.OpenApiReference) error { 357 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles 358 return publishContainerToTenants(globalRole.client, "GlobalRole", globalRole.GlobalRole.Name, globalRole.GlobalRole.Id, endpoint, tenants, "add") 359 } 360 361 // ReplacePublishedTenants publishes a global role to one or more tenants, removing the tenants already present 362 func (globalRole *GlobalRole) ReplacePublishedTenants(tenants []types.OpenApiReference) error { 363 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles 364 return publishContainerToTenants(globalRole.client, "GlobalRole", globalRole.GlobalRole.Name, globalRole.GlobalRole.Id, endpoint, tenants, "replace") 365 } 366 367 // UnpublishTenants remove tenats from a global role 368 func (globalRole *GlobalRole) UnpublishTenants(tenants []types.OpenApiReference) error { 369 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles 370 return publishContainerToTenants(globalRole.client, "GlobalRole", globalRole.GlobalRole.Name, globalRole.GlobalRole.Id, endpoint, tenants, "remove") 371 } 372 373 // PublishAllTenants publishes a global role to all tenants 374 func (globalRole *GlobalRole) PublishAllTenants() error { 375 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles 376 return publishContainerToAllTenants(globalRole.client, "GlobalRole", globalRole.GlobalRole.Name, globalRole.GlobalRole.Id, endpoint, true) 377 } 378 379 // UnpublishAllTenants remove publication status of a global role from all tenants 380 func (globalRole *GlobalRole) UnpublishAllTenants() error { 381 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles 382 return publishContainerToAllTenants(globalRole.client, "GlobalRole", globalRole.GlobalRole.Name, globalRole.GlobalRole.Id, endpoint, false) 383 }