From c4648bc1b320a191c9d913e6a4931285ee8d7a9a Mon Sep 17 00:00:00 2001 From: Fawad Khaliq Date: Tue, 8 Jul 2014 11:10:12 -0700 Subject: [PATCH] Security groups extension for PLUMgrid plugin This patch includes immplementation of security groups extension in PLUMgrid plugin. APIs include CRUD operations for security groups and security group rules. Added unit tests. Implements: blueprint plumgrid-plugin-security-groups Change-Id: I23fea3fe6c3abbe310e883e00706b93863db3bfb --- .../plugins/plumgrid/drivers/fake_plumlib.py | 18 ++ neutron/plugins/plumgrid/drivers/plumlib.py | 18 ++ .../plumgrid_plugin/plumgrid_plugin.py | 287 +++++++++++++++--- .../unit/plumgrid/extensions/__init__.py | 0 .../extensions/test_securitygroups.py | 67 ++++ .../unit/plumgrid/test_plumgrid_plugin.py | 1 + 6 files changed, 344 insertions(+), 47 deletions(-) create mode 100644 neutron/tests/unit/plumgrid/extensions/__init__.py create mode 100644 neutron/tests/unit/plumgrid/extensions/test_securitygroups.py diff --git a/neutron/plugins/plumgrid/drivers/fake_plumlib.py b/neutron/plugins/plumgrid/drivers/fake_plumlib.py index 16ce799fc..dab2a99a0 100644 --- a/neutron/plugins/plumgrid/drivers/fake_plumlib.py +++ b/neutron/plugins/plumgrid/drivers/fake_plumlib.py @@ -96,3 +96,21 @@ class Plumlib(): def disassociate_floatingips(self, fip, port_id): return dict((key, fip[key]) for key in ("id", "floating_network_id", "floating_ip_address")) + + def create_security_group(self, sg_db): + pass + + def update_security_group(self, sg_db): + pass + + def delete_security_group(self, sg_db): + pass + + def create_security_group_rule(self, sg_rule_db): + pass + + def create_security_group_rule_bulk(self, sg_rule_db): + pass + + def delete_security_group_rule(self, sg_rule_db): + pass diff --git a/neutron/plugins/plumgrid/drivers/plumlib.py b/neutron/plugins/plumgrid/drivers/plumlib.py index e0c59dd56..ba241f4b3 100644 --- a/neutron/plugins/plumgrid/drivers/plumlib.py +++ b/neutron/plugins/plumgrid/drivers/plumlib.py @@ -97,3 +97,21 @@ class Plumlib(object): def disassociate_floatingips(self, floating_ip, port_id): self.plumlib.disassociate_floatingips(floating_ip, port_id) + + def create_security_group(self, sg_db): + self.plumlib.create_security_group(sg_db) + + def update_security_group(self, sg_db): + self.plumlib.update_security_group(sg_db) + + def delete_security_group(self, sg_db): + self.plumlib.delete_security_group(sg_db) + + def create_security_group_rule(self, sg_rule_db): + self.plumlib.create_security_group_rule(sg_rule_db) + + def create_security_group_rule_bulk(self, sg_rule_db): + self.plumlib.create_security_group_rule_bulk(sg_rule_db) + + def delete_security_group_rule(self, sg_rule_db): + self.plumlib.delete_security_group_rule(sg_rule_db) diff --git a/neutron/plugins/plumgrid/plumgrid_plugin/plumgrid_plugin.py b/neutron/plugins/plumgrid/plumgrid_plugin/plumgrid_plugin.py index 32177fdfc..5e1aed555 100644 --- a/neutron/plugins/plumgrid/plumgrid_plugin/plumgrid_plugin.py +++ b/neutron/plugins/plumgrid/plumgrid_plugin/plumgrid_plugin.py @@ -31,7 +31,9 @@ from neutron.db import external_net_db from neutron.db import l3_db from neutron.db import portbindings_db from neutron.db import quota_db # noqa +from neutron.db import securitygroups_db from neutron.extensions import portbindings +from neutron.extensions import securitygroup as sec_grp from neutron.openstack.common import importutils from neutron.openstack.common import log as logging from neutron.plugins.plumgrid.common import exceptions as plum_excep @@ -58,12 +60,13 @@ cfg.CONF.register_opts(director_server_opts, "plumgriddirector") class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, - portbindings_db.PortBindingMixin, external_net_db.External_net_db_mixin, - l3_db.L3_NAT_db_mixin): + l3_db.L3_NAT_db_mixin, + portbindings_db.PortBindingMixin, + securitygroups_db.SecurityGroupDbMixin): - supported_extension_aliases = ["external-net", "router", "binding", - "quotas", "provider"] + supported_extension_aliases = ["binding", "external-net", "provider", + "quotas", "router", "security-group"] binding_view = "extension:port_binding:view" binding_set = "extension:port_binding:set" @@ -74,8 +77,8 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, super(NeutronPluginPLUMgridV2, self).__init__() self.plumgrid_init() - LOG.debug(_('Neutron PLUMgrid Director: Neutron server with ' - 'PLUMgrid Plugin has started')) + LOG.debug('Neutron PLUMgrid Director: Neutron server with ' + 'PLUMgrid Plugin has started') def plumgrid_init(self): """PLUMgrid initialization.""" @@ -98,7 +101,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, Creates a PLUMgrid-based bridge. """ - LOG.debug(_('Neutron PLUMgrid Director: create_network() called')) + LOG.debug('Neutron PLUMgrid Director: create_network() called') # Plugin DB - Network Create and validation tenant_id = self._get_tenant_id_for_create(context, @@ -110,9 +113,10 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, self).create_network(context, network) # Propagate all L3 data into DB self._process_l3_create(context, net_db, network['network']) + self._ensure_default_security_group(context, tenant_id) try: - LOG.debug(_('PLUMgrid Library: create_network() called')) + LOG.debug('PLUMgrid Library: create_network() called') self._plumlib.create_network(tenant_id, net_db, network) except Exception as err_message: @@ -127,7 +131,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, Updates a PLUMgrid-based bridge. """ - LOG.debug(_("Neutron PLUMgrid Director: update_network() called")) + LOG.debug("Neutron PLUMgrid Director: update_network() called") self._network_admin_state(network) tenant_id = self._get_tenant_id_for_create(context, network["network"]) @@ -139,7 +143,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, self._process_l3_update(context, net_db, network['network']) try: - LOG.debug(_("PLUMgrid Library: update_network() called")) + LOG.debug("PLUMgrid Library: update_network() called") self._plumlib.update_network(tenant_id, net_id) except Exception as err_message: @@ -154,7 +158,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, Deletes a PLUMgrid-based bridge. """ - LOG.debug(_("Neutron PLUMgrid Director: delete_network() called")) + LOG.debug("Neutron PLUMgrid Director: delete_network() called") net_db = super(NeutronPluginPLUMgridV2, self).get_network(context, net_id) @@ -165,7 +169,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, net_id) try: - LOG.debug(_("PLUMgrid Library: update_network() called")) + LOG.debug("PLUMgrid Library: update_network() called") self._plumlib.delete_network(net_db, net_id) except Exception as err_message: @@ -177,18 +181,33 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, Creates a PLUMgrid-based port on the specific Virtual Network Function (VNF). """ - LOG.debug(_("Neutron PLUMgrid Director: create_port() called")) + LOG.debug("Neutron PLUMgrid Director: create_port() called") # Port operations on PLUMgrid Director is an automatic operation # from the VIF driver operations in Nova. # It requires admin_state_up to be True port["port"]["admin_state_up"] = True + port_data = port["port"] with context.session.begin(subtransactions=True): # Plugin DB - Port Create and Return port port_db = super(NeutronPluginPLUMgridV2, self).create_port(context, port) + # Update port security + port_data.update(port_db) + + self._ensure_default_security_group_on_port(context, port) + + port_data[sec_grp.SECURITYGROUPS] = ( + self._get_security_groups_on_port(context, port)) + + self._process_port_create_security_group( + context, port_db, port_data[sec_grp.SECURITYGROUPS]) + + self._process_portbindings_create_and_update(context, + port_data, port_db) + device_id = port_db["device_id"] if port_db["device_owner"] == constants.DEVICE_OWNER_ROUTER_GW: router_db = self._get_router(context, device_id) @@ -196,7 +215,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, router_db = None try: - LOG.debug(_("PLUMgrid Library: create_port() called")) + LOG.debug("PLUMgrid Library: create_port() called") self._plumlib.create_port(port_db, router_db) except Exception as err_message: @@ -211,7 +230,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, Updates a PLUMgrid-based port on the specific Virtual Network Function (VNF). """ - LOG.debug(_("Neutron PLUMgrid Director: update_port() called")) + LOG.debug("Neutron PLUMgrid Director: update_port() called") with context.session.begin(subtransactions=True): # Plugin DB - Port Create and Return port @@ -222,8 +241,22 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, router_db = self._get_router(context, device_id) else: router_db = None + + if (self._check_update_deletes_security_groups(port) or + self._check_update_has_security_groups(port)): + self._delete_port_security_group_bindings(context, + port_db["id"]) + sg_ids = self._get_security_groups_on_port(context, port) + self._process_port_create_security_group(context, + port_db, + sg_ids) + + self._process_portbindings_create_and_update(context, + port['port'], + port_db) + try: - LOG.debug(_("PLUMgrid Library: create_port() called")) + LOG.debug("PLUMgrid Library: create_port() called") self._plumlib.update_port(port_db, router_db) except Exception as err_message: @@ -239,7 +272,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, Function (VNF). """ - LOG.debug(_("Neutron PLUMgrid Director: delete_port() called")) + LOG.debug("Neutron PLUMgrid Director: delete_port() called") with context.session.begin(subtransactions=True): # Plugin DB - Port Create and Return port @@ -255,7 +288,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, else: router_db = None try: - LOG.debug(_("PLUMgrid Library: delete_port() called")) + LOG.debug("PLUMgrid Library: delete_port() called") self._plumlib.delete_port(port_db, router_db) except Exception as err_message: @@ -287,7 +320,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, Functions (VNFs). """ - LOG.debug(_("Neutron PLUMgrid Director: create_subnet() called")) + LOG.debug("Neutron PLUMgrid Director: create_subnet() called") with context.session.begin(subtransactions=True): # Plugin DB - Subnet Create @@ -311,7 +344,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, context, subnet) try: - LOG.debug(_("PLUMgrid Library: create_subnet() called")) + LOG.debug("PLUMgrid Library: create_subnet() called") self._plumlib.create_subnet(sub_db, net_db, ipnet) except Exception as err_message: raise plum_excep.PLUMgridException(err_msg=err_message) @@ -321,7 +354,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, def delete_subnet(self, context, subnet_id): """Delete subnet core Neutron API.""" - LOG.debug(_("Neutron PLUMgrid Director: delete_subnet() called")) + LOG.debug("Neutron PLUMgrid Director: delete_subnet() called") # Collecting subnet info sub_db = self._get_subnet(context, subnet_id) tenant_id = self._get_tenant_id_for_create(context, subnet_id) @@ -333,7 +366,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, super(NeutronPluginPLUMgridV2, self).delete_subnet( context, subnet_id) try: - LOG.debug(_("PLUMgrid Library: delete_subnet() called")) + LOG.debug("PLUMgrid Library: delete_subnet() called") self._plumlib.delete_subnet(tenant_id, net_db, net_id) except Exception as err_message: raise plum_excep.PLUMgridException(err_msg=err_message) @@ -341,7 +374,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, def update_subnet(self, context, subnet_id, subnet): """Update subnet core Neutron API.""" - LOG.debug(_("update_subnet() called")) + LOG.debug("update_subnet() called") # Collecting subnet info orig_sub_db = self._get_subnet(context, subnet_id) @@ -353,7 +386,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, try: # PLUMgrid Server does not support updating resources yet - LOG.debug(_("PLUMgrid Library: update_network() called")) + LOG.debug("PLUMgrid Library: update_network() called") self._plumlib.update_subnet(orig_sub_db, new_sub_db, ipnet) except Exception as err_message: @@ -365,7 +398,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, """ Create router extension Neutron API """ - LOG.debug(_("Neutron PLUMgrid Director: create_router() called")) + LOG.debug("Neutron PLUMgrid Director: create_router() called") tenant_id = self._get_tenant_id_for_create(context, router["router"]) @@ -377,7 +410,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, # Create router on the network controller try: # Add Router to VND - LOG.debug(_("PLUMgrid Library: create_router() called")) + LOG.debug("PLUMgrid Library: create_router() called") self._plumlib.create_router(tenant_id, router_db) except Exception as err_message: raise plum_excep.PLUMgridException(err_msg=err_message) @@ -387,13 +420,13 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, def update_router(self, context, router_id, router): - LOG.debug(_("Neutron PLUMgrid Director: update_router() called")) + LOG.debug("Neutron PLUMgrid Director: update_router() called") with context.session.begin(subtransactions=True): router_db = super(NeutronPluginPLUMgridV2, self).update_router(context, router_id, router) try: - LOG.debug(_("PLUMgrid Library: update_router() called")) + LOG.debug("PLUMgrid Library: update_router() called") self._plumlib.update_router(router_db, router_id) except Exception as err_message: raise plum_excep.PLUMgridException(err_msg=err_message) @@ -402,7 +435,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, return router_db def delete_router(self, context, router_id): - LOG.debug(_("Neutron PLUMgrid Director: delete_router() called")) + LOG.debug("Neutron PLUMgrid Director: delete_router() called") with context.session.begin(subtransactions=True): orig_router = self._get_router(context, router_id) @@ -412,7 +445,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, router_id) try: - LOG.debug(_("PLUMgrid Library: delete_router() called")) + LOG.debug("PLUMgrid Library: delete_router() called") self._plumlib.delete_router(tenant_id, router_id) except Exception as err_message: @@ -420,8 +453,8 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, def add_router_interface(self, context, router_id, interface_info): - LOG.debug(_("Neutron PLUMgrid Director: " - "add_router_interface() called")) + LOG.debug("Neutron PLUMgrid Director: " + "add_router_interface() called") with context.session.begin(subtransactions=True): # Validate args router_db = self._get_router(context, router_id) @@ -440,7 +473,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, # Create interface on the network controller try: - LOG.debug(_("PLUMgrid Library: add_router_interface() called")) + LOG.debug("PLUMgrid Library: add_router_interface() called") self._plumlib.add_router_interface(tenant_id, router_id, port_db, ipnet) @@ -451,8 +484,8 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, def remove_router_interface(self, context, router_id, int_info): - LOG.debug(_("Neutron PLUMgrid Director: " - "remove_router_interface() called")) + LOG.debug("Neutron PLUMgrid Director: remove_router_interface()" + " called") with context.session.begin(subtransactions=True): # Validate args router_db = self._get_router(context, router_id) @@ -473,8 +506,8 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, int_info) try: - LOG.debug(_("PLUMgrid Library: " - "remove_router_interface() called")) + LOG.debug("PLUMgrid Library: " + "remove_router_interface() called") self._plumlib.remove_router_interface(tenant_id, net_id, router_id) @@ -484,14 +517,14 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, return del_int_router def create_floatingip(self, context, floatingip): - LOG.debug(_("Neutron PLUMgrid Director: create_floatingip() called")) + LOG.debug("Neutron PLUMgrid Director: create_floatingip() called") with context.session.begin(subtransactions=True): floating_ip = super(NeutronPluginPLUMgridV2, self).create_floatingip(context, floatingip) try: - LOG.debug(_("PLUMgrid Library: create_floatingip() called")) + LOG.debug("PLUMgrid Library: create_floatingip() called") self._plumlib.create_floatingip(floating_ip) except Exception as err_message: @@ -500,7 +533,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, return floating_ip def update_floatingip(self, context, id, floatingip): - LOG.debug(_("Neutron PLUMgrid Director: update_floatingip() called")) + LOG.debug("Neutron PLUMgrid Director: update_floatingip() called") with context.session.begin(subtransactions=True): floating_ip_orig = super(NeutronPluginPLUMgridV2, @@ -509,7 +542,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, self).update_floatingip(context, id, floatingip) try: - LOG.debug(_("PLUMgrid Library: update_floatingip() called")) + LOG.debug("PLUMgrid Library: update_floatingip() called") self._plumlib.update_floatingip(floating_ip_orig, floating_ip, id) @@ -519,7 +552,7 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, return floating_ip def delete_floatingip(self, context, id): - LOG.debug(_("Neutron PLUMgrid Director: delete_floatingip() called")) + LOG.debug("Neutron PLUMgrid Director: delete_floatingip() called") with context.session.begin(subtransactions=True): @@ -529,22 +562,22 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, super(NeutronPluginPLUMgridV2, self).delete_floatingip(context, id) try: - LOG.debug(_("PLUMgrid Library: delete_floatingip() called")) + LOG.debug("PLUMgrid Library: delete_floatingip() called") self._plumlib.delete_floatingip(floating_ip_orig, id) except Exception as err_message: raise plum_excep.PLUMgridException(err_msg=err_message) def disassociate_floatingips(self, context, port_id, do_notify=True): - LOG.debug(_("Neutron PLUMgrid Director: disassociate_floatingips() " - "called")) + LOG.debug("Neutron PLUMgrid Director: disassociate_floatingips() " + "called") try: fip_qry = context.session.query(l3_db.FloatingIP) floating_ip = fip_qry.filter_by(fixed_port_id=port_id).one() - LOG.debug(_("PLUMgrid Library: disassociate_floatingips()" - " called")) + LOG.debug("PLUMgrid Library: disassociate_floatingips()" + " called") self._plumlib.disassociate_floatingips(floating_ip, port_id) except sa_exc.NoResultFound: @@ -557,6 +590,166 @@ class NeutronPluginPLUMgridV2(db_base_plugin_v2.NeutronDbPluginV2, self).disassociate_floatingips( context, port_id, do_notify=do_notify) + def create_security_group(self, context, security_group, default_sg=False): + """Create a security group + + Create a new security group, including the default security group + """ + LOG.debug("Neutron PLUMgrid Director: create_security_group()" + " called") + + with context.session.begin(subtransactions=True): + + sg = security_group.get('security_group') + + tenant_id = self._get_tenant_id_for_create(context, sg) + if not default_sg: + self._ensure_default_security_group(context, tenant_id) + + sg_db = super(NeutronPluginPLUMgridV2, + self).create_security_group(context, security_group, + default_sg) + try: + LOG.debug("PLUMgrid Library: create_security_group()" + " called") + self._plumlib.create_security_group(sg_db) + + except Exception as err_message: + raise plum_excep.PLUMgridException(err_msg=err_message) + + return sg_db + + def update_security_group(self, context, sg_id, security_group): + """Update a security group + + Update security group name/description in Neutron and PLUMgrid + platform + """ + with context.session.begin(subtransactions=True): + sg_db = (super(NeutronPluginPLUMgridV2, + self).update_security_group(context, + sg_id, + security_group)) + if ('name' in security_group['security_group'] and + sg_db['name'] != 'default'): + try: + LOG.debug("PLUMgrid Library: update_security_group()" + " called") + self._plumlib.update_security_group(sg_db) + + except Exception as err_message: + raise plum_excep.PLUMgridException(err_msg=err_message) + return sg_db + + def delete_security_group(self, context, sg_id): + """Delete a security group + + Delete security group from Neutron and PLUMgrid Platform + + :param sg_id: security group ID of the rule to be removed + """ + with context.session.begin(subtransactions=True): + + sg = super(NeutronPluginPLUMgridV2, self).get_security_group( + context, sg_id) + if not sg: + raise sec_grp.SecurityGroupNotFound(id=sg_id) + + if sg['name'] == 'default' and not context.is_admin: + raise sec_grp.SecurityGroupCannotRemoveDefault() + + sec_grp_ip = sg['id'] + filters = {'security_group_id': [sec_grp_ip]} + if super(NeutronPluginPLUMgridV2, + self)._get_port_security_group_bindings(context, + filters): + raise sec_grp.SecurityGroupInUse(id=sec_grp_ip) + + sec_db = super(NeutronPluginPLUMgridV2, + self).delete_security_group(context, sg_id) + try: + LOG.debug("PLUMgrid Library: delete_security_group()" + " called") + self._plumlib.delete_security_group(sg) + + except Exception as err_message: + raise plum_excep.PLUMgridException(err_msg=err_message) + + return sec_db + + def create_security_group_rule(self, context, security_group_rule): + """Create a security group rule + + Create a security group rule in Neutron and PLUMgrid Platform + """ + LOG.debug("Neutron PLUMgrid Director: create_security_group_rule()" + " called") + bulk_rule = {'security_group_rules': [security_group_rule]} + return self.create_security_group_rule_bulk(context, bulk_rule)[0] + + def create_security_group_rule_bulk(self, context, security_group_rule): + """Create security group rules + + Create security group rules in Neutron and PLUMgrid Platform + + :param security_group_rule: list of rules to create + """ + sg_rules = security_group_rule.get('security_group_rules') + + with context.session.begin(subtransactions=True): + sg_id = super(NeutronPluginPLUMgridV2, + self)._validate_security_group_rules( + context, security_group_rule) + + # Check to make sure security group exists + security_group = super(NeutronPluginPLUMgridV2, + self).get_security_group(context, + sg_id) + + if not security_group: + raise sec_grp.SecurityGroupNotFound(id=sg_id) + + # Check for duplicate rules + self._check_for_duplicate_rules(context, sg_rules) + + sec_db = (super(NeutronPluginPLUMgridV2, + self).create_security_group_rule_bulk_native( + context, security_group_rule)) + try: + LOG.debug("PLUMgrid Library: create_security_" + "group_rule_bulk() called") + self._plumlib.create_security_group_rule_bulk(sec_db) + + except Exception as err_message: + raise plum_excep.PLUMgridException(err_msg=err_message) + + return sec_db + + def delete_security_group_rule(self, context, sgr_id): + """Delete a security group rule + + Delete a security group rule in Neutron and PLUMgrid Platform + """ + + LOG.debug("Neutron PLUMgrid Director: delete_security_group_rule()" + " called") + + sgr = (super(NeutronPluginPLUMgridV2, + self).get_security_group_rule(context, sgr_id)) + + if not sgr: + raise sec_grp.SecurityGroupRuleNotFound(id=sgr_id) + + super(NeutronPluginPLUMgridV2, + self).delete_security_group_rule(context, sgr_id) + try: + LOG.debug("PLUMgrid Library: delete_security_" + "group_rule() called") + self._plumlib.delete_security_group_rule(sgr) + + except Exception as err_message: + raise plum_excep.PLUMgridException(err_msg=err_message) + """ Internal PLUMgrid Fuctions """ diff --git a/neutron/tests/unit/plumgrid/extensions/__init__.py b/neutron/tests/unit/plumgrid/extensions/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/neutron/tests/unit/plumgrid/extensions/test_securitygroups.py b/neutron/tests/unit/plumgrid/extensions/test_securitygroups.py new file mode 100644 index 000000000..702549d6d --- /dev/null +++ b/neutron/tests/unit/plumgrid/extensions/test_securitygroups.py @@ -0,0 +1,67 @@ +# Copyright 2014 PLUMgrid, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +""" +PLUMgrid plugin security group extension unit tests +""" + +import mock + +from neutron.openstack.common import importutils +from neutron.plugins.plumgrid.plumgrid_plugin import plumgrid_plugin +from neutron.tests.unit import test_extension_security_group as ext_sg + + +PLUM_DRIVER = ('neutron.plugins.plumgrid.drivers.fake_plumlib.Plumlib') +FAKE_DIRECTOR = '1.1.1.1' +FAKE_PORT = '1234' +FAKE_USERNAME = 'fake_admin' +FAKE_PASSWORD = 'fake_password' +FAKE_TIMEOUT = '0' + + +class SecurityGroupsTestCase(ext_sg.SecurityGroupDBTestCase): + _plugin_name = ('neutron.plugins.plumgrid.plumgrid_plugin.' + 'plumgrid_plugin.NeutronPluginPLUMgridV2') + + def setUp(self): + def mocked_plumlib_init(self): + director_plumgrid = FAKE_DIRECTOR + director_port = FAKE_PORT + director_username = FAKE_USERNAME + director_password = FAKE_PASSWORD + timeout = FAKE_TIMEOUT + self._plumlib = importutils.import_object(PLUM_DRIVER) + self._plumlib.director_conn(director_plumgrid, + director_port, timeout, + director_username, + director_password) + + with mock.patch.object(plumgrid_plugin.NeutronPluginPLUMgridV2, + 'plumgrid_init', new=mocked_plumlib_init): + super(SecurityGroupsTestCase, self).setUp(self._plugin_name) + + def tearDown(self): + super(SecurityGroupsTestCase, self).tearDown() + + +class TestSecurityGroups(ext_sg.TestSecurityGroups, SecurityGroupsTestCase): + + pass + + +class TestSecurityGroupsXML(TestSecurityGroups): + + fmt = 'xml' diff --git a/neutron/tests/unit/plumgrid/test_plumgrid_plugin.py b/neutron/tests/unit/plumgrid/test_plumgrid_plugin.py index 83daf2d80..7a1a6a7a0 100644 --- a/neutron/tests/unit/plumgrid/test_plumgrid_plugin.py +++ b/neutron/tests/unit/plumgrid/test_plumgrid_plugin.py @@ -96,6 +96,7 @@ class TestPlumgridPluginSubnetsV2(test_plugin.TestSubnetsV2, class TestPlumgridPluginPortBinding(PLUMgridPluginV2TestCase, test_bindings.PortBindingsTestCase): VIF_TYPE = portbindings.VIF_TYPE_IOVISOR + HAS_PORT_FILTER = True def setUp(self): super(TestPlumgridPluginPortBinding, self).setUp() -- 2.45.2