diff --git a/acceptance/openstack/loadbalancer/v2/loadbalancers_test.go b/acceptance/openstack/loadbalancer/v2/loadbalancers_test.go index 02d4136a5d..d4fa02f8b6 100644 --- a/acceptance/openstack/loadbalancer/v2/loadbalancers_test.go +++ b/acceptance/openstack/loadbalancer/v2/loadbalancers_test.go @@ -108,6 +108,18 @@ func TestLoadbalancersCRUD(t *testing.T) { } defer DeleteL7Policy(t, lbClient, lb.ID, policy.ID) + updateL7policyOpts := l7policies.UpdateOpts{ + Description: "New l7 policy description", + } + _, err = l7policies.Update(lbClient, policy.ID, updateL7policyOpts).Extract() + if err != nil { + t.Fatalf("Unable to update l7 policy") + } + + if err := WaitForLoadBalancerState(lbClient, lb.ID, "ACTIVE", loadbalancerActiveTimeoutSeconds); err != nil { + t.Fatalf("Timed out waiting for loadbalancer to become active") + } + newPolicy, err := l7policies.Get(lbClient, policy.ID).Extract() if err != nil { t.Fatalf("Unable to get l7 policy: %v", err) diff --git a/openstack/loadbalancer/v2/l7policies/doc.go b/openstack/loadbalancer/v2/l7policies/doc.go index 9c9a40471b..7165dd522a 100644 --- a/openstack/loadbalancer/v2/l7policies/doc.go +++ b/openstack/loadbalancer/v2/l7policies/doc.go @@ -46,5 +46,16 @@ Example to Delete a L7Policy if err != nil { panic(err) } + +Example to Update a L7Policy + + l7policyID := "d67d56a6-4a86-4688-a282-f46444705c64" + updateOpts := l7policies.UpdateOpts{ + Name: "new-name", + } + l7policy, err := l7policies.Update(lbClient, l7policyID, updateOpts).Extract() + if err != nil { + panic(err) + } */ package l7policies diff --git a/openstack/loadbalancer/v2/l7policies/requests.go b/openstack/loadbalancer/v2/l7policies/requests.go index c565da5f67..a6af4f8d0d 100644 --- a/openstack/loadbalancer/v2/l7policies/requests.go +++ b/openstack/loadbalancer/v2/l7policies/requests.go @@ -143,3 +143,51 @@ func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) { _, r.Err = c.Delete(resourceURL(c, id), nil) return } + +// UpdateOptsBuilder allows extensions to add additional parameters to the +// Update request. +type UpdateOptsBuilder interface { + ToL7PolicyUpdateMap() (map[string]interface{}, error) +} + +// UpdateOpts is the common options struct used in this package's Update +// operation. +type UpdateOpts struct { + // Name of the L7 policy. + Name string `json:"name,omitempty"` + + // The L7 policy action. One of REDIRECT_TO_POOL, REDIRECT_TO_URL, or REJECT. + Action Action `json:"action,omitempty"` + + // The position of this policy on the listener. + Position int32 `json:"position,omitempty"` + + // A human-readable description for the resource. + Description string `json:"description,omitempty"` + + // Requests matching this policy will be redirected to the pool with this ID. + // Only valid if action is REDIRECT_TO_POOL. + RedirectPoolID string `json:"redirect_pool_id,omitempty"` + + // Requests matching this policy will be redirected to this URL. + // Only valid if action is REDIRECT_TO_URL. + RedirectURL string `json:"redirect_url,omitempty"` +} + +// ToL7PolicyUpdateMap builds a request body from UpdateOpts. +func (opts UpdateOpts) ToL7PolicyUpdateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "l7policy") +} + +// Update allows l7policy to be updated. +func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { + b, err := opts.ToL7PolicyUpdateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return +} diff --git a/openstack/loadbalancer/v2/l7policies/results.go b/openstack/loadbalancer/v2/l7policies/results.go index 8ab9493baf..f4907a3f59 100644 --- a/openstack/loadbalancer/v2/l7policies/results.go +++ b/openstack/loadbalancer/v2/l7policies/results.go @@ -141,3 +141,9 @@ type GetResult struct { type DeleteResult struct { gophercloud.ErrResult } + +// UpdateResult represents the result of an Update operation. Call its Extract +// method to interpret the result as a L7Policy. +type UpdateResult struct { + commonResult +} diff --git a/openstack/loadbalancer/v2/l7policies/testing/fixtures.go b/openstack/loadbalancer/v2/l7policies/testing/fixtures.go index 3c9bf6cc74..24d2cf8500 100644 --- a/openstack/loadbalancer/v2/l7policies/testing/fixtures.go +++ b/openstack/loadbalancer/v2/l7policies/testing/fixtures.go @@ -56,6 +56,19 @@ var ( AdminStateUp: true, Rules: []l7policies.Rule{}, } + L7PolicyUpdated = l7policies.L7Policy{ + ID: "8a1412f0-4c32-4257-8b07-af4770b604fd", + Name: "NewL7PolicyName", + ListenerID: "023f2e34-7806-443b-bfae-16c324569a3d", + Action: "REDIRECT_TO_URL", + Position: 1, + Description: "Redirect requests to example.com", + TenantID: "e3cd678b11784734bc366148aa37580e", + RedirectPoolID: "", + RedirectURL: "http://www.new-example.com", + AdminStateUp: true, + Rules: []l7policies.Rule{}, + } ) // HandleL7PolicyCreationSuccessfully sets up the test server to respond to a l7policy creation request @@ -112,6 +125,25 @@ const L7PoliciesListBody = ` } ` +// PostUpdateL7PolicyBody is the canned response body of a Update request on an existing l7policy. +const PostUpdateL7PolicyBody = ` +{ + "l7policy": { + "listener_id": "023f2e34-7806-443b-bfae-16c324569a3d", + "description": "Redirect requests to example.com", + "admin_state_up": true, + "redirect_pool_id": null, + "redirect_url": "http://www.new-example.com", + "action": "REDIRECT_TO_URL", + "position": 1, + "tenant_id": "e3cd678b11784734bc366148aa37580e", + "id": "8a1412f0-4c32-4257-8b07-af4770b604fd", + "name": "NewL7PolicyName", + "rules": [] + } +} +` + // HandleL7PolicyListSuccessfully sets up the test server to respond to a l7policy List request. func HandleL7PolicyListSuccessfully(t *testing.T) { th.Mux.HandleFunc("/v2.0/lbaas/l7policies", func(w http.ResponseWriter, r *http.Request) { @@ -152,3 +184,21 @@ func HandleL7PolicyDeletionSuccessfully(t *testing.T) { w.WriteHeader(http.StatusNoContent) }) } + +// HandleL7PolicyUpdateSuccessfully sets up the test server to respond to a l7policy Update request. +func HandleL7PolicyUpdateSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/v2.0/lbaas/l7policies/8a1412f0-4c32-4257-8b07-af4770b604fd", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestHeader(t, r, "Accept", "application/json") + th.TestHeader(t, r, "Content-Type", "application/json") + th.TestJSONRequest(t, r, `{ + "l7policy": { + "name": "NewL7PolicyName", + "redirect_url": "http://www.new-example.com" + } + }`) + + fmt.Fprintf(w, PostUpdateL7PolicyBody) + }) +} diff --git a/openstack/loadbalancer/v2/l7policies/testing/requests_test.go b/openstack/loadbalancer/v2/l7policies/testing/requests_test.go index e350bc8541..a53b24fc98 100644 --- a/openstack/loadbalancer/v2/l7policies/testing/requests_test.go +++ b/openstack/loadbalancer/v2/l7policies/testing/requests_test.go @@ -107,3 +107,21 @@ func TestDeleteL7Policy(t *testing.T) { res := l7policies.Delete(fake.ServiceClient(), "8a1412f0-4c32-4257-8b07-af4770b604fd") th.AssertNoErr(t, res.Err) } + +func TestUpdateL7Policy(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + HandleL7PolicyUpdateSuccessfully(t) + + client := fake.ServiceClient() + actual, err := l7policies.Update(client, "8a1412f0-4c32-4257-8b07-af4770b604fd", l7policies.UpdateOpts{ + Name: "NewL7PolicyName", + Action: l7policies.ActionRedirectToURL, + RedirectURL: "http://www.new-example.com", + }).Extract() + if err != nil { + t.Fatalf("Unexpected Update error: %v", err) + } + + th.CheckDeepEquals(t, L7PolicyUpdated, *actual) +}