Merge "Implements securitygroup extension for nuage plugin"

This commit is contained in:
Jenkins 2014-08-23 07:37:30 +00:00 committed by Gerrit Code Review
commit 34883286dd
3 changed files with 211 additions and 14 deletions

View File

@ -32,11 +32,14 @@ from neutron.db import external_net_db
from neutron.db import extraroute_db from neutron.db import extraroute_db
from neutron.db import l3_db from neutron.db import l3_db
from neutron.db import quota_db # noqa from neutron.db import quota_db # noqa
from neutron.db import securitygroups_db as sg_db
from neutron.extensions import external_net from neutron.extensions import external_net
from neutron.extensions import l3 from neutron.extensions import l3
from neutron.extensions import portbindings from neutron.extensions import portbindings
from neutron.extensions import securitygroup as ext_sg
from neutron.openstack.common import excutils from neutron.openstack.common import excutils
from neutron.openstack.common import importutils from neutron.openstack.common import importutils
from neutron.openstack.common import lockutils
from neutron.plugins.nuage.common import config from neutron.plugins.nuage.common import config
from neutron.plugins.nuage.common import constants from neutron.plugins.nuage.common import constants
from neutron.plugins.nuage.common import exceptions as nuage_exc from neutron.plugins.nuage.common import exceptions as nuage_exc
@ -50,11 +53,13 @@ class NuagePlugin(db_base_plugin_v2.NeutronDbPluginV2,
external_net_db.External_net_db_mixin, external_net_db.External_net_db_mixin,
extraroute_db.ExtraRoute_db_mixin, extraroute_db.ExtraRoute_db_mixin,
l3_db.L3_NAT_db_mixin, l3_db.L3_NAT_db_mixin,
netpartition.NetPartitionPluginBase): netpartition.NetPartitionPluginBase,
sg_db.SecurityGroupDbMixin):
"""Class that implements Nuage Networks' plugin functionality.""" """Class that implements Nuage Networks' plugin functionality."""
supported_extension_aliases = ["router", "binding", "external-net", supported_extension_aliases = ["router", "binding", "external-net",
"net-partition", "nuage-router", "net-partition", "nuage-router",
"nuage-subnet", "quotas", "extraroute"] "nuage-subnet", "quotas",
"extraroute", "security-group"]
binding_view = "extension:port_binding:view" binding_view = "extension:port_binding:view"
@ -122,18 +127,93 @@ class NuagePlugin(db_base_plugin_v2.NeutronDbPluginV2,
'net_partition': net_partition, 'net_partition': net_partition,
'ip': port['fixed_ips'][0]['ip_address'], 'ip': port['fixed_ips'][0]['ip_address'],
'no_of_ports': len(ports), 'no_of_ports': len(ports),
'tenant': port['tenant_id'] 'tenant': port['tenant_id'],
} }
self.nuageclient.create_vms(params) nuage_vm = self.nuageclient.create_vms(params)
if nuage_vm:
if port['fixed_ips'][0]['ip_address'] != str(nuage_vm['ip']):
self._update_port_ip(context, port, nuage_vm['ip'])
def _get_router_by_subnet(self, context, subnet_id):
filters = {
'fixed_ips': {'subnet_id': [subnet_id]},
'device_owner': [os_constants.DEVICE_OWNER_ROUTER_INTF]
}
router_port = self.get_ports(context, filters=filters)
if not router_port:
msg = (_("Router for subnet %s not found ") % subnet_id)
raise n_exc.BadRequest(resource='port', msg=msg)
return router_port[0]['device_id']
def _process_port_create_security_group(self, context, port,
sec_group):
if not attributes.is_attr_set(sec_group):
port[ext_sg.SECURITYGROUPS] = []
return
port_id = port['id']
with context.session.begin(subtransactions=True):
for sg_id in sec_group:
super(NuagePlugin,
self)._create_port_security_group_binding(context,
port_id,
sg_id)
try:
vptag_vport_list = []
for sg_id in sec_group:
params = {
'neutron_port_id': port_id
}
nuage_port = self.nuageclient.get_nuage_port_by_id(params)
if nuage_port and nuage_port.get('nuage_vport_id'):
nuage_vport_id = nuage_port['nuage_vport_id']
sg = self._get_security_group(context, sg_id)
sg_rules = self.get_security_group_rules(
context,
{'security_group_id': [sg_id]})
sg_params = {
'nuage_port': nuage_port,
'sg': sg,
'sg_rules': sg_rules
}
nuage_vptag_id = (
self.nuageclient.process_port_create_security_group(
sg_params))
vptag_vport = {
'nuage_vporttag_id': nuage_vptag_id
}
vptag_vport_list.append(vptag_vport)
if vptag_vport_list:
params = {
'vptag_vport_list': vptag_vport_list,
'nuage_vport_id': nuage_vport_id
}
self.nuageclient.update_nuage_vport(params)
except Exception:
with excutils.save_and_reraise_exception():
for sg_id in sec_group:
super(NuagePlugin,
self)._delete_port_security_group_bindings(context,
port_id)
# Convert to list as a set might be passed here and
# this has to be serialized
port[ext_sg.SECURITYGROUPS] = (list(sec_group) if sec_group else [])
def _delete_port_security_group_bindings(self, context, port_id):
super(NuagePlugin,
self)._delete_port_security_group_bindings(context, port_id)
self.nuageclient.delete_port_security_group_bindings(port_id)
@lockutils.synchronized('create_port', 'nuage-port', external=True)
def create_port(self, context, port): def create_port(self, context, port):
session = context.session session = context.session
with session.begin(subtransactions=True): with session.begin(subtransactions=True):
p = port['port']
self._ensure_default_security_group_on_port(context, port)
port = super(NuagePlugin, self).create_port(context, port) port = super(NuagePlugin, self).create_port(context, port)
device_owner = port.get('device_owner', None) device_owner = port.get('device_owner', None)
if (device_owner and if device_owner not in constants.AUTO_CREATE_PORT_OWNERS:
device_owner not in constants.AUTO_CREATE_PORT_OWNERS):
if 'fixed_ips' not in port or len(port['fixed_ips']) == 0: if 'fixed_ips' not in port or len(port['fixed_ips']) == 0:
return self._extend_port_dict_binding(context, port) return self._extend_port_dict_binding(context, port)
subnet_id = port['fixed_ips'][0]['subnet_id'] subnet_id = port['fixed_ips'][0]['subnet_id']
@ -154,17 +234,23 @@ class NuagePlugin(db_base_plugin_v2.NeutronDbPluginV2,
super(NuagePlugin, self).delete_port( super(NuagePlugin, self).delete_port(
context, context,
port['id']) port['id'])
if ext_sg.SECURITYGROUPS in p:
self._process_port_create_security_group(
context,
port,
p[ext_sg.SECURITYGROUPS])
return self._extend_port_dict_binding(context, port) return self._extend_port_dict_binding(context, port)
def update_port(self, context, id, port): def update_port(self, context, id, port):
p = port['port'] p = port['port']
sg_groups = None
if p.get('device_owner', '').startswith( if p.get('device_owner', '').startswith(
constants.NOVA_PORT_OWNER_PREF): constants.NOVA_PORT_OWNER_PREF):
session = context.session session = context.session
with session.begin(subtransactions=True): with session.begin(subtransactions=True):
port = self._get_port(context, id) port = self._get_port(context, id)
port.update(p) port.update(p)
if 'fixed_ips' not in port or len(port['fixed_ips']) == 0: if not port.get('fixed_ips'):
return self._make_port_dict(port) return self._make_port_dict(port)
subnet_id = port['fixed_ips'][0]['subnet_id'] subnet_id = port['fixed_ips'][0]['subnet_id']
@ -178,24 +264,48 @@ class NuagePlugin(db_base_plugin_v2.NeutronDbPluginV2,
'neutron_port_id': id, 'neutron_port_id': id,
} }
nuage_port = self.nuageclient.get_nuage_port_by_id(params) nuage_port = self.nuageclient.get_nuage_port_by_id(params)
if not nuage_port: if not nuage_port or not nuage_port.get('nuage_vport_id'):
msg = (_("Port %s not found on VSD") % id)
raise n_exc.BadRequest(resource='port', msg=msg)
if not nuage_port['nuage_vport_id']:
self._create_update_port(context, port, self._create_update_port(context, port,
subnet_mapping[ subnet_mapping[
'net_partition_id'], 'net_partition_id'],
subnet_mapping['nuage_subnet_id']) subnet_mapping['nuage_subnet_id'])
updated_port = self._make_port_dict(port) updated_port = self._make_port_dict(port)
sg_port = self._extend_port_dict_security_group(
updated_port,
port
)
sg_groups = sg_port[ext_sg.SECURITYGROUPS]
else: else:
updated_port = super(NuagePlugin, self).update_port(context, id, updated_port = super(NuagePlugin, self).update_port(context, id,
port) port)
if not updated_port.get('fixed_ips'):
return updated_port
subnet_id = updated_port['fixed_ips'][0]['subnet_id']
subnet_mapping = nuagedb.get_subnet_l2dom_by_id(context.session,
subnet_id)
if subnet_mapping:
if sg_groups:
self._delete_port_security_group_bindings(context,
updated_port['id'])
self._process_port_create_security_group(context,
updated_port,
sg_groups)
elif ext_sg.SECURITYGROUPS in p:
self._delete_port_security_group_bindings(context,
updated_port['id'])
self._process_port_create_security_group(
context,
updated_port,
p[ext_sg.SECURITYGROUPS]
)
return updated_port return updated_port
@lockutils.synchronized('delete-port', 'nuage-del', external=True)
def delete_port(self, context, id, l3_port_check=True): def delete_port(self, context, id, l3_port_check=True):
if l3_port_check: if l3_port_check:
self.prevent_l3_port_deletion(context, id) self.prevent_l3_port_deletion(context, id)
port = self._get_port(context, id) port = self._get_port(context, id)
nuage_vif_id = None
params = { params = {
'neutron_port_id': id, 'neutron_port_id': id,
} }
@ -212,12 +322,19 @@ class NuagePlugin(db_base_plugin_v2.NeutronDbPluginV2,
sub_id) sub_id)
if not subnet_mapping: if not subnet_mapping:
return super(NuagePlugin, self).delete_port(context, id) return super(NuagePlugin, self).delete_port(context, id)
# Need to call this explicitly to delete vport to vporttag binding
if ext_sg.SECURITYGROUPS in port:
self._delete_port_security_group_bindings(context, id)
netpart_id = subnet_mapping['net_partition_id'] netpart_id = subnet_mapping['net_partition_id']
net_partition = nuagedb.get_net_partition_by_id(context.session, net_partition = nuagedb.get_net_partition_by_id(context.session,
netpart_id) netpart_id)
# Need to call this explicitly to delete vport_vporttag_mapping # Need to call this explicitly to delete vport
if constants.NOVA_PORT_OWNER_PREF in port['device_owner']: if constants.NOVA_PORT_OWNER_PREF in port['device_owner']:
if nuage_port:
nuage_vif_id = nuage_port['nuage_vif_id']
# This was a VM Port # This was a VM Port
filters = {'device_id': [port['device_id']]} filters = {'device_id': [port['device_id']]}
ports = self.get_ports(context, filters) ports = self.get_ports(context, filters)
@ -226,7 +343,7 @@ class NuagePlugin(db_base_plugin_v2.NeutronDbPluginV2,
'net_partition': net_partition, 'net_partition': net_partition,
'tenant': port['tenant_id'], 'tenant': port['tenant_id'],
'mac': port['mac_address'], 'mac': port['mac_address'],
'nuage_vif_id': nuage_port['nuage_vif_id'], 'nuage_vif_id': nuage_vif_id,
'id': port['device_id'] 'id': port['device_id']
} }
self.nuageclient.delete_vms(params) self.nuageclient.delete_vms(params)
@ -264,6 +381,10 @@ class NuagePlugin(db_base_plugin_v2.NeutronDbPluginV2,
def create_network(self, context, network): def create_network(self, context, network):
net = network['network'] net = network['network']
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
self._ensure_default_security_group(
context,
network['network']['tenant_id']
)
net = super(NuagePlugin, self).create_network(context, net = super(NuagePlugin, self).create_network(context,
network) network)
self._process_l3_create(context, net, network['network']) self._process_l3_create(context, net, network['network'])
@ -1011,3 +1132,49 @@ class NuagePlugin(db_base_plugin_v2.NeutronDbPluginV2,
self.nuageclient.delete_nuage_floatingip( self.nuageclient.delete_nuage_floatingip(
fip['nuage_fip_id']) fip['nuage_fip_id'])
super(NuagePlugin, self).delete_floatingip(context, id) super(NuagePlugin, self).delete_floatingip(context, id)
def delete_security_group(self, context, id):
filters = {'security_group_id': [id]}
ports = self._get_port_security_group_bindings(context,
filters)
if ports:
raise ext_sg.SecurityGroupInUse(id=id)
sg_rules = self.get_security_group_rules(context,
{'security_group_id': [id]})
if sg_rules:
self.nuageclient.delete_nuage_sgrule(sg_rules)
self.nuageclient.delete_nuage_secgroup(id)
super(NuagePlugin, self).delete_security_group(context, id)
def create_security_group_rule(self, context, security_group_rule):
sg_rule = security_group_rule['security_group_rule']
self.nuageclient.validate_nuage_sg_rule_definition(sg_rule)
sg_id = sg_rule['security_group_id']
local_sg_rule = super(NuagePlugin,
self).create_security_group_rule(
context, security_group_rule)
try:
nuage_vptag = self.nuageclient.get_sg_vptag_mapping(sg_id)
if nuage_vptag:
sg_params = {
'sg_id': sg_id,
'neutron_sg_rule': local_sg_rule,
'vptag': nuage_vptag
}
self.nuageclient.create_nuage_sgrule(sg_params)
except Exception:
with excutils.save_and_reraise_exception():
super(NuagePlugin,
self).delete_security_group_rule(context,
local_sg_rule['id'])
return local_sg_rule
def delete_security_group_rule(self, context, id):
local_sg_rule = self.get_security_group_rule(context, id)
super(NuagePlugin, self).delete_security_group_rule(context, id)
self.nuageclient.delete_nuage_sgrule([local_sg_rule])

View File

@ -161,3 +161,27 @@ class FakeNuageClient(object):
def get_usergroup(self, tenant, net_partition_id): def get_usergroup(self, tenant, net_partition_id):
return uuidutils.generate_uuid(), uuidutils.generate_uuid() return uuidutils.generate_uuid(), uuidutils.generate_uuid()
def get_sg_vptag_mapping(self, id):
pass
def validate_nuage_sg_rule_definition(self, params):
pass
def create_nuage_sgrule(self, params):
pass
def update_nuage_vport(self, params):
pass
def delete_nuage_sgrule(self, params):
pass
def delete_nuage_secgroup(self, params):
pass
def process_port_create_security_group(self, params):
pass
def delete_port_security_group_bindings(self, params):
pass

View File

@ -29,6 +29,7 @@ from neutron.tests.unit import _test_extension_portbindings as test_bindings
from neutron.tests.unit.nuage import fake_nuageclient from neutron.tests.unit.nuage import fake_nuageclient
from neutron.tests.unit import test_db_plugin from neutron.tests.unit import test_db_plugin
from neutron.tests.unit import test_extension_extraroute as extraroute_test from neutron.tests.unit import test_extension_extraroute as extraroute_test
from neutron.tests.unit import test_extension_security_group as test_sg
from neutron.tests.unit import test_l3_plugin from neutron.tests.unit import test_l3_plugin
API_EXT_PATH = os.path.dirname(extensions.__file__) API_EXT_PATH = os.path.dirname(extensions.__file__)
@ -287,3 +288,8 @@ class TestNuageExtrarouteTestCase(NuagePluginV2TestCase,
def test_network_update_external_failure(self): def test_network_update_external_failure(self):
self._test_network_update_external_failure() self._test_network_update_external_failure()
class TestNuageSecurityGroupTestCase(NuagePluginV2TestCase,
test_sg.TestSecurityGroups):
pass