Skip to content
This repository was archived by the owner on Aug 1, 2023. It is now read-only.

Commit 0765099

Browse files
committed
Merge pull request #2 from jamiehannaford/pr/475
Adds list extract function and squashes struct
2 parents 4b97ac2 + 1b17d0a commit 0765099

File tree

5 files changed

+335
-182
lines changed

5 files changed

+335
-182
lines changed

acceptance/openstack/networking/v2/extensions/portsbinding/portsbinding_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/rackspace/gophercloud/openstack/networking/v2/networks"
1111
"github.com/rackspace/gophercloud/openstack/networking/v2/ports"
1212
"github.com/rackspace/gophercloud/openstack/networking/v2/subnets"
13+
"github.com/rackspace/gophercloud/pagination"
1314
th "github.com/rackspace/gophercloud/testhelper"
1415
)
1516

@@ -53,11 +54,40 @@ func TestPortBinding(t *testing.T) {
5354
th.AssertNoErr(t, err)
5455
th.AssertEquals(t, p.HostID, newHostID)
5556

57+
// List ports
58+
t.Logf("Listing all ports")
59+
listPorts(t)
60+
5661
// Delete port
5762
res := ports.Delete(base.Client, portID)
5863
th.AssertNoErr(t, res.Err)
5964
}
6065

66+
func listPorts(t *testing.T) {
67+
count := 0
68+
pager := ports.List(base.Client, ports.ListOpts{})
69+
err := pager.EachPage(func(page pagination.Page) (bool, error) {
70+
count++
71+
t.Logf("--- Page ---")
72+
73+
portList, err := portsbinding.ExtractPorts(page)
74+
th.AssertNoErr(t, err)
75+
76+
for _, p := range portList {
77+
t.Logf("Port: ID [%s] Name [%s] HostID [%s] VNICType [%s] VIFType [%s]",
78+
p.ID, p.Name, p.HostID, p.VNICType, p.VIFType)
79+
}
80+
81+
return true, nil
82+
})
83+
84+
th.CheckNoErr(t, err)
85+
86+
if count == 0 {
87+
t.Logf("No pages were iterated over when listing ports")
88+
}
89+
}
90+
6191
func createPort(t *testing.T, networkID, subnetID, hostID string) string {
6292
enable := false
6393
opts := portsbinding.CreateOpts{
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
package portsbinding
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"testing"
7+
8+
fake "github.com/rackspace/gophercloud/openstack/networking/v2/common"
9+
th "github.com/rackspace/gophercloud/testhelper"
10+
)
11+
12+
func HandleListSuccessfully(t *testing.T) {
13+
th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) {
14+
th.TestMethod(t, r, "GET")
15+
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
16+
17+
w.Header().Add("Content-Type", "application/json")
18+
w.WriteHeader(http.StatusOK)
19+
20+
fmt.Fprintf(w, `
21+
{
22+
"ports": [
23+
{
24+
"status": "ACTIVE",
25+
"binding:host_id": "devstack",
26+
"name": "",
27+
"admin_state_up": true,
28+
"network_id": "70c1db1f-b701-45bd-96e0-a313ee3430b3",
29+
"tenant_id": "",
30+
"device_owner": "network:router_gateway",
31+
"mac_address": "fa:16:3e:58:42:ed",
32+
"fixed_ips": [
33+
{
34+
"subnet_id": "008ba151-0b8c-4a67-98b5-0d2b87666062",
35+
"ip_address": "172.24.4.2"
36+
}
37+
],
38+
"id": "d80b1a3b-4fc1-49f3-952e-1e2ab7081d8b",
39+
"security_groups": [],
40+
"device_id": "9ae135f4-b6e0-4dad-9e91-3c223e385824",
41+
"binding:vnic_type": "normal"
42+
}
43+
]
44+
}
45+
`)
46+
})
47+
}
48+
49+
func HandleGet(t *testing.T) {
50+
th.Mux.HandleFunc("/v2.0/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", func(w http.ResponseWriter, r *http.Request) {
51+
th.TestMethod(t, r, "GET")
52+
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
53+
54+
w.Header().Add("Content-Type", "application/json")
55+
w.WriteHeader(http.StatusOK)
56+
57+
fmt.Fprintf(w, `
58+
{
59+
"port": {
60+
"status": "ACTIVE",
61+
"binding:host_id": "devstack",
62+
"name": "",
63+
"allowed_address_pairs": [],
64+
"admin_state_up": true,
65+
"network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
66+
"tenant_id": "7e02058126cc4950b75f9970368ba177",
67+
"extra_dhcp_opts": [],
68+
"binding:vif_details": {
69+
"port_filter": true,
70+
"ovs_hybrid_plug": true
71+
},
72+
"binding:vif_type": "ovs",
73+
"device_owner": "network:router_interface",
74+
"port_security_enabled": false,
75+
"mac_address": "fa:16:3e:23:fd:d7",
76+
"binding:profile": {},
77+
"binding:vnic_type": "normal",
78+
"fixed_ips": [
79+
{
80+
"subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
81+
"ip_address": "10.0.0.1"
82+
}
83+
],
84+
"id": "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2",
85+
"security_groups": [],
86+
"device_id": "5e3898d7-11be-483e-9732-b2f5eccd2b2e"
87+
}
88+
}
89+
`)
90+
})
91+
}
92+
93+
func HandleCreate(t *testing.T) {
94+
th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) {
95+
th.TestMethod(t, r, "POST")
96+
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
97+
th.TestHeader(t, r, "Content-Type", "application/json")
98+
th.TestHeader(t, r, "Accept", "application/json")
99+
th.TestJSONRequest(t, r, `
100+
{
101+
"port": {
102+
"network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
103+
"name": "private-port",
104+
"admin_state_up": true,
105+
"fixed_ips": [
106+
{
107+
"subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
108+
"ip_address": "10.0.0.2"
109+
}
110+
],
111+
"security_groups": ["foo"],
112+
"binding:host_id": "HOST1",
113+
"binding:vnic_type": "normal"
114+
}
115+
}
116+
`)
117+
118+
w.Header().Add("Content-Type", "application/json")
119+
w.WriteHeader(http.StatusCreated)
120+
121+
fmt.Fprintf(w, `
122+
{
123+
"port": {
124+
"status": "DOWN",
125+
"name": "private-port",
126+
"allowed_address_pairs": [],
127+
"admin_state_up": true,
128+
"network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
129+
"tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
130+
"device_owner": "",
131+
"mac_address": "fa:16:3e:c9:cb:f0",
132+
"fixed_ips": [
133+
{
134+
"subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
135+
"ip_address": "10.0.0.2"
136+
}
137+
],
138+
"binding:host_id": "HOST1",
139+
"binding:vnic_type": "normal",
140+
"id": "65c0ee9f-d634-4522-8954-51021b570b0d",
141+
"security_groups": [
142+
"f0ac4394-7e4a-4409-9701-ba8be283dbc3"
143+
],
144+
"device_id": ""
145+
}
146+
}
147+
`)
148+
})
149+
}
150+
151+
func HandleUpdate(t *testing.T) {
152+
th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) {
153+
th.TestMethod(t, r, "PUT")
154+
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
155+
th.TestHeader(t, r, "Content-Type", "application/json")
156+
th.TestHeader(t, r, "Accept", "application/json")
157+
th.TestJSONRequest(t, r, `
158+
{
159+
"port": {
160+
"name": "new_port_name",
161+
"fixed_ips": [
162+
{
163+
"subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
164+
"ip_address": "10.0.0.3"
165+
}
166+
],
167+
"security_groups": [
168+
"f0ac4394-7e4a-4409-9701-ba8be283dbc3"
169+
],
170+
"binding:host_id": "HOST1",
171+
"binding:vnic_type": "normal"
172+
}
173+
}
174+
`)
175+
176+
w.Header().Add("Content-Type", "application/json")
177+
w.WriteHeader(http.StatusOK)
178+
179+
fmt.Fprintf(w, `
180+
{
181+
"port": {
182+
"status": "DOWN",
183+
"name": "new_port_name",
184+
"admin_state_up": true,
185+
"network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
186+
"tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
187+
"device_owner": "",
188+
"mac_address": "fa:16:3e:c9:cb:f0",
189+
"fixed_ips": [
190+
{
191+
"subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
192+
"ip_address": "10.0.0.3"
193+
}
194+
],
195+
"id": "65c0ee9f-d634-4522-8954-51021b570b0d",
196+
"security_groups": [
197+
"f0ac4394-7e4a-4409-9701-ba8be283dbc3"
198+
],
199+
"device_id": "",
200+
"binding:host_id": "HOST1",
201+
"binding:vnic_type": "normal"
202+
}
203+
}
204+
`)
205+
})
206+
}

