--- /dev/null
+# Copyright 2014 OpenStack Foundation
+#
+# 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.
+#
+
+"""nuage_floatingip
+
+Revision ID: 2db5203cb7a9
+Revises: 10cd28e692e9
+Create Date: 2014-05-19 16:39:42.048125
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '2db5203cb7a9'
+down_revision = '10cd28e692e9'
+
+migration_for_plugins = [
+ 'neutron.plugins.nuage.plugin.NuagePlugin'
+]
+
+from alembic import op
+import sqlalchemy as sa
+
+from neutron.db import migration
+
+
+def upgrade(active_plugins=None, options=None):
+ if not migration.should_run(active_plugins, migration_for_plugins):
+ return
+
+ op.create_table(
+ 'nuage_floatingip_pool_mapping',
+ sa.Column('fip_pool_id', sa.String(length=36), nullable=False),
+ sa.Column('net_id', sa.String(length=36), nullable=True),
+ sa.Column('router_id', sa.String(length=36), nullable=True),
+ sa.ForeignKeyConstraint(['net_id'], ['networks.id'],
+ ondelete='CASCADE'),
+ sa.ForeignKeyConstraint(['router_id'], ['routers.id'],
+ ondelete='CASCADE'),
+ sa.PrimaryKeyConstraint('fip_pool_id'),
+ )
+ op.create_table(
+ 'nuage_floatingip_mapping',
+ sa.Column('fip_id', sa.String(length=36), nullable=False),
+ sa.Column('router_id', sa.String(length=36), nullable=True),
+ sa.Column('nuage_fip_id', sa.String(length=36), nullable=True),
+ sa.ForeignKeyConstraint(['fip_id'], ['floatingips.id'],
+ ondelete='CASCADE'),
+ sa.PrimaryKeyConstraint('fip_id'),
+ )
+ op.rename_table('net_partitions', 'nuage_net_partitions')
+ op.rename_table('net_partition_router_mapping',
+ 'nuage_net_partition_router_mapping')
+ op.rename_table('router_zone_mapping', 'nuage_router_zone_mapping')
+ op.rename_table('subnet_l2dom_mapping', 'nuage_subnet_l2dom_mapping')
+ op.rename_table('port_mapping', 'nuage_port_mapping')
+ op.rename_table('routerroutes_mapping', 'nuage_routerroutes_mapping')
+
+
+def downgrade(active_plugins=None, options=None):
+ if not migration.should_run(active_plugins, migration_for_plugins):
+ return
+
+ op.drop_table('nuage_floatingip_mapping')
+ op.drop_table('nuage_floatingip_pool_mapping')
+ op.rename_table('nuage_net_partitions', 'net_partitions')
+ op.rename_table('nuage_net_partition_router_mapping',
+ 'net_partition_router_mapping')
+ op.rename_table('nuage_router_zone_mapping', 'router_zone_mapping')
+ op.rename_table('nuage_subnet_l2dom_mapping', 'subnet_l2dom_mapping')
+ op.rename_table('nuage_port_mapping', 'port_mapping')
+ op.rename_table('nuage_routerroutes_mapping', 'routerroutes_mapping')
-10cd28e692e9
\ No newline at end of file
+2db5203cb7a9
\ No newline at end of file
]
NOVA_PORT_OWNER_PREF = 'compute:'
+
+SR_TYPE_FLOATING = "FLOATING"
class NetPartition(model_base.BASEV2, models_v2.HasId):
- __tablename__ = 'net_partitions'
+ __tablename__ = 'nuage_net_partitions'
name = Column(String(64))
l3dom_tmplt_id = Column(String(36))
l2dom_tmplt_id = Column(String(36))
class NetPartitionRouter(model_base.BASEV2):
- __tablename__ = "net_partition_router_mapping"
+ __tablename__ = "nuage_net_partition_router_mapping"
net_partition_id = Column(String(36),
- ForeignKey('net_partitions.id',
+ ForeignKey('nuage_net_partitions.id',
ondelete="CASCADE"),
primary_key=True)
router_id = Column(String(36),
class RouterZone(model_base.BASEV2):
- __tablename__ = "router_zone_mapping"
+ __tablename__ = "nuage_router_zone_mapping"
router_id = Column(String(36),
ForeignKey('routers.id', ondelete="CASCADE"),
primary_key=True)
class SubnetL2Domain(model_base.BASEV2):
- __tablename__ = 'subnet_l2dom_mapping'
+ __tablename__ = 'nuage_subnet_l2dom_mapping'
subnet_id = Column(String(36),
ForeignKey('subnets.id', ondelete="CASCADE"),
primary_key=True)
net_partition_id = Column(String(36),
- ForeignKey('net_partitions.id',
+ ForeignKey('nuage_net_partitions.id',
ondelete="CASCADE"))
nuage_subnet_id = Column(String(36))
nuage_l2dom_tmplt_id = Column(String(36))
class PortVPortMapping(model_base.BASEV2):
- __tablename__ = 'port_mapping'
+ __tablename__ = 'nuage_port_mapping'
port_id = Column(String(36),
ForeignKey('ports.id', ondelete="CASCADE"),
primary_key=True)
class RouterRoutesMapping(model_base.BASEV2, models_v2.Route):
- __tablename__ = 'routerroutes_mapping'
+ __tablename__ = 'nuage_routerroutes_mapping'
router_id = Column(String(36),
ForeignKey('routers.id',
ondelete="CASCADE"),
primary_key=True,
nullable=False)
nuage_route_id = Column(String(36))
+
+
+class FloatingIPPoolMapping(model_base.BASEV2):
+ __tablename__ = "nuage_floatingip_pool_mapping"
+ fip_pool_id = Column(String(36), primary_key=True)
+ net_id = Column(String(36),
+ ForeignKey('networks.id', ondelete="CASCADE"))
+ router_id = Column(String(36))
+
+
+class FloatingIPMapping(model_base.BASEV2):
+ __tablename__ = 'nuage_floatingip_mapping'
+ fip_id = Column(String(36),
+ ForeignKey('floatingips.id',
+ ondelete="CASCADE"),
+ primary_key=True)
+ router_id = Column(String(36))
+ nuage_fip_id = Column(String(36))
subnet_l2dom.update(new_dict)
+def delete_subnetl2dom_mapping(session, subnet_l2dom):
+ session.delete(subnet_l2dom)
+
+
def add_port_vport_mapping(session, port_id, nuage_vport_id,
nuage_vif_id, static_ip):
port_mapping = nuage_models.PortVPortMapping(port_id=port_id,
nexthop=nexthop)
session.add(staticrt)
return staticrt
+
+
+def add_fip_mapping(session, neutron_fip_id, router_id, nuage_fip_id):
+ fip = nuage_models.FloatingIPMapping(fip_id=neutron_fip_id,
+ router_id=router_id,
+ nuage_fip_id=nuage_fip_id)
+ session.add(fip)
+ return fip
+
+
+def delete_fip_mapping(session, fip_mapping):
+ session.delete(fip_mapping)
+
+
+def add_fip_pool_mapping(session, fip_pool_id, net_id, router_id=None):
+ fip_pool_mapping = nuage_models.FloatingIPPoolMapping(
+ fip_pool_id=fip_pool_id,
+ net_id=net_id,
+ router_id=router_id)
+ session.add(fip_pool_mapping)
+ return fip_pool_mapping
+
+
+def delete_fip_pool_mapping(session, fip_pool_mapping):
+ session.delete(fip_pool_mapping)
+
+
+def get_fip_pool_by_id(session, id):
+ query = session.query(nuage_models.FloatingIPPoolMapping)
+ return query.filter_by(fip_pool_id=id).first()
+
+
+def get_fip_pool_from_netid(session, net_id):
+ query = session.query(nuage_models.FloatingIPPoolMapping)
+ return query.filter_by(net_id=net_id).first()
+
+
+def get_fip_mapping_by_id(session, id):
+ qry = session.query(nuage_models.FloatingIPMapping)
+ return qry.filter_by(fip_id=id).first()
+
+
+def update_fip_pool_mapping(fip_pool_mapping, new_dict):
+ fip_pool_mapping.update(new_dict)
from neutron.db import l3_db
from neutron.db import models_v2
from neutron.db import quota_db # noqa
+from neutron.extensions import external_net
from neutron.extensions import l3
from neutron.extensions import portbindings
from neutron.openstack.common import excutils
self._process_l3_create(context, net, network['network'])
return net
+ def _validate_update_network(self, context, id, network):
+ req_data = network['network']
+ is_external_set = req_data.get(external_net.EXTERNAL)
+ if not attributes.is_attr_set(is_external_set):
+ return (None, None)
+ neutron_net = self.get_network(context, id)
+ if neutron_net.get(external_net.EXTERNAL) == is_external_set:
+ return (None, None)
+ subnet = self._validate_nuage_sharedresource(context, 'network', id)
+ if subnet and not is_external_set:
+ msg = _('External network with subnets can not be '
+ 'changed to non-external network')
+ raise nuage_exc.OperationNotSupported(msg=msg)
+ return (is_external_set, subnet)
+
def update_network(self, context, id, network):
with context.session.begin(subtransactions=True):
+ is_external_set, subnet = self._validate_update_network(context,
+ id,
+ network)
net = super(NuagePlugin, self).update_network(context, id,
network)
self._process_l3_update(context, net, network['network'])
+ if subnet and is_external_set:
+ subn = subnet[0]
+ subnet_l2dom = nuagedb.get_subnet_l2dom_by_id(context.session,
+ subn['id'])
+ if subnet_l2dom:
+ nuage_subnet_id = subnet_l2dom['nuage_subnet_id']
+ nuage_l2dom_tid = subnet_l2dom['nuage_l2dom_tmplt_id']
+ user_id = subnet_l2dom['nuage_user_id']
+ group_id = subnet_l2dom['nuage_group_id']
+ self.nuageclient.delete_subnet(nuage_subnet_id,
+ nuage_l2dom_tid)
+ self.nuageclient.delete_user(user_id)
+ self.nuageclient.delete_group(group_id)
+ nuagedb.delete_subnetl2dom_mapping(context.session,
+ subnet_l2dom)
+ self._add_nuage_sharedresource(context,
+ subnet[0],
+ id,
+ constants.SR_TYPE_FLOATING)
return net
def delete_network(self, context, id):
msg = "no-gateway option not supported with subnets"
raise nuage_exc.OperationNotSupported(msg=msg)
- def create_subnet(self, context, subnet):
- subn = subnet['subnet']
- net_id = subn['network_id']
+ def _delete_nuage_sharedresource(self, context, net_id):
+ sharedresource_id = self.nuageclient.delete_nuage_sharedresource(
+ net_id)
+ if sharedresource_id:
+ fip_pool_mapping = nuagedb.get_fip_pool_by_id(context.session,
+ sharedresource_id)
+ if fip_pool_mapping:
+ with context.session.begin(subtransactions=True):
+ nuagedb.delete_fip_pool_mapping(context.session,
+ fip_pool_mapping)
+
+ def _validate_nuage_sharedresource(self, context, resource, net_id):
+ filter = {'network_id': [net_id]}
+ existing_subn = self.get_subnets(context, filters=filter)
+ if len(existing_subn) > 1:
+ msg = _('Only one subnet is allowed per '
+ 'external network %s') % net_id
+ raise nuage_exc.OperationNotSupported(msg=msg)
+ return existing_subn
- if self._network_is_external(context, net_id):
- return super(NuagePlugin, self).create_subnet(context, subnet)
+ def _add_nuage_sharedresource(self, context, subnet, net_id, type):
+ net = netaddr.IPNetwork(subnet['cidr'])
+ params = {
+ 'neutron_subnet': subnet,
+ 'net': net,
+ 'type': type
+ }
+ fip_pool_id = self.nuageclient.create_nuage_sharedresource(params)
+ nuagedb.add_fip_pool_mapping(context.session, fip_pool_id, net_id)
- self._validate_create_subnet(subn)
+ def _create_nuage_sharedresource(self, context, subnet, type):
+ subn = subnet['subnet']
+ net_id = subn['network_id']
+ self._validate_nuage_sharedresource(context, 'subnet', net_id)
+ with context.session.begin(subtransactions=True):
+ subn = super(NuagePlugin, self).create_subnet(context, subnet)
+ self._add_nuage_sharedresource(context, subn, net_id, type)
+ return subn
- net_partition = self._get_net_partition_for_subnet(context, subnet)
- neutron_subnet = super(NuagePlugin, self).create_subnet(context,
- subnet)
+ def _create_nuage_subnet(self, context, neutron_subnet, net_partition):
net = netaddr.IPNetwork(neutron_subnet['cidr'])
params = {
'net_partition': net_partition,
user_id = nuage_subnet['nuage_userid']
group_id = nuage_subnet['nuage_groupid']
id = nuage_subnet['nuage_l2domain_id']
- session = context.session
- with session.begin(subtransactions=True):
- nuagedb.add_subnetl2dom_mapping(session,
+ with context.session.begin(subtransactions=True):
+ nuagedb.add_subnetl2dom_mapping(context.session,
neutron_subnet['id'],
id,
net_partition['id'],
l2dom_id=l2dom_id,
nuage_user_id=user_id,
nuage_group_id=group_id)
+
+ def create_subnet(self, context, subnet):
+ subn = subnet['subnet']
+ net_id = subn['network_id']
+
+ if self._network_is_external(context, net_id):
+ return self._create_nuage_sharedresource(
+ context, subnet, constants.SR_TYPE_FLOATING)
+
+ self._validate_create_subnet(subn)
+
+ net_partition = self._get_net_partition_for_subnet(context, subnet)
+ neutron_subnet = super(NuagePlugin, self).create_subnet(context,
+ subnet)
+ self._create_nuage_subnet(context, neutron_subnet, net_partition)
return neutron_subnet
def delete_subnet(self, context, id):
subnet = self.get_subnet(context, id)
if self._network_is_external(context, subnet['network_id']):
- return super(NuagePlugin, self).delete_subnet(context, id)
+ super(NuagePlugin, self).delete_subnet(context, id)
+ return self._delete_nuage_sharedresource(context, id)
subnet_l2dom = nuagedb.get_subnet_l2dom_by_id(context.session, id)
if subnet_l2dom:
with session.begin(subtransactions=True):
subnet_l2dom = nuagedb.get_subnet_l2dom_by_id(session,
subnet_id)
+ if not subnet_l2dom:
+ return super(NuagePlugin,
+ self).remove_router_interface(context,
+ router_id,
+ interface_info)
nuage_subn_id = subnet_l2dom['nuage_subnet_id']
if self.nuageclient.vms_on_l2domain(nuage_subn_id):
msg = (_("Subnet %s has one or more active VMs "
if net_partition:
with session.begin(subtransactions=True):
nuagedb.delete_net_partition(session, net_partition)
-
self._create_net_partition(session, default_net_part)
def create_net_partition(self, context, net_partition):
fields=fields)
return [self._make_net_partition_dict(net_partition, fields)
for net_partition in net_partitions]
+
+ def _check_floatingip_update(self, context, port):
+ filter = {'fixed_port_id': [port['id']]}
+ local_fip = self.get_floatingips(context,
+ filters=filter)
+ if local_fip:
+ fip = local_fip[0]
+ self._create_update_floatingip(context,
+ fip, port['id'])
+
+ def _create_update_floatingip(self, context,
+ neutron_fip, port_id):
+ rtr_id = neutron_fip['router_id']
+ net_id = neutron_fip['floating_network_id']
+
+ fip_pool_mapping = nuagedb.get_fip_pool_from_netid(context.session,
+ net_id)
+ fip_mapping = nuagedb.get_fip_mapping_by_id(context.session,
+ neutron_fip['id'])
+
+ if not fip_mapping:
+ ent_rtr_mapping = nuagedb.get_ent_rtr_mapping_by_rtrid(
+ context.session, rtr_id)
+ if not ent_rtr_mapping:
+ msg = _('router %s is not associated with '
+ 'any net-partition') % rtr_id
+ raise n_exc.BadRequest(resource='floatingip',
+ msg=msg)
+ params = {
+ 'nuage_rtr_id': ent_rtr_mapping['nuage_router_id'],
+ 'nuage_fippool_id': fip_pool_mapping['fip_pool_id'],
+ 'neutron_fip_ip': neutron_fip['floating_ip_address']
+ }
+ nuage_fip_id = self.nuageclient.create_nuage_floatingip(params)
+ nuagedb.add_fip_mapping(context.session,
+ neutron_fip['id'],
+ rtr_id, nuage_fip_id)
+ else:
+ if rtr_id != fip_mapping['router_id']:
+ msg = _('Floating IP can not be associated to VM in '
+ 'different router context')
+ raise nuage_exc.OperationNotSupported(msg=msg)
+ nuage_fip_id = fip_mapping['nuage_fip_id']
+
+ fip_pool_dict = {'router_id': neutron_fip['router_id']}
+ nuagedb.update_fip_pool_mapping(fip_pool_mapping,
+ fip_pool_dict)
+
+ # Update VM if required
+ port_mapping = nuagedb.get_port_mapping_by_id(context.session,
+ port_id)
+ if port_mapping:
+ params = {
+ 'nuage_vport_id': port_mapping['nuage_vport_id'],
+ 'nuage_fip_id': nuage_fip_id
+ }
+ self.nuageclient.update_nuage_vm_vport(params)
+
+ def create_floatingip(self, context, floatingip):
+ fip = floatingip['floatingip']
+ with context.session.begin(subtransactions=True):
+ neutron_fip = super(NuagePlugin, self).create_floatingip(
+ context, floatingip)
+ if not neutron_fip['router_id']:
+ return neutron_fip
+ try:
+ self._create_update_floatingip(context, neutron_fip,
+ fip['port_id'])
+ except (nuage_exc.OperationNotSupported, n_exc.BadRequest):
+ with excutils.save_and_reraise_exception():
+ super(NuagePlugin, self).delete_floatingip(
+ context, neutron_fip['id'])
+ return neutron_fip
+
+ def disassociate_floatingips(self, context, port_id):
+ super(NuagePlugin, self).disassociate_floatingips(context, port_id)
+ port_mapping = nuagedb.get_port_mapping_by_id(context.session,
+ port_id)
+ if port_mapping:
+ params = {
+ 'nuage_vport_id': port_mapping['nuage_vport_id'],
+ 'nuage_fip_id': None
+ }
+ self.nuageclient.update_nuage_vm_vport(params)
+
+ def update_floatingip(self, context, id, floatingip):
+ fip = floatingip['floatingip']
+ orig_fip = self._get_floatingip(context, id)
+ port_id = orig_fip['fixed_port_id']
+ with context.session.begin(subtransactions=True):
+ neutron_fip = super(NuagePlugin, self).update_floatingip(
+ context, id, floatingip)
+ if fip['port_id'] is not None:
+ if not neutron_fip['router_id']:
+ ret_msg = 'floating-ip is not associated yet'
+ raise n_exc.BadRequest(resource='floatingip',
+ msg=ret_msg)
+
+ try:
+ self._create_update_floatingip(context,
+ neutron_fip,
+ fip['port_id'])
+ except nuage_exc.OperationNotSupported:
+ with excutils.save_and_reraise_exception():
+ super(NuagePlugin,
+ self).disassociate_floatingips(context,
+ fip['port_id'])
+ except n_exc.BadRequest:
+ with excutils.save_and_reraise_exception():
+ super(NuagePlugin, self).delete_floatingip(context,
+ id)
+ else:
+ port_mapping = nuagedb.get_port_mapping_by_id(context.session,
+ port_id)
+ if port_mapping:
+ params = {
+ 'nuage_vport_id': port_mapping['nuage_vport_id'],
+ 'nuage_fip_id': None
+ }
+ self.nuageclient.update_nuage_vm_vport(params)
+ return neutron_fip
+
+ def delete_floatingip(self, context, id):
+ fip = self._get_floatingip(context, id)
+ port_id = fip['fixed_port_id']
+ with context.session.begin(subtransactions=True):
+ if port_id:
+ port_mapping = nuagedb.get_port_mapping_by_id(context.session,
+ port_id)
+ if (port_mapping and
+ port_mapping['nuage_vport_id'] is not None):
+ params = {
+ 'nuage_vport_id': port_mapping['nuage_vport_id'],
+ 'nuage_fip_id': None
+ }
+ self.nuageclient.update_nuage_vm_vport(params)
+ fip_mapping = nuagedb.get_fip_mapping_by_id(context.session,
+ id)
+ if fip_mapping:
+ self.nuageclient.delete_nuage_floatingip(
+ fip_mapping['nuage_fip_id'])
+ nuagedb.delete_fip_mapping(context.session, fip_mapping)
+ super(NuagePlugin, self).delete_floatingip(context, id)
#
# @author: Ronak Shah, Aniket Dandekar, Nuage Networks, Alcatel-Lucent USA Inc.
-import uuid
+from neutron.openstack.common import uuidutils
class FakeNuageClient(object):
def create_subnet(self, neutron_subnet, params):
nuage_subnet = {
- 'nuage_l2template_id': str(uuid.uuid4()),
- 'nuage_userid': str(uuid.uuid4()),
- 'nuage_groupid': str(uuid.uuid4()),
- 'nuage_l2domain_id': str(uuid.uuid4())
+ 'nuage_l2template_id': uuidutils.generate_uuid(),
+ 'nuage_userid': uuidutils.generate_uuid(),
+ 'nuage_groupid': uuidutils.generate_uuid(),
+ 'nuage_l2domain_id': uuidutils.generate_uuid()
}
return nuage_subnet
def create_router(self, neutron_router, router, params):
nuage_router = {
- 'nuage_userid': str(uuid.uuid4()),
- 'nuage_groupid': str(uuid.uuid4()),
- 'nuage_domain_id': str(uuid.uuid4()),
- 'nuage_def_zone_id': str(uuid.uuid4()),
+ 'nuage_userid': uuidutils.generate_uuid(),
+ 'nuage_groupid': uuidutils.generate_uuid(),
+ 'nuage_domain_id': uuidutils.generate_uuid(),
+ 'nuage_def_zone_id': uuidutils.generate_uuid(),
}
return nuage_router
def create_net_partition(self, params):
fake_net_partition = {
- 'nuage_entid': str(uuid.uuid4()),
- 'l3dom_id': str(uuid.uuid4()),
- 'l2dom_id': str(uuid.uuid4()),
+ 'nuage_entid': uuidutils.generate_uuid(),
+ 'l3dom_id': uuidutils.generate_uuid(),
+ 'l2dom_id': uuidutils.generate_uuid(),
}
return fake_net_partition
pass
def create_nuage_staticroute(self, params):
- return str(uuid.uuid4())
+ return uuidutils.generate_uuid()
def delete_nuage_staticroute(self, id):
pass
+
+ def create_nuage_sharedresource(self, params):
+ return uuidutils.generate_uuid()
+
+ def delete_nuage_sharedresource(self, id):
+ pass
+
+ def create_nuage_floatingip(self, params):
+ return uuidutils.generate_uuid()
+
+ def delete_nuage_floatingip(self, id):
+ pass
+
+ def update_nuage_vm_vport(self, params):
+ pass
#
# @author: Ronak Shah, Aniket Dandekar, Nuage Networks, Alcatel-Lucent USA Inc.
+import contextlib
import os
import mock
from oslo.config import cfg
from webob import exc
+from neutron.extensions import external_net
from neutron.extensions import portbindings
from neutron.plugins.nuage import extensions
from neutron.plugins.nuage import plugin as nuage_plugin
super(NuagePluginV2TestCase, self).setUp(plugin=plugin,
ext_mgr=ext_mgr)
+ def _assert_no_assoc_fip(self, fip):
+ body = self._show('floatingips',
+ fip['floatingip']['id'])
+ self.assertIsNone(body['floatingip']['port_id'])
+ self.assertIsNone(
+ body['floatingip']['fixed_ip_address'])
+
+ def _associate_and_assert_fip(self, fip, port, allow=True):
+ port_id = port['port']['id']
+ ip_address = (port['port']['fixed_ips']
+ [0]['ip_address'])
+ if allow:
+ body = self._update(
+ 'floatingips', fip['floatingip']['id'],
+ {'floatingip': {'port_id': port_id}})
+ self.assertEqual(
+ body['floatingip']['port_id'], port_id)
+ self.assertEqual(
+ body['floatingip']['fixed_ip_address'],
+ ip_address)
+ return body['floatingip']['router_id']
+ else:
+ code = exc.HTTPInternalServerError.code
+ self._update(
+ 'floatingips', fip['floatingip']['id'],
+ {'floatingip': {'port_id': port_id}},
+ expected_code=code)
+
+ def _test_floatingip_update_different_router(self):
+ with contextlib.nested(self.subnet(cidr='10.0.0.0/24'),
+ self.subnet(cidr='10.0.1.0/24')) as (
+ s1, s2):
+ with contextlib.nested(self.port(subnet=s1),
+ self.port(subnet=s2)) as (p1, p2):
+ private_sub1 = {'subnet':
+ {'id':
+ p1['port']['fixed_ips'][0]['subnet_id']}}
+ private_sub2 = {'subnet':
+ {'id':
+ p2['port']['fixed_ips'][0]['subnet_id']}}
+ with self.subnet(cidr='12.0.0.0/24') as public_sub:
+ with contextlib.nested(
+ self.floatingip_no_assoc_with_public_sub(
+ private_sub1, public_sub=public_sub),
+ self.floatingip_no_assoc_with_public_sub(
+ private_sub2, public_sub=public_sub)) as (
+ (fip1, r1), (fip2, r2)):
+
+ self._assert_no_assoc_fip(fip1)
+ self._assert_no_assoc_fip(fip2)
+
+ fip1_r1_res = self._associate_and_assert_fip(fip1, p1)
+ self.assertEqual(fip1_r1_res, r1['router']['id'])
+ # The following operation will associate the floating
+ # ip to a different router and should fail
+ self._associate_and_assert_fip(fip1, p2, allow=False)
+ # disassociate fip1
+ self._update(
+ 'floatingips', fip1['floatingip']['id'],
+ {'floatingip': {'port_id': None}})
+ fip2_r2_res = self._associate_and_assert_fip(fip2, p2)
+ self.assertEqual(fip2_r2_res, r2['router']['id'])
+
+ def _test_network_update_external_failure(self):
+ with self.router() as r:
+ with self.subnet() as s1:
+ self._set_net_external(s1['subnet']['network_id'])
+ self._add_external_gateway_to_router(
+ r['router']['id'],
+ s1['subnet']['network_id'])
+ self._update('networks', s1['subnet']['network_id'],
+ {'network': {external_net.EXTERNAL: False}},
+ expected_code=exc.HTTPInternalServerError.code)
+ self._remove_external_gateway_from_router(
+ r['router']['id'],
+ s1['subnet']['network_id'])
+
class TestNuageBasicGet(NuagePluginV2TestCase,
test_db_plugin.TestBasicGet):
class TestNuageL3NatTestCase(NuagePluginV2TestCase,
test_l3_plugin.L3NatDBIntTestCase):
- pass
+
+ def test_floatingip_update_different_router(self):
+ self._test_floatingip_update_different_router()
+
+ def test_network_update_external_failure(self):
+ self._test_network_update_external_failure()
class TestNuageExtrarouteTestCase(NuagePluginV2TestCase,
r['router']['id'],
None,
p['port']['id'])
+
+ def test_floatingip_update_different_router(self):
+ self._test_floatingip_update_different_router()
+
+ def test_network_update_external_failure(self):
+ self._test_network_update_external_failure()