Skip to content

Commit

Permalink
LBaaS v2 l7 policy support - part 2: list l7policy
Browse files Browse the repository at this point in the history
  • Loading branch information
lingxiankong committed Apr 5, 2018
1 parent 54a8a6b commit 4b59796
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 0 deletions.
32 changes: 32 additions & 0 deletions acceptance/openstack/loadbalancer/v2/l7policies_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// +build acceptance networking loadbalancer l7policies

package v2

import (
"testing"

"github.com/gophercloud/gophercloud/acceptance/clients"
"github.com/gophercloud/gophercloud/acceptance/tools"
"github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/l7policies"
)

func TestL7PoliciesList(t *testing.T) {
client, err := clients.NewLoadBalancerV2Client()
if err != nil {
t.Fatalf("Unable to create a network client: %v", err)
}

allPages, err := l7policies.List(client, nil).AllPages()
if err != nil {
t.Fatalf("Unable to list l7policies: %v", err)
}

allL7Policies, err := l7policies.ExtractL7Policies(allPages)
if err != nil {
t.Fatalf("Unable to extract l7policies: %v", err)
}

for _, policy := range allL7Policies {
tools.PrintResource(t, policy)
}
}
16 changes: 16 additions & 0 deletions openstack/loadbalancer/v2/l7policies/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,21 @@ Example to Create a L7Policy
if err != nil {
panic(err)
}
Example to List L7Policies
listOpts := l7policies.ListOpts{
ListenerID: "c79a4468-d788-410c-bf79-9a8ef6354852",
}
allPages, err := l7policies.List(networkClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allL7Policies, err := l7policies.ExtractL7Policies(allPages)
if err != nil {
panic(err)
}
for _, l7policy := range allL7Policies {
fmt.Printf("%+v\n", l7policy)
}
*/
package l7policies
49 changes: 49 additions & 0 deletions openstack/loadbalancer/v2/l7policies/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package l7policies

import (
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)

// CreateOptsBuilder allows extensions to add additional parameters to the
Expand Down Expand Up @@ -82,3 +83,51 @@ func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResul
_, r.Err = c.Post(rootURL(c), b, &r.Body, nil)
return
}

// ListOptsBuilder allows extensions to add additional parameters to the
// List request.
type ListOptsBuilder interface {
ToL7PolicyListQuery() (string, error)
}

// ListOpts allows the filtering and sorting of paginated collections through
// the API.
type ListOpts struct {
Name string `q:"name"`
ListenerID string `q:"listener_id"`
Action string `q:"action"`
TenantID string `q:"tenant_id"`
RedirectPoolID string `q:"redirect_pool_id"`
RedirectURL string `q:"redirect_url"`
ID string `q:"id"`
Limit int `q:"limit"`
Marker string `q:"marker"`
SortKey string `q:"sort_key"`
SortDir string `q:"sort_dir"`
}

// ToL7PolicyListQuery formats a ListOpts into a query string.
func (opts ListOpts) ToL7PolicyListQuery() (string, error) {
q, err := gophercloud.BuildQueryString(opts)
return q.String(), err
}

// List returns a Pager which allows you to iterate over a collection of
// l7policies. It accepts a ListOpts struct, which allows you to filter and sort
// the returned collection for greater efficiency.
//
// Default policy settings return only those l7policies that are owned by the
// tenant who submits the request, unless an admin user submits the request.
func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
url := rootURL(c)
if opts != nil {
query, err := opts.ToL7PolicyListQuery()
if err != nil {
return pagination.Pager{Err: err}
}
url += query
}
return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
return L7PolicyPage{pagination.LinkedPageBase{PageResult: r}}
})
}
38 changes: 38 additions & 0 deletions openstack/loadbalancer/v2/l7policies/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package l7policies

import (
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)

