791 lines
24 KiB
Go
791 lines
24 KiB
Go
package cfclient
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type SpaceRequest struct {
|
|
Name string `json:"name"`
|
|
OrganizationGuid string `json:"organization_guid"`
|
|
DeveloperGuid []string `json:"developer_guids,omitempty"`
|
|
ManagerGuid []string `json:"manager_guids,omitempty"`
|
|
AuditorGuid []string `json:"auditor_guids,omitempty"`
|
|
DomainGuid []string `json:"domain_guids,omitempty"`
|
|
SecurityGroupGuids []string `json:"security_group_guids,omitempty"`
|
|
SpaceQuotaDefGuid string `json:"space_quota_definition_guid,omitempty"`
|
|
IsolationSegmentGuid string `json:"isolation_segment_guid,omitempty"`
|
|
AllowSSH bool `json:"allow_ssh"`
|
|
}
|
|
|
|
type SpaceResponse struct {
|
|
Count int `json:"total_results"`
|
|
Pages int `json:"total_pages"`
|
|
NextUrl string `json:"next_url"`
|
|
Resources []SpaceResource `json:"resources"`
|
|
}
|
|
|
|
type SpaceResource struct {
|
|
Meta Meta `json:"metadata"`
|
|
Entity Space `json:"entity"`
|
|
}
|
|
|
|
type ServicePlanEntity struct {
|
|
Name string `json:"name"`
|
|
Free bool `json:"free"`
|
|
Public bool `json:"public"`
|
|
Active bool `json:"active"`
|
|
Description string `json:"description"`
|
|
ServiceOfferingGUID string `json:"service_guid"`
|
|
ServiceOffering ServiceOfferingResource `json:"service"`
|
|
}
|
|
|
|
type ServiceOfferingExtra struct {
|
|
DisplayName string `json:"displayName"`
|
|
DocumentationURL string `json:"documentationURL"`
|
|
LongDescription string `json:"longDescription"`
|
|
}
|
|
|
|
type ServiceOfferingEntity struct {
|
|
Label string
|
|
Description string
|
|
Provider string `json:"provider"`
|
|
BrokerGUID string `json:"service_broker_guid"`
|
|
Requires []string `json:"requires"`
|
|
ServicePlans []interface{} `json:"service_plans"`
|
|
Extra ServiceOfferingExtra
|
|
}
|
|
|
|
type ServiceOfferingResource struct {
|
|
Metadata Meta
|
|
Entity ServiceOfferingEntity
|
|
}
|
|
|
|
type ServiceOfferingResponse struct {
|
|
Count int `json:"total_results"`
|
|
Pages int `json:"total_pages"`
|
|
NextUrl string `json:"next_url"`
|
|
PrevUrl string `json:"prev_url"`
|
|
Resources []ServiceOfferingResource `json:"resources"`
|
|
}
|
|
|
|
type SpaceUserResponse struct {
|
|
Count int `json:"total_results"`
|
|
Pages int `json:"total_pages"`
|
|
NextURL string `json:"next_url"`
|
|
Resources []UserResource `json:"resources"`
|
|
}
|
|
|
|
type Space struct {
|
|
Guid string `json:"guid"`
|
|
CreatedAt string `json:"created_at"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
Name string `json:"name"`
|
|
OrganizationGuid string `json:"organization_guid"`
|
|
OrgURL string `json:"organization_url"`
|
|
OrgData OrgResource `json:"organization"`
|
|
QuotaDefinitionGuid string `json:"space_quota_definition_guid"`
|
|
IsolationSegmentGuid string `json:"isolation_segment_guid"`
|
|
AllowSSH bool `json:"allow_ssh"`
|
|
c *Client
|
|
}
|
|
|
|
type SpaceSummary struct {
|
|
Guid string `json:"guid"`
|
|
Name string `json:"name"`
|
|
Apps []AppSummary `json:"apps"`
|
|
Services []ServiceSummary `json:"services"`
|
|
}
|
|
|
|
type SpaceRoleResponse struct {
|
|
Count int `json:"total_results"`
|
|
Pages int `json:"total_pages"`
|
|
NextUrl string `json:"next_url"`
|
|
Resources []SpaceRoleResource `json:"resources"`
|
|
}
|
|
|
|
type SpaceRoleResource struct {
|
|
Meta Meta `json:"metadata"`
|
|
Entity SpaceRole `json:"entity"`
|
|
}
|
|
|
|
type SpaceRole struct {
|
|
Guid string `json:"guid"`
|
|
Admin bool `json:"admin"`
|
|
Active bool `json:"active"`
|
|
DefaultSpaceGuid string `json:"default_space_guid"`
|
|
Username string `json:"username"`
|
|
SpaceRoles []string `json:"space_roles"`
|
|
SpacesUrl string `json:"spaces_url"`
|
|
OrganizationsUrl string `json:"organizations_url"`
|
|
ManagedOrganizationsUrl string `json:"managed_organizations_url"`
|
|
BillingManagedOrganizationsUrl string `json:"billing_managed_organizations_url"`
|
|
AuditedOrganizationsUrl string `json:"audited_organizations_url"`
|
|
ManagedSpacesUrl string `json:"managed_spaces_url"`
|
|
AuditedSpacesUrl string `json:"audited_spaces_url"`
|
|
c *Client
|
|
}
|
|
|
|
func (s *Space) Org() (Org, error) {
|
|
var orgResource OrgResource
|
|
r := s.c.NewRequest("GET", s.OrgURL)
|
|
resp, err := s.c.DoRequest(r)
|
|
if err != nil {
|
|
return Org{}, errors.Wrap(err, "Error requesting org")
|
|
}
|
|
resBody, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return Org{}, errors.Wrap(err, "Error reading org request")
|
|
}
|
|
|
|
err = json.Unmarshal(resBody, &orgResource)
|
|
if err != nil {
|
|
return Org{}, errors.Wrap(err, "Error unmarshaling org")
|
|
}
|
|
return s.c.mergeOrgResource(orgResource), nil
|
|
}
|
|
|
|
func (s *Space) Quota() (*SpaceQuota, error) {
|
|
var spaceQuota *SpaceQuota
|
|
var spaceQuotaResource SpaceQuotasResource
|
|
if s.QuotaDefinitionGuid == "" {
|
|
return nil, nil
|
|
}
|
|
requestUrl := fmt.Sprintf("/v2/space_quota_definitions/%s", s.QuotaDefinitionGuid)
|
|
r := s.c.NewRequest("GET", requestUrl)
|
|
resp, err := s.c.DoRequest(r)
|
|
if err != nil {
|
|
return &SpaceQuota{}, errors.Wrap(err, "Error requesting space quota")
|
|
}
|
|
resBody, err := ioutil.ReadAll(resp.Body)
|
|
defer resp.Body.Close()
|
|
if err != nil {
|
|
return &SpaceQuota{}, errors.Wrap(err, "Error reading space quota body")
|
|
}
|
|
err = json.Unmarshal(resBody, &spaceQuotaResource)
|
|
if err != nil {
|
|
return &SpaceQuota{}, errors.Wrap(err, "Error unmarshalling space quota")
|
|
}
|
|
spaceQuota = &spaceQuotaResource.Entity
|
|
spaceQuota.Guid = spaceQuotaResource.Meta.Guid
|
|
spaceQuota.c = s.c
|
|
return spaceQuota, nil
|
|
}
|
|
|
|
func (s *Space) Summary() (SpaceSummary, error) {
|
|
var spaceSummary SpaceSummary
|
|
requestUrl := fmt.Sprintf("/v2/spaces/%s/summary", s.Guid)
|
|
r := s.c.NewRequest("GET", requestUrl)
|
|
resp, err := s.c.DoRequest(r)
|
|
if err != nil {
|
|
return SpaceSummary{}, errors.Wrap(err, "Error requesting space summary")
|
|
}
|
|
resBody, err := ioutil.ReadAll(resp.Body)
|
|
defer resp.Body.Close()
|
|
if err != nil {
|
|
return SpaceSummary{}, errors.Wrap(err, "Error reading space summary body")
|
|
}
|
|
err = json.Unmarshal(resBody, &spaceSummary)
|
|
if err != nil {
|
|
return SpaceSummary{}, errors.Wrap(err, "Error unmarshalling space summary")
|
|
}
|
|
return spaceSummary, nil
|
|
}
|
|
|
|
func (s *Space) Roles() ([]SpaceRole, error) {
|
|
var roles []SpaceRole
|
|
requestUrl := fmt.Sprintf("/v2/spaces/%s/user_roles", s.Guid)
|
|
for {
|
|
rolesResp, err := s.c.getSpaceRolesResponse(requestUrl)
|
|
if err != nil {
|
|
return roles, err
|
|
}
|
|
for _, role := range rolesResp.Resources {
|
|
role.Entity.Guid = role.Meta.Guid
|
|
role.Entity.c = s.c
|
|
roles = append(roles, role.Entity)
|
|
}
|
|
requestUrl = rolesResp.NextUrl
|
|
if requestUrl == "" {
|
|
break
|
|
}
|
|
}
|
|
return roles, nil
|
|
}
|
|
|
|
func (c *Client) CreateSpace(req SpaceRequest) (Space, error) {
|
|
buf := bytes.NewBuffer(nil)
|
|
err := json.NewEncoder(buf).Encode(req)
|
|
if err != nil {
|
|
return Space{}, err
|
|
}
|
|
r := c.NewRequestWithBody("POST", "/v2/spaces", buf)
|
|
resp, err := c.DoRequest(r)
|
|
if err != nil {
|
|
return Space{}, err
|
|
}
|
|
if resp.StatusCode != http.StatusCreated {
|
|
return Space{}, fmt.Errorf("CF API returned with status code %d", resp.StatusCode)
|
|
}
|
|
return c.handleSpaceResp(resp)
|
|
}
|
|
|
|
func (c *Client) UpdateSpace(spaceGUID string, req SpaceRequest) (Space, error) {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.Update(req)
|
|
}
|
|
|
|
func (c *Client) DeleteSpace(guid string, recursive, async bool) error {
|
|
resp, err := c.DoRequest(c.NewRequest("DELETE", fmt.Sprintf("/v2/spaces/%s?recursive=%t&async=%t", guid, recursive, async)))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if resp.StatusCode != http.StatusNoContent {
|
|
return errors.Wrapf(err, "Error deleting space %s, response code: %d", guid, resp.StatusCode)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *Client) ListSpaceManagersByQuery(spaceGUID string, query url.Values) ([]User, error) {
|
|
return c.listSpaceUsersByRoleAndQuery(spaceGUID, "managers", query)
|
|
}
|
|
|
|
func (c *Client) ListSpaceManagers(spaceGUID string) ([]User, error) {
|
|
return c.ListSpaceManagersByQuery(spaceGUID, nil)
|
|
}
|
|
|
|
func (c *Client) ListSpaceAuditorsByQuery(spaceGUID string, query url.Values) ([]User, error) {
|
|
return c.listSpaceUsersByRoleAndQuery(spaceGUID, "auditors", query)
|
|
}
|
|
|
|
func (c *Client) ListSpaceAuditors(spaceGUID string) ([]User, error) {
|
|
return c.ListSpaceAuditorsByQuery(spaceGUID, nil)
|
|
}
|
|
|
|
func (c *Client) ListSpaceDevelopersByQuery(spaceGUID string, query url.Values) ([]User, error) {
|
|
return c.listSpaceUsersByRoleAndQuery(spaceGUID, "developers", query)
|
|
}
|
|
|
|
func (c *Client) listSpaceUsersByRoleAndQuery(spaceGUID, role string, query url.Values) ([]User, error) {
|
|
var users []User
|
|
requestURL := fmt.Sprintf("/v2/spaces/%s/%s?%s", spaceGUID, role, query.Encode())
|
|
for {
|
|
userResp, err := c.getUserResponse(requestURL)
|
|
if err != nil {
|
|
return []User{}, err
|
|
}
|
|
for _, u := range userResp.Resources {
|
|
users = append(users, c.mergeUserResource(u))
|
|
}
|
|
requestURL = userResp.NextUrl
|
|
if requestURL == "" {
|
|
break
|
|
}
|
|
}
|
|
return users, nil
|
|
}
|
|
|
|
func (c *Client) ListSpaceDevelopers(spaceGUID string) ([]User, error) {
|
|
return c.ListSpaceDevelopersByQuery(spaceGUID, nil)
|
|
}
|
|
|
|
func (c *Client) AssociateSpaceDeveloper(spaceGUID, userGUID string) (Space, error) {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.AssociateDeveloper(userGUID)
|
|
}
|
|
|
|
func (c *Client) AssociateSpaceDeveloperByUsername(spaceGUID, name string) (Space, error) {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.AssociateDeveloperByUsername(name)
|
|
}
|
|
|
|
func (c *Client) AssociateSpaceDeveloperByUsernameAndOrigin(spaceGUID, name, origin string) (Space, error) {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.AssociateDeveloperByUsernameAndOrigin(name, origin)
|
|
}
|
|
|
|
func (c *Client) RemoveSpaceDeveloper(spaceGUID, userGUID string) error {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.RemoveDeveloper(userGUID)
|
|
}
|
|
|
|
func (c *Client) RemoveSpaceDeveloperByUsername(spaceGUID, name string) error {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.RemoveDeveloperByUsername(name)
|
|
}
|
|
|
|
func (c *Client) RemoveSpaceDeveloperByUsernameAndOrigin(spaceGUID, name, origin string) error {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.RemoveDeveloperByUsernameAndOrigin(name, origin)
|
|
}
|
|
|
|
func (c *Client) AssociateSpaceAuditor(spaceGUID, userGUID string) (Space, error) {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.AssociateAuditor(userGUID)
|
|
}
|
|
|
|
func (c *Client) AssociateSpaceAuditorByUsername(spaceGUID, name string) (Space, error) {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.AssociateAuditorByUsername(name)
|
|
}
|
|
|
|
func (c *Client) AssociateSpaceAuditorByUsernameAndOrigin(spaceGUID, name, origin string) (Space, error) {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.AssociateAuditorByUsernameAndOrigin(name, origin)
|
|
}
|
|
|
|
func (c *Client) RemoveSpaceAuditor(spaceGUID, userGUID string) error {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.RemoveAuditor(userGUID)
|
|
}
|
|
|
|
func (c *Client) RemoveSpaceAuditorByUsername(spaceGUID, name string) error {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.RemoveAuditorByUsername(name)
|
|
}
|
|
|
|
func (c *Client) RemoveSpaceAuditorByUsernameAndOrigin(spaceGUID, name, origin string) error {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.RemoveAuditorByUsernameAndOrigin(name, origin)
|
|
}
|
|
|
|
func (c *Client) AssociateSpaceManager(spaceGUID, userGUID string) (Space, error) {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.AssociateManager(userGUID)
|
|
}
|
|
|
|
func (c *Client) AssociateSpaceManagerByUsername(spaceGUID, name string) (Space, error) {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.AssociateManagerByUsername(name)
|
|
}
|
|
|
|
func (c *Client) AssociateSpaceManagerByUsernameAndOrigin(spaceGUID, name, origin string) (Space, error) {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.AssociateManagerByUsernameAndOrigin(name, origin)
|
|
}
|
|
|
|
func (c *Client) RemoveSpaceManager(spaceGUID, userGUID string) error {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.RemoveManager(userGUID)
|
|
}
|
|
|
|
func (c *Client) RemoveSpaceManagerByUsername(spaceGUID, name string) error {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.RemoveManagerByUsername(name)
|
|
}
|
|
|
|
func (c *Client) RemoveSpaceManagerByUsernameAndOrigin(spaceGUID, name, origin string) error {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.RemoveManagerByUsernameAndOrigin(name, origin)
|
|
}
|
|
|
|
func (s *Space) AssociateDeveloper(userGUID string) (Space, error) {
|
|
return s.associateRole(userGUID, "developers")
|
|
}
|
|
|
|
func (s *Space) AssociateDeveloperByUsername(name string) (Space, error) {
|
|
return s.associateUserByRole(name, "developers", "")
|
|
}
|
|
|
|
func (s *Space) AssociateDeveloperByUsernameAndOrigin(name, origin string) (Space, error) {
|
|
return s.associateUserByRole(name, "developers", origin)
|
|
}
|
|
|
|
func (s *Space) RemoveDeveloper(userGUID string) error {
|
|
return s.removeRole(userGUID, "developers")
|
|
}
|
|
|
|
func (s *Space) RemoveDeveloperByUsername(name string) error {
|
|
return s.removeUserByRole(name, "developers", "")
|
|
}
|
|
|
|
func (s *Space) RemoveDeveloperByUsernameAndOrigin(name, origin string) error {
|
|
return s.removeUserByRole(name, "developers", origin)
|
|
}
|
|
|
|
func (s *Space) AssociateAuditor(userGUID string) (Space, error) {
|
|
return s.associateRole(userGUID, "auditors")
|
|
}
|
|
|
|
func (s *Space) AssociateAuditorByUsername(name string) (Space, error) {
|
|
return s.associateUserByRole(name, "auditors", "")
|
|
}
|
|
|
|
func (s *Space) AssociateAuditorByUsernameAndOrigin(name, origin string) (Space, error) {
|
|
return s.associateUserByRole(name, "auditors", origin)
|
|
}
|
|
|
|
func (s *Space) RemoveAuditor(userGUID string) error {
|
|
return s.removeRole(userGUID, "auditors")
|
|
}
|
|
|
|
func (s *Space) RemoveAuditorByUsername(name string) error {
|
|
return s.removeUserByRole(name, "auditors", "")
|
|
}
|
|
|
|
func (s *Space) RemoveAuditorByUsernameAndOrigin(name, origin string) error {
|
|
return s.removeUserByRole(name, "auditors", origin)
|
|
}
|
|
|
|
func (s *Space) AssociateManager(userGUID string) (Space, error) {
|
|
return s.associateRole(userGUID, "managers")
|
|
}
|
|
|
|
func (s *Space) AssociateManagerByUsername(name string) (Space, error) {
|
|
return s.associateUserByRole(name, "managers", "")
|
|
}
|
|
|
|
func (s *Space) AssociateManagerByUsernameAndOrigin(name, origin string) (Space, error) {
|
|
return s.associateUserByRole(name, "managers", origin)
|
|
}
|
|
|
|
func (s *Space) RemoveManager(userGUID string) error {
|
|
return s.removeRole(userGUID, "managers")
|
|
}
|
|
|
|
func (s *Space) RemoveManagerByUsername(name string) error {
|
|
return s.removeUserByRole(name, "managers", "")
|
|
}
|
|
func (s *Space) RemoveManagerByUsernameAndOrigin(name, origin string) error {
|
|
return s.removeUserByRole(name, "managers", origin)
|
|
}
|
|
|
|
func (s *Space) associateRole(userGUID, role string) (Space, error) {
|
|
requestUrl := fmt.Sprintf("/v2/spaces/%s/%s/%s", s.Guid, role, userGUID)
|
|
r := s.c.NewRequest("PUT", requestUrl)
|
|
resp, err := s.c.DoRequest(r)
|
|
if err != nil {
|
|
return Space{}, err
|
|
}
|
|
if resp.StatusCode != http.StatusCreated {
|
|
return Space{}, errors.Wrapf(err, "Error associating %s %s, response code: %d", role, userGUID, resp.StatusCode)
|
|
}
|
|
return s.c.handleSpaceResp(resp)
|
|
}
|
|
|
|
func (s *Space) associateUserByRole(name, role, origin string) (Space, error) {
|
|
requestUrl := fmt.Sprintf("/v2/spaces/%s/%s", s.Guid, role)
|
|
buf := bytes.NewBuffer(nil)
|
|
payload := make(map[string]string)
|
|
payload["username"] = name
|
|
if origin != "" {
|
|
payload["origin"] = origin
|
|
}
|
|
err := json.NewEncoder(buf).Encode(payload)
|
|
if err != nil {
|
|
return Space{}, err
|
|
}
|
|
r := s.c.NewRequestWithBody("PUT", requestUrl, buf)
|
|
resp, err := s.c.DoRequest(r)
|
|
if err != nil {
|
|
return Space{}, err
|
|
}
|
|
if resp.StatusCode != http.StatusCreated {
|
|
return Space{}, errors.Wrapf(err, "Error associating %s %s, response code: %d", role, name, resp.StatusCode)
|
|
}
|
|
return s.c.handleSpaceResp(resp)
|
|
}
|
|
|
|
func (s *Space) removeRole(userGUID, role string) error {
|
|
requestUrl := fmt.Sprintf("/v2/spaces/%s/%s/%s", s.Guid, role, userGUID)
|
|
r := s.c.NewRequest("DELETE", requestUrl)
|
|
resp, err := s.c.DoRequest(r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if resp.StatusCode != http.StatusNoContent {
|
|
return errors.Wrapf(err, "Error removing %s %s, response code: %d", role, userGUID, resp.StatusCode)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *Space) removeUserByRole(name, role, origin string) error {
|
|
var requestURL string
|
|
var method string
|
|
|
|
buf := bytes.NewBuffer(nil)
|
|
payload := make(map[string]string)
|
|
payload["username"] = name
|
|
if origin != "" {
|
|
payload["origin"] = origin
|
|
requestURL = fmt.Sprintf("/v2/spaces/%s/%s/remove", s.Guid, role)
|
|
method = "POST"
|
|
} else {
|
|
requestURL = fmt.Sprintf("/v2/spaces/%s/%s", s.Guid, role)
|
|
method = "DELETE"
|
|
}
|
|
err := json.NewEncoder(buf).Encode(payload)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
r := s.c.NewRequestWithBody(method, requestURL, buf)
|
|
resp, err := s.c.DoRequest(r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if resp.StatusCode != http.StatusOK {
|
|
return errors.Wrapf(err, "Error removing %s %s, response code: %d", role, name, resp.StatusCode)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *Client) ListSpaceSecGroups(spaceGUID string) (secGroups []SecGroup, err error) {
|
|
space := Space{Guid: spaceGUID, c: c}
|
|
return space.ListSecGroups()
|
|
}
|
|
|
|
func (s *Space) ListSecGroups() (secGroups []SecGroup, err error) {
|
|
requestURL := fmt.Sprintf("/v2/spaces/%s/security_groups?inline-relations-depth=1", s.Guid)
|
|
for requestURL != "" {
|
|
var secGroupResp SecGroupResponse
|
|
r := s.c.NewRequest("GET", requestURL)
|
|
resp, err := s.c.DoRequest(r)
|
|
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "Error requesting sec groups")
|
|
}
|
|
resBody, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "Error reading sec group response body")
|
|
}
|
|
|
|
err = json.Unmarshal(resBody, &secGroupResp)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "Error unmarshaling sec group")
|
|
}
|
|
|
|
for _, secGroup := range secGroupResp.Resources {
|
|
secGroup.Entity.Guid = secGroup.Meta.Guid
|
|
secGroup.Entity.c = s.c
|
|
for i, space := range secGroup.Entity.SpacesData {
|
|
space.Entity.Guid = space.Meta.Guid
|
|
secGroup.Entity.SpacesData[i] = space
|
|
}
|
|
if len(secGroup.Entity.SpacesData) == 0 {
|
|
spaces, err := secGroup.Entity.ListSpaceResources()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, space := range spaces {
|
|
secGroup.Entity.SpacesData = append(secGroup.Entity.SpacesData, space)
|
|
}
|
|
}
|
|
secGroups = append(secGroups, secGroup.Entity)
|
|
}
|
|
|
|
requestURL = secGroupResp.NextUrl
|
|
resp.Body.Close()
|
|
}
|
|
return secGroups, nil
|
|
}
|
|
|
|
func (s *Space) GetServiceOfferings() (ServiceOfferingResponse, error) {
|
|
var response ServiceOfferingResponse
|
|
requestURL := fmt.Sprintf("/v2/spaces/%s/services", s.Guid)
|
|
req := s.c.NewRequest("GET", requestURL)
|
|
|
|
resp, err := s.c.DoRequest(req)
|
|
if err != nil {
|
|
return ServiceOfferingResponse{}, errors.Wrap(err, "Error requesting service offerings")
|
|
}
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return ServiceOfferingResponse{}, errors.Wrap(err, "Error reading service offering response")
|
|
}
|
|
|
|
err = json.Unmarshal(body, &response)
|
|
if err != nil {
|
|
return ServiceOfferingResponse{}, errors.Wrap(err, "Error unmarshalling service offering response")
|
|
}
|
|
|
|
return response, nil
|
|
}
|
|
|
|
func (s *Space) Update(req SpaceRequest) (Space, error) {
|
|
buf := bytes.NewBuffer(nil)
|
|
err := json.NewEncoder(buf).Encode(req)
|
|
if err != nil {
|
|
return Space{}, err
|
|
}
|
|
r := s.c.NewRequestWithBody("PUT", fmt.Sprintf("/v2/spaces/%s", s.Guid), buf)
|
|
resp, err := s.c.DoRequest(r)
|
|
if err != nil {
|
|
return Space{}, err
|
|
}
|
|
if resp.StatusCode != http.StatusCreated {
|
|
return Space{}, fmt.Errorf("CF API returned with status code %d", resp.StatusCode)
|
|
}
|
|
return s.c.handleSpaceResp(resp)
|
|
}
|
|
|
|
func (c *Client) ListSpacesByQuery(query url.Values) ([]Space, error) {
|
|
return c.fetchSpaces("/v2/spaces?" + query.Encode())
|
|
}
|
|
|
|
func (c *Client) ListSpaces() ([]Space, error) {
|
|
return c.ListSpacesByQuery(nil)
|
|
}
|
|
|
|
func (c *Client) fetchSpaces(requestUrl string) ([]Space, error) {
|
|
var spaces []Space
|
|
for {
|
|
spaceResp, err := c.getSpaceResponse(requestUrl)
|
|
if err != nil {
|
|
return []Space{}, err
|
|
}
|
|
for _, space := range spaceResp.Resources {
|
|
spaces = append(spaces, c.mergeSpaceResource(space))
|
|
}
|
|
requestUrl = spaceResp.NextUrl
|
|
if requestUrl == "" {
|
|
break
|
|
}
|
|
}
|
|
return spaces, nil
|
|
}
|
|
|
|
func (c *Client) GetSpaceByName(spaceName string, orgGuid string) (space Space, err error) {
|
|
query := url.Values{}
|
|
query.Add("q", fmt.Sprintf("organization_guid:%s", orgGuid))
|
|
query.Add("q", fmt.Sprintf("name:%s", spaceName))
|
|
spaces, err := c.ListSpacesByQuery(query)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if len(spaces) == 0 {
|
|
return space, fmt.Errorf("No space found with name: `%s` in org with GUID: `%s`", spaceName, orgGuid)
|
|
}
|
|
|
|
return spaces[0], nil
|
|
|
|
}
|
|
|
|
func (c *Client) GetSpaceByGuid(spaceGUID string) (Space, error) {
|
|
requestUrl := fmt.Sprintf("/v2/spaces/%s", spaceGUID)
|
|
r := c.NewRequest("GET", requestUrl)
|
|
resp, err := c.DoRequest(r)
|
|
if err != nil {
|
|
return Space{}, errors.Wrap(err, "Error requesting space info")
|
|
}
|
|
return c.handleSpaceResp(resp)
|
|
}
|
|
|
|
func (c *Client) getSpaceResponse(requestUrl string) (SpaceResponse, error) {
|
|
var spaceResp SpaceResponse
|
|
r := c.NewRequest("GET", requestUrl)
|
|
resp, err := c.DoRequest(r)
|
|
if err != nil {
|
|
return SpaceResponse{}, errors.Wrap(err, "Error requesting spaces")
|
|
}
|
|
resBody, err := ioutil.ReadAll(resp.Body)
|
|
defer resp.Body.Close()
|
|
if err != nil {
|
|
return SpaceResponse{}, errors.Wrap(err, "Error reading space request")
|
|
}
|
|
err = json.Unmarshal(resBody, &spaceResp)
|
|
if err != nil {
|
|
return SpaceResponse{}, errors.Wrap(err, "Error unmarshalling space")
|
|
}
|
|
return spaceResp, nil
|
|
}
|
|
|
|
func (c *Client) getSpaceRolesResponse(requestUrl string) (SpaceRoleResponse, error) {
|
|
var roleResp SpaceRoleResponse
|
|
r := c.NewRequest("GET", requestUrl)
|
|
resp, err := c.DoRequest(r)
|
|
if err != nil {
|
|
return roleResp, errors.Wrap(err, "Error requesting space roles")
|
|
}
|
|
resBody, err := ioutil.ReadAll(resp.Body)
|
|
defer resp.Body.Close()
|
|
if err != nil {
|
|
return roleResp, errors.Wrap(err, "Error reading space roles request")
|
|
}
|
|
err = json.Unmarshal(resBody, &roleResp)
|
|
if err != nil {
|
|
return roleResp, errors.Wrap(err, "Error unmarshalling space roles")
|
|
}
|
|
return roleResp, nil
|
|
}
|
|
|
|
func (c *Client) handleSpaceResp(resp *http.Response) (Space, error) {
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
defer resp.Body.Close()
|
|
if err != nil {
|
|
return Space{}, err
|
|
}
|
|
var spaceResource SpaceResource
|
|
err = json.Unmarshal(body, &spaceResource)
|
|
if err != nil {
|
|
return Space{}, err
|
|
}
|
|
return c.mergeSpaceResource(spaceResource), nil
|
|
}
|
|
|
|
func (c *Client) mergeSpaceResource(space SpaceResource) Space {
|
|
space.Entity.Guid = space.Meta.Guid
|
|
space.Entity.CreatedAt = space.Meta.CreatedAt
|
|
space.Entity.UpdatedAt = space.Meta.UpdatedAt
|
|
space.Entity.c = c
|
|
return space.Entity
|
|
}
|
|
|
|
type serviceOfferingExtra ServiceOfferingExtra
|
|
|
|
func (resource *ServiceOfferingExtra) UnmarshalJSON(rawData []byte) error {
|
|
if string(rawData) == "null" {
|
|
return nil
|
|
}
|
|
|
|
extra := serviceOfferingExtra{}
|
|
|
|
unquoted, err := strconv.Unquote(string(rawData))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = json.Unmarshal([]byte(unquoted), &extra)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
*resource = ServiceOfferingExtra(extra)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *Client) IsolationSegmentForSpace(spaceGUID, isolationSegmentGUID string) error {
|
|
return c.updateSpaceIsolationSegment(spaceGUID, map[string]interface{}{"guid": isolationSegmentGUID})
|
|
}
|
|
|
|
func (c *Client) ResetIsolationSegmentForSpace(spaceGUID string) error {
|
|
return c.updateSpaceIsolationSegment(spaceGUID, nil)
|
|
}
|
|
|
|
func (c *Client) updateSpaceIsolationSegment(spaceGUID string, data interface{}) error {
|
|
requestURL := fmt.Sprintf("/v3/spaces/%s/relationships/isolation_segment", spaceGUID)
|
|
buf := bytes.NewBuffer(nil)
|
|
err := json.NewEncoder(buf).Encode(map[string]interface{}{"data": data})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
r := c.NewRequestWithBody("PATCH", requestURL, buf)
|
|
resp, err := c.DoRequest(r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if resp.StatusCode != http.StatusOK {
|
|
return errors.Wrapf(err, "Error setting isolation segment for space %s, response code: %d", spaceGUID, resp.StatusCode)
|
|
}
|
|
return nil
|
|
}
|