Making return types more consistent :boom:
diff --git a/acceptance/openstack/networking/v2/network_test.go b/acceptance/openstack/networking/v2/network_test.go
index 4fe7775..27a7e1a 100644
--- a/acceptance/openstack/networking/v2/network_test.go
+++ b/acceptance/openstack/networking/v2/network_test.go
@@ -154,17 +154,23 @@
}
Equals(t, n.Status, "ACTIVE")
- DeepEquals(t, n.Subnets, []string{})
+ DeepEquals(t, n.Subnets, []interface{}{})
Equals(t, n.Name, "sample_network")
Equals(t, n.ProviderPhysicalNetwork, "")
Equals(t, n.ProviderNetworkType, "local")
- Equals(t, n.ProviderSegmentationID, "")
+ Equals(t, n.ProviderSegmentationID, 0)
Equals(t, n.AdminStateUp, true)
Equals(t, n.RouterExternal, false)
Equals(t, n.Shared, false)
Equals(t, n.ID, networkID)
// Update network
+ n, err = networks.Update(Client, networkID, networks.NetworkOpts{Name: "new_network_name"})
+ if err != nil {
+ t.Fatalf("Unexpected error: %#v", err)
+ }
+
+ Equals(t, n.Name, "new_network_name")
// Delete network
}
diff --git a/openstack/networking/v2/networks/requests.go b/openstack/networking/v2/networks/requests.go
index 7b647fe..9a23cc0 100644
--- a/openstack/networking/v2/networks/requests.go
+++ b/openstack/networking/v2/networks/requests.go
@@ -1,9 +1,6 @@
package networks
import (
- "encoding/json"
- "fmt"
-
"github.com/racker/perigee"
"github.com/rackspace/gophercloud"
)
@@ -52,12 +49,12 @@
return &ext, nil
}
-func Get(c *gophercloud.ServiceClient, id string) (*Network, error) {
- var n Network
+func Get(c *gophercloud.ServiceClient, id string) (*NetworkResult, error) {
+ var n NetworkResult
_, err := perigee.Request("GET", NetworkURL(c, id), perigee.Options{
MoreHeaders: c.Provider.AuthenticatedHeaders(),
Results: &struct {
- Network *Network `json:"network"`
+ Network *NetworkResult `json:"network"`
}{&n},
OkCodes: []int{200},
})
@@ -74,25 +71,7 @@
TenantID string
}
-type NetworkProvider struct {
- ProviderSegmentationID int `json:"provider:segmentation_id"`
- ProviderPhysicalNetwork string `json:"provider:physical_network"`
- ProviderNetworkType string `json:"provider:network_type"`
-}
-
-type NetworkResult struct {
- Status string `json:"status"`
- Subnets []interface{} `json:"subnets"`
- Name string `json:"name"`
- AdminStateUp bool `json:"admin_state_up"`
- TenantID string `json:"tenant_id"`
- Segments []NetworkProvider `json:"segments"`
- Shared bool `json:"shared"`
- PortSecurityEnabled bool `json:"port_security_enabled"`
- ID string `json:"id"`
-}
-
-func Create(c *gophercloud.ServiceClient, opts NetworkOpts) (*NetworkResult, error) {
+func Create(c *gophercloud.ServiceClient, opts NetworkOpts) (*NetworkCreateResult, error) {
// Define structures
type network struct {
AdminStateUp bool `json:"admin_state_up"`
@@ -104,7 +83,7 @@
Network network `json:"network"`
}
type response struct {
- Network *NetworkResult `json:"network"`
+ Network *NetworkCreateResult `json:"network"`
}
// Validate
@@ -123,9 +102,6 @@
reqBody.Network.TenantID = &opts.TenantID
}
- j, _ := json.Marshal(reqBody)
- fmt.Println(string(j))
-
// Send request to API
var res response
_, err := perigee.Request("POST", CreateURL(c), perigee.Options{
@@ -140,3 +116,45 @@
return res.Network, nil
}
+
+func Update(c *gophercloud.ServiceClient, networkID string, opts NetworkOpts) (*NetworkResult, error) {
+ // Define structures
+ type network struct {
+ AdminStateUp bool `json:"admin_state_up"`
+ Name string `json:"name"`
+ Shared *bool `json:"shared,omitempty"`
+ TenantID *string `json:"tenant_id,omitempty"`
+ }
+
+ type request struct {
+ Network network `json:"network"`
+ }
+ type response struct {
+ Network *NetworkResult `json:"network"`
+ }
+
+ // Populate request body
+ reqBody := request{Network: network{
+ AdminStateUp: opts.AdminStateUp,
+ Name: opts.Name,
+ Shared: opts.Shared,
+ }}
+
+ if opts.TenantID != "" {
+ reqBody.Network.TenantID = &opts.TenantID
+ }
+
+ // Send request to API
+ var res response
+ _, err := perigee.Request("PUT", NetworkURL(c, networkID), perigee.Options{
+ MoreHeaders: c.Provider.AuthenticatedHeaders(),
+ ReqBody: &reqBody,
+ Results: &res,
+ OkCodes: []int{200},
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return res.Network, nil
+}
diff --git a/openstack/networking/v2/networks/requests_test.go b/openstack/networking/v2/networks/requests_test.go
index 61d9268..a52adab 100644
--- a/openstack/networking/v2/networks/requests_test.go
+++ b/openstack/networking/v2/networks/requests_test.go
@@ -251,11 +251,11 @@
}
Equals(t, n.Status, "ACTIVE")
- DeepEquals(t, n.Subnets, []string{"54d6f61d-db07-451c-9ab3-b9609b6b6f0b"})
+ DeepEquals(t, n.Subnets, []interface{}{"54d6f61d-db07-451c-9ab3-b9609b6b6f0b"})
Equals(t, n.Name, "private-network")
Equals(t, n.ProviderPhysicalNetwork, "")
Equals(t, n.ProviderNetworkType, "local")
- Equals(t, n.ProviderSegmentationID, "")
+ Equals(t, n.ProviderSegmentationID, 0)
Equals(t, n.AdminStateUp, true)
Equals(t, n.TenantID, "4fd44f30292945e481c7b8a0c8908869")
Equals(t, n.RouterExternal, true)
@@ -364,3 +364,58 @@
t.Fatalf("Unexpected error: %#v", err)
}
}
+
+func TestUpdateNetwork(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+
+ th.Mux.HandleFunc("/v2.0/networks/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "PUT")
+ th.TestHeader(t, r, "X-Auth-Token", TokenID)
+ th.TestHeader(t, r, "Content-Type", "application/json")
+ th.TestHeader(t, r, "Accept", "application/json")
+ th.TestJSONRequest(t, r, `
+{
+ "network": {
+ "name": "new_network_name",
+ "admin_state_up": false,
+ "shared": true
+ }
+}
+ `)
+
+ w.Header().Add("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+
+ fmt.Fprintf(w, `
+{
+ "network": {
+ "status": "ACTIVE",
+ "subnets": [],
+ "name": "new_network_name",
+ "provider:physical_network": null,
+ "admin_state_up": false,
+ "tenant_id": "4fd44f30292945e481c7b8a0c8908869",
+ "provider:network_type": "local",
+ "router:external": false,
+ "shared": true,
+ "id": "4e8e5957-649f-477b-9e5b-f1f75b21c03c",
+ "provider:segmentation_id": null
+ }
+}
+ `)
+ })
+
+ shared := true
+ options := NetworkOpts{Name: "new_network_name", AdminStateUp: false, Shared: &shared}
+
+ n, err := Update(ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options)
+ if err != nil {
+ t.Fatalf("Unexpected error: %#v", err)
+ }
+
+ Equals(t, n.Name, "new_network_name")
+ Equals(t, n.AdminStateUp, false)
+ Equals(t, n.Shared, true)
+ Equals(t, n.ID, "4e8e5957-649f-477b-9e5b-f1f75b21c03c")
+}
diff --git a/openstack/networking/v2/networks/results.go b/openstack/networking/v2/networks/results.go
index b48086c..741a959 100644
--- a/openstack/networking/v2/networks/results.go
+++ b/openstack/networking/v2/networks/results.go
@@ -7,30 +7,32 @@
"github.com/rackspace/gophercloud"
)
-// A Network represents a a virtual layer-2 broadcast domain.
-type Network struct {
- // Id is the unique identifier for the network.
- ID string `json:"id"`
- // Name is the (not necessarily unique) human-readable identifier for the network.
- Name string `json:"name"`
- // AdminStateUp is administrative state of the network. If false, network is down.
- AdminStateUp bool `json:"admin_state_up"`
- // Status indicates if the network is operational. Possible values: active, down, build, error.
- Status string `json:"status"`
- // Subnets are IP address blocks that can be used to assign IP addresses to virtual instances.
- Subnets []string `json:"subnets"`
- // Shared indicates whether the network can be accessed by any tenant or not.
- Shared bool `json:"shared"`
- // TenantId is the owner of the network. Admins may specify TenantId other than their own.
- TenantID string `json:"tenant_id"`
- // RouterExternal indicates if the network is connected to an external router.
- RouterExternal bool `json:"router:external"`
- // ProviderPhysicalNetwork is the name of the provider physical network.
+type NetworkProvider struct {
+ ProviderSegmentationID int `json:"provider:segmentation_id"`
ProviderPhysicalNetwork string `json:"provider:physical_network"`
- // ProviderNetworkType is the type of provider network (eg "vlan").
- ProviderNetworkType string `json:"provider:network_type"`
- // ProviderSegmentationId is the provider network identifier (such as the vlan id).
- ProviderSegmentationID string `json:"provider:segmentation_id"`
+ ProviderNetworkType string `json:"provider:network_type"`
+}
+
+type Network struct {
+ Status string `json:"status"`
+ Subnets []interface{} `json:"subnets"`
+ Name string `json:"name"`
+ AdminStateUp bool `json:"admin_state_up"`
+ TenantID string `json:"tenant_id"`
+ Shared bool `json:"shared"`
+ ID string `json:"id"`
+}
+
+type NetworkResult struct {
+ Network
+ NetworkProvider
+ RouterExternal bool `json:"router:external"`
+}
+
+type NetworkCreateResult struct {
+ Network
+ Segments []NetworkProvider `json:"segments"`
+ PortSecurityEnabled bool `json:"port_security_enabled"`
}
type APIVersion struct {