openstack/networking/v2/extensions/portsbinding/requests.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ import (
55
"github.com/rackspace/gophercloud/openstack/networking/v2/ports"
66
)
77

8+
// Get retrieves a specific port based on its unique ID.
9+
func Get(c *gophercloud.ServiceClient, id string) GetResult {
10+
var res GetResult
11+
_, res.Err = c.Get(getURL(c, id), &res.Body, nil)
12+
return res
13+
}
14+
815
// CreateOpts represents the attributes used when creating a new
916
// port with extended attributes.
1017
type CreateOpts struct {
@@ -22,13 +29,6 @@ type CreateOpts struct {
2229
Profile map[string]string
2330
}
2431

25-
// Get retrieves a specific port based on its unique ID.
26-
func Get(c *gophercloud.ServiceClient, id string) GetResult {
27-
var res GetResult
28-
_, res.Err = c.Get(getURL(c, id), &res.Body, nil)
29-
return res
30-
}
31-
3232
// ToPortCreateMap casts a CreateOpts struct to a map.
3333
func (opts CreateOpts) ToPortCreateMap() (map[string]interface{}, error) {
3434
p, err := opts.CreateOptsBuilder.ToPortCreateMap()
@@ -68,10 +68,18 @@ func Create(c *gophercloud.ServiceClient, opts ports.CreateOptsBuilder) CreateRe
6868

6969
// UpdateOpts represents the attributes used when updating an existing port.
7070
type UpdateOpts struct {
71+
// UpdateOptsBuilder is the interface options structs have to satisfy in order
72+
// to be used in the main Update operation in this package.
7173
ports.UpdateOptsBuilder
72-
HostID string
74+
// The ID of the host where the port is allocated
75+
HostID string
76+
// The virtual network interface card (vNIC) type that is bound to the
77+
// neutron port
7378
VNICType string
74-
Profile map[string]string
79+
// A dictionary that enables the application running on the specified
80+
// host to pass and receive virtual network interface (VIF) port-specific
81+
// information to the plug-in
82+
Profile map[string]string
7583
}
7684

7785
// ToPortUpdateMap casts an UpdateOpts struct to a map.

0 commit comments

Comments
 (0)