From 76069c79df1296f845e4f0a424a4f77e69c8d4e9 Mon Sep 17 00:00:00 2001 From: Chris Branch Date: Mon, 24 Jul 2017 18:51:09 +0100 Subject: [PATCH] [feat] Load Balancers, User LB Monitors, User LB Pools --- README.md | 1 + load_balancing.go | 323 ++++++++++ load_balancing_test.go | 1262 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1586 insertions(+) create mode 100644 load_balancing.go create mode 100644 load_balancing_test.go diff --git a/README.md b/README.md index 536bd97a20..14e2581931 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ The current feature list includes: - [ ] [Railgun](https://www.cloudflare.com/railgun/) administration - [ ] [Keyless SSL](https://blog.cloudflare.com/keyless-ssl-the-nitty-gritty-technical-details/) - [x] [Origin CA](https://blog.cloudflare.com/universal-ssl-encryption-all-the-way-to-the-origin-for-free/) +- [x] Load Balancing (user pools and monitors only) Pull Requests are welcome, but please open an issue (or comment in an existing issue) to discuss any non-trivial changes before submitting code. diff --git a/load_balancing.go b/load_balancing.go new file mode 100644 index 0000000000..b726227cab --- /dev/null +++ b/load_balancing.go @@ -0,0 +1,323 @@ +package cloudflare + +import ( + "encoding/json" + "time" + + "github.com/pkg/errors" +) + +// LoadBalancerPool represents a load balancer pool's properties. +type LoadBalancerPool struct { + ID string `json:"id,omitempty"` + CreatedOn *time.Time `json:"created_on,omitempty"` + ModifiedOn *time.Time `json:"modified_on,omitempty"` + Description string `json:"description"` + Name string `json:"name"` + Enabled bool `json:"enabled"` + Monitor string `json:"monitor,omitempty"` + Origins []LoadBalancerOrigin `json:"origins"` + NotificationEmail string `json:"notification_email,omitempty"` +} + +type LoadBalancerOrigin struct { + Name string `json:"name"` + Address string `json:"address"` + Enabled bool `json:"enabled"` +} + +// LoadBalancerMonitor represents a load balancer monitor's properties. +type LoadBalancerMonitor struct { + ID string `json:"id,omitempty"` + CreatedOn *time.Time `json:"created_on,omitempty"` + ModifiedOn *time.Time `json:"modified_on,omitempty"` + Type string `json:"type"` + Description string `json:"description"` + Method string `json:"method"` + Path string `json:"path"` + Header map[string][]string `json:"header"` + Timeout int `json:"timeout"` + Retries int `json:"retries"` + Interval int `json:"interval"` + ExpectedBody string `json:"expected_body"` + ExpectedCodes string `json:"expected_codes"` +} + +// LoadBalancer represents a load balancer's properties. +type LoadBalancer struct { + ID string `json:"id,omitempty"` + CreatedOn *time.Time `json:"created_on,omitempty"` + ModifiedOn *time.Time `json:"modified_on,omitempty"` + Description string `json:"description"` + Name string `json:"name"` + TTL int `json:"ttl"` + FallbackPool string `json:"fallback_pool"` + DefaultPools []string `json:"default_pools"` + RegionPools map[string][]string `json:"region_pools"` + PopPools map[string][]string `json:"pop_pools"` + Proxied bool `json:"proxied"` +} + +// loadBalancerPoolResponse represents the response from the load balancer pool endpoints. +type loadBalancerPoolResponse struct { + Response + Result LoadBalancerPool `json:"result"` +} + +// loadBalancerPoolListResponse represents the response from the List Pools endpoint. +type loadBalancerPoolListResponse struct { + Response + Result []LoadBalancerPool `json:"result"` + ResultInfo ResultInfo `json:"result_info"` +} + +// loadBalancerMonitorResponse represents the response from the load balancer monitor endpoints. +type loadBalancerMonitorResponse struct { + Response + Result LoadBalancerMonitor `json:"result"` +} + +// loadBalancerMonitorListResponse represents the response from the List Monitors endpoint. +type loadBalancerMonitorListResponse struct { + Response + Result []LoadBalancerMonitor `json:"result"` + ResultInfo ResultInfo `json:"result_info"` +} + +// loadBalancerResponse represents the response from the load balancer endpoints. +type loadBalancerResponse struct { + Response + Result LoadBalancer `json:"result"` +} + +// loadBalancerListResponse represents the response from the List Load Balancers endpoint. +type loadBalancerListResponse struct { + Response + Result []LoadBalancer `json:"result"` + ResultInfo ResultInfo `json:"result_info"` +} + +// CreateLoadBalancerPool creates a new load balancer pool. +// +// API reference: https://api.cloudflare.com/#load-balancer-pools-create-a-pool +func (api *API) CreateLoadBalancerPool(pool LoadBalancerPool) (LoadBalancerPool, error) { + uri := "/user/load_balancers/pools" + res, err := api.makeRequest("POST", uri, pool) + if err != nil { + return LoadBalancerPool{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerPoolResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancerPool{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ListLoadBalancerPools lists load balancer pools connected to an account. +// +// API reference: https://api.cloudflare.com/#load-balancer-pools-list-pools +func (api *API) ListLoadBalancerPools() ([]LoadBalancerPool, error) { + uri := "/user/load_balancers/pools" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerPoolListResponse + if err := json.Unmarshal(res, &r); err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// LoadBalancerPoolDetails returns the details for a load balancer pool. +// +// API reference: https://api.cloudflare.com/#load-balancer-pools-pool-details +func (api *API) LoadBalancerPoolDetails(poolID string) (LoadBalancerPool, error) { + uri := "/user/load_balancers/pools/" + poolID + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return LoadBalancerPool{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerPoolResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancerPool{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// DeleteLoadBalancerPool disables and deletes a load balancer pool. +// +// API reference: https://api.cloudflare.com/#load-balancer-pools-delete-a-pool +func (api *API) DeleteLoadBalancerPool(poolID string) error { + uri := "/user/load_balancers/pools/" + poolID + if _, err := api.makeRequest("DELETE", uri, nil); err != nil { + return errors.Wrap(err, errMakeRequestError) + } + return nil +} + +// ModifyLoadBalancerPool modifies a configured load balancer pool. +// +// API reference: https://api.cloudflare.com/#load-balancer-pools-modify-a-pool +func (api *API) ModifyLoadBalancerPool(pool LoadBalancerPool) (LoadBalancerPool, error) { + uri := "/user/load_balancers/pools/" + pool.ID + res, err := api.makeRequest("PUT", uri, pool) + if err != nil { + return LoadBalancerPool{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerPoolResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancerPool{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// CreateLoadBalancerMonitor creates a new load balancer monitor. +// +// API reference: https://api.cloudflare.com/#load-balancer-monitors-create-a-monitor +func (api *API) CreateLoadBalancerMonitor(monitor LoadBalancerMonitor) (LoadBalancerMonitor, error) { + uri := "/user/load_balancers/monitors" + res, err := api.makeRequest("POST", uri, monitor) + if err != nil { + return LoadBalancerMonitor{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerMonitorResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancerMonitor{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ListLoadBalancerMonitors lists load balancer monitors connected to an account. +// +// API reference: https://api.cloudflare.com/#load-balancer-monitors-list-monitors +func (api *API) ListLoadBalancerMonitors() ([]LoadBalancerMonitor, error) { + uri := "/user/load_balancers/monitors" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerMonitorListResponse + if err := json.Unmarshal(res, &r); err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// LoadBalancerMonitorDetails returns the details for a load balancer monitor. +// +// API reference: https://api.cloudflare.com/#load-balancer-monitors-monitor-details +func (api *API) LoadBalancerMonitorDetails(monitorID string) (LoadBalancerMonitor, error) { + uri := "/user/load_balancers/monitors/" + monitorID + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return LoadBalancerMonitor{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerMonitorResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancerMonitor{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// DeleteLoadBalancerMonitor disables and deletes a load balancer monitor. +// +// API reference: https://api.cloudflare.com/#load-balancer-monitors-delete-a-monitor +func (api *API) DeleteLoadBalancerMonitor(monitorID string) error { + uri := "/user/load_balancers/monitors/" + monitorID + if _, err := api.makeRequest("DELETE", uri, nil); err != nil { + return errors.Wrap(err, errMakeRequestError) + } + return nil +} + +// ModifyLoadBalancerMonitor modifies a configured load balancer monitor. +// +// API reference: https://api.cloudflare.com/#load-balancer-monitors-modify-a-monitor +func (api *API) ModifyLoadBalancerMonitor(monitor LoadBalancerMonitor) (LoadBalancerMonitor, error) { + uri := "/user/load_balancers/monitors/" + monitor.ID + res, err := api.makeRequest("PUT", uri, monitor) + if err != nil { + return LoadBalancerMonitor{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerMonitorResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancerMonitor{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// CreateLoadBalancer creates a new load balancer. +// +// API reference: https://api.cloudflare.com/#load-balancers-create-a-load-balancer +func (api *API) CreateLoadBalancer(zoneID string, lb LoadBalancer) (LoadBalancer, error) { + uri := "/zones/" + zoneID + "/load_balancers" + res, err := api.makeRequest("POST", uri, lb) + if err != nil { + return LoadBalancer{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancer{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ListLoadBalancers lists load balancers configured on a zone. +// +// API reference: https://api.cloudflare.com/#load-balancers-list-load-balancers +func (api *API) ListLoadBalancers(zoneID string) ([]LoadBalancer, error) { + uri := "/zones/" + zoneID + "/load_balancers" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerListResponse + if err := json.Unmarshal(res, &r); err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// LoadBalancerDetails returns the details for a load balancer. +// +// API reference: https://api.cloudflare.com/#load-balancers-load-balancer-details +func (api *API) LoadBalancerDetails(zoneID, lbID string) (LoadBalancer, error) { + uri := "/zones/" + zoneID + "/load_balancers/" + lbID + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return LoadBalancer{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancer{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// DeleteLoadBalancer disables and deletes a load balancer. +// +// API reference: https://api.cloudflare.com/#load-balancers-delete-a-load-balancer +func (api *API) DeleteLoadBalancer(zoneID, lbID string) error { + uri := "/zones/" + zoneID + "/load_balancers/" + lbID + if _, err := api.makeRequest("DELETE", uri, nil); err != nil { + return errors.Wrap(err, errMakeRequestError) + } + return nil +} + +// ModifyLoadBalancer modifies a configured load balancer. +// +// API reference: https://api.cloudflare.com/#load-balancers-modify-a-load-balancer +func (api *API) ModifyLoadBalancer(zoneID string, lb LoadBalancer) (LoadBalancer, error) { + uri := "/zones/" + zoneID + "/load_balancers/" + lb.ID + res, err := api.makeRequest("PUT", uri, lb) + if err != nil { + return LoadBalancer{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancer{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} diff --git a/load_balancing_test.go b/load_balancing_test.go new file mode 100644 index 0000000000..478fee4452 --- /dev/null +++ b/load_balancing_test.go @@ -0,0 +1,1262 @@ +package cloudflare + +import ( + "fmt" + "io/ioutil" + "net/http" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestCreateLoadBalancerPool(t *testing.T) { + setup() + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.Method, "POST", "Expected method 'POST', got %s", r.Method) + w.Header().Set("content-type", "application/json") + b, err := ioutil.ReadAll(r.Body) + defer r.Body.Close() + if assert.NoError(t, err) { + assert.JSONEq(t, `{ + "description": "Primary data center - Provider XYZ", + "name": "primary-dc-1", + "enabled": true, + "monitor": "f1aba936b94213e5b8dca0c0dbf1f9cc", + "origins": [ + { + "name": "app-server-1", + "address": "0.0.0.0", + "enabled": true + } + ], + "notification_email": "someone@example.com" + }`, string(b)) + } + fmt.Fprint(w, `{ + "success": true, + "errors": [], + "messages": [], + "result": { + "id": "17b5962d775c646f3f9725cbc7a53df4", + "created_on": "2014-01-01T05:20:00.12345Z", + "modified_on": "2014-02-01T05:20:00.12345Z", + "description": "Primary data center - Provider XYZ", + "name": "primary-dc-1", + "enabled": true, + "monitor": "f1aba936b94213e5b8dca0c0dbf1f9cc", + "origins": [ + { + "name": "app-server-1", + "address": "0.0.0.0", + "enabled": true + } + ], + "notification_email": "someone@example.com" + } + }`) + } + + mux.HandleFunc("/user/load_balancers/pools", handler) + createdOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z") + modifiedOn, _ := time.Parse(time.RFC3339, "2014-02-01T05:20:00.12345Z") + want := LoadBalancerPool{ + ID: "17b5962d775c646f3f9725cbc7a53df4", + CreatedOn: &createdOn, + ModifiedOn: &modifiedOn, + Description: "Primary data center - Provider XYZ", + Name: "primary-dc-1", + Enabled: true, + Monitor: "f1aba936b94213e5b8dca0c0dbf1f9cc", + Origins: []LoadBalancerOrigin{ + { + Name: "app-server-1", + Address: "0.0.0.0", + Enabled: true, + }, + }, + NotificationEmail: "someone@example.com", + } + request := LoadBalancerPool{ + Description: "Primary data center - Provider XYZ", + Name: "primary-dc-1", + Enabled: true, + Monitor: "f1aba936b94213e5b8dca0c0dbf1f9cc", + Origins: []LoadBalancerOrigin{ + { + Name: "app-server-1", + Address: "0.0.0.0", + Enabled: true, + }, + }, + NotificationEmail: "someone@example.com", + } + + actual, err := client.CreateLoadBalancerPool(request) + if assert.NoError(t, err) { + assert.Equal(t, want, actual) + } +} + +func TestListLoadBalancerPools(t *testing.T) { + setup() + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.Method, "GET", "Expected method 'GET', got %s", r.Method) + w.Header().Set("content-type", "application/json") + fmt.Fprint(w, `{ + "success": true, + "errors": [], + "messages": [], + "result": [ + { + "id": "17b5962d775c646f3f9725cbc7a53df4", + "created_on": "2014-01-01T05:20:00.12345Z", + "modified_on": "2014-02-01T05:20:00.12345Z", + "description": "Primary data center - Provider XYZ", + "name": "primary-dc-1", + "enabled": true, + "monitor": "f1aba936b94213e5b8dca0c0dbf1f9cc", + "origins": [ + { + "name": "app-server-1", + "address": "0.0.0.0", + "enabled": true + } + ], + "notification_email": "someone@example.com" + } + ], + "result_info": { + "page": 1, + "per_page": 20, + "count": 1, + "total_count": 2000 + } + }`) + } + + mux.HandleFunc("/user/load_balancers/pools", handler) + createdOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z") + modifiedOn, _ := time.Parse(time.RFC3339, "2014-02-01T05:20:00.12345Z") + want := []LoadBalancerPool{ + { + ID: "17b5962d775c646f3f9725cbc7a53df4", + CreatedOn: &createdOn, + ModifiedOn: &modifiedOn, + Description: "Primary data center - Provider XYZ", + Name: "primary-dc-1", + Enabled: true, + Monitor: "f1aba936b94213e5b8dca0c0dbf1f9cc", + Origins: []LoadBalancerOrigin{ + { + Name: "app-server-1", + Address: "0.0.0.0", + Enabled: true, + }, + }, + NotificationEmail: "someone@example.com", + }, + } + + actual, err := client.ListLoadBalancerPools() + if assert.NoError(t, err) { + assert.Equal(t, want, actual) + } +} + +func TestLoadBalancerPoolDetails(t *testing.T) { + setup() + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.Method, "GET", "Expected method 'GET', got %s", r.Method) + w.Header().Set("content-type", "application/json") + fmt.Fprint(w, `{ + "success": true, + "errors": [], + "messages": [], + "result": { + "id": "17b5962d775c646f3f9725cbc7a53df4", + "created_on": "2014-01-01T05:20:00.12345Z", + "modified_on": "2014-02-01T05:20:00.12345Z", + "description": "Primary data center - Provider XYZ", + "name": "primary-dc-1", + "enabled": true, + "monitor": "f1aba936b94213e5b8dca0c0dbf1f9cc", + "origins": [ + { + "name": "app-server-1", + "address": "0.0.0.0", + "enabled": true + } + ], + "notification_email": "someone@example.com" + } + }`) + } + + mux.HandleFunc("/user/load_balancers/pools/17b5962d775c646f3f9725cbc7a53df4", handler) + createdOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z") + modifiedOn, _ := time.Parse(time.RFC3339, "2014-02-01T05:20:00.12345Z") + want := LoadBalancerPool{ + ID: "17b5962d775c646f3f9725cbc7a53df4", + CreatedOn: &createdOn, + ModifiedOn: &modifiedOn, + Description: "Primary data center - Provider XYZ", + Name: "primary-dc-1", + Enabled: true, + Monitor: "f1aba936b94213e5b8dca0c0dbf1f9cc", + Origins: []LoadBalancerOrigin{ + { + Name: "app-server-1", + Address: "0.0.0.0", + Enabled: true, + }, + }, + NotificationEmail: "someone@example.com", + } + + actual, err := client.LoadBalancerPoolDetails("17b5962d775c646f3f9725cbc7a53df4") + if assert.NoError(t, err) { + assert.Equal(t, want, actual) + } + + _, err = client.LoadBalancerPoolDetails("bar") + assert.Error(t, err) +} + +func TestDeleteLoadBalancerPool(t *testing.T) { + setup() + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.Method, "DELETE", "Expected method 'DELETE', got %s", r.Method) + w.Header().Set("content-type", "application/json") + fmt.Fprint(w, `{ + "success": true, + "errors": [], + "messages": [], + "result": { + "id": "17b5962d775c646f3f9725cbc7a53df4" + } + }`) + } + + mux.HandleFunc("/user/load_balancers/pools/17b5962d775c646f3f9725cbc7a53df4", handler) + assert.NoError(t, client.DeleteLoadBalancerPool("17b5962d775c646f3f9725cbc7a53df4")) + assert.Error(t, client.DeleteLoadBalancerPool("bar")) +} + +func TestModifyLoadBalancerPool(t *testing.T) { + setup() + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.Method, "PUT", "Expected method 'PUT', got %s", r.Method) + w.Header().Set("content-type", "application/json") + b, err := ioutil.ReadAll(r.Body) + defer r.Body.Close() + if assert.NoError(t, err) { + assert.JSONEq(t, `{ + "id": "17b5962d775c646f3f9725cbc7a53df4", + "description": "Primary data center - Provider XYZZY", + "name": "primary-dc-2", + "enabled": false, + "origins": [ + { + "name": "app-server-2", + "address": "0.0.0.1", + "enabled": false + } + ], + "notification_email": "nobody@example.com" + }`, string(b)) + } + fmt.Fprint(w, `{ + "success": true, + "errors": [], + "messages": [], + "result": { + "id": "17b5962d775c646f3f9725cbc7a53df4", + "created_on": "2014-01-01T05:20:00.12345Z", + "modified_on": "2017-02-01T05:20:00.12345Z", + "description": "Primary data center - Provider XYZZY", + "name": "primary-dc-2", + "enabled": false, + "origins": [ + { + "name": "app-server-2", + "address": "0.0.0.1", + "enabled": false + } + ], + "notification_email": "nobody@example.com" + } + }`) + } + + mux.HandleFunc("/user/load_balancers/pools/17b5962d775c646f3f9725cbc7a53df4", handler) + createdOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z") + modifiedOn, _ := time.Parse(time.RFC3339, "2017-02-01T05:20:00.12345Z") + want := LoadBalancerPool{ + ID: "17b5962d775c646f3f9725cbc7a53df4", + CreatedOn: &createdOn, + ModifiedOn: &modifiedOn, + Description: "Primary data center - Provider XYZZY", + Name: "primary-dc-2", + Enabled: false, + Origins: []LoadBalancerOrigin{ + { + Name: "app-server-2", + Address: "0.0.0.1", + Enabled: false, + }, + }, + NotificationEmail: "nobody@example.com", + } + request := LoadBalancerPool{ + ID: "17b5962d775c646f3f9725cbc7a53df4", + Description: "Primary data center - Provider XYZZY", + Name: "primary-dc-2", + Enabled: false, + Origins: []LoadBalancerOrigin{ + { + Name: "app-server-2", + Address: "0.0.0.1", + Enabled: false, + }, + }, + NotificationEmail: "nobody@example.com", + } + + actual, err := client.ModifyLoadBalancerPool(request) + if assert.NoError(t, err) { + assert.Equal(t, want, actual) + } +} + +func TestCreateLoadBalancerMonitor(t *testing.T) { + setup() + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.Method, "POST", "Expected method 'POST', got %s", r.Method) + w.Header().Set("content-type", "application/json") + b, err := ioutil.ReadAll(r.Body) + defer r.Body.Close() + if assert.NoError(t, err) { + assert.JSONEq(t, `{ + "type": "https", + "description": "Login page monitor", + "method": "GET", + "path": "/health", + "header": { + "Host": [ + "example.com" + ], + "X-App-ID": [ + "abc123" + ] + }, + "timeout": 3, + "retries": 0, + "interval": 90, + "expected_body": "alive", + "expected_codes": "2xx" + }`, string(b)) + } + fmt.Fprint(w, `{ + "success": true, + "errors": [], + "messages": [], + "result": { + "id": "f1aba936b94213e5b8dca0c0dbf1f9cc", + "created_on": "2014-01-01T05:20:00.12345Z", + "modified_on": "2014-02-01T05:20:00.12345Z", + "type": "https", + "description": "Login page monitor", + "method": "GET", + "path": "/health", + "header": { + "Host": [ + "example.com" + ], + "X-App-ID": [ + "abc123" + ] + }, + "timeout": 3, + "retries": 0, + "interval": 90, + "expected_body": "alive", + "expected_codes": "2xx" + } + }`) + } + + mux.HandleFunc("/user/load_balancers/monitors", handler) + createdOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z") + modifiedOn, _ := time.Parse(time.RFC3339, "2014-02-01T05:20:00.12345Z") + want := LoadBalancerMonitor{ + ID: "f1aba936b94213e5b8dca0c0dbf1f9cc", + CreatedOn: &createdOn, + ModifiedOn: &modifiedOn, + Type: "https", + Description: "Login page monitor", + Method: "GET", + Path: "/health", + Header: map[string][]string{ + "Host": []string{"example.com"}, + "X-App-ID": []string{"abc123"}, + }, + Timeout: 3, + Retries: 0, + Interval: 90, + ExpectedBody: "alive", + ExpectedCodes: "2xx", + } + request := LoadBalancerMonitor{ + Type: "https", + Description: "Login page monitor", + Method: "GET", + Path: "/health", + Header: map[string][]string{ + "Host": []string{"example.com"}, + "X-App-ID": []string{"abc123"}, + }, + Timeout: 3, + Retries: 0, + Interval: 90, + ExpectedBody: "alive", + ExpectedCodes: "2xx", + } + + actual, err := client.CreateLoadBalancerMonitor(request) + if assert.NoError(t, err) { + assert.Equal(t, want, actual) + } +} + +func TestListLoadBalancerMonitors(t *testing.T) { + setup() + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.Method, "GET", "Expected method 'GET', got %s", r.Method) + w.Header().Set("content-type", "application/json") + fmt.Fprint(w, `{ + "success": true, + "errors": [], + "messages": [], + "result": [ + { + "id": "f1aba936b94213e5b8dca0c0dbf1f9cc", + "created_on": "2014-01-01T05:20:00.12345Z", + "modified_on": "2014-02-01T05:20:00.12345Z", + "type": "https", + "description": "Login page monitor", + "method": "GET", + "path": "/health", + "header": { + "Host": [ + "example.com" + ], + "X-App-ID": [ + "abc123" + ] + }, + "timeout": 3, + "retries": 0, + "interval": 90, + "expected_body": "alive", + "expected_codes": "2xx" + } + ], + "result_info": { + "page": 1, + "per_page": 20, + "count": 1, + "total_count": 2000 + } + }`) + } + + mux.HandleFunc("/user/load_balancers/monitors", handler) + createdOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z") + modifiedOn, _ := time.Parse(time.RFC3339, "2014-02-01T05:20:00.12345Z") + want := []LoadBalancerMonitor{ + { + ID: "f1aba936b94213e5b8dca0c0dbf1f9cc", + CreatedOn: &createdOn, + ModifiedOn: &modifiedOn, + Type: "https", + Description: "Login page monitor", + Method: "GET", + Path: "/health", + Header: map[string][]string{ + "Host": []string{"example.com"}, + "X-App-ID": []string{"abc123"}, + }, + Timeout: 3, + Retries: 0, + Interval: 90, + ExpectedBody: "alive", + ExpectedCodes: "2xx", + }, + } + + actual, err := client.ListLoadBalancerMonitors() + if assert.NoError(t, err) { + assert.Equal(t, want, actual) + } +} + +func TestLoadBalancerMonitorDetails(t *testing.T) { + setup() + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.Method, "GET", "Expected method 'GET', got %s", r.Method) + w.Header().Set("content-type", "application/json") + fmt.Fprint(w, `{ + "success": true, + "errors": [], + "messages": [], + "result": { + "id": "f1aba936b94213e5b8dca0c0dbf1f9cc", + "created_on": "2014-01-01T05:20:00.12345Z", + "modified_on": "2014-02-01T05:20:00.12345Z", + "type": "https", + "description": "Login page monitor", + "method": "GET", + "path": "/health", + "header": { + "Host": [ + "example.com" + ], + "X-App-ID": [ + "abc123" + ] + }, + "timeout": 3, + "retries": 0, + "interval": 90, + "expected_body": "alive", + "expected_codes": "2xx" + } + }`) + } + + mux.HandleFunc("/user/load_balancers/monitors/f1aba936b94213e5b8dca0c0dbf1f9cc", handler) + createdOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z") + modifiedOn, _ := time.Parse(time.RFC3339, "2014-02-01T05:20:00.12345Z") + want := LoadBalancerMonitor{ + ID: "f1aba936b94213e5b8dca0c0dbf1f9cc", + CreatedOn: &createdOn, + ModifiedOn: &modifiedOn, + Type: "https", + Description: "Login page monitor", + Method: "GET", + Path: "/health", + Header: map[string][]string{ + "Host": []string{"example.com"}, + "X-App-ID": []string{"abc123"}, + }, + Timeout: 3, + Retries: 0, + Interval: 90, + ExpectedBody: "alive", + ExpectedCodes: "2xx", + } + + actual, err := client.LoadBalancerMonitorDetails("f1aba936b94213e5b8dca0c0dbf1f9cc") + if assert.NoError(t, err) { + assert.Equal(t, want, actual) + } + + _, err = client.LoadBalancerMonitorDetails("bar") + assert.Error(t, err) +} + +func TestDeleteLoadBalancerMonitor(t *testing.T) { + setup() + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.Method, "DELETE", "Expected method 'DELETE', got %s", r.Method) + w.Header().Set("content-type", "application/json") + fmt.Fprint(w, `{ + "success": true, + "errors": [], + "messages": [], + "result": { + "id": "f1aba936b94213e5b8dca0c0dbf1f9cc" + } + }`) + } + + mux.HandleFunc("/user/load_balancers/monitors/f1aba936b94213e5b8dca0c0dbf1f9cc", handler) + assert.NoError(t, client.DeleteLoadBalancerMonitor("f1aba936b94213e5b8dca0c0dbf1f9cc")) + assert.Error(t, client.DeleteLoadBalancerMonitor("bar")) +} + +func TestModifyLoadBalancerMonitor(t *testing.T) { + setup() + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.Method, "PUT", "Expected method 'PUT', got %s", r.Method) + w.Header().Set("content-type", "application/json") + b, err := ioutil.ReadAll(r.Body) + defer r.Body.Close() + if assert.NoError(t, err) { + assert.JSONEq(t, `{ + "id": "f1aba936b94213e5b8dca0c0dbf1f9cc", + "type": "http", + "description": "Login page monitor", + "method": "GET", + "path": "/status", + "header": { + "Host": [ + "example.com" + ], + "X-App-ID": [ + "easy" + ] + }, + "timeout": 3, + "retries": 0, + "interval": 90, + "expected_body": "kicking", + "expected_codes": "200" + }`, string(b)) + } + fmt.Fprint(w, `{ + "success": true, + "errors": [], + "messages": [], + "result": { + "id": "f1aba936b94213e5b8dca0c0dbf1f9cc", + "created_on": "2014-01-01T05:20:00.12345Z", + "modified_on": "2017-02-01T05:20:00.12345Z", + "type": "http", + "description": "Login page monitor", + "method": "GET", + "path": "/status", + "header": { + "Host": [ + "example.com" + ], + "X-App-ID": [ + "easy" + ] + }, + "timeout": 3, + "retries": 0, + "interval": 90, + "expected_body": "kicking", + "expected_codes": "200" + } + }`) + } + + mux.HandleFunc("/user/load_balancers/monitors/f1aba936b94213e5b8dca0c0dbf1f9cc", handler) + createdOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z") + modifiedOn, _ := time.Parse(time.RFC3339, "2017-02-01T05:20:00.12345Z") + want := LoadBalancerMonitor{ + ID: "f1aba936b94213e5b8dca0c0dbf1f9cc", + CreatedOn: &createdOn, + ModifiedOn: &modifiedOn, + Type: "http", + Description: "Login page monitor", + Method: "GET", + Path: "/status", + Header: map[string][]string{ + "Host": []string{"example.com"}, + "X-App-ID": []string{"easy"}, + }, + Timeout: 3, + Retries: 0, + Interval: 90, + ExpectedBody: "kicking", + ExpectedCodes: "200", + } + request := LoadBalancerMonitor{ + ID: "f1aba936b94213e5b8dca0c0dbf1f9cc", + Type: "http", + Description: "Login page monitor", + Method: "GET", + Path: "/status", + Header: map[string][]string{ + "Host": []string{"example.com"}, + "X-App-ID": []string{"easy"}, + }, + Timeout: 3, + Retries: 0, + Interval: 90, + ExpectedBody: "kicking", + ExpectedCodes: "200", + } + + actual, err := client.ModifyLoadBalancerMonitor(request) + if assert.NoError(t, err) { + assert.Equal(t, want, actual) + } +} + +func TestCreateLoadBalancer(t *testing.T) { + setup() + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.Method, "POST", "Expected method 'POST', got %s", r.Method) + w.Header().Set("content-type", "application/json") + b, err := ioutil.ReadAll(r.Body) + defer r.Body.Close() + if assert.NoError(t, err) { + assert.JSONEq(t, `{ + "description": "Load Balancer for www.example.com", + "name": "www.example.com", + "ttl": 30, + "fallback_pool": "17b5962d775c646f3f9725cbc7a53df4", + "default_pools": [ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196", + "00920f38ce07c2e2f4df50b1f61d4194" + ], + "region_pools": { + "WNAM": [ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196" + ], + "ENAM": [ + "00920f38ce07c2e2f4df50b1f61d4194" + ] + }, + "pop_pools": { + "LAX": [ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196" + ], + "LHR": [ + "abd90f38ced07c2e2f4df50b1f61d4194", + "f9138c5d07c2e2f4df57b1f61d4196" + ], + "SJC": [ + "00920f38ce07c2e2f4df50b1f61d4194" + ] + }, + "proxied": true + }`, string(b)) + } + fmt.Fprint(w, `{ + "success": true, + "errors": [], + "messages": [], + "result": { + "id": "699d98642c564d2e855e9661899b7252", + "created_on": "2014-01-01T05:20:00.12345Z", + "modified_on": "2014-02-01T05:20:00.12345Z", + "description": "Load Balancer for www.example.com", + "name": "www.example.com", + "ttl": 30, + "fallback_pool": "17b5962d775c646f3f9725cbc7a53df4", + "default_pools": [ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196", + "00920f38ce07c2e2f4df50b1f61d4194" + ], + "region_pools": { + "WNAM": [ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196" + ], + "ENAM": [ + "00920f38ce07c2e2f4df50b1f61d4194" + ] + }, + "pop_pools": { + "LAX": [ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196" + ], + "LHR": [ + "abd90f38ced07c2e2f4df50b1f61d4194", + "f9138c5d07c2e2f4df57b1f61d4196" + ], + "SJC": [ + "00920f38ce07c2e2f4df50b1f61d4194" + ] + }, + "proxied": true + } + }`) + } + + mux.HandleFunc("/zones/199d98642c564d2e855e9661899b7252/load_balancers", handler) + createdOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z") + modifiedOn, _ := time.Parse(time.RFC3339, "2014-02-01T05:20:00.12345Z") + want := LoadBalancer{ + ID: "699d98642c564d2e855e9661899b7252", + CreatedOn: &createdOn, + ModifiedOn: &modifiedOn, + Description: "Load Balancer for www.example.com", + Name: "www.example.com", + TTL: 30, + FallbackPool: "17b5962d775c646f3f9725cbc7a53df4", + DefaultPools: []string{ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196", + "00920f38ce07c2e2f4df50b1f61d4194", + }, + RegionPools: map[string][]string{ + "WNAM": []string{ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196", + }, + "ENAM": []string{ + "00920f38ce07c2e2f4df50b1f61d4194", + }, + }, + PopPools: map[string][]string{ + "LAX": []string{ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196", + }, + "LHR": []string{ + "abd90f38ced07c2e2f4df50b1f61d4194", + "f9138c5d07c2e2f4df57b1f61d4196", + }, + "SJC": []string{ + "00920f38ce07c2e2f4df50b1f61d4194", + }, + }, + Proxied: true, + } + request := LoadBalancer{ + Description: "Load Balancer for www.example.com", + Name: "www.example.com", + TTL: 30, + FallbackPool: "17b5962d775c646f3f9725cbc7a53df4", + DefaultPools: []string{ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196", + "00920f38ce07c2e2f4df50b1f61d4194", + }, + RegionPools: map[string][]string{ + "WNAM": []string{ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196", + }, + "ENAM": []string{ + "00920f38ce07c2e2f4df50b1f61d4194", + }, + }, + PopPools: map[string][]string{ + "LAX": []string{ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196", + }, + "LHR": []string{ + "abd90f38ced07c2e2f4df50b1f61d4194", + "f9138c5d07c2e2f4df57b1f61d4196", + }, + "SJC": []string{ + "00920f38ce07c2e2f4df50b1f61d4194", + }, + }, + Proxied: true, + } + + actual, err := client.CreateLoadBalancer("199d98642c564d2e855e9661899b7252", request) + if assert.NoError(t, err) { + assert.Equal(t, want, actual) + } +} + +func TestListLoadBalancers(t *testing.T) { + setup() + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.Method, "GET", "Expected method 'GET', got %s", r.Method) + w.Header().Set("content-type", "application/json") + fmt.Fprint(w, `{ + "success": true, + "errors": [], + "messages": [], + "result": [ + { + "id": "699d98642c564d2e855e9661899b7252", + "created_on": "2014-01-01T05:20:00.12345Z", + "modified_on": "2014-02-01T05:20:00.12345Z", + "description": "Load Balancer for www.example.com", + "name": "www.example.com", + "ttl": 30, + "fallback_pool": "17b5962d775c646f3f9725cbc7a53df4", + "default_pools": [ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196", + "00920f38ce07c2e2f4df50b1f61d4194" + ], + "region_pools": { + "WNAM": [ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196" + ], + "ENAM": [ + "00920f38ce07c2e2f4df50b1f61d4194" + ] + }, + "pop_pools": { + "LAX": [ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196" + ], + "LHR": [ + "abd90f38ced07c2e2f4df50b1f61d4194", + "f9138c5d07c2e2f4df57b1f61d4196" + ], + "SJC": [ + "00920f38ce07c2e2f4df50b1f61d4194" + ] + }, + "proxied": true + } + ], + "result_info": { + "page": 1, + "per_page": 20, + "count": 1, + "total_count": 2000 + } + }`) + } + + mux.HandleFunc("/zones/199d98642c564d2e855e9661899b7252/load_balancers", handler) + createdOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z") + modifiedOn, _ := time.Parse(time.RFC3339, "2014-02-01T05:20:00.12345Z") + want := []LoadBalancer{ + { + ID: "699d98642c564d2e855e9661899b7252", + CreatedOn: &createdOn, + ModifiedOn: &modifiedOn, + Description: "Load Balancer for www.example.com", + Name: "www.example.com", + TTL: 30, + FallbackPool: "17b5962d775c646f3f9725cbc7a53df4", + DefaultPools: []string{ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196", + "00920f38ce07c2e2f4df50b1f61d4194", + }, + RegionPools: map[string][]string{ + "WNAM": []string{ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196", + }, + "ENAM": []string{ + "00920f38ce07c2e2f4df50b1f61d4194", + }, + }, + PopPools: map[string][]string{ + "LAX": []string{ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196", + }, + "LHR": []string{ + "abd90f38ced07c2e2f4df50b1f61d4194", + "f9138c5d07c2e2f4df57b1f61d4196", + }, + "SJC": []string{ + "00920f38ce07c2e2f4df50b1f61d4194", + }, + }, + Proxied: true, + }, + } + + actual, err := client.ListLoadBalancers("199d98642c564d2e855e9661899b7252") + if assert.NoError(t, err) { + assert.Equal(t, want, actual) + } +} + +func TestLoadBalancerDetails(t *testing.T) { + setup() + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.Method, "GET", "Expected method 'GET', got %s", r.Method) + w.Header().Set("content-type", "application/json") + fmt.Fprint(w, `{ + "success": true, + "errors": [], + "messages": [], + "result": { + "id": "699d98642c564d2e855e9661899b7252", + "created_on": "2014-01-01T05:20:00.12345Z", + "modified_on": "2014-02-01T05:20:00.12345Z", + "description": "Load Balancer for www.example.com", + "name": "www.example.com", + "ttl": 30, + "fallback_pool": "17b5962d775c646f3f9725cbc7a53df4", + "default_pools": [ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196", + "00920f38ce07c2e2f4df50b1f61d4194" + ], + "region_pools": { + "WNAM": [ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196" + ], + "ENAM": [ + "00920f38ce07c2e2f4df50b1f61d4194" + ] + }, + "pop_pools": { + "LAX": [ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196" + ], + "LHR": [ + "abd90f38ced07c2e2f4df50b1f61d4194", + "f9138c5d07c2e2f4df57b1f61d4196" + ], + "SJC": [ + "00920f38ce07c2e2f4df50b1f61d4194" + ] + }, + "proxied": true + } + }`) + } + + mux.HandleFunc("/zones/199d98642c564d2e855e9661899b7252/load_balancers/699d98642c564d2e855e9661899b7252", handler) + createdOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z") + modifiedOn, _ := time.Parse(time.RFC3339, "2014-02-01T05:20:00.12345Z") + want := LoadBalancer{ + ID: "699d98642c564d2e855e9661899b7252", + CreatedOn: &createdOn, + ModifiedOn: &modifiedOn, + Description: "Load Balancer for www.example.com", + Name: "www.example.com", + TTL: 30, + FallbackPool: "17b5962d775c646f3f9725cbc7a53df4", + DefaultPools: []string{ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196", + "00920f38ce07c2e2f4df50b1f61d4194", + }, + RegionPools: map[string][]string{ + "WNAM": []string{ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196", + }, + "ENAM": []string{ + "00920f38ce07c2e2f4df50b1f61d4194", + }, + }, + PopPools: map[string][]string{ + "LAX": []string{ + "de90f38ced07c2e2f4df50b1f61d4194", + "9290f38c5d07c2e2f4df57b1f61d4196", + }, + "LHR": []string{ + "abd90f38ced07c2e2f4df50b1f61d4194", + "f9138c5d07c2e2f4df57b1f61d4196", + }, + "SJC": []string{ + "00920f38ce07c2e2f4df50b1f61d4194", + }, + }, + Proxied: true, + } + + actual, err := client.LoadBalancerDetails("199d98642c564d2e855e9661899b7252", "699d98642c564d2e855e9661899b7252") + if assert.NoError(t, err) { + assert.Equal(t, want, actual) + } + + _, err = client.LoadBalancerDetails("199d98642c564d2e855e9661899b7252", "bar") + assert.Error(t, err) +} + +func TestDeleteLoadBalancer(t *testing.T) { + setup() + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.Method, "DELETE", "Expected method 'DELETE', got %s", r.Method) + w.Header().Set("content-type", "application/json") + fmt.Fprint(w, `{ + "success": true, + "errors": [], + "messages": [], + "result": { + "id": "699d98642c564d2e855e9661899b7252" + } + }`) + } + + mux.HandleFunc("/zones/199d98642c564d2e855e9661899b7252/load_balancers/699d98642c564d2e855e9661899b7252", handler) + assert.NoError(t, client.DeleteLoadBalancer("199d98642c564d2e855e9661899b7252", "699d98642c564d2e855e9661899b7252")) + assert.Error(t, client.DeleteLoadBalancer("199d98642c564d2e855e9661899b7252", "bar")) +} + +func TestModifyLoadBalancer(t *testing.T) { + setup() + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.Method, "PUT", "Expected method 'PUT', got %s", r.Method) + w.Header().Set("content-type", "application/json") + b, err := ioutil.ReadAll(r.Body) + defer r.Body.Close() + if assert.NoError(t, err) { + assert.JSONEq(t, `{ + "id": "699d98642c564d2e855e9661899b7252", + "description": "Load Balancer for www.example.com", + "name": "www.example.com", + "ttl": 30, + "fallback_pool": "17b5962d775c646f3f9725cbc7a53df4", + "default_pools": [ + "00920f38ce07c2e2f4df50b1f61d4194" + ], + "region_pools": { + "WNAM": [ + "9290f38c5d07c2e2f4df57b1f61d4196" + ], + "ENAM": [ + "00920f38ce07c2e2f4df50b1f61d4194" + ] + }, + "pop_pools": { + "LAX": [ + "9290f38c5d07c2e2f4df57b1f61d4196" + ], + "LHR": [ + "f9138c5d07c2e2f4df57b1f61d4196" + ], + "SJC": [ + "00920f38ce07c2e2f4df50b1f61d4194" + ] + }, + "proxied": true + }`, string(b)) + } + fmt.Fprint(w, `{ + "success": true, + "errors": [], + "messages": [], + "result": { + "id": "699d98642c564d2e855e9661899b7252", + "created_on": "2014-01-01T05:20:00.12345Z", + "modified_on": "2017-02-01T05:20:00.12345Z", + "description": "Load Balancer for www.example.com", + "name": "www.example.com", + "ttl": 30, + "fallback_pool": "17b5962d775c646f3f9725cbc7a53df4", + "default_pools": [ + "00920f38ce07c2e2f4df50b1f61d4194" + ], + "region_pools": { + "WNAM": [ + "9290f38c5d07c2e2f4df57b1f61d4196" + ], + "ENAM": [ + "00920f38ce07c2e2f4df50b1f61d4194" + ] + }, + "pop_pools": { + "LAX": [ + "9290f38c5d07c2e2f4df57b1f61d4196" + ], + "LHR": [ + "f9138c5d07c2e2f4df57b1f61d4196" + ], + "SJC": [ + "00920f38ce07c2e2f4df50b1f61d4194" + ] + }, + "proxied": true + } + }`) + } + + mux.HandleFunc("/zones/199d98642c564d2e855e9661899b7252/load_balancers/699d98642c564d2e855e9661899b7252", handler) + createdOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z") + modifiedOn, _ := time.Parse(time.RFC3339, "2017-02-01T05:20:00.12345Z") + want := LoadBalancer{ + ID: "699d98642c564d2e855e9661899b7252", + CreatedOn: &createdOn, + ModifiedOn: &modifiedOn, + Description: "Load Balancer for www.example.com", + Name: "www.example.com", + TTL: 30, + FallbackPool: "17b5962d775c646f3f9725cbc7a53df4", + DefaultPools: []string{ + "00920f38ce07c2e2f4df50b1f61d4194", + }, + RegionPools: map[string][]string{ + "WNAM": []string{ + "9290f38c5d07c2e2f4df57b1f61d4196", + }, + "ENAM": []string{ + "00920f38ce07c2e2f4df50b1f61d4194", + }, + }, + PopPools: map[string][]string{ + "LAX": []string{ + "9290f38c5d07c2e2f4df57b1f61d4196", + }, + "LHR": []string{ + "f9138c5d07c2e2f4df57b1f61d4196", + }, + "SJC": []string{ + "00920f38ce07c2e2f4df50b1f61d4194", + }, + }, + Proxied: true, + } + request := LoadBalancer{ + ID: "699d98642c564d2e855e9661899b7252", + Description: "Load Balancer for www.example.com", + Name: "www.example.com", + TTL: 30, + FallbackPool: "17b5962d775c646f3f9725cbc7a53df4", + DefaultPools: []string{ + "00920f38ce07c2e2f4df50b1f61d4194", + }, + RegionPools: map[string][]string{ + "WNAM": []string{ + "9290f38c5d07c2e2f4df57b1f61d4196", + }, + "ENAM": []string{ + "00920f38ce07c2e2f4df50b1f61d4194", + }, + }, + PopPools: map[string][]string{ + "LAX": []string{ + "9290f38c5d07c2e2f4df57b1f61d4196", + }, + "LHR": []string{ + "f9138c5d07c2e2f4df57b1f61d4196", + }, + "SJC": []string{ + "00920f38ce07c2e2f4df50b1f61d4194", + }, + }, + Proxied: true, + } + + actual, err := client.ModifyLoadBalancer("199d98642c564d2e855e9661899b7252", request) + if assert.NoError(t, err) { + assert.Equal(t, want, actual) + } +}