summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/api_samples/all_extensions/extensions-get-resp.json12
-rw-r--r--doc/api_samples/all_extensions/extensions-get-resp.xml4
-rw-r--r--doc/api_samples/os-tenant-networks/networks-list-res.json (renamed from doc/api_samples/os-networks/networks-list-res.json)0
-rw-r--r--doc/api_samples/os-tenant-networks/networks-post-res.json (renamed from doc/api_samples/os-networks/networks-post-res.json)0
-rw-r--r--nova/api/openstack/compute/contrib/admin_networks.py170
-rw-r--r--nova/api/openstack/compute/contrib/networks_associate.py2
-rw-r--r--nova/api/openstack/compute/contrib/os_networks.py261
-rw-r--r--nova/api/openstack/compute/contrib/os_tenant_networks.py214
-rw-r--r--nova/compute/api.py3
-rw-r--r--nova/compute/manager.py23
-rw-r--r--nova/compute/rpcapi.py8
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_networks.py4
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_services.py4
-rw-r--r--nova/tests/api/openstack/compute/test_extensions.py1
-rw-r--r--nova/tests/compute/test_compute.py28
-rw-r--r--nova/tests/compute/test_rpcapi.py3
-rw-r--r--nova/tests/fake_policy.py6
-rw-r--r--nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl12
-rw-r--r--nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl4
-rw-r--r--nova/tests/integrated/api_samples/os-tenant-networks/networks-list-res.json.tpl (renamed from nova/tests/integrated/api_samples/os-networks/networks-list-res.json.tpl)0
-rw-r--r--nova/tests/integrated/api_samples/os-tenant-networks/networks-post-req.json.tpl (renamed from nova/tests/integrated/api_samples/os-networks/networks-post-req.json.tpl)0
-rw-r--r--nova/tests/integrated/api_samples/os-tenant-networks/networks-post-res.json.tpl (renamed from nova/tests/integrated/api_samples/os-networks/networks-post-res.json.tpl)0
-rw-r--r--nova/tests/integrated/test_api_samples.py27
23 files changed, 389 insertions, 397 deletions
diff --git a/doc/api_samples/all_extensions/extensions-get-resp.json b/doc/api_samples/all_extensions/extensions-get-resp.json
index 42e86eadd..25d077f27 100644
--- a/doc/api_samples/all_extensions/extensions-get-resp.json
+++ b/doc/api_samples/all_extensions/extensions-get-resp.json
@@ -297,19 +297,19 @@
"updated": "2012-08-07T00:00:00+00:00"
},
{
- "alias": "os-admin-networks",
+ "alias": "os-networks",
"description": "Admin-only Network Management Extension.",
"links": [],
- "name": "AdminNetworks",
- "namespace": "http://docs.openstack.org/compute/ext/os-admin-networks/api/v1.1",
+ "name": "Networks",
+ "namespace": "http://docs.openstack.org/compute/ext/os-networks/api/v1.1",
"updated": "2011-12-23T00:00:00+00:00"
},
{
- "alias": "os-networks",
+ "alias": "os-tenant-networks",
"description": "Tenant-based Network Management Extension.",
"links": [],
- "name": "OSNetworks",
- "namespace": "http://docs.openstack.org/compute/ext/os-networks/api/v1.1",
+ "name": "OSTenantNetworks",
+ "namespace": "http://docs.openstack.org/compute/ext/os-tenant-networks/api/v2",
"updated": "2011-12-23T00:00:00+00:00"
},
{
diff --git a/doc/api_samples/all_extensions/extensions-get-resp.xml b/doc/api_samples/all_extensions/extensions-get-resp.xml
index ea0b45a12..b66c3dbe7 100644
--- a/doc/api_samples/all_extensions/extensions-get-resp.xml
+++ b/doc/api_samples/all_extensions/extensions-get-resp.xml
@@ -125,13 +125,13 @@
<extension alias="os-multiple-create" updated="2012-08-07T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/multiplecreate/api/v1.1" name="MultipleCreate">
<description>Allow multiple create in the Create Server v1.1 API.</description>
</extension>
- <extension alias="os-admin-networks" updated="2011-12-23T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/os-admin-networks/api/v1.1" name="AdminNetworks">
+ <extension alias="os-networks" updated="2011-12-23T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/os-networks/api/v1.1" name="Networks">
<description>Admin-only Network Management Extension.</description>
</extension>
<extension alias="os-networks-associate" updated="2012-11-19T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/networks_associate/api/v2" name="NetworkAssociationSupport">
<description>Network association support.</description>
</extension>
- <extension alias="os-networks" updated="2011-12-23T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/os-networks/api/v1.1" name="OSNetworks">
+ <extension alias="os-tenant-networks" updated="2011-12-23T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/os-tenant-networks/api/v2" name="OSTenantNetworks">
<description>Tenant-based Network Management Extension.</description>
</extension>
<extension alias="os-quota-class-sets" updated="2012-03-12T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/quota-classes-sets/api/v1.1" name="QuotaClasses">
diff --git a/doc/api_samples/os-networks/networks-list-res.json b/doc/api_samples/os-tenant-networks/networks-list-res.json
index b857e8112..b857e8112 100644
--- a/doc/api_samples/os-networks/networks-list-res.json
+++ b/doc/api_samples/os-tenant-networks/networks-list-res.json
diff --git a/doc/api_samples/os-networks/networks-post-res.json b/doc/api_samples/os-tenant-networks/networks-post-res.json
index 536a9a0a4..536a9a0a4 100644
--- a/doc/api_samples/os-networks/networks-post-res.json
+++ b/doc/api_samples/os-tenant-networks/networks-post-res.json
diff --git a/nova/api/openstack/compute/contrib/admin_networks.py b/nova/api/openstack/compute/contrib/admin_networks.py
deleted file mode 100644
index f5facd601..000000000
--- a/nova/api/openstack/compute/contrib/admin_networks.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 Grid Dynamics
-# Copyright 2011 OpenStack LLC.
-# 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.
-
-import netaddr
-import webob
-from webob import exc
-
-from nova.api.openstack import extensions
-from nova.api.openstack import wsgi
-from nova import exception
-from nova import network
-from nova.openstack.common import log as logging
-
-LOG = logging.getLogger(__name__)
-authorize = extensions.extension_authorizer('compute', 'admin_networks')
-authorize_view = extensions.extension_authorizer('compute',
- 'admin_networks:view')
-
-
-def network_dict(context, network):
- fields = ('id', 'cidr', 'netmask', 'gateway', 'broadcast', 'dns1', 'dns2',
- 'cidr_v6', 'gateway_v6', 'label', 'netmask_v6')
- admin_fields = ('created_at', 'updated_at', 'deleted_at', 'deleted',
- 'injected', 'bridge', 'vlan', 'vpn_public_address',
- 'vpn_public_port', 'vpn_private_address', 'dhcp_start',
- 'project_id', 'host', 'bridge_interface', 'multi_host',
- 'priority', 'rxtx_base')
- if network:
- # NOTE(mnaser): We display a limited set of fields so users can know
- # what networks are available, extra system-only fields
- # are only visible if they are an admin.
- if context.is_admin:
- fields += admin_fields
- result = dict((field, network[field]) for field in fields)
- if 'uuid' in network:
- result['id'] = network['uuid']
- return result
- else:
- return {}
-
-
-class AdminNetworkController(wsgi.Controller):
-
- def __init__(self, network_api=None):
- self.network_api = network_api or network.API()
-
- 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]
- return {'networks': result}
-
- @wsgi.action("disassociate")
- def _disassociate_host_and_project(self, req, id, body):
- context = req.environ['nova.context']
- authorize(context)
- LOG.debug(_("Disassociating network with id %s"), id)
-
- try:
- self.network_api.associate(context, id, host=None, project=None)
- except exception.NetworkNotFound:
- raise exc.HTTPNotFound(_("Network not found"))
- return exc.HTTPAccepted()
-
- def show(self, req, id):
- context = req.environ['nova.context']
- authorize_view(context)
- LOG.debug(_("Showing network with id %s") % id)
- try:
- network = self.network_api.get(context, id)
- except exception.NetworkNotFound:
- raise exc.HTTPNotFound(_("Network not found"))
- return {'network': network_dict(context, network)}
-
- def delete(self, req, id):
- context = req.environ['nova.context']
- authorize(context)
- LOG.info(_("Deleting network with id %s") % id)
- try:
- self.network_api.delete(context, id)
- except exception.NetworkNotFound:
- raise exc.HTTPNotFound(_("Network not found"))
- return exc.HTTPAccepted()
-
- def create(self, req, body):
- context = req.environ['nova.context']
- authorize(context)
-
- def bad(e):
- return exc.HTTPUnprocessableEntity(explanation=e)
-
- if not (body and body.get("network")):
- raise bad(_("Missing network in body"))
-
- params = body["network"]
- if not params.get("label"):
- raise bad(_("Network label is required"))
-
- cidr = params.get("cidr") or params.get("cidr_v6")
- if not cidr:
- raise bad(_("Network cidr or cidr_v6 is required"))
-
- LOG.debug(_("Creating network with label %s") % params["label"])
-
- params["num_networks"] = 1
- params["network_size"] = netaddr.IPNetwork(cidr).size
-
- network = self.network_api.create(context, **params)[0]
- return {"network": network_dict(context, network)}
-
- def add(self, req, body):
- context = req.environ['nova.context']
- authorize(context)
- if not body:
- raise exc.HTTPUnprocessableEntity()
-
- network_id = body.get('id', None)
- project_id = context.project_id
- LOG.debug(_("Associating network %(network)s"
- " with project %(project)s") %
- {"network": network_id or "",
- "project": project_id})
- try:
- self.network_api.add_network_to_project(
- context, project_id, network_id)
- except Exception as ex:
- msg = (_("Cannot associate network %(network)s"
- " with project %(project)s: %(message)s") %
- {"network": network_id or "",
- "project": project_id,
- "message": getattr(ex, "value", str(ex))})
- raise exc.HTTPBadRequest(explanation=msg)
-
- return webob.Response(status_int=202)
-
-
-class Admin_networks(extensions.ExtensionDescriptor):
- """Admin-only Network Management Extension."""
-
- name = "AdminNetworks"
- alias = "os-admin-networks"
- namespace = ("http://docs.openstack.org/compute/"
- "ext/os-admin-networks/api/v1.1")
- updated = "2011-12-23T00:00:00+00:00"
-
- def get_resources(self):
- member_actions = {'action': 'POST'}
- collection_actions = {'add': 'POST'}
- res = extensions.ResourceExtension(
- 'os-admin-networks',
- AdminNetworkController(),
- member_actions=member_actions,
- collection_actions=collection_actions)
- return [res]
diff --git a/nova/api/openstack/compute/contrib/networks_associate.py b/nova/api/openstack/compute/contrib/networks_associate.py
index 4990c1b5e..3cdda1d76 100644
--- a/nova/api/openstack/compute/contrib/networks_associate.py
+++ b/nova/api/openstack/compute/contrib/networks_associate.py
@@ -62,6 +62,6 @@ class Networks_associate(extensions.ExtensionDescriptor):
def get_controller_extensions(self):
extension = extensions.ControllerExtension(
- self, 'os-admin-networks', NetworkAssociateActionController())
+ self, 'os-networks', NetworkAssociateActionController())
return [extension]
diff --git a/nova/api/openstack/compute/contrib/os_networks.py b/nova/api/openstack/compute/contrib/os_networks.py
index 4be0bd100..d1d172686 100644
--- a/nova/api/openstack/compute/contrib/os_networks.py
+++ b/nova/api/openstack/compute/contrib/os_networks.py
@@ -1,6 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2013 OpenStack LLC.
+# Copyright 2011 Grid Dynamics
+# Copyright 2011 OpenStack LLC.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -15,199 +16,155 @@
# License for the specific language governing permissions and limitations
# under the License.
-
import netaddr
-import netaddr.core as netexc
+import webob
from webob import exc
from nova.api.openstack import extensions
-from nova import context as nova_context
+from nova.api.openstack import wsgi
from nova import exception
-import nova.network
-from nova.openstack.common import cfg
+from nova import network
from nova.openstack.common import log as logging
-from nova import quota
-
-
-CONF = cfg.CONF
-
-try:
- os_network_opts = [
- cfg.BoolOpt("enable_network_quota",
- default=False,
- help="Enables or disables quotaing of tenant networks"),
- cfg.StrOpt('use_quantum_default_nets',
- default="False",
- help=('Control for checking for default networks')),
- cfg.StrOpt('quantum_default_tenant_id',
- default="default",
- help=('Default tenant id when creating quantum '
- 'networks'))
- ]
- CONF.register_opts(os_network_opts)
-except cfg.DuplicateOptError:
- # NOTE(jkoelker) These options are verbatim elsewhere this is here
- # to make sure they are registered for our use.
- pass
-
-if CONF.enable_network_quota:
- opts = [
- cfg.IntOpt('quota_networks',
- default=3,
- help='number of private networks allowed per project'),
- ]
- CONF.register_opts(opts)
-
-QUOTAS = quota.QUOTAS
-LOG = logging.getLogger(__name__)
-authorize = extensions.extension_authorizer('compute', 'os-networks')
-
-
-def network_dict(network):
- return {"id": network.get("uuid") or network["id"],
- "cidr": network["cidr"],
- "label": network["label"]}
+LOG = logging.getLogger(__name__)
+authorize = extensions.extension_authorizer('compute', 'networks')
+authorize_view = extensions.extension_authorizer('compute',
+ 'networks:view')
+
+
+def network_dict(context, network):
+ fields = ('id', 'cidr', 'netmask', 'gateway', 'broadcast', 'dns1', 'dns2',
+ 'cidr_v6', 'gateway_v6', 'label', 'netmask_v6')
+ admin_fields = ('created_at', 'updated_at', 'deleted_at', 'deleted',
+ 'injected', 'bridge', 'vlan', 'vpn_public_address',
+ 'vpn_public_port', 'vpn_private_address', 'dhcp_start',
+ 'project_id', 'host', 'bridge_interface', 'multi_host',
+ 'priority', 'rxtx_base')
+ if network:
+ # NOTE(mnaser): We display a limited set of fields so users can know
+ # what networks are available, extra system-only fields
+ # are only visible if they are an admin.
+ if context.is_admin:
+ fields += admin_fields
+ result = dict((field, network[field]) for field in fields)
+ if 'uuid' in network:
+ result['id'] = network['uuid']
+ return result
+ else:
+ return {}
+
+
+class NetworkController(wsgi.Controller):
-class NetworkController(object):
def __init__(self, network_api=None):
- self.network_api = nova.network.API()
- self._default_networks = []
-
- def _refresh_default_networks(self):
- self._default_networks = []
- if CONF.use_quantum_default_nets == "True":
- try:
- self._default_networks = self._get_default_networks()
- except Exception:
- LOG.exception("Failed to get default networks")
-
- def _get_default_networks(self):
- project_id = CONF.quantum_default_tenant_id
- ctx = nova_context.RequestContext(user_id=None,
- project_id=project_id)
- networks = {}
- for n in self.network_api.get_all(ctx):
- networks[n['id']] = n['label']
- return [{'id': k, 'label': v} for k, v in networks.iteritems()]
+ self.network_api = network_api or network.API()
def index(self, req):
context = req.environ['nova.context']
- authorize(context)
+ authorize_view(context)
networks = self.network_api.get_all(context)
- if not self._default_networks:
- self._refresh_default_networks()
- networks.extend(self._default_networks)
- return {'networks': [network_dict(n) for n in networks]}
+ result = [network_dict(context, net_ref) for net_ref in networks]
+ return {'networks': result}
- def show(self, req, id):
+ @wsgi.action("disassociate")
+ def _disassociate_host_and_project(self, req, id, body):
context = req.environ['nova.context']
authorize(context)
+ LOG.debug(_("Disassociating network with id %s"), id)
+
+ try:
+ self.network_api.associate(context, id, host=None, project=None)
+ except exception.NetworkNotFound:
+ raise exc.HTTPNotFound(_("Network not found"))
+ return exc.HTTPAccepted()
+
+ def show(self, req, id):
+ context = req.environ['nova.context']
+ authorize_view(context)
LOG.debug(_("Showing network with id %s") % id)
try:
network = self.network_api.get(context, id)
except exception.NetworkNotFound:
raise exc.HTTPNotFound(_("Network not found"))
- return network_dict(network)
+ return {'network': network_dict(context, network)}
def delete(self, req, id):
context = req.environ['nova.context']
authorize(context)
- try:
- if CONF.enable_network_quota:
- reservation = QUOTAS.reserve(context, networks=-1)
- except Exception:
- reservation = None
- LOG.exception(_("Failed to update usages deallocating "
- "network."))
-
LOG.info(_("Deleting network with id %s") % id)
-
try:
self.network_api.delete(context, id)
- if CONF.enable_network_quota and reservation:
- QUOTAS.commit(context, reservation)
- response = exc.HTTPAccepted()
except exception.NetworkNotFound:
- response = exc.HTTPNotFound(_("Network not found"))
-
- return response
+ raise exc.HTTPNotFound(_("Network not found"))
+ return exc.HTTPAccepted()
def create(self, req, body):
- if not body:
- raise exc.HTTPUnprocessableEntity()
-
- context = req.environ["nova.context"]
+ context = req.environ['nova.context']
authorize(context)
- network = body["network"]
- keys = ["cidr", "cidr_v6", "ipam", "vlan_start", "network_size",
- "num_networks"]
- kwargs = dict((k, network.get(k)) for k in keys)
+ def bad(e):
+ return exc.HTTPUnprocessableEntity(explanation=e)
- label = network["label"]
+ if not (body and body.get("network")):
+ raise bad(_("Missing network in body"))
- if not (kwargs["cidr"] or kwargs["cidr_v6"]):
- msg = _("No CIDR requested")
- raise exc.HTTPBadRequest(explanation=msg)
- if kwargs["cidr"]:
- try:
- net = netaddr.IPNetwork(kwargs["cidr"])
- if net.size < 4:
- msg = _("Requested network does not contain "
- "enough (2+) usable hosts")
- raise exc.HTTPBadRequest(explanation=msg)
- except netexc.AddrFormatError:
- msg = _("CIDR is malformed.")
- raise exc.HTTPBadRequest(explanation=msg)
- except netexc.AddrConversionError:
- msg = _("Address could not be converted.")
- raise exc.HTTPBadRequest(explanation=msg)
-
- networks = []
+ params = body["network"]
+ if not params.get("label"):
+ raise bad(_("Network label is required"))
+
+ cidr = params.get("cidr") or params.get("cidr_v6")
+ if not cidr:
+ raise bad(_("Network cidr or cidr_v6 is required"))
+
+ LOG.debug(_("Creating network with label %s") % params["label"])
+
+ params["num_networks"] = 1
+ params["network_size"] = netaddr.IPNetwork(cidr).size
+
+ network = self.network_api.create(context, **params)[0]
+ return {"network": network_dict(context, network)}
+
+ def add(self, req, body):
+ context = req.environ['nova.context']
+ authorize(context)
+ if not body:
+ raise exc.HTTPUnprocessableEntity()
+
+ network_id = body.get('id', None)
+ project_id = context.project_id
+ LOG.debug(_("Associating network %(network)s"
+ " with project %(project)s") %
+ {"network": network_id or "",
+ "project": project_id})
try:
- if CONF.enable_network_quota:
- reservation = QUOTAS.reserve(context, networks=1)
- except exception.OverQuota:
- msg = _("Quota exceeded, too many networks.")
+ self.network_api.add_network_to_project(
+ context, project_id, network_id)
+ except Exception as ex:
+ msg = (_("Cannot associate network %(network)s"
+ " with project %(project)s: %(message)s") %
+ {"network": network_id or "",
+ "project": project_id,
+ "message": getattr(ex, "value", str(ex))})
raise exc.HTTPBadRequest(explanation=msg)
- try:
- networks = self.network_api.create(context,
- label=label, **kwargs)
- if CONF.enable_network_quota:
- QUOTAS.commit(context, reservation)
- except Exception:
- if CONF.enable_network_quota:
- QUOTAS.rollback(context, reservation)
- msg = _("Create networks failed")
- LOG.exception(msg, extra=network)
- raise exc.HTTPServiceUnavailable(explanation=msg)
- return {"network": network_dict(networks[0])}
+ return webob.Response(status_int=202)
class Os_networks(extensions.ExtensionDescriptor):
- """Tenant-based Network Management Extension."""
+ """Admin-only Network Management Extension."""
- name = "OSNetworks"
+ name = "Networks"
alias = "os-networks"
- namespace = "http://docs.openstack.org/compute/ext/os-networks/api/v1.1"
- updated = "2012-03-07T09:46:43-05:00"
+ namespace = ("http://docs.openstack.org/compute/"
+ "ext/os-networks/api/v1.1")
+ updated = "2011-12-23T00:00:00+00:00"
def get_resources(self):
- ext = extensions.ResourceExtension('os-networks',
- NetworkController())
- return [ext]
-
-
-def _sync_networks(context, project_id, session):
- ctx = nova_context.RequestContext(user_id=None, project_id=project_id)
- ctx = ctx.elevated()
- networks = nova.network.api.API().get_all(ctx)
- return dict(networks=len(networks))
-
-
-if CONF.enable_network_quota:
- QUOTAS.register_resource(quota.ReservableResource('networks',
- _sync_networks,
- 'quota_networks'))
+ member_actions = {'action': 'POST'}
+ collection_actions = {'add': 'POST'}
+ res = extensions.ResourceExtension(
+ 'os-networks',
+ NetworkController(),
+ member_actions=member_actions,
+ collection_actions=collection_actions)
+ return [res]
diff --git a/nova/api/openstack/compute/contrib/os_tenant_networks.py b/nova/api/openstack/compute/contrib/os_tenant_networks.py
new file mode 100644
index 000000000..03178ab65
--- /dev/null
+++ b/nova/api/openstack/compute/contrib/os_tenant_networks.py
@@ -0,0 +1,214 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 OpenStack LLC.
+# 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.
+
+
+import netaddr
+import netaddr.core as netexc
+from webob import exc
+
+from nova.api.openstack import extensions
+from nova import context as nova_context
+from nova import exception
+import nova.network
+from nova.openstack.common import cfg
+from nova.openstack.common import log as logging
+from nova import quota
+
+
+CONF = cfg.CONF
+
+try:
+ os_network_opts = [
+ cfg.BoolOpt("enable_network_quota",
+ default=False,
+ help="Enables or disables quotaing of tenant networks"),
+ cfg.StrOpt('use_quantum_default_nets',
+ default="False",
+ help=('Control for checking for default networks')),
+ cfg.StrOpt('quantum_default_tenant_id',
+ default="default",
+ help=('Default tenant id when creating quantum '
+ 'networks'))
+ ]
+ CONF.register_opts(os_network_opts)
+except cfg.DuplicateOptError:
+ # NOTE(jkoelker) These options are verbatim elsewhere this is here
+ # to make sure they are registered for our use.
+ pass
+
+if CONF.enable_network_quota:
+ opts = [
+ cfg.IntOpt('quota_networks',
+ default=3,
+ help='number of private networks allowed per project'),
+ ]
+ CONF.register_opts(opts)
+
+QUOTAS = quota.QUOTAS
+LOG = logging.getLogger(__name__)
+authorize = extensions.extension_authorizer('compute', 'os-tenant-networks')
+
+
+def network_dict(network):
+ return {"id": network.get("uuid") or network["id"],
+ "cidr": network["cidr"],
+ "label": network["label"]}
+
+
+class NetworkController(object):
+ def __init__(self, network_api=None):
+ self.network_api = nova.network.API()
+ self._default_networks = []
+
+ def _refresh_default_networks(self):
+ self._default_networks = []
+ if CONF.use_quantum_default_nets == "True":
+ try:
+ self._default_networks = self._get_default_networks()
+ except Exception:
+ LOG.exception("Failed to get default networks")
+
+ def _get_default_networks(self):
+ project_id = CONF.quantum_default_tenant_id
+ ctx = nova_context.RequestContext(user_id=None,
+ project_id=project_id)
+ networks = {}
+ for n in self.network_api.get_all(ctx):
+ networks[n['id']] = n['label']
+ return [{'id': k, 'label': v} for k, v in networks.iteritems()]
+
+ def index(self, req):
+ context = req.environ['nova.context']
+ authorize(context)
+ networks = self.network_api.get_all(context)
+ if not self._default_networks:
+ self._refresh_default_networks()
+ networks.extend(self._default_networks)
+ return {'networks': [network_dict(n) for n in networks]}
+
+ def show(self, req, id):
+ context = req.environ['nova.context']
+ authorize(context)
+ LOG.debug(_("Showing network with id %s") % id)
+ try:
+ network = self.network_api.get(context, id)
+ except exception.NetworkNotFound:
+ raise exc.HTTPNotFound(_("Network not found"))
+ return network_dict(network)
+
+ def delete(self, req, id):
+ context = req.environ['nova.context']
+ authorize(context)
+ try:
+ if CONF.enable_network_quota:
+ reservation = QUOTAS.reserve(context, networks=-1)
+ except Exception:
+ reservation = None
+ LOG.exception(_("Failed to update usages deallocating "
+ "network."))
+
+ LOG.info(_("Deleting network with id %s") % id)
+
+ try:
+ self.network_api.delete(context, id)
+ if CONF.enable_network_quota and reservation:
+ QUOTAS.commit(context, reservation)
+ response = exc.HTTPAccepted()
+ except exception.NetworkNotFound:
+ response = exc.HTTPNotFound(_("Network not found"))
+
+ return response
+
+ def create(self, req, body):
+ if not body:
+ raise exc.HTTPUnprocessableEntity()
+
+ context = req.environ["nova.context"]
+ authorize(context)
+
+ network = body["network"]
+ keys = ["cidr", "cidr_v6", "ipam", "vlan_start", "network_size",
+ "num_networks"]
+ kwargs = dict((k, network.get(k)) for k in keys)
+
+ label = network["label"]
+
+ if not (kwargs["cidr"] or kwargs["cidr_v6"]):
+ msg = _("No CIDR requested")
+ raise exc.HTTPBadRequest(explanation=msg)
+ if kwargs["cidr"]:
+ try:
+ net = netaddr.IPNetwork(kwargs["cidr"])
+ if net.size < 4:
+ msg = _("Requested network does not contain "
+ "enough (2+) usable hosts")
+ raise exc.HTTPBadRequest(explanation=msg)
+ except netexc.AddrFormatError:
+ msg = _("CIDR is malformed.")
+ raise exc.HTTPBadRequest(explanation=msg)
+ except netexc.AddrConversionError:
+ msg = _("Address could not be converted.")
+ raise exc.HTTPBadRequest(explanation=msg)
+
+ networks = []
+ try:
+ if CONF.enable_network_quota:
+ reservation = QUOTAS.reserve(context, networks=1)
+ except exception.OverQuota:
+ msg = _("Quota exceeded, too many networks.")
+ raise exc.HTTPBadRequest(explanation=msg)
+
+ try:
+ networks = self.network_api.create(context,
+ label=label, **kwargs)
+ if CONF.enable_network_quota:
+ QUOTAS.commit(context, reservation)
+ except Exception:
+ if CONF.enable_network_quota:
+ QUOTAS.rollback(context, reservation)
+ msg = _("Create networks failed")
+ LOG.exception(msg, extra=network)
+ raise exc.HTTPServiceUnavailable(explanation=msg)
+ return {"network": network_dict(networks[0])}
+
+
+class Os_tenant_networks(extensions.ExtensionDescriptor):
+ """Tenant-based Network Management Extension."""
+
+ name = "OSTenantNetworks"
+ alias = "os-tenant-networks"
+ namespace = ("http://docs.openstack.org/compute/"
+ "ext/os-tenant-networks/api/v2")
+ updated = "2012-03-07T09:46:43-05:00"
+
+ def get_resources(self):
+ ext = extensions.ResourceExtension('os-tenant-networks',
+ NetworkController())
+ return [ext]
+
+
+def _sync_networks(context, project_id, session):
+ ctx = nova_context.RequestContext(user_id=None, project_id=project_id)
+ ctx = ctx.elevated()
+ networks = nova.network.api.API().get_all(ctx)
+ return dict(networks=len(networks))
+
+
+if CONF.enable_network_quota:
+ QUOTAS.register_resource(quota.ReservableResource('networks',
+ _sync_networks,
+ 'quota_networks'))
diff --git a/nova/compute/api.py b/nova/compute/api.py
index bddb83449..65e33ff06 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -1547,12 +1547,9 @@ class API(base.Base):
elevated = context.elevated()
block_info = self._get_block_device_info(elevated,
instance['uuid'])
- network_info = self.network_api.get_instance_nw_info(elevated,
- instance)
self.compute_rpcapi.reboot_instance(context, instance=instance,
block_device_info=block_info,
- network_info=network_info,
reboot_type=reboot_type)
def _get_image(self, context, image_href):
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index a4f17ee3d..3bf8e61ef 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -293,7 +293,7 @@ class ComputeVirtAPI(virtapi.VirtAPI):
class ComputeManager(manager.SchedulerDependentManager):
"""Manages the running instances from creation to destruction."""
- RPC_API_VERSION = '2.22'
+ RPC_API_VERSION = '2.23'
def __init__(self, compute_driver=None, *args, **kwargs):
"""Load configuration options and connect to the hypervisor."""
@@ -1440,19 +1440,14 @@ class ComputeManager(manager.SchedulerDependentManager):
if block_device_info is None:
block_device_info = self._get_instance_volume_block_device_info(
context, instance)
- # NOTE(danms): remove this when RPC API < 2.5 compatibility
- # is no longer needed
- if network_info is None:
- network_info = self._get_instance_nw_info(context, instance)
- else:
- network_info = network_model.NetworkInfo.hydrate(network_info)
+ network_info = self._get_instance_nw_info(context, instance)
self._notify_about_instance_usage(context, instance, "reboot.start")
current_power_state = self._get_power_state(context, instance)
- self._instance_update(context, instance['uuid'],
- power_state=current_power_state,
- vm_state=vm_states.ACTIVE)
+ instance = self._instance_update(context, instance['uuid'],
+ power_state=current_power_state,
+ vm_state=vm_states.ACTIVE)
if instance['power_state'] != power_state.RUNNING:
state = instance['power_state']
@@ -1473,10 +1468,10 @@ class ComputeManager(manager.SchedulerDependentManager):
# Fall through and reset task_state to None
current_power_state = self._get_power_state(context, instance)
- self._instance_update(context, instance['uuid'],
- power_state=current_power_state,
- vm_state=vm_states.ACTIVE,
- task_state=None)
+ instance = self._instance_update(context, instance['uuid'],
+ power_state=current_power_state,
+ vm_state=vm_states.ACTIVE,
+ task_state=None)
self._notify_about_instance_usage(context, instance, "reboot.end")
diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py
index 1c53b6084..3e7ed1cfd 100644
--- a/nova/compute/rpcapi.py
+++ b/nova/compute/rpcapi.py
@@ -157,6 +157,7 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
2.21 - Add migrate_data dict param to pre_live_migration()
2.22 - Add recreate, on_shared_storage and host arguments to
rebuild_instance()
+ 2.23 - Remove network_info from reboot_instance
'''
#
@@ -383,16 +384,15 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
_compute_topic(self.topic, ctxt, host, None),
version='2.20')
- def reboot_instance(self, ctxt, instance,
- block_device_info, network_info, reboot_type):
+ def reboot_instance(self, ctxt, instance, block_device_info,
+ reboot_type):
instance_p = jsonutils.to_primitive(instance)
self.cast(ctxt, self.make_msg('reboot_instance',
instance=instance_p,
block_device_info=block_device_info,
- network_info=network_info,
reboot_type=reboot_type),
topic=_compute_topic(self.topic, ctxt, None, instance),
- version='2.5')
+ version='2.23')
def rebuild_instance(self, ctxt, instance, new_pass, injected_files,
image_ref, orig_image_ref, orig_sys_metadata, bdms,
diff --git a/nova/tests/api/openstack/compute/contrib/test_networks.py b/nova/tests/api/openstack/compute/contrib/test_networks.py
index ba65e8f6a..44d9e8af3 100644
--- a/nova/tests/api/openstack/compute/contrib/test_networks.py
+++ b/nova/tests/api/openstack/compute/contrib/test_networks.py
@@ -21,8 +21,8 @@ import uuid
import webob
-from nova.api.openstack.compute.contrib import admin_networks as networks
from nova.api.openstack.compute.contrib import networks_associate
+from nova.api.openstack.compute.contrib import os_networks as networks
from nova import exception
from nova.openstack.common import cfg
from nova import test
@@ -177,7 +177,7 @@ class NetworksTest(test.TestCase):
def setUp(self):
super(NetworksTest, self).setUp()
self.fake_network_api = FakeNetworkAPI()
- self.controller = networks.AdminNetworkController(
+ self.controller = networks.NetworkController(
self.fake_network_api)
self.associate_controller = networks_associate\
.NetworkAssociateActionController(self.fake_network_api)
diff --git a/nova/tests/api/openstack/compute/contrib/test_services.py b/nova/tests/api/openstack/compute/contrib/test_services.py
index aa0e2ed0f..1bd47b67a 100644
--- a/nova/tests/api/openstack/compute/contrib/test_services.py
+++ b/nova/tests/api/openstack/compute/contrib/test_services.py
@@ -75,7 +75,7 @@ class FakeRequestWithHostService(object):
GET = {"host": "host1", "service": "nova-compute"}
-def fake_servcie_get_all(context):
+def fake_service_get_all(context):
return fake_services_list
@@ -111,7 +111,7 @@ class ServicesTest(test.TestCase):
def setUp(self):
super(ServicesTest, self).setUp()
- self.stubs.Set(db, "service_get_all", fake_servcie_get_all)
+ self.stubs.Set(db, "service_get_all", fake_service_get_all)
self.stubs.Set(timeutils, "utcnow", fake_utcnow)
self.stubs.Set(db, "service_get_by_args",
fake_service_get_by_host_binary)
diff --git a/nova/tests/api/openstack/compute/test_extensions.py b/nova/tests/api/openstack/compute/test_extensions.py
index e3810510b..485968209 100644
--- a/nova/tests/api/openstack/compute/test_extensions.py
+++ b/nova/tests/api/openstack/compute/test_extensions.py
@@ -185,7 +185,6 @@ class ExtensionControllerTest(ExtensionTestCase):
"Keypairs",
"Multinic",
"MultipleCreate",
- "OSNetworks",
"QuotaClasses",
"Quotas",
"Rescue",
diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py
index 40bc8d148..0c14fb891 100644
--- a/nova/tests/compute/test_compute.py
+++ b/nova/tests/compute/test_compute.py
@@ -1000,8 +1000,7 @@ class ComputeTestCase(BaseTestCase):
# This is a true unit test, so we don't need the network stubs.
fake_network.unset_stub_network_methods(self.stubs)
- self.mox.StubOutWithMock(network_model.NetworkInfo,
- 'hydrate')
+ self.mox.StubOutWithMock(self.compute, '_get_instance_nw_info')
self.mox.StubOutWithMock(self.compute, '_notify_about_instance_usage')
self.mox.StubOutWithMock(self.compute, '_instance_update')
self.mox.StubOutWithMock(self.compute, '_get_power_state')
@@ -1010,8 +1009,11 @@ class ComputeTestCase(BaseTestCase):
instance = dict(uuid='fake-instance',
power_state='unknown')
+ updated_instance1 = dict(uuid='updated-instance1',
+ power_state='fake')
+ updated_instance2 = dict(uuid='updated-instance2',
+ power_state='fake')
- fake_nw_info = 'fake-network-info'
fake_nw_model = network_model.NetworkInfo()
self.mox.StubOutWithMock(fake_nw_model, 'legacy')
@@ -1031,8 +1033,9 @@ class ComputeTestCase(BaseTestCase):
self.mox.StubOutWithMock(self.context, 'elevated')
self.context.elevated().AndReturn(econtext)
- network_model.NetworkInfo.hydrate(fake_nw_info).AndReturn(
- fake_nw_model)
+ self.compute._get_instance_nw_info(econtext,
+ instance).AndReturn(
+ fake_nw_model)
self.compute._notify_about_instance_usage(econtext,
instance,
'reboot.start')
@@ -1040,7 +1043,7 @@ class ComputeTestCase(BaseTestCase):
instance).AndReturn(fake_power_state1)
self.compute._instance_update(econtext, instance['uuid'],
power_state=fake_power_state1,
- vm_state=vm_states.ACTIVE)
+ vm_state=vm_states.ACTIVE).AndReturn(updated_instance1)
# Reboot should check the driver to see if legacy nwinfo is
# needed. If it is, the model's legacy() method should be
@@ -1058,7 +1061,7 @@ class ComputeTestCase(BaseTestCase):
# this is called with the wrong args, so we have to hack
# around it.
reboot_call_info = {}
- expected_call_info = {'args': (instance, expected_nw_info,
+ expected_call_info = {'args': (updated_instance1, expected_nw_info,
reboot_type, fake_block_dev_info),
'kwargs': {}}
@@ -1070,19 +1073,18 @@ class ComputeTestCase(BaseTestCase):
# Power state should be updated again
self.compute._get_power_state(econtext,
- instance).AndReturn(fake_power_state2)
- self.compute._instance_update(econtext, instance['uuid'],
+ updated_instance1).AndReturn(fake_power_state2)
+ self.compute._instance_update(econtext, updated_instance1['uuid'],
power_state=fake_power_state2,
task_state=None,
- vm_state=vm_states.ACTIVE)
+ vm_state=vm_states.ACTIVE).AndReturn(updated_instance2)
self.compute._notify_about_instance_usage(econtext,
- instance,
+ updated_instance2,
'reboot.end')
self.mox.ReplayAll()
self.compute.reboot_instance(self.context, instance=instance,
block_device_info=fake_block_dev_info,
- network_info=fake_nw_info,
reboot_type=reboot_type)
self.assertEqual(expected_call_info, reboot_call_info)
@@ -4233,12 +4235,10 @@ class ComputeAPITestCase(BaseTestCase):
def _stub_out_reboot(self, device_name):
def fake_reboot_instance(rpcapi, context, instance,
block_device_info,
- network_info,
reboot_type):
self.assertEqual(
block_device_info['block_device_mapping'][0]['mount_device'],
device_name)
- self.assertEqual(network_info[0]['network']['bridge'], 'fake_br1')
self.stubs.Set(nova.compute.rpcapi.ComputeAPI, 'reboot_instance',
fake_reboot_instance)
diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py
index a31d9a14b..00b90ea65 100644
--- a/nova/tests/compute/test_rpcapi.py
+++ b/nova/tests/compute/test_rpcapi.py
@@ -236,9 +236,8 @@ class ComputeRpcAPITestCase(test.TestCase):
self._test_compute_api('reboot_instance', 'cast',
instance=self.fake_instance,
block_device_info={},
- network_info={},
reboot_type='type',
- version='2.5')
+ version='2.23')
def test_rebuild_instance(self):
self._test_compute_api('rebuild_instance', 'cast',
diff --git a/nova/tests/fake_policy.py b/nova/tests/fake_policy.py
index c5d160209..51f3a3f85 100644
--- a/nova/tests/fake_policy.py
+++ b/nova/tests/fake_policy.py
@@ -136,10 +136,10 @@ policy_data = """
"compute_extension:instance_usage_audit_log": "",
"compute_extension:keypairs": "",
"compute_extension:multinic": "",
- "compute_extension:admin_networks": "",
- "compute_extension:admin_networks:view": "",
+ "compute_extension:networks": "",
+ "compute_extension:networks:view": "",
"compute_extension:networks_associate": "",
- "compute_extension:os-networks": "",
+ "compute_extension:os-tenant-networks": "",
"compute_extension:quotas:show": "",
"compute_extension:quotas:update": "",
"compute_extension:quota_classes": "",
diff --git a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl
index 0dd777fe2..3d69fad45 100644
--- a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl
+++ b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl
@@ -305,19 +305,19 @@
"updated": "%(timestamp)s"
},
{
- "alias": "os-admin-networks",
+ "alias": "os-networks",
"description": "%(text)s",
"links": [],
- "name": "AdminNetworks",
- "namespace": "http://docs.openstack.org/compute/ext/os-admin-networks/api/v1.1",
+ "name": "Networks",
+ "namespace": "http://docs.openstack.org/compute/ext/os-networks/api/v1.1",
"updated": "%(timestamp)s"
},
{
- "alias": "os-networks",
+ "alias": "os-tenant-networks",
"description": "%(text)s",
"links": [],
- "name": "OSNetworks",
- "namespace": "http://docs.openstack.org/compute/ext/os-networks/api/v1.1",
+ "name": "OSTenantNetworks",
+ "namespace": "http://docs.openstack.org/compute/ext/os-tenant-networks/api/v2",
"updated": "%(timestamp)s"
},
{
diff --git a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl
index fe34f369b..5953ba704 100644
--- a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl
+++ b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl
@@ -114,10 +114,10 @@
<extension alias="os-multiple-create" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/multiplecreate/api/v1.1" name="MultipleCreate">
<description>%(text)s</description>
</extension>
- <extension alias="os-admin-networks" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/os-admin-networks/api/v1.1" name="AdminNetworks">
+ <extension alias="os-networks" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/os-networks/api/v1.1" name="Networks">
<description>%(text)s</description>
</extension>
- <extension alias="os-networks" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/os-networks/api/v1.1" name="OSNetworks">
+ <extension alias="os-tenant-networks" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/os-tenant-networks/api/v2" name="OSTenantNetworks">
<description>%(text)s</description>
</extension>
<extension alias="os-networks-associate" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/networks_associate/api/v2" name="NetworkAssociationSupport">
diff --git a/nova/tests/integrated/api_samples/os-networks/networks-list-res.json.tpl b/nova/tests/integrated/api_samples/os-tenant-networks/networks-list-res.json.tpl
index 757084d2f..757084d2f 100644
--- a/nova/tests/integrated/api_samples/os-networks/networks-list-res.json.tpl
+++ b/nova/tests/integrated/api_samples/os-tenant-networks/networks-list-res.json.tpl
diff --git a/nova/tests/integrated/api_samples/os-networks/networks-post-req.json.tpl b/nova/tests/integrated/api_samples/os-tenant-networks/networks-post-req.json.tpl
index fb1c2d3d0..fb1c2d3d0 100644
--- a/nova/tests/integrated/api_samples/os-networks/networks-post-req.json.tpl
+++ b/nova/tests/integrated/api_samples/os-tenant-networks/networks-post-req.json.tpl
diff --git a/nova/tests/integrated/api_samples/os-networks/networks-post-res.json.tpl b/nova/tests/integrated/api_samples/os-tenant-networks/networks-post-res.json.tpl
index ff9e2273d..ff9e2273d 100644
--- a/nova/tests/integrated/api_samples/os-networks/networks-post-res.json.tpl
+++ b/nova/tests/integrated/api_samples/os-tenant-networks/networks-post-res.json.tpl
diff --git a/nova/tests/integrated/test_api_samples.py b/nova/tests/integrated/test_api_samples.py
index 0fb0e9107..98ac6a230 100644
--- a/nova/tests/integrated/test_api_samples.py
+++ b/nova/tests/integrated/test_api_samples.py
@@ -371,7 +371,7 @@ class ApiSamplesTrap(ApiSampleTestBase):
do_not_approve_additions.append('os-fping')
do_not_approve_additions.append('os-hypervisors')
do_not_approve_additions.append('os-instance_usage_audit_log')
- do_not_approve_additions.append('os-admin-networks')
+ do_not_approve_additions.append('os-networks')
do_not_approve_additions.append('os-services')
do_not_approve_additions.append('os-volumes')
@@ -2359,8 +2359,8 @@ class DiskConfigXmlTest(DiskConfigJsonTest):
class OsNetworksJsonTests(ApiSampleTestBase):
- extension_name = ("nova.api.openstack.compute.contrib.os_networks"
- ".Os_networks")
+ extension_name = ("nova.api.openstack.compute.contrib.os_tenant_networks"
+ ".Os_tenant_networks")
def setUp(self):
super(OsNetworksJsonTests, self).setUp()
@@ -2377,21 +2377,22 @@ class OsNetworksJsonTests(ApiSampleTestBase):
self.stubs.Set(nova.quota.QuotaEngine, "rollback", fake)
def test_list_networks(self):
- response = self._do_get('os-networks')
+ response = self._do_get('os-tenant-networks')
self.assertEqual(response.status, 200)
subs = self._get_regexes()
return self._verify_response('networks-list-res', subs, response)
def test_create_network(self):
- response = self._do_post('os-networks', "networks-post-req", {})
+ response = self._do_post('os-tenant-networks', "networks-post-req", {})
self.assertEqual(response.status, 200)
subs = self._get_regexes()
self._verify_response('networks-post-res', subs, response)
- def test_delete_networK(self):
- response = self._do_post('os-networks', "networks-post-req", {})
+ def test_delete_network(self):
+ response = self._do_post('os-tenant-networks', "networks-post-req", {})
net = json.loads(response.read())
- response = self._do_delete('os-networks/%s' % net["network"]["id"])
+ response = self._do_delete('os-tenant-networks/%s' %
+ net["network"]["id"])
self.assertEqual(response.status, 202)
@@ -2406,7 +2407,7 @@ class NetworksAssociateJsonTests(ApiSampleTestBase):
f['osapi_compute_extension'] = CONF.osapi_compute_extension[:]
# Networks_associate requires Networks to be update
f['osapi_compute_extension'].append(
- 'nova.api.openstack.compute.contrib.admin_networks.Admin_networks')
+ 'nova.api.openstack.compute.contrib.os_networks.Os_networks')
return f
def setUp(self):
@@ -2420,25 +2421,25 @@ class NetworksAssociateJsonTests(ApiSampleTestBase):
self.stubs.Set(network_api.API, "associate", fake_associate)
def test_disassociate(self):
- response = self._do_post('os-admin-networks/1/action',
+ response = self._do_post('os-networks/1/action',
'network-disassociate-req',
{})
self.assertEqual(response.status, 202)
def test_disassociate_host(self):
- response = self._do_post('os-admin-networks/1/action',
+ response = self._do_post('os-networks/1/action',
'network-disassociate-host-req',
{})
self.assertEqual(response.status, 202)
def test_disassociate_project(self):
- response = self._do_post('os-admin-networks/1/action',
+ response = self._do_post('os-networks/1/action',
'network-disassociate-project-req',
{})
self.assertEqual(response.status, 202)
def test_associate_host(self):
- response = self._do_post('os-admin-networks/1/action',
+ response = self._do_post('os-networks/1/action',
'network-associate-host-req',
{"host": "testHost"})
self.assertEqual(response.status, 202)