// L7Policy is a collection of L7 rules associated with a Listener, and which
Expand Down Expand Up @@ -91,3 +92,40 @@ func (r commonResult) Extract() (*L7Policy, error) {
type CreateResult struct {
commonResult
}

// L7PolicyPage is the page returned by a pager when traversing over a
// collection of l7policies.
type L7PolicyPage struct {
pagination.LinkedPageBase
}

// NextPageURL is invoked when a paginated collection of l7policies has reached
// the end of a page and the pager seeks to traverse over a new one. In order
// to do this, it needs to construct the next page's URL.
func (r L7PolicyPage) NextPageURL() (string, error) {
var s struct {
Links []gophercloud.Link `json:"l7policies_links"`
}
err := r.ExtractInto(&s)
if err != nil {
return "", err
}
return gophercloud.ExtractNextURL(s.Links)
}

// IsEmpty checks whether a L7PolicyPage struct is empty.
func (r L7PolicyPage) IsEmpty() (bool, error) {
is, err := ExtractL7Policies(r)
return len(is) == 0, err
}

// ExtractL7Policies accepts a Page struct, specifically a L7PolicyPage struct,
// and extracts the elements into a slice of L7Policy structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractL7Policies(r pagination.Page) ([]L7Policy, error) {
var s struct {
L7Policies []L7Policy `json:"l7policies"`
}
err := (r.(L7PolicyPage)).ExtractInto(&s)
return s.L7Policies, err
}
66 changes: 66 additions & 0 deletions openstack/loadbalancer/v2/l7policies/testing/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@ var (
AdminStateUp: true,
Rules: []l7policies.Rule{},
}
L7PolicyToPool = l7policies.L7Policy{
ID: "964f4ba4-f6cd-405c-bebd-639460af7231",
Name: "redirect-pool",
ListenerID: "be3138a3-5cf7-4513-a4c2-bb137e668bab",
Action: "REDIRECT_TO_POOL",
Position: 1,
Description: "",
TenantID: "c1f7910086964990847dc6c8b128f63c",
RedirectPoolID: "bac433c6-5bea-4311-80da-bd1cd90fbd25",
RedirectURL: "",
AdminStateUp: true,
Rules: []l7policies.Rule{},
}
)

// HandleL7PolicyCreationSuccessfully sets up the test server to respond to a l7policy creation request
Expand All @@ -65,3 +78,56 @@ func HandleL7PolicyCreationSuccessfully(t *testing.T, response string) {
fmt.Fprintf(w, response)
})
}

// L7PoliciesListBody contains the canned body of a l7policy list response.
const L7PoliciesListBody = `
{
"l7policies": [
{
"redirect_pool_id": null,
"description": "",
"admin_state_up": true,
"rules": [],
"tenant_id": "e3cd678b11784734bc366148aa37580e",
"listener_id": "023f2e34-7806-443b-bfae-16c324569a3d",
"redirect_url": "http://www.example.com",
"action": "REDIRECT_TO_URL",
"position": 1,
"id": "8a1412f0-4c32-4257-8b07-af4770b604fd",
"name": "redirect-example.com"
},
{
"redirect_pool_id": "bac433c6-5bea-4311-80da-bd1cd90fbd25",
"description": "",
"admin_state_up": true,
"rules": [],
"tenant_id": "c1f7910086964990847dc6c8b128f63c",
"listener_id": "be3138a3-5cf7-4513-a4c2-bb137e668bab",
"action": "REDIRECT_TO_POOL",
"position": 1,
"id": "964f4ba4-f6cd-405c-bebd-639460af7231",
"name": "redirect-pool"
}
]
}
`

// 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) {
th.TestMethod(t, r, "GET")
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)

w.Header().Add("Content-Type", "application/json")
r.ParseForm()
marker := r.Form.Get("marker")
switch marker {
case "":
fmt.Fprintf(w, L7PoliciesListBody)
case "45e08a3e-a78f-4b40-a229-1e7e23eee1ab":
fmt.Fprintf(w, `{ "l7policies": [] }`)
default:
t.Fatalf("/v2.0/lbaas/l7policies invoked with unexpected marker=[%s]", marker)
}
})
}
44 changes: 44 additions & 0 deletions openstack/loadbalancer/v2/l7policies/testing/requests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/l7policies"
fake "github.com/gophercloud/gophercloud/openstack/networking/v2/common"
"github.com/gophercloud/gophercloud/pagination"
th "github.com/gophercloud/gophercloud/testhelper"
)

Expand Down Expand Up @@ -40,3 +41,46 @@ func TestRequiredL7PolicyCreateOpts(t *testing.T) {
t.Fatalf("Expected error, but got none")
}
}

func TestListL7Policies(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()
HandleL7PolicyListSuccessfully(t)

pages := 0
err := l7policies.List(fake.ServiceClient(), l7policies.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
pages++

actual, err := l7policies.ExtractL7Policies(page)
if err != nil {
return false, err
}

if len(actual) != 2 {
t.Fatalf("Expected 2 l7policies, got %d", len(actual))
}
th.CheckDeepEquals(t, L7PolicyToURL, actual[0])
th.CheckDeepEquals(t, L7PolicyToPool, actual[1])

return true, nil
})

th.AssertNoErr(t, err)

if pages != 1 {
t.Errorf("Expected 1 page, saw %d", pages)
}
}

func TestListAllL7Policies(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()
HandleL7PolicyListSuccessfully(t)

allPages, err := l7policies.List(fake.ServiceClient(), l7policies.ListOpts{}).AllPages()
th.AssertNoErr(t, err)
actual, err := l7policies.ExtractL7Policies(allPages)
th.AssertNoErr(t, err)
th.CheckDeepEquals(t, L7PolicyToURL, actual[0])
th.CheckDeepEquals(t, L7PolicyToPool, actual[1])
}

0 comments on commit 4b59796

Please sign in to comment.