Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vpnaas: List Endpoint groups #813

Merged
merged 4 commits into from
Mar 9, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions acceptance/openstack/networking/v2/extensions/vpnaas/group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,27 @@ import (
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/vpnaas/endpointgroups"
)

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

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

allGroups, err := endpointgroups.ExtractEndpointGroups(allPages)
if err != nil {
t.Fatalf("Unable to extract endpoint groups: %v", err)
}

for _, group := range allGroups {
tools.PrintResource(t, group)
}
}

func TestGroupCRUD(t *testing.T) {
client, err := clients.NewNetworkV2Client()
if err != nil {
Expand Down
11 changes: 11 additions & 0 deletions openstack/networking/v2/extensions/vpnaas/endpointgroups/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,16 @@ Example to Delete an Endpoint Group
panic(err)
}

Example to List Endpoint groups

allPages, err := endpointgroups.List(client, nil).AllPages()
if err != nil {
panic(err)
}

allGroups, err := endpointgroups.ExtractEndpointGroups(allPages)
if err != nil {
panic(err)
}
*/
package endpointgroups
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package endpointgroups

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

type EndpointType string

Expand Down Expand Up @@ -63,6 +66,45 @@ func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
return
}

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

// ListOpts allows the filtering of paginated collections through
// the API. Filtering is achieved by passing in struct field values that map to
// the Endpoint group attributes you want to see returned.
type ListOpts struct {
TenantID string `q:"tenant_id"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add ProjectID as well.

Description string `q:"description"`
Name string `q:"name"`
Type string `q:"type"`
}

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

// List returns a Pager which allows you to iterate over a collection of
// Endpoint groups. It accepts a ListOpts struct, which allows you to filter
// the returned collection for greater efficiency.
func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
url := rootURL(c)
if opts != nil {
query, err := opts.ToEndpointGroupListQuery()
if err != nil {
return pagination.Pager{Err: err}
}
url += query
}
return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
return EndpointGroupPage{pagination.LinkedPageBase{PageResult: r}}
})
}

// Delete will permanently delete a particular endpoint group based on its
// unique ID.
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package endpointgroups

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

// EndpointGroup is an endpoint group.
Expand Down Expand Up @@ -41,6 +42,43 @@ func (r commonResult) Extract() (*EndpointGroup, error) {
return s.Service, err
}

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

// NextPageURL is invoked when a paginated collection of Endpoint groups 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 EndpointGroupPage) NextPageURL() (string, error) {
var s struct {
Links []gophercloud.Link `json:"endpoint_groups_links"`
}
err := r.ExtractInto(&s)
if err != nil {
return "", err
}
return gophercloud.ExtractNextURL(s.Links)
}

// IsEmpty checks whether an EndpointGroupPage struct is empty.
func (r EndpointGroupPage) IsEmpty() (bool, error) {
is, err := ExtractEndpointGroups(r)
return len(is) == 0, err
}

// ExtractEndpointGroups accepts a Page struct, specifically an EndpointGroupPage struct,
// and extracts the elements into a slice of Endpoint group structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractEndpointGroups(r pagination.Page) ([]EndpointGroup, error) {
var s struct {
EndpointGroups []EndpointGroup `json:"endpoint_groups"`
}
err := (r.(EndpointGroupPage)).ExtractInto(&s)
return s.EndpointGroups, err
}

// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as an endpoint group.
type CreateResult struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

fake "github.com/gophercloud/gophercloud/openstack/networking/v2/common"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/vpnaas/endpointgroups"
"github.com/gophercloud/gophercloud/pagination"
th "github.com/gophercloud/gophercloud/testhelper"
)

Expand Down Expand Up @@ -123,6 +124,69 @@ func TestGet(t *testing.T) {
th.AssertDeepEquals(t, expected, *actual)
}

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

th.Mux.HandleFunc("/v2.0/vpn/endpoint-groups", func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "GET")
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
w.Header().Add("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)

fmt.Fprintf(w, `
{
"endpoint_groups": [
{
"description": "",
"tenant_id": "4ad57e7ce0b24fca8f12b9834d91079d",
"project_id": "4ad57e7ce0b24fca8f12b9834d91079d",
"endpoints": [
"10.2.0.0/24",
"10.3.0.0/24"
],
"type": "cidr",
"id": "6ecd9cf3-ca64-46c7-863f-f2eb1b9e838a",
"name": "peers"
}
]
}
`)
})

count := 0

endpointgroups.List(fake.ServiceClient(), endpointgroups.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
count++
actual, err := endpointgroups.ExtractEndpointGroups(page)
if err != nil {
t.Errorf("Failed to extract members: %v", err)
return false, err
}
expected := []endpointgroups.EndpointGroup{
{
Name: "peers",
TenantID: "4ad57e7ce0b24fca8f12b9834d91079d",
ProjectID: "4ad57e7ce0b24fca8f12b9834d91079d",
ID: "6ecd9cf3-ca64-46c7-863f-f2eb1b9e838a",
Description: "",
Endpoints: []string{
"10.2.0.0/24",
"10.3.0.0/24",
},
Type: "cidr",
},
}
th.CheckDeepEquals(t, expected, actual)

return true, nil
})

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

func TestDelete(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()
Expand Down