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 SpaceQuotasResponse struct { 15 Count int `json:"total_results"` 16 Pages int `json:"total_pages"` 17 NextUrl string `json:"next_url"` 18 Resources []SpaceQuotasResource `json:"resources"` 19} 20 21type SpaceQuotasResource struct { 22 Meta Meta `json:"metadata"` 23 Entity SpaceQuota `json:"entity"` 24} 25 26type SpaceQuotaRequest struct { 27 Name string `json:"name"` 28 OrganizationGuid string `json:"organization_guid"` 29 NonBasicServicesAllowed bool `json:"non_basic_services_allowed"` 30 TotalServices int `json:"total_services"` 31 TotalRoutes int `json:"total_routes"` 32 MemoryLimit int `json:"memory_limit"` 33 InstanceMemoryLimit int `json:"instance_memory_limit"` 34 AppInstanceLimit int `json:"app_instance_limit"` 35 AppTaskLimit int `json:"app_task_limit"` 36 TotalServiceKeys int `json:"total_service_keys"` 37 TotalReservedRoutePorts int `json:"total_reserved_route_ports"` 38} 39 40type SpaceQuota struct { 41 Guid string `json:"guid"` 42 CreatedAt string `json:"created_at,omitempty"` 43 UpdatedAt string `json:"updated_at,omitempty"` 44 Name string `json:"name"` 45 OrganizationGuid string `json:"organization_guid"` 46 NonBasicServicesAllowed bool `json:"non_basic_services_allowed"` 47 TotalServices int `json:"total_services"` 48 TotalRoutes int `json:"total_routes"` 49 MemoryLimit int `json:"memory_limit"` 50 InstanceMemoryLimit int `json:"instance_memory_limit"` 51 AppInstanceLimit int `json:"app_instance_limit"` 52 AppTaskLimit int `json:"app_task_limit"` 53 TotalServiceKeys int `json:"total_service_keys"` 54 TotalReservedRoutePorts int `json:"total_reserved_route_ports"` 55 c *Client 56} 57 58func (c *Client) ListSpaceQuotasByQuery(query url.Values) ([]SpaceQuota, error) { 59 var spaceQuotas []SpaceQuota 60 requestUrl := "/v2/space_quota_definitions?" + query.Encode() 61 for { 62 spaceQuotasResp, err := c.getSpaceQuotasResponse(requestUrl) 63 if err != nil { 64 return []SpaceQuota{}, err 65 } 66 for _, space := range spaceQuotasResp.Resources { 67 space.Entity.Guid = space.Meta.Guid 68 space.Entity.CreatedAt = space.Meta.CreatedAt 69 space.Entity.UpdatedAt = space.Meta.UpdatedAt 70 space.Entity.c = c 71 spaceQuotas = append(spaceQuotas, space.Entity) 72 } 73 requestUrl = spaceQuotasResp.NextUrl 74 if requestUrl == "" { 75 break 76 } 77 } 78 return spaceQuotas, nil 79} 80 81func (c *Client) ListSpaceQuotas() ([]SpaceQuota, error) { 82 return c.ListSpaceQuotasByQuery(nil) 83} 84 85func (c *Client) GetSpaceQuotaByName(name string) (SpaceQuota, error) { 86 q := url.Values{} 87 q.Set("q", "name:"+name) 88 spaceQuotas, err := c.ListSpaceQuotasByQuery(q) 89 if err != nil { 90 return SpaceQuota{}, err 91 } 92 if len(spaceQuotas) != 1 { 93 return SpaceQuota{}, fmt.Errorf("Unable to find space quota " + name) 94 } 95 return spaceQuotas[0], nil 96} 97 98func (c *Client) getSpaceQuotasResponse(requestUrl string) (SpaceQuotasResponse, error) { 99 var spaceQuotasResp SpaceQuotasResponse 100 r := c.NewRequest("GET", requestUrl) 101 resp, err := c.DoRequest(r) 102 if err != nil { 103 return SpaceQuotasResponse{}, errors.Wrap(err, "Error requesting space quotas") 104 } 105 resBody, err := ioutil.ReadAll(resp.Body) 106 defer resp.Body.Close() 107 if err != nil { 108 return SpaceQuotasResponse{}, errors.Wrap(err, "Error reading space quotas body") 109 } 110 err = json.Unmarshal(resBody, &spaceQuotasResp) 111 if err != nil { 112 return SpaceQuotasResponse{}, errors.Wrap(err, "Error unmarshalling space quotas") 113 } 114 return spaceQuotasResp, nil 115} 116 117func (c *Client) AssignSpaceQuota(quotaGUID, spaceGUID string) error { 118 //Perform the PUT and check for errors 119 resp, err := c.DoRequest(c.NewRequest("PUT", fmt.Sprintf("/v2/space_quota_definitions/%s/spaces/%s", quotaGUID, spaceGUID))) 120 if err != nil { 121 return err 122 } 123 if resp.StatusCode != http.StatusCreated { //201 124 return fmt.Errorf("CF API returned with status code %d", resp.StatusCode) 125 } 126 return nil 127} 128 129func (c *Client) CreateSpaceQuota(spaceQuote SpaceQuotaRequest) (*SpaceQuota, error) { 130 buf := bytes.NewBuffer(nil) 131 err := json.NewEncoder(buf).Encode(spaceQuote) 132 if err != nil { 133 return nil, err 134 } 135 r := c.NewRequestWithBody("POST", "/v2/space_quota_definitions", buf) 136 resp, err := c.DoRequest(r) 137 if err != nil { 138 return nil, err 139 } 140 if resp.StatusCode != http.StatusCreated { 141 return nil, fmt.Errorf("CF API returned with status code %d", resp.StatusCode) 142 } 143 return c.handleSpaceQuotaResp(resp) 144} 145 146func (c *Client) UpdateSpaceQuota(spaceQuotaGUID string, spaceQuote SpaceQuotaRequest) (*SpaceQuota, error) { 147 buf := bytes.NewBuffer(nil) 148 err := json.NewEncoder(buf).Encode(spaceQuote) 149 if err != nil { 150 return nil, err 151 } 152 r := c.NewRequestWithBody("PUT", fmt.Sprintf("/v2/space_quota_definitions/%s", spaceQuotaGUID), buf) 153 resp, err := c.DoRequest(r) 154 if err != nil { 155 return nil, err 156 } 157 if resp.StatusCode != http.StatusCreated { 158 return nil, fmt.Errorf("CF API returned with status code %d", resp.StatusCode) 159 } 160 return c.handleSpaceQuotaResp(resp) 161} 162 163func (c *Client) handleSpaceQuotaResp(resp *http.Response) (*SpaceQuota, error) { 164 body, err := ioutil.ReadAll(resp.Body) 165 defer resp.Body.Close() 166 if err != nil { 167 return nil, err 168 } 169 var spaceQuotasResource SpaceQuotasResource 170 err = json.Unmarshal(body, &spaceQuotasResource) 171 if err != nil { 172 return nil, err 173 } 174 return c.mergeSpaceQuotaResource(spaceQuotasResource), nil 175} 176 177func (c *Client) mergeSpaceQuotaResource(spaceQuote SpaceQuotasResource) *SpaceQuota { 178 spaceQuote.Entity.Guid = spaceQuote.Meta.Guid 179 spaceQuote.Entity.CreatedAt = spaceQuote.Meta.CreatedAt 180 spaceQuote.Entity.UpdatedAt = spaceQuote.Meta.UpdatedAt 181 spaceQuote.Entity.c = c 182 return &spaceQuote.Entity 183} 184