1package cfclient 2 3import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 "net/url" 10 11 "github.com/pkg/errors" 12) 13 14type OrgResponse struct { 15 Count int `json:"total_results"` 16 Pages int `json:"total_pages"` 17 NextUrl string `json:"next_url"` 18 Resources []OrgResource `json:"resources"` 19} 20 21type OrgResource struct { 22 Meta Meta `json:"metadata"` 23 Entity Org `json:"entity"` 24} 25 26type OrgUserResponse struct { 27 Count int `json:"total_results"` 28 Pages int `json:"total_pages"` 29 NextURL string `json:"next_url"` 30 Resources []UserResource `json:"resources"` 31} 32 33type Org struct { 34 Guid string `json:"guid"` 35 CreatedAt string `json:"created_at"` 36 UpdatedAt string `json:"updated_at"` 37 Name string `json:"name"` 38 Status string `json:"status"` 39 QuotaDefinitionGuid string `json:"quota_definition_guid"` 40 DefaultIsolationSegmentGuid string `json:"default_isolation_segment_guid"` 41 c *Client 42} 43 44type OrgSummary struct { 45 Guid string `json:"guid"` 46 Name string `json:"name"` 47 Status string `json:"status"` 48 Spaces []OrgSummarySpaces `json:"spaces"` 49} 50 51type OrgSummarySpaces struct { 52 Guid string `json:"guid"` 53 Name string `json:"name"` 54 ServiceCount int `json:"service_count"` 55 AppCount int `json:"app_count"` 56 MemDevTotal int `json:"mem_dev_total"` 57 MemProdTotal int `json:"mem_prod_total"` 58} 59 60type OrgRequest struct { 61 Name string `json:"name"` 62 Status string `json:"status,omitempty"` 63 QuotaDefinitionGuid string `json:"quota_definition_guid,omitempty"` 64 DefaultIsolationSegmentGuid string `json:"default_isolation_segment_guid,omitempty"` 65} 66 67func (c *Client) ListOrgsByQuery(query url.Values) ([]Org, error) { 68 var orgs []Org 69 requestURL := "/v2/organizations?" + query.Encode() 70 for { 71 orgResp, err := c.getOrgResponse(requestURL) 72 if err != nil { 73 return []Org{}, err 74 } 75 for _, org := range orgResp.Resources { 76 orgs = append(orgs, c.mergeOrgResource(org)) 77 } 78 requestURL = orgResp.NextUrl 79 if requestURL == "" { 80 break 81 } 82 } 83 return orgs, nil 84} 85 86func (c *Client) ListOrgs() ([]Org, error) { 87 return c.ListOrgsByQuery(nil) 88} 89 90func (c *Client) GetOrgByName(name string) (Org, error) { 91 var org Org 92 q := url.Values{} 93 q.Set("q", "name:"+name) 94 orgs, err := c.ListOrgsByQuery(q) 95 if err != nil { 96 return org, err 97 } 98 if len(orgs) == 0 { 99 return org, fmt.Errorf("Unable to find org %s", name) 100 } 101 return orgs[0], nil 102} 103 104func (c *Client) GetOrgByGuid(guid string) (Org, error) { 105 var orgRes OrgResource 106 r := c.NewRequest("GET", "/v2/organizations/"+guid) 107 resp, err := c.DoRequest(r) 108 if err != nil { 109 return Org{}, err 110 } 111 body, err := ioutil.ReadAll(resp.Body) 112 defer resp.Body.Close() 113 if err != nil { 114 return Org{}, err 115 } 116 err = json.Unmarshal(body, &orgRes) 117 if err != nil { 118 return Org{}, err 119 } 120 return c.mergeOrgResource(orgRes), nil 121} 122 123func (c *Client) OrgSpaces(guid string) ([]Space, error) { 124 return c.fetchSpaces(fmt.Sprintf("/v2/organizations/%s/spaces", guid)) 125} 126 127func (o *Org) Summary() (OrgSummary, error) { 128 var orgSummary OrgSummary 129 requestURL := fmt.Sprintf("/v2/organizations/%s/summary", o.Guid) 130 r := o.c.NewRequest("GET", requestURL) 131 resp, err := o.c.DoRequest(r) 132 if err != nil { 133 return OrgSummary{}, errors.Wrap(err, "Error requesting org summary") 134 } 135 resBody, err := ioutil.ReadAll(resp.Body) 136 defer resp.Body.Close() 137 if err != nil { 138 return OrgSummary{}, errors.Wrap(err, "Error reading org summary body") 139 } 140 err = json.Unmarshal(resBody, &orgSummary) 141 if err != nil { 142 return OrgSummary{}, errors.Wrap(err, "Error unmarshalling org summary") 143 } 144 return orgSummary, nil 145} 146 147func (o *Org) Quota() (*OrgQuota, error) { 148 var orgQuota *OrgQuota 149 var orgQuotaResource OrgQuotasResource 150 if o.QuotaDefinitionGuid == "" { 151 return nil, nil 152 } 153 requestURL := fmt.Sprintf("/v2/quota_definitions/%s", o.QuotaDefinitionGuid) 154 r := o.c.NewRequest("GET", requestURL) 155 resp, err := o.c.DoRequest(r) 156 if err != nil { 157 return &OrgQuota{}, errors.Wrap(err, "Error requesting org quota") 158 } 159 resBody, err := ioutil.ReadAll(resp.Body) 160 defer resp.Body.Close() 161 if err != nil { 162 return &OrgQuota{}, errors.Wrap(err, "Error reading org quota body") 163 } 164 err = json.Unmarshal(resBody, &orgQuotaResource) 165 if err != nil { 166 return &OrgQuota{}, errors.Wrap(err, "Error unmarshalling org quota") 167 } 168 orgQuota = &orgQuotaResource.Entity 169 orgQuota.Guid = orgQuotaResource.Meta.Guid 170 orgQuota.c = o.c 171 return orgQuota, nil 172} 173 174func (c *Client) ListOrgUsersByQuery(orgGUID string, query url.Values) ([]User, error) { 175 var users []User 176 requestURL := fmt.Sprintf("/v2/organizations/%s/users?%s", orgGUID, query.Encode()) 177 for { 178 omResp, err := c.getOrgUserResponse(requestURL) 179 if err != nil { 180 return []User{}, err 181 } 182 for _, u := range omResp.Resources { 183 users = append(users, c.mergeUserResource(u)) 184 } 185 requestURL = omResp.NextURL 186 if requestURL == "" { 187 break 188 } 189 } 190 return users, nil 191} 192 193func (c *Client) ListOrgUsers(orgGUID string) ([]User, error) { 194 return c.ListOrgUsersByQuery(orgGUID, nil) 195} 196 197func (c *Client) listOrgRolesByQuery(orgGUID, role string, query url.Values) ([]User, error) { 198 var users []User 199 requestURL := fmt.Sprintf("/v2/organizations/%s/%s?%s", orgGUID, role, query.Encode()) 200 for { 201 omResp, err := c.getOrgUserResponse(requestURL) 202 if err != nil { 203 return []User{}, err 204 } 205 for _, u := range omResp.Resources { 206 users = append(users, c.mergeUserResource(u)) 207 } 208 requestURL = omResp.NextURL 209 if requestURL == "" { 210 break 211 } 212 } 213 return users, nil 214} 215 216func (c *Client) ListOrgManagersByQuery(orgGUID string, query url.Values) ([]User, error) { 217 return c.listOrgRolesByQuery(orgGUID, "managers", query) 218} 219 220func (c *Client) ListOrgManagers(orgGUID string) ([]User, error) { 221 return c.ListOrgManagersByQuery(orgGUID, nil) 222} 223 224func (c *Client) ListOrgAuditorsByQuery(orgGUID string, query url.Values) ([]User, error) { 225 return c.listOrgRolesByQuery(orgGUID, "auditors", query) 226} 227 228func (c *Client) ListOrgAuditors(orgGUID string) ([]User, error) { 229 return c.ListOrgAuditorsByQuery(orgGUID, nil) 230} 231 232func (c *Client) ListOrgBillingManagersByQuery(orgGUID string, query url.Values) ([]User, error) { 233 return c.listOrgRolesByQuery(orgGUID, "billing_managers", query) 234} 235 236func (c *Client) ListOrgBillingManagers(orgGUID string) ([]User, error) { 237 return c.ListOrgBillingManagersByQuery(orgGUID, nil) 238} 239 240func (c *Client) AssociateOrgManager(orgGUID, userGUID string) (Org, error) { 241 org := Org{Guid: orgGUID, c: c} 242 return org.AssociateManager(userGUID) 243} 244 245func (c *Client) AssociateOrgManagerByUsername(orgGUID, name string) (Org, error) { 246 org := Org{Guid: orgGUID, c: c} 247 return org.AssociateManagerByUsername(name) 248} 249 250func (c *Client) AssociateOrgManagerByUsernameAndOrigin(orgGUID, name, origin string) (Org, error) { 251 org := Org{Guid: orgGUID, c: c} 252 return org.AssociateManagerByUsernameAndOrigin(name, origin) 253} 254 255func (c *Client) AssociateOrgUser(orgGUID, userGUID string) (Org, error) { 256 org := Org{Guid: orgGUID, c: c} 257 return org.AssociateUser(userGUID) 258} 259 260func (c *Client) AssociateOrgAuditor(orgGUID, userGUID string) (Org, error) { 261 org := Org{Guid: orgGUID, c: c} 262 return org.AssociateAuditor(userGUID) 263} 264 265func (c *Client) AssociateOrgUserByUsername(orgGUID, name string) (Org, error) { 266 org := Org{Guid: orgGUID, c: c} 267 return org.AssociateUserByUsername(name) 268} 269 270func (c *Client) AssociateOrgUserByUsernameAndOrigin(orgGUID, name, origin string) (Org, error) { 271 org := Org{Guid: orgGUID, c: c} 272 return org.AssociateUserByUsernameAndOrigin(name, origin) 273} 274 275func (c *Client) AssociateOrgAuditorByUsername(orgGUID, name string) (Org, error) { 276 org := Org{Guid: orgGUID, c: c} 277 return org.AssociateAuditorByUsername(name) 278} 279 280func (c *Client) AssociateOrgAuditorByUsernameAndOrigin(orgGUID, name, origin string) (Org, error) { 281 org := Org{Guid: orgGUID, c: c} 282 return org.AssociateAuditorByUsernameAndOrigin(name, origin) 283} 284 285func (c *Client) AssociateOrgBillingManager(orgGUID, userGUID string) (Org, error) { 286 org := Org{Guid: orgGUID, c: c} 287 return org.AssociateBillingManager(userGUID) 288} 289 290func (c *Client) AssociateOrgBillingManagerByUsername(orgGUID, name string) (Org, error) { 291 org := Org{Guid: orgGUID, c: c} 292 return org.AssociateBillingManagerByUsername(name) 293} 294 295func (c *Client) AssociateOrgBillingManagerByUsernameAndOrigin(orgGUID, name, origin string) (Org, error) { 296 org := Org{Guid: orgGUID, c: c} 297 return org.AssociateBillingManagerByUsernameAndOrigin(name, origin) 298} 299 300func (c *Client) RemoveOrgManager(orgGUID, userGUID string) error { 301 org := Org{Guid: orgGUID, c: c} 302 return org.RemoveManager(userGUID) 303} 304 305func (c *Client) RemoveOrgManagerByUsername(orgGUID, name string) error { 306 org := Org{Guid: orgGUID, c: c} 307 return org.RemoveManagerByUsername(name) 308} 309 310func (c *Client) RemoveOrgManagerByUsernameAndOrigin(orgGUID, name, origin string) error { 311 org := Org{Guid: orgGUID, c: c} 312 return org.RemoveManagerByUsernameAndOrigin(name, origin) 313} 314 315func (c *Client) RemoveOrgUser(orgGUID, userGUID string) error { 316 org := Org{Guid: orgGUID, c: c} 317 return org.RemoveUser(userGUID) 318} 319 320func (c *Client) RemoveOrgAuditor(orgGUID, userGUID string) error { 321 org := Org{Guid: orgGUID, c: c} 322 return org.RemoveAuditor(userGUID) 323} 324 325func (c *Client) RemoveOrgUserByUsername(orgGUID, name string) error { 326 org := Org{Guid: orgGUID, c: c} 327 return org.RemoveUserByUsername(name) 328} 329 330func (c *Client) RemoveOrgUserByUsernameAndOrigin(orgGUID, name, origin string) error { 331 org := Org{Guid: orgGUID, c: c} 332 return org.RemoveUserByUsernameAndOrigin(name, origin) 333} 334 335func (c *Client) RemoveOrgAuditorByUsername(orgGUID, name string) error { 336 org := Org{Guid: orgGUID, c: c} 337 return org.RemoveAuditorByUsername(name) 338} 339 340func (c *Client) RemoveOrgAuditorByUsernameAndOrigin(orgGUID, name, origin string) error { 341 org := Org{Guid: orgGUID, c: c} 342 return org.RemoveAuditorByUsernameAndOrigin(name, origin) 343} 344 345func (c *Client) RemoveOrgBillingManager(orgGUID, userGUID string) error { 346 org := Org{Guid: orgGUID, c: c} 347 return org.RemoveBillingManager(userGUID) 348} 349 350func (c *Client) RemoveOrgBillingManagerByUsername(orgGUID, name string) error { 351 org := Org{Guid: orgGUID, c: c} 352 return org.RemoveBillingManagerByUsername(name) 353} 354 355func (c *Client) RemoveOrgBillingManagerByUsernameAndOrigin(orgGUID, name, origin string) error { 356 org := Org{Guid: orgGUID, c: c} 357 return org.RemoveBillingManagerByUsernameAndOrigin(name, origin) 358} 359 360func (c *Client) ListOrgSpaceQuotas(orgGUID string) ([]SpaceQuota, error) { 361 org := Org{Guid: orgGUID, c: c} 362 return org.ListSpaceQuotas() 363} 364 365func (c *Client) ListOrgPrivateDomains(orgGUID string) ([]Domain, error) { 366 org := Org{Guid: orgGUID, c: c} 367 return org.ListPrivateDomains() 368} 369 370func (c *Client) ShareOrgPrivateDomain(orgGUID, privateDomainGUID string) (*Domain, error) { 371 org := Org{Guid: orgGUID, c: c} 372 return org.SharePrivateDomain(privateDomainGUID) 373} 374 375func (c *Client) UnshareOrgPrivateDomain(orgGUID, privateDomainGUID string) error { 376 org := Org{Guid: orgGUID, c: c} 377 return org.UnsharePrivateDomain(privateDomainGUID) 378} 379 380func (o *Org) ListSpaceQuotas() ([]SpaceQuota, error) { 381 var spaceQuotas []SpaceQuota 382 requestURL := fmt.Sprintf("/v2/organizations/%s/space_quota_definitions", o.Guid) 383 for { 384 spaceQuotasResp, err := o.c.getSpaceQuotasResponse(requestURL) 385 if err != nil { 386 return []SpaceQuota{}, err 387 } 388 for _, resource := range spaceQuotasResp.Resources { 389 spaceQuotas = append(spaceQuotas, *o.c.mergeSpaceQuotaResource(resource)) 390 } 391 requestURL = spaceQuotasResp.NextUrl 392 if requestURL == "" { 393 break 394 } 395 } 396 return spaceQuotas, nil 397} 398 399func (o *Org) ListPrivateDomains() ([]Domain, error) { 400 var domains []Domain 401 requestURL := fmt.Sprintf("/v2/organizations/%s/private_domains", o.Guid) 402 for { 403 domainsResp, err := o.c.getDomainsResponse(requestURL) 404 if err != nil { 405 return []Domain{}, err 406 } 407 for _, resource := range domainsResp.Resources { 408 domains = append(domains, *o.c.mergeDomainResource(resource)) 409 } 410 requestURL = domainsResp.NextUrl 411 if requestURL == "" { 412 break 413 } 414 } 415 return domains, nil 416} 417 418func (o *Org) SharePrivateDomain(privateDomainGUID string) (*Domain, error) { 419 requestURL := fmt.Sprintf("/v2/organizations/%s/private_domains/%s", o.Guid, privateDomainGUID) 420 r := o.c.NewRequest("PUT", requestURL) 421 resp, err := o.c.DoRequest(r) 422 if err != nil { 423 return nil, err 424 } 425 if resp.StatusCode != http.StatusCreated { 426 return nil, errors.Wrapf(err, "Error sharing domain %s for org %s, response code: %d", privateDomainGUID, o.Guid, resp.StatusCode) 427 } 428 return o.c.handleDomainResp(resp) 429} 430 431func (o *Org) UnsharePrivateDomain(privateDomainGUID string) error { 432 requestURL := fmt.Sprintf("/v2/organizations/%s/private_domains/%s", o.Guid, privateDomainGUID) 433 r := o.c.NewRequest("DELETE", requestURL) 434 resp, err := o.c.DoRequest(r) 435 if err != nil { 436 return err 437 } 438 if resp.StatusCode != http.StatusNoContent { 439 return errors.Wrapf(err, "Error unsharing domain %s for org %s, response code: %d", privateDomainGUID, o.Guid, resp.StatusCode) 440 } 441 return nil 442} 443 444func (o *Org) associateRole(userGUID, role string) (Org, error) { 445 requestURL := fmt.Sprintf("/v2/organizations/%s/%s/%s", o.Guid, role, userGUID) 446 r := o.c.NewRequest("PUT", requestURL) 447 resp, err := o.c.DoRequest(r) 448 if err != nil { 449 return Org{}, err 450 } 451 if resp.StatusCode != http.StatusCreated { 452 return Org{}, errors.Wrapf(err, "Error associating %s %s, response code: %d", role, userGUID, resp.StatusCode) 453 } 454 return o.c.handleOrgResp(resp) 455} 456 457func (o *Org) associateRoleByUsernameAndOrigin(name, role, origin string) (Org, error) { 458 requestURL := fmt.Sprintf("/v2/organizations/%s/%s", o.Guid, role) 459 buf := bytes.NewBuffer(nil) 460 payload := make(map[string]string) 461 payload["username"] = name 462 if origin != "" { 463 payload["origin"] = origin 464 } 465 err := json.NewEncoder(buf).Encode(payload) 466 if err != nil { 467 return Org{}, err 468 } 469 r := o.c.NewRequestWithBody("PUT", requestURL, buf) 470 resp, err := o.c.DoRequest(r) 471 if err != nil { 472 return Org{}, err 473 } 474 if resp.StatusCode != http.StatusCreated { 475 return Org{}, errors.Wrapf(err, "Error associating %s %s, response code: %d", role, name, resp.StatusCode) 476 } 477 return o.c.handleOrgResp(resp) 478} 479 480func (o *Org) AssociateManager(userGUID string) (Org, error) { 481 return o.associateRole(userGUID, "managers") 482} 483 484func (o *Org) AssociateManagerByUsername(name string) (Org, error) { 485 return o.associateRoleByUsernameAndOrigin(name, "managers", "") 486} 487 488func (o *Org) AssociateManagerByUsernameAndOrigin(name, origin string) (Org, error) { 489 return o.associateRoleByUsernameAndOrigin(name, "managers", origin) 490} 491 492func (o *Org) AssociateUser(userGUID string) (Org, error) { 493 requestURL := fmt.Sprintf("/v2/organizations/%s/users/%s", o.Guid, userGUID) 494 r := o.c.NewRequest("PUT", requestURL) 495 resp, err := o.c.DoRequest(r) 496 if err != nil { 497 return Org{}, err 498 } 499 if resp.StatusCode != http.StatusCreated { 500 return Org{}, errors.Wrapf(err, "Error associating user %s, response code: %d", userGUID, resp.StatusCode) 501 } 502 return o.c.handleOrgResp(resp) 503} 504 505func (o *Org) AssociateAuditor(userGUID string) (Org, error) { 506 return o.associateRole(userGUID, "auditors") 507} 508 509func (o *Org) AssociateAuditorByUsername(name string) (Org, error) { 510 return o.associateRoleByUsernameAndOrigin(name, "auditors", "") 511} 512 513func (o *Org) AssociateAuditorByUsernameAndOrigin(name, origin string) (Org, error) { 514 return o.associateRoleByUsernameAndOrigin(name, "auditors", origin) 515} 516 517func (o *Org) AssociateBillingManager(userGUID string) (Org, error) { 518 return o.associateRole(userGUID, "billing_managers") 519} 520 521func (o *Org) AssociateBillingManagerByUsername(name string) (Org, error) { 522 return o.associateRoleByUsernameAndOrigin(name, "billing_managers", "") 523} 524func (o *Org) AssociateBillingManagerByUsernameAndOrigin(name, origin string) (Org, error) { 525 return o.associateRoleByUsernameAndOrigin(name, "billing_managers", origin) 526} 527 528func (o *Org) AssociateUserByUsername(name string) (Org, error) { 529 return o.associateUserByUsernameAndOrigin(name, "") 530} 531 532func (o *Org) AssociateUserByUsernameAndOrigin(name, origin string) (Org, error) { 533 return o.associateUserByUsernameAndOrigin(name, origin) 534} 535 536func (o *Org) associateUserByUsernameAndOrigin(name, origin string) (Org, error) { 537 requestURL := fmt.Sprintf("/v2/organizations/%s/users", o.Guid) 538 buf := bytes.NewBuffer(nil) 539 payload := make(map[string]string) 540 payload["username"] = name 541 if origin != "" { 542 payload["origin"] = origin 543 } 544 err := json.NewEncoder(buf).Encode(payload) 545 if err != nil { 546 return Org{}, err 547 } 548 r := o.c.NewRequestWithBody("PUT", requestURL, buf) 549 resp, err := o.c.DoRequest(r) 550 if err != nil { 551 return Org{}, err 552 } 553 if resp.StatusCode != http.StatusCreated { 554 return Org{}, errors.Wrapf(err, "Error associating user %s, response code: %d", name, resp.StatusCode) 555 } 556 return o.c.handleOrgResp(resp) 557} 558 559func (o *Org) removeRole(userGUID, role string) error { 560 requestURL := fmt.Sprintf("/v2/organizations/%s/%s/%s", o.Guid, role, userGUID) 561 r := o.c.NewRequest("DELETE", requestURL) 562 resp, err := o.c.DoRequest(r) 563 if err != nil { 564 return err 565 } 566 if resp.StatusCode != http.StatusNoContent { 567 return errors.Wrapf(err, "Error removing %s %s, response code: %d", role, userGUID, resp.StatusCode) 568 } 569 return nil 570} 571 572func (o *Org) removeRoleByUsernameAndOrigin(name, role, origin string) error { 573 var requestURL string 574 var method string 575 buf := bytes.NewBuffer(nil) 576 payload := make(map[string]string) 577 payload["username"] = name 578 if origin != "" { 579 requestURL = fmt.Sprintf("/v2/organizations/%s/%s/remove", o.Guid, role) 580 method = "POST" 581 payload["origin"] = origin 582 } else { 583 requestURL = fmt.Sprintf("/v2/organizations/%s/%s", o.Guid, role) 584 method = "DELETE" 585 } 586 err := json.NewEncoder(buf).Encode(payload) 587 if err != nil { 588 return err 589 } 590 591 r := o.c.NewRequestWithBody(method, requestURL, buf) 592 resp, err := o.c.DoRequest(r) 593 if err != nil { 594 return err 595 } 596 if resp.StatusCode != http.StatusNoContent { 597 return errors.Wrapf(err, "Error removing manager %s, response code: %d", name, resp.StatusCode) 598 } 599 return nil 600} 601 602func (o *Org) RemoveManager(userGUID string) error { 603 return o.removeRole(userGUID, "managers") 604} 605 606func (o *Org) RemoveManagerByUsername(name string) error { 607 return o.removeRoleByUsernameAndOrigin(name, "managers", "") 608} 609func (o *Org) RemoveManagerByUsernameAndOrigin(name, origin string) error { 610 return o.removeRoleByUsernameAndOrigin(name, "managers", origin) 611} 612 613func (o *Org) RemoveAuditor(userGUID string) error { 614 return o.removeRole(userGUID, "auditors") 615} 616 617func (o *Org) RemoveAuditorByUsername(name string) error { 618 return o.removeRoleByUsernameAndOrigin(name, "auditors", "") 619} 620func (o *Org) RemoveAuditorByUsernameAndOrigin(name, origin string) error { 621 return o.removeRoleByUsernameAndOrigin(name, "auditors", origin) 622} 623 624func (o *Org) RemoveBillingManager(userGUID string) error { 625 return o.removeRole(userGUID, "billing_managers") 626} 627 628func (o *Org) RemoveBillingManagerByUsername(name string) error { 629 return o.removeRoleByUsernameAndOrigin(name, "billing_managers", "") 630} 631 632func (o *Org) RemoveBillingManagerByUsernameAndOrigin(name, origin string) error { 633 return o.removeRoleByUsernameAndOrigin(name, "billing_managers", origin) 634} 635 636func (o *Org) RemoveUser(userGUID string) error { 637 requestURL := fmt.Sprintf("/v2/organizations/%s/users/%s", o.Guid, userGUID) 638 r := o.c.NewRequest("DELETE", requestURL) 639 resp, err := o.c.DoRequest(r) 640 if err != nil { 641 return err 642 } 643 if resp.StatusCode != http.StatusNoContent { 644 return errors.Wrapf(err, "Error removing user %s, response code: %d", userGUID, resp.StatusCode) 645 } 646 return nil 647} 648 649func (o *Org) RemoveUserByUsername(name string) error { 650 return o.removeUserByUsernameAndOrigin(name, "") 651} 652 653func (o *Org) RemoveUserByUsernameAndOrigin(name, origin string) error { 654 return o.removeUserByUsernameAndOrigin(name, origin) 655} 656 657func (o *Org) removeUserByUsernameAndOrigin(name, origin string) error { 658 var requestURL string 659 var method string 660 buf := bytes.NewBuffer(nil) 661 payload := make(map[string]string) 662 payload["username"] = name 663 if origin != "" { 664 payload["origin"] = origin 665 requestURL = fmt.Sprintf("/v2/organizations/%s/users/remove", o.Guid) 666 method = "POST" 667 } else { 668 requestURL = fmt.Sprintf("/v2/organizations/%s/users", o.Guid) 669 method = "DELETE" 670 } 671 err := json.NewEncoder(buf).Encode(payload) 672 if err != nil { 673 return err 674 } 675 r := o.c.NewRequestWithBody(method, requestURL, buf) 676 resp, err := o.c.DoRequest(r) 677 if err != nil { 678 return err 679 } 680 if resp.StatusCode != http.StatusNoContent { 681 return errors.Wrapf(err, "Error removing user %s, response code: %d", name, resp.StatusCode) 682 } 683 return nil 684} 685 686func (c *Client) CreateOrg(req OrgRequest) (Org, error) { 687 buf := bytes.NewBuffer(nil) 688 err := json.NewEncoder(buf).Encode(req) 689 if err != nil { 690 return Org{}, err 691 } 692 r := c.NewRequestWithBody("POST", "/v2/organizations", buf) 693 resp, err := c.DoRequest(r) 694 if err != nil { 695 return Org{}, err 696 } 697 if resp.StatusCode != http.StatusCreated { 698 return Org{}, errors.Wrapf(err, "Error creating organization, response code: %d", resp.StatusCode) 699 } 700 return c.handleOrgResp(resp) 701} 702 703func (c *Client) UpdateOrg(orgGUID string, orgRequest OrgRequest) (Org, error) { 704 buf := bytes.NewBuffer(nil) 705 err := json.NewEncoder(buf).Encode(orgRequest) 706 if err != nil { 707 return Org{}, err 708 } 709 r := c.NewRequestWithBody("PUT", fmt.Sprintf("/v2/organizations/%s", orgGUID), buf) 710 resp, err := c.DoRequest(r) 711 if err != nil { 712 return Org{}, err 713 } 714 if resp.StatusCode != http.StatusCreated { 715 return Org{}, errors.Wrapf(err, "Error updating organization, response code: %d", resp.StatusCode) 716 } 717 return c.handleOrgResp(resp) 718} 719 720func (c *Client) DeleteOrg(guid string, recursive, async bool) error { 721 resp, err := c.DoRequest(c.NewRequest("DELETE", fmt.Sprintf("/v2/organizations/%s?recursive=%t&async=%t", guid, recursive, async))) 722 if err != nil { 723 return err 724 } 725 if resp.StatusCode != http.StatusNoContent { 726 return errors.Wrapf(err, "Error deleting organization %s, response code: %d", guid, resp.StatusCode) 727 } 728 return nil 729} 730 731func (c *Client) getOrgResponse(requestURL string) (OrgResponse, error) { 732 var orgResp OrgResponse 733 r := c.NewRequest("GET", requestURL) 734 resp, err := c.DoRequest(r) 735 if err != nil { 736 return OrgResponse{}, errors.Wrap(err, "Error requesting orgs") 737 } 738 resBody, err := ioutil.ReadAll(resp.Body) 739 defer resp.Body.Close() 740 if err != nil { 741 return OrgResponse{}, errors.Wrap(err, "Error reading org request") 742 } 743 err = json.Unmarshal(resBody, &orgResp) 744 if err != nil { 745 return OrgResponse{}, errors.Wrap(err, "Error unmarshalling org") 746 } 747 return orgResp, nil 748} 749 750func (c *Client) fetchOrgs(requestURL string) ([]Org, error) { 751 var orgs []Org 752 for { 753 orgResp, err := c.getOrgResponse(requestURL) 754 if err != nil { 755 return []Org{}, err 756 } 757 for _, org := range orgResp.Resources { 758 orgs = append(orgs, c.mergeOrgResource(org)) 759 } 760 requestURL = orgResp.NextUrl 761 if requestURL == "" { 762 break 763 } 764 } 765 return orgs, nil 766} 767 768func (c *Client) handleOrgResp(resp *http.Response) (Org, error) { 769 body, err := ioutil.ReadAll(resp.Body) 770 defer resp.Body.Close() 771 if err != nil { 772 return Org{}, err 773 } 774 var orgResource OrgResource 775 err = json.Unmarshal(body, &orgResource) 776 if err != nil { 777 return Org{}, err 778 } 779 return c.mergeOrgResource(orgResource), nil 780} 781 782func (c *Client) getOrgUserResponse(requestURL string) (OrgUserResponse, error) { 783 var omResp OrgUserResponse 784 r := c.NewRequest("GET", requestURL) 785 resp, err := c.DoRequest(r) 786 if err != nil { 787 return OrgUserResponse{}, errors.Wrap(err, "error requesting org managers") 788 } 789 defer resp.Body.Close() 790 resBody, err := ioutil.ReadAll(resp.Body) 791 if err != nil { 792 return OrgUserResponse{}, errors.Wrap(err, "error reading org managers response body") 793 } 794 if err := json.Unmarshal(resBody, &omResp); err != nil { 795 return OrgUserResponse{}, errors.Wrap(err, "error unmarshaling org managers") 796 } 797 return omResp, nil 798} 799 800func (c *Client) mergeOrgResource(org OrgResource) Org { 801 org.Entity.Guid = org.Meta.Guid 802 org.Entity.CreatedAt = org.Meta.CreatedAt 803 org.Entity.UpdatedAt = org.Meta.UpdatedAt 804 org.Entity.c = c 805 return org.Entity 806} 807 808func (c *Client) DefaultIsolationSegmentForOrg(orgGUID, isolationSegmentGUID string) error { 809 return c.updateOrgDefaultIsolationSegment(orgGUID, map[string]interface{}{"guid": isolationSegmentGUID}) 810} 811 812func (c *Client) ResetDefaultIsolationSegmentForOrg(orgGUID string) error { 813 return c.updateOrgDefaultIsolationSegment(orgGUID, nil) 814} 815 816func (c *Client) updateOrgDefaultIsolationSegment(orgGUID string, data interface{}) error { 817 requestURL := fmt.Sprintf("/v3/organizations/%s/relationships/default_isolation_segment", orgGUID) 818 buf := bytes.NewBuffer(nil) 819 err := json.NewEncoder(buf).Encode(map[string]interface{}{"data": data}) 820 if err != nil { 821 return err 822 } 823 r := c.NewRequestWithBody("PATCH", requestURL, buf) 824 resp, err := c.DoRequest(r) 825 if err != nil { 826 return err 827 } 828 if resp.StatusCode != http.StatusOK { 829 return errors.Wrapf(err, "Error setting default isolation segment for org %s, response code: %d", orgGUID, resp.StatusCode) 830 } 831 return nil 832} 833