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

Commit 99a0613

Browse files
committed
os-networks extension
This commit adds the os-networks extention. This can be used to view details about the nova-network-based networks that a tenant has access to.
1 parent f956c6c commit 99a0613

File tree

8 files changed

+612
-0
lines changed

8 files changed

+612
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// +build acceptance compute servers
2+
3+
package v2
4+
5+
import (
6+
"os"
7+
"testing"
8+
9+
"github.com/rackspace/gophercloud"
10+
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks"
11+
"github.com/rackspace/gophercloud/openstack/compute/v2/servers"
12+
th "github.com/rackspace/gophercloud/testhelper"
13+
)
14+
15+
func getNetworkIDFromNetworkExtension(t *testing.T, client *gophercloud.ServiceClient, networkName string) (string, error) {
16+
allPages, err := networks.List(client).AllPages()
17+
if err != nil {
18+
t.Fatalf("Unable to list networks: %v", err)
19+
}
20+
21+
networkList, err := networks.ExtractNetworks(allPages)
22+
if err != nil {
23+
t.Fatalf("Unable to list networks: %v", err)
24+
}
25+
26+
networkID := ""
27+
for _, network := range networkList {
28+
t.Logf("Network: %v", network)
29+
if network.Label == networkName {
30+
networkID = network.ID
31+
}
32+
}
33+
34+
t.Logf("Found network ID for %s: %s\n", networkName, networkID)
35+
36+
return networkID, nil
37+
}
38+
39+
func TestNetworks(t *testing.T) {
40+
networkName := os.Getenv("OS_NETWORK_NAME")
41+
if networkName == "" {
42+
t.Fatalf("OS_NETWORK_NAME must be set")
43+
}
44+
45+
choices, err := ComputeChoicesFromEnv()
46+
if err != nil {
47+
t.Fatal(err)
48+
}
49+
50+
client, err := newClient()
51+
if err != nil {
52+
t.Fatalf("Unable to create a compute client: %v", err)
53+
}
54+
55+
networkID, err := getNetworkIDFromNetworkExtension(t, client, networkName)
56+
if err != nil {
57+
t.Fatalf("Unable to get network ID: %v", err)
58+
}
59+
60+
// createNetworkServer is defined in tenantnetworks_test.go
61+
server, err := createNetworkServer(t, client, choices, networkID)
62+
if err != nil {
63+
t.Fatalf("Unable to create server: %v", err)
64+
}
65+
defer func() {
66+
servers.Delete(client, server.ID)
67+
t.Logf("Server deleted.")
68+
}()
69+
70+
if err = waitForStatus(client, server, "ACTIVE"); err != nil {
71+
t.Fatalf("Unable to wait for server: %v", err)
72+
}
73+
74+
allPages, err := networks.List(client).AllPages()
75+
allNetworks, err := networks.ExtractNetworks(allPages)
76+
th.AssertNoErr(t, err)
77+
t.Logf("Retrieved all %d networks: %+v", len(allNetworks), allNetworks)
78+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Package network provides the ability to manage nova-networks
2+
package networks
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
// +build fixtures
2+
3+
package networks
4+
5+
import (
6+
"fmt"
7+
"net/http"
8+
"testing"
9+
"time"
10+
11+
th "github.com/rackspace/gophercloud/testhelper"
12+
"github.com/rackspace/gophercloud/testhelper/client"
13+
)
14+
15+
// ListOutput is a sample response to a List call.
16+
const ListOutput = `
17+
{
18+
"networks": [
19+
{
20+
"bridge": "br100",
21+
"bridge_interface": "eth0",
22+
"broadcast": "10.0.0.7",
23+
"cidr": "10.0.0.0/29",
24+
"cidr_v6": null,
25+
"created_at": "2011-08-15 06:19:19.387525",
26+
"deleted": false,
27+
"deleted_at": null,
28+
"dhcp_start": "10.0.0.3",
29+
"dns1": null,
30+
"dns2": null,
31+
"gateway": "10.0.0.1",
32+
"gateway_v6": null,
33+
"host": "nsokolov-desktop",
34+
"id": "20c8acc0-f747-4d71-a389-46d078ebf047",
35+
"injected": false,
36+
"label": "mynet_0",
37+
"multi_host": false,
38+
"netmask": "255.255.255.248",
39+
"netmask_v6": null,
40+
"priority": null,
41+
"project_id": "1234",
42+
"rxtx_base": null,
43+
"updated_at": "2011-08-16 09:26:13.048257",
44+
"vlan": 100,
45+
"vpn_private_address": "10.0.0.2",
46+
"vpn_public_address": "127.0.0.1",
47+
"vpn_public_port": 1000
48+
},
49+
{
50+
"bridge": "br101",
51+
"bridge_interface": "eth0",
52+
"broadcast": "10.0.0.15",
53+
"cidr": "10.0.0.10/29",
54+
"cidr_v6": null,
55+
"created_at": "2011-08-15 06:19:19.885495",
56+
"deleted": false,
57+
"deleted_at": null,
58+
"dhcp_start": "10.0.0.11",
59+
"dns1": null,
60+
"dns2": null,
61+
"gateway": "10.0.0.9",
62+
"gateway_v6": null,
63+
"host": null,
64+
"id": "20c8acc0-f747-4d71-a389-46d078ebf000",
65+
"injected": false,
66+
"label": "mynet_1",
67+
"multi_host": false,
68+
"netmask": "255.255.255.248",
69+
"netmask_v6": null,
70+
"priority": null,
71+
"project_id": null,
72+
"rxtx_base": null,
73+
"updated_at": null,
74+
"vlan": 101,
75+
"vpn_private_address": "10.0.0.10",
76+
"vpn_public_address": null,
77+
"vpn_public_port": 1001
78+
}
79+
]
80+
}
81+
`
82+
83+
// GetOutput is a sample response to a Get call.
84+
const GetOutput = `
85+
{
86+
"network": {
87+
"bridge": "br101",
88+
"bridge_interface": "eth0",
89+
"broadcast": "10.0.0.15",
90+
"cidr": "10.0.0.10/29",
91+
"cidr_v6": null,
92+
"created_at": "2011-08-15 06:19:19.885495",
93+
"deleted": false,
94+
"deleted_at": null,
95+
"dhcp_start": "10.0.0.11",
96+
"dns1": null,
97+
"dns2": null,
98+
"gateway": "10.0.0.9",
99+
"gateway_v6": null,
100+
"host": null,
101+
"id": "20c8acc0-f747-4d71-a389-46d078ebf000",
102+
"injected": false,
103+
"label": "mynet_1",
104+
"multi_host": false,
105+
"netmask": "255.255.255.248",
106+
"netmask_v6": null,
107+
"priority": null,
108+
"project_id": null,
109+
"rxtx_base": null,
110+
"updated_at": null,
111+
"vlan": 101,
112+
"vpn_private_address": "10.0.0.10",
113+
"vpn_public_address": null,
114+
"vpn_public_port": 1001
115+
}
116+
}
117+
`
118+
119+
// FirstNetwork is the first result in ListOutput.
120+
var nilTime time.Time
121+
var FirstNetwork = Network{
122+
Bridge: "br100",
123+
BridgeInterface: "eth0",
124+
Broadcast: "10.0.0.7",
125+
CIDR: "10.0.0.0/29",
126+
CIDRv6: "",
127+
CreatedAt: time.Date(2011, 8, 15, 6, 19, 19, 387525000, time.UTC),
128+
Deleted: false,
129+
DeletedAt: nilTime,
130+
DHCPStart: "10.0.0.3",
131+
DNS1: "",
132+
DNS2: "",
133+
Gateway: "10.0.0.1",
134+
Gatewayv6: "",
135+
Host: "nsokolov-desktop",
136+
ID: "20c8acc0-f747-4d71-a389-46d078ebf047",
137+
Injected: false,
138+
Label: "mynet_0",
139+
MultiHost: false,
140+
Netmask: "255.255.255.248",
141+
Netmaskv6: "",
142+
Priority: 0,
143+
ProjectID: "1234",
144+
RXTXBase: 0,
145+
UpdatedAt: time.Date(2011, 8, 16, 9, 26, 13, 48257000, time.UTC),
146+
VLAN: 100,
147+
VPNPrivateAddress: "10.0.0.2",
148+
VPNPublicAddress: "127.0.0.1",
149+
VPNPublicPort: 1000,
150+
}
151+
152+
// SecondNetwork is the second result in ListOutput.
153+
var SecondNetwork = Network{
154+
Bridge: "br101",
155+
BridgeInterface: "eth0",
156+
Broadcast: "10.0.0.15",
157+
CIDR: "10.0.0.10/29",
158+
CIDRv6: "",
159+
CreatedAt: time.Date(2011, 8, 15, 6, 19, 19, 885495000, time.UTC),
160+
Deleted: false,
161+
DeletedAt: nilTime,
162+
DHCPStart: "10.0.0.11",
163+
DNS1: "",
164+
DNS2: "",
165+
Gateway: "10.0.0.9",
166+
Gatewayv6: "",
167+
Host: "",
168+
ID: "20c8acc0-f747-4d71-a389-46d078ebf000",
169+
Injected: false,
170+
Label: "mynet_1",
171+
MultiHost: false,
172+
Netmask: "255.255.255.248",
173+
Netmaskv6: "",
174+
Priority: 0,
175+
ProjectID: "",
176+
RXTXBase: 0,
177+
UpdatedAt: nilTime,
178+
VLAN: 101,
179+
VPNPrivateAddress: "10.0.0.10",
180+
VPNPublicAddress: "",
181+
VPNPublicPort: 1001,
182+
}
183+
184+
// ExpectedNetworkSlice is the slice of results that should be parsed
185+
// from ListOutput, in the expected order.
186+
var ExpectedNetworkSlice = []Network{FirstNetwork, SecondNetwork}
187+
188+
// HandleListSuccessfully configures the test server to respond to a List request.
189+
func HandleListSuccessfully(t *testing.T) {
190+
th.Mux.HandleFunc("/os-networks", func(w http.ResponseWriter, r *http.Request) {
191+
th.TestMethod(t, r, "GET")
192+
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
193+
194+
w.Header().Add("Content-Type", "application/json")
195+
fmt.Fprintf(w, ListOutput)
196+
})
197+
}
198+
199+
// HandleGetSuccessfully configures the test server to respond to a Get request
200+
// for an existing network.
201+
func HandleGetSuccessfully(t *testing.T) {
202+
th.Mux.HandleFunc("/os-networks/20c8acc0-f747-4d71-a389-46d078ebf000", func(w http.ResponseWriter, r *http.Request) {
203+
th.TestMethod(t, r, "GET")
204+
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
205+
206+
w.Header().Add("Content-Type", "application/json")
207+
fmt.Fprintf(w, GetOutput)
208+
})
209+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package networks
2+
3+
import (
4+
"github.com/rackspace/gophercloud"
5+
"github.com/rackspace/gophercloud/pagination"
6+
)
7+
8+
// List returns a Pager that allows you to iterate over a collection of Network.
9+
func List(client *gophercloud.ServiceClient) pagination.Pager {
10+
url := listURL(client)
11+
createPage := func(r pagination.PageResult) pagination.Page {
12+
return NetworkPage{pagination.SinglePageBase(r)}
13+
}
14+
return pagination.NewPager(client, url, createPage)
15+
}
16+
17+
// Get returns data about a previously created Network.
18+
func Get(client *gophercloud.ServiceClient, id string) GetResult {
19+
var res GetResult
20+
_, res.Err = client.Get(getURL(client, id), &res.Body, nil)
21+
return res
22+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package networks
2+
3+
import (
4+
"testing"
5+
6+
"github.com/rackspace/gophercloud/pagination"
7+
th "github.com/rackspace/gophercloud/testhelper"
8+
"github.com/rackspace/gophercloud/testhelper/client"
9+
)
10+
11+
func TestList(t *testing.T) {
12+
th.SetupHTTP()
13+
defer th.TeardownHTTP()
14+
HandleListSuccessfully(t)
15+
16+
count := 0
17+
err := List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) {
18+
count++
19+
actual, err := ExtractNetworks(page)
20+
th.AssertNoErr(t, err)
21+
th.CheckDeepEquals(t, ExpectedNetworkSlice, actual)
22+
23+
return true, nil
24+
})
25+
th.AssertNoErr(t, err)
26+
th.CheckEquals(t, 1, count)
27+
}
28+
29+
func TestGet(t *testing.T) {
30+
th.SetupHTTP()
31+
defer th.TeardownHTTP()
32+
HandleGetSuccessfully(t)
33+
34+
actual, err := Get(client.ServiceClient(), "20c8acc0-f747-4d71-a389-46d078ebf000").Extract()
35+
th.AssertNoErr(t, err)
36+
th.CheckDeepEquals(t, &SecondNetwork, actual)
37+
}

0 commit comments

Comments
 (0)