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