Add api extension for new network fields.
This uses the existing api extension to implement the actual control of the fields, but the check is based on a new dummy extension called os-extended-networks. Api sample tests added for new extension. DocImpact: Adds an extension that enables extra fields for network create. The new fields are: mtu: int (default flag) if set, nova sets the mtu on bridge. This allows network_device_mtu flag to be set per network. dhcp_server: ip (default == gateway) if different from gateway, sets nova to assume gateway is external. enable_dhcp: bool (default true) false will disable dhcp on network. share_address: bool (default flag) if specifed, network will have the same dhcp ip on every host. This allows share_dhcp_address flag to be set per network. allowed_start: ip if specified, reserves all ips before allowed_start. allowed_end: ip if specified, reserves all ips after allowed_end. Partially-implements blueprint better-support-for-multiple-networks Change-Id: I577fe5f6560be50106f345a42a826e97d5e7d64c
This commit is contained in:
parent
7d61239dfe
commit
71fabdc8dc
|
@ -296,6 +296,14 @@
|
|||
"namespace": "http://docs.openstack.org/compute/ext/extended_hypervisors/api/v1.1",
|
||||
"updated": "2014-01-04T00:00:00Z"
|
||||
},
|
||||
{
|
||||
"alias": "os-extended-networks",
|
||||
"description": "Adds additional fields to networks",
|
||||
"links": [],
|
||||
"name": "ExtendedNetworks",
|
||||
"namespace": "http://docs.openstack.org/compute/ext/extended_networks/api/v2",
|
||||
"updated": "2014-05-09T00:00:00Z"
|
||||
},
|
||||
{
|
||||
"alias": "os-extended-quotas",
|
||||
"description": "Adds ability for admins to delete quota\n and optionally force the update Quota command.\n ",
|
||||
|
|
|
@ -129,6 +129,9 @@
|
|||
<extension alias="os-extended-hypervisors" updated="2014-01-04T00:00:00Z" namespace="http://docs.openstack.org/compute/ext/extended_hypervisors/api/v1.1" name="ExtendedHypervisors">
|
||||
<description>Extended hypervisors support.</description>
|
||||
</extension>
|
||||
<extension alias="os-extended-networks" updated="2014-05-09T00:00:00Z" namespace="http://docs.openstack.org/compute/ext/extended_networks/api/v2" name="ExtendedNetworks">
|
||||
<description>Adds additional fields to networks</description>
|
||||
</extension>
|
||||
<extension alias="os-extended-quotas" updated="2013-06-09T00:00:00Z" namespace="http://docs.openstack.org/compute/ext/extended_quotas/api/v1.1" name="ExtendedQuotas">
|
||||
<description>Adds ability for admins to delete quota
|
||||
and optionally force the update Quota command.
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"network": {
|
||||
"label": "new net 111",
|
||||
"cidr": "10.20.105.0/24",
|
||||
"mtu": 9000,
|
||||
"dhcp_server": "10.20.105.2",
|
||||
"enable_dhcp": false,
|
||||
"share_address": true,
|
||||
"allowed_start": "10.20.105.10",
|
||||
"allowed_end": "10.20.105.200"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<network>
|
||||
<label>new net 111</label>
|
||||
<cidr>10.20.105.0/24</cidr>
|
||||
<mtu>9000</mtu>
|
||||
<dhcp_server>10.20.105.2</dhcp_server>
|
||||
<enable_dhcp>False</enable_dhcp>
|
||||
<share_address>True</share_address>
|
||||
<allowed_start>10.20.105.10</allowed_start>
|
||||
<allowed_end>10.20.105.200</allowed_end>
|
||||
</network>
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"network": {
|
||||
"bridge": null,
|
||||
"bridge_interface": null,
|
||||
"broadcast": "10.20.105.255",
|
||||
"cidr": "10.20.105.0/24",
|
||||
"cidr_v6": null,
|
||||
"created_at": null,
|
||||
"deleted": null,
|
||||
"deleted_at": null,
|
||||
"dhcp_server": "10.20.105.2",
|
||||
"dhcp_start": "10.20.105.2",
|
||||
"dns1": null,
|
||||
"dns2": null,
|
||||
"enable_dhcp": false,
|
||||
"gateway": "10.20.105.1",
|
||||
"gateway_v6": null,
|
||||
"host": null,
|
||||
"id": "d7a17c0c-457e-4ab4-a99c-4fa1762f5359",
|
||||
"injected": null,
|
||||
"label": "new net 111",
|
||||
"mtu": 9000,
|
||||
"multi_host": null,
|
||||
"netmask": "255.255.255.0",
|
||||
"netmask_v6": null,
|
||||
"priority": null,
|
||||
"project_id": null,
|
||||
"rxtx_base": null,
|
||||
"share_address": true,
|
||||
"updated_at": null,
|
||||
"vlan": null,
|
||||
"vpn_private_address": null,
|
||||
"vpn_public_address": null,
|
||||
"vpn_public_port": null
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<network>
|
||||
<bridge>None</bridge>
|
||||
<vpn_public_port>None</vpn_public_port>
|
||||
<dhcp_start>10.20.105.2</dhcp_start>
|
||||
<bridge_interface>None</bridge_interface>
|
||||
<share_address>True</share_address>
|
||||
<updated_at>None</updated_at>
|
||||
<id>a931ead3-4c5c-4b85-a90e-b248ffa71134</id>
|
||||
<cidr_v6>None</cidr_v6>
|
||||
<deleted_at>None</deleted_at>
|
||||
<gateway>10.20.105.1</gateway>
|
||||
<rxtx_base>None</rxtx_base>
|
||||
<label>new net 111</label>
|
||||
<priority>None</priority>
|
||||
<project_id>None</project_id>
|
||||
<vpn_private_address>None</vpn_private_address>
|
||||
<deleted>False</deleted>
|
||||
<vlan>None</vlan>
|
||||
<broadcast>10.20.105.255</broadcast>
|
||||
<netmask>255.255.255.0</netmask>
|
||||
<injected>None</injected>
|
||||
<cidr>10.20.105.0/24</cidr>
|
||||
<vpn_public_address>None</vpn_public_address>
|
||||
<multi_host>None</multi_host>
|
||||
<enable_dhcp>False</enable_dhcp>
|
||||
<dns2>None</dns2>
|
||||
<created_at>None</created_at>
|
||||
<host>None</host>
|
||||
<mtu>9000</mtu>
|
||||
<gateway_v6>None</gateway_v6>
|
||||
<netmask_v6>None</netmask_v6>
|
||||
<dhcp_server>10.20.105.2</dhcp_server>
|
||||
<dns1>None</dns1>
|
||||
</network>
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"network": {
|
||||
"bridge": "br100",
|
||||
"bridge_interface": "eth0",
|
||||
"broadcast": "10.0.0.7",
|
||||
"cidr": "10.0.0.0/29",
|
||||
"cidr_v6": null,
|
||||
"created_at": "2011-08-15T06:19:19.387525",
|
||||
"deleted": false,
|
||||
"deleted_at": null,
|
||||
"dhcp_server": "10.0.0.1",
|
||||
"dhcp_start": "10.0.0.3",
|
||||
"dns1": null,
|
||||
"dns2": null,
|
||||
"enable_dhcp": true,
|
||||
"gateway": "10.0.0.1",
|
||||
"gateway_v6": null,
|
||||
"host": "nsokolov-desktop",
|
||||
"id": "20c8acc0-f747-4d71-a389-46d078ebf047",
|
||||
"injected": false,
|
||||
"label": "mynet_0",
|
||||
"mtu": null,
|
||||
"multi_host": false,
|
||||
"netmask": "255.255.255.248",
|
||||
"netmask_v6": null,
|
||||
"priority": null,
|
||||
"project_id": "1234",
|
||||
"rxtx_base": null,
|
||||
"share_address": false,
|
||||
"updated_at": "2011-08-16T09:26:13.048257",
|
||||
"vlan": 100,
|
||||
"vpn_private_address": "10.0.0.2",
|
||||
"vpn_public_address": "127.0.0.1",
|
||||
"vpn_public_port": 1000
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<network>
|
||||
<bridge>br100</bridge>
|
||||
<vpn_public_port>1000</vpn_public_port>
|
||||
<dhcp_start>10.0.0.3</dhcp_start>
|
||||
<bridge_interface>eth0</bridge_interface>
|
||||
<share_address>False</share_address>
|
||||
<updated_at>2011-08-16 09:26:13.048257</updated_at>
|
||||
<id>20c8acc0-f747-4d71-a389-46d078ebf047</id>
|
||||
<cidr_v6>None</cidr_v6>
|
||||
<deleted_at>None</deleted_at>
|
||||
<gateway>10.0.0.1</gateway>
|
||||
<rxtx_base>None</rxtx_base>
|
||||
<label>mynet_0</label>
|
||||
<priority>None</priority>
|
||||
<project_id>1234</project_id>
|
||||
<vpn_private_address>10.0.0.2</vpn_private_address>
|
||||
<deleted>False</deleted>
|
||||
<vlan>100</vlan>
|
||||
<broadcast>10.0.0.7</broadcast>
|
||||
<netmask>255.255.255.248</netmask>
|
||||
<injected>False</injected>
|
||||
<cidr>10.0.0.0/29</cidr>
|
||||
<vpn_public_address>127.0.0.1</vpn_public_address>
|
||||
<multi_host>False</multi_host>
|
||||
<enable_dhcp>True</enable_dhcp>
|
||||
<dns2>None</dns2>
|
||||
<created_at>2011-08-15 06:19:19.387525</created_at>
|
||||
<host>nsokolov-desktop</host>
|
||||
<mtu>None</mtu>
|
||||
<gateway_v6>None</gateway_v6>
|
||||
<netmask_v6>None</netmask_v6>
|
||||
<dhcp_server>10.0.0.1</dhcp_server>
|
||||
<dns1>None</dns1>
|
||||
</network>
|
|
@ -0,0 +1,72 @@
|
|||
{
|
||||
"networks": [
|
||||
{
|
||||
"bridge": "br100",
|
||||
"bridge_interface": "eth0",
|
||||
"broadcast": "10.0.0.7",
|
||||
"cidr": "10.0.0.0/29",
|
||||
"cidr_v6": null,
|
||||
"created_at": "2011-08-15T06:19:19.387525",
|
||||
"deleted": false,
|
||||
"deleted_at": null,
|
||||
"dhcp_server": "10.0.0.1",
|
||||
"dhcp_start": "10.0.0.3",
|
||||
"dns1": null,
|
||||
"dns2": null,
|
||||
"enable_dhcp": true,
|
||||
"gateway": "10.0.0.1",
|
||||
"gateway_v6": null,
|
||||
"host": "nsokolov-desktop",
|
||||
"id": "20c8acc0-f747-4d71-a389-46d078ebf047",
|
||||
"injected": false,
|
||||
"label": "mynet_0",
|
||||
"mtu": null,
|
||||
"multi_host": false,
|
||||
"netmask": "255.255.255.248",
|
||||
"netmask_v6": null,
|
||||
"priority": null,
|
||||
"project_id": "1234",
|
||||
"rxtx_base": null,
|
||||
"share_address": false,
|
||||
"updated_at": "2011-08-16T09:26:13.048257",
|
||||
"vlan": 100,
|
||||
"vpn_private_address": "10.0.0.2",
|
||||
"vpn_public_address": "127.0.0.1",
|
||||
"vpn_public_port": 1000
|
||||
},
|
||||
{
|
||||
"bridge": "br101",
|
||||
"bridge_interface": "eth0",
|
||||
"broadcast": "10.0.0.15",
|
||||
"cidr": "10.0.0.10/29",
|
||||
"cidr_v6": null,
|
||||
"created_at": "2011-08-15T06:19:19.885495",
|
||||
"deleted": false,
|
||||
"deleted_at": null,
|
||||
"dhcp_server": "10.0.0.9",
|
||||
"dhcp_start": "10.0.0.11",
|
||||
"dns1": null,
|
||||
"dns2": null,
|
||||
"enable_dhcp": true,
|
||||
"gateway": "10.0.0.9",
|
||||
"gateway_v6": null,
|
||||
"host": null,
|
||||
"id": "20c8acc0-f747-4d71-a389-46d078ebf000",
|
||||
"injected": false,
|
||||
"label": "mynet_1",
|
||||
"mtu": null,
|
||||
"multi_host": false,
|
||||
"netmask": "255.255.255.248",
|
||||
"netmask_v6": null,
|
||||
"priority": null,
|
||||
"project_id": null,
|
||||
"rxtx_base": null,
|
||||
"share_address": false,
|
||||
"updated_at": null,
|
||||
"vlan": 101,
|
||||
"vpn_private_address": "10.0.0.10",
|
||||
"vpn_public_address": null,
|
||||
"vpn_public_port": 1001
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<networks>
|
||||
<network>
|
||||
<bridge>br100</bridge>
|
||||
<vpn_public_port>1000</vpn_public_port>
|
||||
<dhcp_start>10.0.0.3</dhcp_start>
|
||||
<bridge_interface>eth0</bridge_interface>
|
||||
<share_address>False</share_address>
|
||||
<updated_at>2011-08-16 09:26:13.048257</updated_at>
|
||||
<id>20c8acc0-f747-4d71-a389-46d078ebf047</id>
|
||||
<cidr_v6>None</cidr_v6>
|
||||
<deleted_at>None</deleted_at>
|
||||
<gateway>10.0.0.1</gateway>
|
||||
<rxtx_base>None</rxtx_base>
|
||||
<label>mynet_0</label>
|
||||
<priority>None</priority>
|
||||
<project_id>1234</project_id>
|
||||
<vpn_private_address>10.0.0.2</vpn_private_address>
|
||||
<deleted>False</deleted>
|
||||
<vlan>100</vlan>
|
||||
<broadcast>10.0.0.7</broadcast>
|
||||
<netmask>255.255.255.248</netmask>
|
||||
<injected>False</injected>
|
||||
<cidr>10.0.0.0/29</cidr>
|
||||
<vpn_public_address>127.0.0.1</vpn_public_address>
|
||||
<multi_host>False</multi_host>
|
||||
<enable_dhcp>True</enable_dhcp>
|
||||
<dns2>None</dns2>
|
||||
<created_at>2011-08-15 06:19:19.387525</created_at>
|
||||
<host>nsokolov-desktop</host>
|
||||
<mtu>None</mtu>
|
||||
<gateway_v6>None</gateway_v6>
|
||||
<netmask_v6>None</netmask_v6>
|
||||
<dhcp_server>10.0.0.1</dhcp_server>
|
||||
<dns1>None</dns1>
|
||||
</network>
|
||||
<network>
|
||||
<bridge>br101</bridge>
|
||||
<vpn_public_port>1001</vpn_public_port>
|
||||
<dhcp_start>10.0.0.11</dhcp_start>
|
||||
<bridge_interface>eth0</bridge_interface>
|
||||
<share_address>False</share_address>
|
||||
<updated_at>None</updated_at>
|
||||
<id>20c8acc0-f747-4d71-a389-46d078ebf000</id>
|
||||
<cidr_v6>None</cidr_v6>
|
||||
<deleted_at>None</deleted_at>
|
||||
<gateway>10.0.0.9</gateway>
|
||||
<rxtx_base>None</rxtx_base>
|
||||
<label>mynet_1</label>
|
||||
<priority>None</priority>
|
||||
<project_id>None</project_id>
|
||||
<vpn_private_address>10.0.0.10</vpn_private_address>
|
||||
<deleted>False</deleted>
|
||||
<vlan>101</vlan>
|
||||
<broadcast>10.0.0.15</broadcast>
|
||||
<netmask>255.255.255.248</netmask>
|
||||
<injected>False</injected>
|
||||
<cidr>10.0.0.10/29</cidr>
|
||||
<vpn_public_address>None</vpn_public_address>
|
||||
<multi_host>False</multi_host>
|
||||
<enable_dhcp>True</enable_dhcp>
|
||||
<dns2>None</dns2>
|
||||
<created_at>2011-08-15 06:19:19.885495</created_at>
|
||||
<host>None</host>
|
||||
<mtu>None</mtu>
|
||||
<gateway_v6>None</gateway_v6>
|
||||
<netmask_v6>None</netmask_v6>
|
||||
<dhcp_server>10.0.0.9</dhcp_server>
|
||||
<dns1>None</dns1>
|
||||
</network>
|
||||
</networks>
|
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2014 Nebula, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nova.api.openstack import extensions
|
||||
|
||||
|
||||
class Extended_networks(extensions.ExtensionDescriptor):
|
||||
"""Adds additional fields to networks."""
|
||||
|
||||
name = "ExtendedNetworks"
|
||||
alias = "os-extended-networks"
|
||||
namespace = ("http://docs.openstack.org/compute/ext/extended_networks"
|
||||
"/api/v2")
|
||||
updated = "2014-05-09T00:00:00Z"
|
|
@ -30,9 +30,10 @@ LOG = logging.getLogger(__name__)
|
|||
authorize = extensions.extension_authorizer('compute', 'networks')
|
||||
authorize_view = extensions.extension_authorizer('compute',
|
||||
'networks:view')
|
||||
extended_fields = ('mtu', 'dhcp_server', 'enable_dhcp', 'share_address')
|
||||
|
||||
|
||||
def network_dict(context, network):
|
||||
def network_dict(context, network, extended):
|
||||
fields = ('id', 'cidr', 'netmask', 'gateway', 'broadcast', 'dns1', 'dns2',
|
||||
'cidr_v6', 'gateway_v6', 'label', 'netmask_v6')
|
||||
admin_fields = ('created_at', 'updated_at', 'deleted_at', 'deleted',
|
||||
|
@ -46,6 +47,8 @@ def network_dict(context, network):
|
|||
# are only visible if they are an admin.
|
||||
if context.is_admin:
|
||||
fields += admin_fields
|
||||
if extended:
|
||||
fields += extended_fields
|
||||
result = dict((field, network.get(field)) for field in fields)
|
||||
uuid = network.get('uuid')
|
||||
if uuid:
|
||||
|
@ -57,14 +60,19 @@ def network_dict(context, network):
|
|||
|
||||
class NetworkController(wsgi.Controller):
|
||||
|
||||
def __init__(self, network_api=None):
|
||||
def __init__(self, network_api=None, ext_mgr=None):
|
||||
self.network_api = network_api or network.API()
|
||||
if ext_mgr:
|
||||
self.extended = ext_mgr.is_loaded('os-extended-networks')
|
||||
else:
|
||||
self.extended = False
|
||||
|
||||
def index(self, req):
|
||||
context = req.environ['nova.context']
|
||||
authorize_view(context)
|
||||
networks = self.network_api.get_all(context)
|
||||
result = [network_dict(context, net_ref) for net_ref in networks]
|
||||
result = [network_dict(context, net_ref, self.extended)
|
||||
for net_ref in networks]
|
||||
return {'networks': result}
|
||||
|
||||
@wsgi.action("disassociate")
|
||||
|
@ -93,7 +101,7 @@ class NetworkController(wsgi.Controller):
|
|||
except exception.NetworkNotFound:
|
||||
msg = _("Network not found")
|
||||
raise exc.HTTPNotFound(explanation=msg)
|
||||
return {'network': network_dict(context, network)}
|
||||
return {'network': network_dict(context, network, self.extended)}
|
||||
|
||||
def delete(self, req, id):
|
||||
context = req.environ['nova.context']
|
||||
|
@ -113,7 +121,7 @@ class NetworkController(wsgi.Controller):
|
|||
authorize(context)
|
||||
|
||||
def bad(e):
|
||||
return exc.HTTPUnprocessableEntity(explanation=e)
|
||||
return exc.HTTPBadRequest(explanation=e)
|
||||
|
||||
if not (body and body.get("network")):
|
||||
raise bad(_("Missing network in body"))
|
||||
|
@ -126,13 +134,31 @@ class NetworkController(wsgi.Controller):
|
|||
if not cidr:
|
||||
raise bad(_("Network cidr or cidr_v6 is required"))
|
||||
|
||||
if params.get("project_id") == "":
|
||||
params["project_id"] = None
|
||||
|
||||
LOG.debug("Creating network with label %s", params["label"])
|
||||
|
||||
params["num_networks"] = 1
|
||||
params["network_size"] = netaddr.IPNetwork(cidr).size
|
||||
try:
|
||||
params["num_networks"] = 1
|
||||
try:
|
||||
params["network_size"] = netaddr.IPNetwork(cidr).size
|
||||
except netaddr.AddrFormatError:
|
||||
raise exception.InvalidCidr(cidr=cidr)
|
||||
if not self.extended:
|
||||
create_params = ('allowed_start', 'allowed_end')
|
||||
for field in extended_fields + create_params:
|
||||
if field in params:
|
||||
del params[field]
|
||||
|
||||
network = self.network_api.create(context, **params)[0]
|
||||
return {"network": network_dict(context, network)}
|
||||
network = self.network_api.create(context, **params)[0]
|
||||
except exception.NovaException as ex:
|
||||
if ex.code == 400:
|
||||
raise bad(ex.format_message())
|
||||
elif ex.code == 409:
|
||||
raise exc.HTTPConflict(explanation=ex.format_message())
|
||||
raise
|
||||
return {"network": network_dict(context, network, self.extended)}
|
||||
|
||||
def add(self, req, body):
|
||||
context = req.environ['nova.context']
|
||||
|
@ -177,7 +203,7 @@ class Os_networks(extensions.ExtensionDescriptor):
|
|||
collection_actions = {'add': 'POST'}
|
||||
res = extensions.ResourceExtension(
|
||||
'os-networks',
|
||||
NetworkController(),
|
||||
NetworkController(ext_mgr=self.ext_mgr),
|
||||
member_actions=member_actions,
|
||||
collection_actions=collection_actions)
|
||||
return [res]
|
||||
|
|
|
@ -590,32 +590,27 @@ class NetworkInUse(NovaException):
|
|||
msg_fmt = _("Network %(network_id)s is still in use.")
|
||||
|
||||
|
||||
class InvalidNetworkParam(Invalid):
|
||||
# NOTE(vish) base class for network create param errors
|
||||
code = 422
|
||||
|
||||
|
||||
class NetworkNotCreated(InvalidNetworkParam):
|
||||
class NetworkNotCreated(Invalid):
|
||||
msg_fmt = _("%(req)s is required to create a network.")
|
||||
|
||||
|
||||
class LabelTooLong(InvalidNetworkParam):
|
||||
class LabelTooLong(Invalid):
|
||||
msg_fmt = _("Maximum allowed length for 'label' is 255.")
|
||||
|
||||
|
||||
class InvalidIntValue(InvalidNetworkParam):
|
||||
class InvalidIntValue(Invalid):
|
||||
msg_fmt = _("%(key)s must be an integer.")
|
||||
|
||||
|
||||
class InvalidCidr(InvalidNetworkParam):
|
||||
class InvalidCidr(Invalid):
|
||||
msg_fmt = _("%(cidr)s is not a valid ip network.")
|
||||
|
||||
|
||||
class InvalidAddress(InvalidNetworkParam):
|
||||
class InvalidAddress(Invalid):
|
||||
msg_fmt = _("%(address)s is not a valid ip address.")
|
||||
|
||||
|
||||
class AddressOutOfRange(InvalidNetworkParam):
|
||||
class AddressOutOfRange(Invalid):
|
||||
msg_fmt = _("%(address)s is not within %(cidr)s.")
|
||||
|
||||
|
||||
|
|
|
@ -27,8 +27,11 @@ import webob
|
|||
from nova.api.openstack.compute.contrib import networks_associate
|
||||
from nova.api.openstack.compute.contrib import os_networks as networks
|
||||
from nova.api.openstack.compute.contrib import os_tenant_networks as tnet
|
||||
from nova.api.openstack import extensions
|
||||
import nova.context
|
||||
from nova import exception
|
||||
from nova.network import manager
|
||||
from nova import objects
|
||||
from nova import test
|
||||
from nova.tests.api.openstack import fakes
|
||||
import nova.utils
|
||||
|
@ -52,6 +55,8 @@ FAKE_NETWORKS = [
|
|||
'dns1': None, 'dns2': None, 'host': 'nsokolov-desktop',
|
||||
'gateway_v6': None, 'netmask_v6': None, 'priority': None,
|
||||
'created_at': datetime.datetime(2011, 8, 15, 6, 19, 19, 387525),
|
||||
'mtu': None, 'dhcp_server': '10.0.0.1', 'enable_dhcp': True,
|
||||
'share_address': False,
|
||||
},
|
||||
{
|
||||
'bridge': 'br101', 'vpn_public_port': 1001,
|
||||
|
@ -67,6 +72,8 @@ FAKE_NETWORKS = [
|
|||
'multi_host': False, 'dns1': None, 'dns2': None, 'host': None,
|
||||
'gateway_v6': None, 'netmask_v6': None, 'priority': None,
|
||||
'created_at': datetime.datetime(2011, 8, 15, 6, 19, 19, 885495),
|
||||
'mtu': None, 'dhcp_server': '10.0.0.9', 'enable_dhcp': True,
|
||||
'share_address': False,
|
||||
},
|
||||
]
|
||||
|
||||
|
@ -198,13 +205,83 @@ class FakeNetworkAPI(object):
|
|||
return new_networks
|
||||
|
||||
|
||||
# NOTE(vish): tests that network create Exceptions actually return
|
||||
# the proper error responses
|
||||
class NetworkCreateExceptionsTest(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(NetworkCreateExceptionsTest, self).setUp()
|
||||
ext_mgr = extensions.ExtensionManager()
|
||||
ext_mgr.extensions = {'os-extended-networks': 'fake'}
|
||||
|
||||
class PassthroughAPI():
|
||||
def __init__(self):
|
||||
self.network_manager = manager.FlatDHCPManager()
|
||||
|
||||
def create(self, *args, **kwargs):
|
||||
return self.network_manager.create_networks(*args, **kwargs)
|
||||
|
||||
self.controller = networks.NetworkController(
|
||||
PassthroughAPI(), ext_mgr)
|
||||
fakes.stub_out_networking(self.stubs)
|
||||
fakes.stub_out_rate_limiting(self.stubs)
|
||||
|
||||
def test_network_create_bad_vlan(self):
|
||||
req = fakes.HTTPRequest.blank('/v2/1234/os-networks')
|
||||
net = copy.deepcopy(NEW_NETWORK)
|
||||
net['network']['vlan_start'] = 'foo'
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.create, req, net)
|
||||
|
||||
def test_network_create_no_cidr(self):
|
||||
req = fakes.HTTPRequest.blank('/v2/1234/os-networks')
|
||||
net = copy.deepcopy(NEW_NETWORK)
|
||||
net['network']['cidr'] = ''
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.create, req, net)
|
||||
|
||||
def test_network_create_invalid_fixed_cidr(self):
|
||||
req = fakes.HTTPRequest.blank('/v2/1234/os-networks')
|
||||
net = copy.deepcopy(NEW_NETWORK)
|
||||
net['network']['fixed_cidr'] = 'foo'
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.create, req, net)
|
||||
|
||||
def test_network_create_invalid_start(self):
|
||||
req = fakes.HTTPRequest.blank('/v2/1234/os-networks')
|
||||
net = copy.deepcopy(NEW_NETWORK)
|
||||
net['network']['allowed_start'] = 'foo'
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.create, req, net)
|
||||
|
||||
def test_network_create_cidr_conflict(self):
|
||||
|
||||
@staticmethod
|
||||
def get_all(context):
|
||||
ret = objects.NetworkList(context=context, objects=[])
|
||||
net = objects.Network(cidr='10.0.0.0/23')
|
||||
ret.objects.append(net)
|
||||
return ret
|
||||
|
||||
self.stubs.Set(objects.NetworkList, 'get_all', get_all)
|
||||
|
||||
req = fakes.HTTPRequest.blank('/v2/1234/os-networks')
|
||||
net = copy.deepcopy(NEW_NETWORK)
|
||||
net['network']['cidr'] = '10.0.0.0/24'
|
||||
self.assertRaises(webob.exc.HTTPConflict,
|
||||
self.controller.create, req, net)
|
||||
|
||||
|
||||
class NetworksTest(test.NoDBTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(NetworksTest, self).setUp()
|
||||
self.fake_network_api = FakeNetworkAPI()
|
||||
ext_mgr = extensions.ExtensionManager()
|
||||
ext_mgr.extensions = {'os-extended-networks': 'fake'}
|
||||
self.controller = networks.NetworkController(
|
||||
self.fake_network_api)
|
||||
self.fake_network_api,
|
||||
ext_mgr)
|
||||
self.associate_controller = networks_associate\
|
||||
.NetworkAssociateActionController(self.fake_network_api)
|
||||
fakes.stub_out_networking(self.stubs)
|
||||
|
@ -313,13 +390,6 @@ class NetworksTest(test.NoDBTestCase):
|
|||
self.assertRaises(webob.exc.HTTPConflict,
|
||||
self.controller.delete, req, -1)
|
||||
|
||||
def test_network_add_vlan_disabled(self):
|
||||
self.fake_network_api.disable_vlan()
|
||||
uuid = FAKE_NETWORKS[1]['uuid']
|
||||
req = fakes.HTTPRequest.blank('/v2/1234/os-networks/add')
|
||||
self.assertRaises(webob.exc.HTTPNotImplemented,
|
||||
self.controller.add, req, {'id': uuid})
|
||||
|
||||
def test_network_add(self):
|
||||
uuid = FAKE_NETWORKS[1]['uuid']
|
||||
req = fakes.HTTPRequest.blank('/v2/1234/os-networks/add')
|
||||
|
@ -359,6 +429,29 @@ class NetworksTest(test.NoDBTestCase):
|
|||
self.assertEqual(res_dict['network']['cidr'],
|
||||
large_network['network']['cidr'])
|
||||
|
||||
def test_network_create_not_extended(self):
|
||||
self.stubs.Set(self.controller, 'extended', False)
|
||||
|
||||
# NOTE(vish): Verify that new params are not passed through if
|
||||
# extension is not enabled.
|
||||
def no_mtu(*args, **kwargs):
|
||||
if 'mtu' in kwargs:
|
||||
raise test.TestingException("mtu should not pass through")
|
||||
return [{}]
|
||||
|
||||
self.stubs.Set(self.controller.network_api, 'create', no_mtu)
|
||||
req = fakes.HTTPRequest.blank('/v2/1234/os-networks')
|
||||
net = copy.deepcopy(NEW_NETWORK)
|
||||
net['network']['mtu'] = 9000
|
||||
self.controller.create(req, net)
|
||||
|
||||
def test_network_create_bad_cidr(self):
|
||||
req = fakes.HTTPRequest.blank('/v2/1234/os-networks')
|
||||
net = copy.deepcopy(NEW_NETWORK)
|
||||
net['network']['cidr'] = '128.0.0.0/900'
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.create, req, net)
|
||||
|
||||
def test_network_neutron_associate_not_implemented(self):
|
||||
uuid = FAKE_NETWORKS[1]['uuid']
|
||||
self.flags(network_api_class='nova.network.neutronv2.api.API')
|
||||
|
|
|
@ -488,6 +488,14 @@
|
|||
"namespace": "http://docs.openstack.org/compute/ext/quota-classes-sets/api/v1.1",
|
||||
"updated": "%(isotime)s"
|
||||
},
|
||||
{
|
||||
"alias": "os-extended-networks",
|
||||
"description": "%(text)s",
|
||||
"links": [],
|
||||
"name": "ExtendedNetworks",
|
||||
"namespace": "http://docs.openstack.org/compute/ext/extended_networks/api/v2",
|
||||
"updated": "%(isotime)s"
|
||||
},
|
||||
{
|
||||
"alias": "os-extended-quotas",
|
||||
"description": "%(text)s",
|
||||
|
|
|
@ -174,6 +174,9 @@
|
|||
<extension alias="os-quota-class-sets" updated="%(isotime)s" namespace="http://docs.openstack.org/compute/ext/quota-classes-sets/api/v1.1" name="QuotaClasses">
|
||||
<description>%(text)s</description>
|
||||
</extension>
|
||||
<extension alias="os-extended-networks" updated="%(isotime)s" namespace="http://docs.openstack.org/compute/ext/extended_networks/api/v2" name="ExtendedNetworks">
|
||||
<description>%(text)s</description>
|
||||
</extension>
|
||||
<extension alias="os-extended-quotas" updated="%(isotime)s" namespace="http://docs.openstack.org/compute/ext/extended_quotas/api/v1.1" name="ExtendedQuotas">
|
||||
<description>%(text)s</description>
|
||||
</extension>
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"network": {
|
||||
"label": "new net 111",
|
||||
"cidr": "10.20.105.0/24",
|
||||
"mtu": 9000,
|
||||
"dhcp_server": "10.20.105.2",
|
||||
"enable_dhcp": false,
|
||||
"share_address": true,
|
||||
"allowed_start": "10.20.105.10",
|
||||
"allowed_end": "10.20.105.200"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<network>
|
||||
<label>new net 111</label>
|
||||
<cidr>10.20.105.0/24</cidr>
|
||||
<mtu>9000</mtu>
|
||||
<dhcp_server>10.20.105.2</dhcp_server>
|
||||
<enable_dhcp>False</enable_dhcp>
|
||||
<share_address>True</share_address>
|
||||
<allowed_start>10.20.105.10</allowed_start>
|
||||
<allowed_end>10.20.105.200</allowed_end>
|
||||
</network>
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"network": {
|
||||
"bridge": null,
|
||||
"vpn_public_port": null,
|
||||
"dhcp_start": "%(ip)s",
|
||||
"bridge_interface": null,
|
||||
"updated_at": null,
|
||||
"id": "%(id)s",
|
||||
"cidr_v6": null,
|
||||
"deleted_at": null,
|
||||
"gateway": "%(ip)s",
|
||||
"rxtx_base": null,
|
||||
"label": "new net 111",
|
||||
"priority": null,
|
||||
"project_id": null,
|
||||
"vpn_private_address": null,
|
||||
"deleted": null,
|
||||
"vlan": null,
|
||||
"broadcast": "%(ip)s",
|
||||
"netmask": "%(ip)s",
|
||||
"injected": null,
|
||||
"cidr": "10.20.105.0/24",
|
||||
"vpn_public_address": null,
|
||||
"multi_host": null,
|
||||
"dns2": null,
|
||||
"created_at": null,
|
||||
"host": null,
|
||||
"gateway_v6": null,
|
||||
"netmask_v6": null,
|
||||
"dns1": null,
|
||||
"mtu": 9000,
|
||||
"dhcp_server": "10.20.105.2",
|
||||
"enable_dhcp": false,
|
||||
"share_address": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<network>
|
||||
<bridge>None</bridge>
|
||||
<vpn_public_port>None</vpn_public_port>
|
||||
<dhcp_start>%(ip)s</dhcp_start>
|
||||
<bridge_interface>None</bridge_interface>
|
||||
<updated_at>None</updated_at>
|
||||
<id>%(id)s</id>
|
||||
<cidr_v6>None</cidr_v6>
|
||||
<deleted_at>None</deleted_at>
|
||||
<gateway>%(ip)s</gateway>
|
||||
<rxtx_base>None</rxtx_base>
|
||||
<label>new net 111</label>
|
||||
<priority>None</priority>
|
||||
<project_id>None</project_id>
|
||||
<vpn_private_address>None</vpn_private_address>
|
||||
<deleted>False</deleted>
|
||||
<vlan>None</vlan>
|
||||
<broadcast>%(ip)s</broadcast>
|
||||
<netmask>%(ip)s</netmask>
|
||||
<injected>None</injected>
|
||||
<cidr>10.20.105.0/24</cidr>
|
||||
<vpn_public_address>None</vpn_public_address>
|
||||
<multi_host>None</multi_host>
|
||||
<dns2>None</dns2>
|
||||
<created_at>None</created_at>
|
||||
<host>None</host>
|
||||
<gateway_v6>None</gateway_v6>
|
||||
<netmask_v6>None</netmask_v6>
|
||||
<dns1>None</dns1>
|
||||
<mtu>9000</mtu>
|
||||
<dhcp_server>10.20.105.2</dhcp_server>
|
||||
<enable_dhcp>False</enable_dhcp>
|
||||
<share_address>True</share_address>
|
||||
</network>
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"network":
|
||||
{
|
||||
"bridge": "br100",
|
||||
"bridge_interface": "eth0",
|
||||
"broadcast": "%(ip)s",
|
||||
"cidr": "10.0.0.0/29",
|
||||
"cidr_v6": null,
|
||||
"created_at": "%(strtime)s",
|
||||
"deleted": false,
|
||||
"deleted_at": null,
|
||||
"dhcp_start": "%(ip)s",
|
||||
"dns1": null,
|
||||
"dns2": null,
|
||||
"gateway": "%(ip)s",
|
||||
"gateway_v6": null,
|
||||
"host": "nsokolov-desktop",
|
||||
"id": "%(id)s",
|
||||
"injected": false,
|
||||
"label": "mynet_0",
|
||||
"multi_host": false,
|
||||
"netmask": "%(ip)s",
|
||||
"netmask_v6": null,
|
||||
"priority": null,
|
||||
"project_id": "1234",
|
||||
"rxtx_base": null,
|
||||
"updated_at": "%(strtime)s",
|
||||
"vlan": 100,
|
||||
"vpn_private_address": "%(ip)s",
|
||||
"vpn_public_address": "%(ip)s",
|
||||
"vpn_public_port": 1000,
|
||||
"mtu": null,
|
||||
"dhcp_server": "%(ip)s",
|
||||
"enable_dhcp": true,
|
||||
"share_address": false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<network>
|
||||
<bridge>br100</bridge>
|
||||
<vpn_public_port>1000</vpn_public_port>
|
||||
<dhcp_start>%(ip)s</dhcp_start>
|
||||
<bridge_interface>eth0</bridge_interface>
|
||||
<updated_at>%(xmltime)s</updated_at>
|
||||
<id>%(id)s</id>
|
||||
<cidr_v6>None</cidr_v6>
|
||||
<deleted_at>None</deleted_at>
|
||||
<gateway>%(ip)s</gateway>
|
||||
<rxtx_base>None</rxtx_base>
|
||||
<label>mynet_0</label>
|
||||
<priority>None</priority>
|
||||
<project_id>1234</project_id>
|
||||
<vpn_private_address>%(ip)s</vpn_private_address>
|
||||
<deleted>False</deleted>
|
||||
<vlan>100</vlan>
|
||||
<broadcast>%(ip)s</broadcast>
|
||||
<netmask>%(ip)s</netmask>
|
||||
<injected>False</injected>
|
||||
<cidr>10.0.0.0/29</cidr>
|
||||
<vpn_public_address>%(ip)s</vpn_public_address>
|
||||
<multi_host>False</multi_host>
|
||||
<dns2>None</dns2>
|
||||
<created_at>%(xmltime)s</created_at>
|
||||
<host>nsokolov-desktop</host>
|
||||
<gateway_v6>None</gateway_v6>
|
||||
<netmask_v6>None</netmask_v6>
|
||||
<dns1>None</dns1>
|
||||
<mtu>None</mtu>
|
||||
<dhcp_server>%(ip)s</dhcp_server>
|
||||
<enable_dhcp>True</enable_dhcp>
|
||||
<share_address>False</share_address>
|
||||
</network>
|
|
@ -0,0 +1,72 @@
|
|||
{
|
||||
"networks": [
|
||||
{
|
||||
"bridge": "br100",
|
||||
"bridge_interface": "eth0",
|
||||
"broadcast": "%(ip)s",
|
||||
"cidr": "10.0.0.0/29",
|
||||
"cidr_v6": null,
|
||||
"created_at": "%(strtime)s",
|
||||
"deleted": false,
|
||||
"deleted_at": null,
|
||||
"dhcp_start": "%(ip)s",
|
||||
"dns1": null,
|
||||
"dns2": null,
|
||||
"gateway": "%(ip)s",
|
||||
"gateway_v6": null,
|
||||
"host": "nsokolov-desktop",
|
||||
"id": "%(id)s",
|
||||
"injected": false,
|
||||
"label": "mynet_0",
|
||||
"multi_host": false,
|
||||
"netmask": "%(ip)s",
|
||||
"netmask_v6": null,
|
||||
"priority": null,
|
||||
"project_id": "1234",
|
||||
"rxtx_base": null,
|
||||
"updated_at": "%(strtime)s",
|
||||
"vlan": 100,
|
||||
"vpn_private_address": "%(ip)s",
|
||||
"vpn_public_address": "%(ip)s",
|
||||
"vpn_public_port": 1000,
|
||||
"mtu": null,
|
||||
"dhcp_server": "%(ip)s",
|
||||
"enable_dhcp": true,
|
||||
"share_address": false
|
||||
},
|
||||
{
|
||||
"bridge": "br101",
|
||||
"bridge_interface": "eth0",
|
||||
"broadcast": "%(ip)s",
|
||||
"cidr": "10.0.0.10/29",
|
||||
"cidr_v6": null,
|
||||
"created_at": "%(strtime)s",
|
||||
"deleted": false,
|
||||
"deleted_at": null,
|
||||
"dhcp_start": "%(ip)s",
|
||||
"dns1": null,
|
||||
"dns2": null,
|
||||
"gateway": "%(ip)s",
|
||||
"gateway_v6": null,
|
||||
"host": null,
|
||||
"id": "%(id)s",
|
||||
"injected": false,
|
||||
"label": "mynet_1",
|
||||
"multi_host": false,
|
||||
"netmask": "%(ip)s",
|
||||
"netmask_v6": null,
|
||||
"priority": null,
|
||||
"project_id": null,
|
||||
"rxtx_base": null,
|
||||
"updated_at": null,
|
||||
"vlan": 101,
|
||||
"vpn_private_address": "%(ip)s",
|
||||
"vpn_public_address": null,
|
||||
"vpn_public_port": 1001,
|
||||
"mtu": null,
|
||||
"dhcp_server": "%(ip)s",
|
||||
"enable_dhcp": true,
|
||||
"share_address": false
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<networks>
|
||||
<network>
|
||||
<bridge>br100</bridge>
|
||||
<vpn_public_port>1000</vpn_public_port>
|
||||
<dhcp_start>%(ip)s</dhcp_start>
|
||||
<bridge_interface>eth0</bridge_interface>
|
||||
<updated_at>%(xmltime)s</updated_at>
|
||||
<id>%(id)s</id>
|
||||
<cidr_v6>None</cidr_v6>
|
||||
<deleted_at>None</deleted_at>
|
||||
<gateway>%(ip)s</gateway>
|
||||
<rxtx_base>None</rxtx_base>
|
||||
<label>mynet_0</label>
|
||||
<priority>None</priority>
|
||||
<project_id>1234</project_id>
|
||||
<vpn_private_address>%(ip)s</vpn_private_address>
|
||||
<deleted>False</deleted>
|
||||
<vlan>100</vlan>
|
||||
<broadcast>%(ip)s</broadcast>
|
||||
<netmask>%(ip)s</netmask>
|
||||
<injected>False</injected>
|
||||
<cidr>10.0.0.0/29</cidr>
|
||||
<vpn_public_address>%(ip)s</vpn_public_address>
|
||||
<multi_host>False</multi_host>
|
||||
<dns2>None</dns2>
|
||||
<created_at>%(xmltime)s</created_at>
|
||||
<host>nsokolov-desktop</host>
|
||||
<gateway_v6>None</gateway_v6>
|
||||
<netmask_v6>None</netmask_v6>
|
||||
<dns1>None</dns1>
|
||||
<mtu>None</mtu>
|
||||
<dhcp_server>%(ip)s</dhcp_server>
|
||||
<enable_dhcp>True</enable_dhcp>
|
||||
<share_address>False</share_address>
|
||||
</network>
|
||||
<network>
|
||||
<bridge>br101</bridge>
|
||||
<vpn_public_port>1001</vpn_public_port>
|
||||
<dhcp_start>%(ip)s</dhcp_start>
|
||||
<bridge_interface>eth0</bridge_interface>
|
||||
<updated_at>None</updated_at>
|
||||
<id>%(id)s</id>
|
||||
<cidr_v6>None</cidr_v6>
|
||||
<deleted_at>None</deleted_at>
|
||||
<gateway>%(ip)s</gateway>
|
||||
<rxtx_base>None</rxtx_base>
|
||||
<label>mynet_1</label>
|
||||
<priority>None</priority>
|
||||
<project_id>None</project_id>
|
||||
<vpn_private_address>%(ip)s</vpn_private_address>
|
||||
<deleted>False</deleted>
|
||||
<vlan>101</vlan>
|
||||
<broadcast>%(ip)s</broadcast>
|
||||
<netmask>%(ip)s</netmask>
|
||||
<injected>False</injected>
|
||||
<cidr>10.0.0.10/29</cidr>
|
||||
<vpn_public_address>None</vpn_public_address>
|
||||
<multi_host>False</multi_host>
|
||||
<dns2>None</dns2>
|
||||
<created_at>%(xmltime)s</created_at>
|
||||
<host>None</host>
|
||||
<gateway_v6>None</gateway_v6>
|
||||
<netmask_v6>None</netmask_v6>
|
||||
<dns1>None</dns1>
|
||||
<mtu>None</mtu>
|
||||
<dhcp_server>%(ip)s</dhcp_server>
|
||||
<enable_dhcp>True</enable_dhcp>
|
||||
<share_address>False</share_address>
|
||||
</network>
|
||||
</networks>
|
|
@ -2669,6 +2669,50 @@ class NetworksXmlTests(NetworksJsonTests):
|
|||
ctype = 'xml'
|
||||
|
||||
|
||||
class ExtendedNetworksJsonTests(ApiSampleTestBaseV2):
|
||||
extends_name = ("nova.api.openstack.compute.contrib."
|
||||
"os_networks.Os_networks")
|
||||
extension_name = ("nova.api.openstack.compute.contrib."
|
||||
"extended_networks.Extended_networks")
|
||||
|
||||
def setUp(self):
|
||||
super(ExtendedNetworksJsonTests, self).setUp()
|
||||
fake_network_api = test_networks.FakeNetworkAPI()
|
||||
self.stubs.Set(network_api.API, "get_all",
|
||||
fake_network_api.get_all)
|
||||
self.stubs.Set(network_api.API, "get",
|
||||
fake_network_api.get)
|
||||
self.stubs.Set(network_api.API, "associate",
|
||||
fake_network_api.associate)
|
||||
self.stubs.Set(network_api.API, "delete",
|
||||
fake_network_api.delete)
|
||||
self.stubs.Set(network_api.API, "create",
|
||||
fake_network_api.create)
|
||||
self.stubs.Set(network_api.API, "add_network_to_project",
|
||||
fake_network_api.add_network_to_project)
|
||||
|
||||
def test_network_list(self):
|
||||
response = self._do_get('os-networks')
|
||||
subs = self._get_regexes()
|
||||
self._verify_response('networks-list-resp', subs, response, 200)
|
||||
|
||||
def test_network_show(self):
|
||||
uuid = test_networks.FAKE_NETWORKS[0]['uuid']
|
||||
response = self._do_get('os-networks/%s' % uuid)
|
||||
subs = self._get_regexes()
|
||||
self._verify_response('network-show-resp', subs, response, 200)
|
||||
|
||||
def test_network_create(self):
|
||||
response = self._do_post("os-networks",
|
||||
'network-create-req', {})
|
||||
subs = self._get_regexes()
|
||||
self._verify_response('network-create-resp', subs, response, 200)
|
||||
|
||||
|
||||
class ExtendedNetworksXmlTests(ExtendedNetworksJsonTests):
|
||||
ctype = 'xml'
|
||||
|
||||
|
||||
class NetworksAssociateJsonTests(ApiSampleTestBaseV2):
|
||||
extension_name = ("nova.api.openstack.compute.contrib"
|
||||
".networks_associate.Networks_associate")
|
||||
|
|
Loading…
Reference in New Issue