Merge "Implements securitygroup extension for nuage plugin"
This commit is contained in:
commit
34883286dd
@ -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])
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user