Example #1
0
 def setUp(self):
     super(TestNeutronDriver, self).setUp()
     self.mox.StubOutWithMock(neutronapi, 'get_client')
     self.moxed_client = self.mox.CreateMock(client.Client)
     neutronapi.get_client(mox.IgnoreArg()).MultipleTimes().AndReturn(
         self.moxed_client)
     self.context = context.RequestContext('userid', 'my_tenantid')
     setattr(self.context, 'auth_token', 'bff4a5a6b9eb4ea2a6efec6eefb77936')
Example #2
0
 def setUp(self):
     super(TestNeutronDriver, self).setUp()
     self.mox.StubOutWithMock(neutronapi, 'get_client')
     self.moxed_client = self.mox.CreateMock(client.Client)
     neutronapi.get_client(mox.IgnoreArg()).MultipleTimes().AndReturn(
         self.moxed_client)
     self.context = context.RequestContext('userid', 'my_tenantid')
     setattr(self.context,
             'auth_token',
             'bff4a5a6b9eb4ea2a6efec6eefb77936')
Example #3
0
    def add_rules(self, context, id, name, vals):
        """Add security group rule(s) to security group.

        Note: the Nova security group API doesn't support adding multiple
        security group rules at once but the EC2 one does. Therefore,
        this function is written to support both. Multiple rules are
        installed to a security group in neutron using bulk support.
        """

        neutron = neutronapi.get_client(context)
        body = self._make_neutron_security_group_rules_list(vals)
        try:
            rules = neutron.create_security_group_rule(
                body).get('security_group_rules')
        except n_exc.NeutronClientException as e:
            exc_info = sys.exc_info()
            if e.status_code == 404:
                LOG.exception(_LE("Neutron Error getting security group %s"),
                              name)
                self.raise_not_found(six.text_type(e))
            elif e.status_code == 409:
                LOG.exception(_LE("Neutron Error adding rules to security "
                                  "group %s"), name)
                self.raise_over_quota(six.text_type(e))
            elif e.status_code == 400:
                LOG.exception(_LE("Neutron Error: %s"), six.text_type(e))
                self.raise_invalid_property(six.text_type(e))
            else:
                LOG.exception(_LE("Neutron Error:"))
                raise exc_info[0], exc_info[1], exc_info[2]
        converted_rules = []
        for rule in rules:
            converted_rules.append(
                self._convert_to_patron_security_group_rule_format(rule))
        return converted_rules
Example #4
0
 def list(self,
          context,
          names=None,
          ids=None,
          project=None,
          search_opts=None):
     """Returns list of security group rules owned by tenant."""
     neutron = neutronapi.get_client(context)
     search_opts = {}
     if names:
         search_opts['name'] = names
     if ids:
         search_opts['id'] = ids
     if project:
         search_opts['tenant_id'] = project
     try:
         security_groups = neutron.list_security_groups(
             **search_opts).get('security_groups')
     except n_exc.NeutronClientException:
         with excutils.save_and_reraise_exception():
             LOG.exception(_LE("Neutron Error getting security groups"))
     converted_rules = []
     for security_group in security_groups:
         converted_rules.append(
             self._convert_to_patron_security_group_format(security_group))
     return converted_rules
Example #5
0
 def get(self, context, name=None, id=None, map_exception=False):
     neutron = neutronapi.get_client(context)
     try:
         if not id and name:
             # NOTE(flwang): The project id should be honoured so as to get
             # the correct security group id when user(with admin role but
             # non-admin project) try to query by name, so as to avoid
             # getting more than duplicated records with the same name.
             id = neutronv20.find_resourceid_by_name_or_id(
                 neutron, 'security_group', name, context.project_id)
         group = neutron.show_security_group(id).get('security_group')
         return self._convert_to_patron_security_group_format(group)
     except n_exc.NeutronClientNoUniqueMatch as e:
         raise exception.NoUniqueMatch(six.text_type(e))
     except n_exc.NeutronClientException as e:
         exc_info = sys.exc_info()
         if e.status_code == 404:
             LOG.debug("Neutron security group %s not found", name)
             raise exception.SecurityGroupNotFound(six.text_type(e))
         else:
             LOG.error(_LE("Neutron Error: %s"), e)
             raise exc_info[0], exc_info[1], exc_info[2]
     except TypeError as e:
         LOG.error(_LE("Neutron Error: %s"), e)
         msg = _("Invalid security group name: %(name)s.") % {"name": name}
         raise exception.SecurityGroupNotFound(six.text_type(msg))
Example #6
0
    def remove_from_instance(self, context, instance, security_group_name):
        """Remove the security group associated with the instance."""
        neutron = neutronapi.get_client(context)
        try:
            security_group_id = neutronv20.find_resourceid_by_name_or_id(
                neutron, 'security_group',
                security_group_name,
                context.project_id)
        except n_exc.NeutronClientException as e:
            exc_info = sys.exc_info()
            if e.status_code == 404:
                msg = (_("Security group %(name)s is not found for "
                         "project %(project)s") %
                       {'name': security_group_name,
                        'project': context.project_id})
                self.raise_not_found(msg)
            else:
                LOG.exception(_LE("Neutron Error:"))
                raise exc_info[0], exc_info[1], exc_info[2]
        params = {'device_id': instance.uuid}
        try:
            ports = neutron.list_ports(**params).get('ports')
        except n_exc.NeutronClientException:
            with excutils.save_and_reraise_exception():
                LOG.exception(_LE("Neutron Error:"))

        if not ports:
            msg = (_("instance_id %s could not be found as device id on"
                   " any ports") % instance.uuid)
            self.raise_not_found(msg)

        found_security_group = False
        for port in ports:
            try:
                port.get('security_groups', []).remove(security_group_id)
            except ValueError:
                # When removing a security group from an instance the security
                # group should be on both ports since it was added this way if
                # done through the patron api. In case it is not a 404 is only
                # raised if the security group is not found on any of the
                # ports on the instance.
                continue

            updated_port = {'security_groups': port['security_groups']}
            try:
                LOG.info(_LI("Adding security group %(security_group_id)s to "
                             "port %(port_id)s"),
                         {'security_group_id': security_group_id,
                          'port_id': port['id']})
                neutron.update_port(port['id'], {'port': updated_port})
                found_security_group = True
            except Exception:
                with excutils.save_and_reraise_exception():
                    LOG.exception(_LE("Neutron Error:"))
        if not found_security_group:
            msg = (_("Security group %(security_group_name)s not associated "
                     "with the instance %(instance)s") %
                   {'security_group_name': security_group_name,
                    'instance': instance.uuid})
            self.raise_not_found(msg)
Example #7
0
 def get(self, context, name=None, id=None, map_exception=False):
     neutron = neutronapi.get_client(context)
     try:
         if not id and name:
             # NOTE(flwang): The project id should be honoured so as to get
             # the correct security group id when user(with admin role but
             # non-admin project) try to query by name, so as to avoid
             # getting more than duplicated records with the same name.
             id = neutronv20.find_resourceid_by_name_or_id(
                 neutron, 'security_group', name, context.project_id)
         group = neutron.show_security_group(id).get('security_group')
         return self._convert_to_patron_security_group_format(group)
     except n_exc.NeutronClientNoUniqueMatch as e:
         raise exception.NoUniqueMatch(six.text_type(e))
     except n_exc.NeutronClientException as e:
         exc_info = sys.exc_info()
         if e.status_code == 404:
             LOG.debug("Neutron security group %s not found", name)
             raise exception.SecurityGroupNotFound(six.text_type(e))
         else:
             LOG.error(_LE("Neutron Error: %s"), e)
             raise exc_info[0], exc_info[1], exc_info[2]
     except TypeError as e:
         LOG.error(_LE("Neutron Error: %s"), e)
         msg = _("Invalid security group name: %(name)s.") % {"name": name}
         raise exception.SecurityGroupNotFound(six.text_type(msg))
Example #8
0
    def add_to_instance(self, context, instance, security_group_name):
        """Add security group to the instance."""

        neutron = neutronapi.get_client(context)
        try:
            security_group_id = neutronv20.find_resourceid_by_name_or_id(
                neutron, 'security_group', security_group_name,
                context.project_id)
        except n_exc.NeutronClientNoUniqueMatch as e:
            raise exception.NoUniqueMatch(six.text_type(e))
        except n_exc.NeutronClientException as e:
            exc_info = sys.exc_info()
            if e.status_code == 404:
                msg = (_("Security group %(name)s is not found for "
                         "project %(project)s") % {
                             'name': security_group_name,
                             'project': context.project_id
                         })
                self.raise_not_found(msg)
            else:
                LOG.exception(_LE("Neutron Error:"))
                raise exc_info[0], exc_info[1], exc_info[2]
        params = {'device_id': instance.uuid}
        try:
            ports = neutron.list_ports(**params).get('ports')
        except n_exc.NeutronClientException:
            with excutils.save_and_reraise_exception():
                LOG.exception(_LE("Neutron Error:"))

        if not ports:
            msg = (_("instance_id %s could not be found as device id on"
                     " any ports") % instance.uuid)
            self.raise_not_found(msg)

        for port in ports:
            if not self._has_security_group_requirements(port):
                LOG.warning(
                    _LW("Cannot add security group %(name)s to "
                        "%(instance)s since the port %(port_id)s "
                        "does not meet security requirements"), {
                            'name': security_group_name,
                            'instance': instance.uuid,
                            'port_id': port['id']
                        })
                raise exception.SecurityGroupCannotBeApplied()
            if 'security_groups' not in port:
                port['security_groups'] = []
            port['security_groups'].append(security_group_id)
            updated_port = {'security_groups': port['security_groups']}
            try:
                LOG.info(
                    _LI("Adding security group %(security_group_id)s to "
                        "port %(port_id)s"), {
                            'security_group_id': security_group_id,
                            'port_id': port['id']
                        })
                neutron.update_port(port['id'], {'port': updated_port})
            except Exception:
                with excutils.save_and_reraise_exception():
                    LOG.exception(_LE("Neutron Error:"))
Example #9
0
    def add_to_instance(self, context, instance, security_group_name):
        """Add security group to the instance."""

        neutron = neutronapi.get_client(context)
        try:
            security_group_id = neutronv20.find_resourceid_by_name_or_id(
                neutron, 'security_group',
                security_group_name,
                context.project_id)
        except n_exc.NeutronClientNoUniqueMatch as e:
            raise exception.NoUniqueMatch(six.text_type(e))
        except n_exc.NeutronClientException as e:
            exc_info = sys.exc_info()
            if e.status_code == 404:
                msg = (_("Security group %(name)s is not found for "
                         "project %(project)s") %
                       {'name': security_group_name,
                        'project': context.project_id})
                self.raise_not_found(msg)
            else:
                LOG.exception(_LE("Neutron Error:"))
                raise exc_info[0], exc_info[1], exc_info[2]
        params = {'device_id': instance.uuid}
        try:
            ports = neutron.list_ports(**params).get('ports')
        except n_exc.NeutronClientException:
            with excutils.save_and_reraise_exception():
                LOG.exception(_LE("Neutron Error:"))

        if not ports:
            msg = (_("instance_id %s could not be found as device id on"
                   " any ports") % instance.uuid)
            self.raise_not_found(msg)

        for port in ports:
            if not self._has_security_group_requirements(port):
                LOG.warning(_LW("Cannot add security group %(name)s to "
                                "%(instance)s since the port %(port_id)s "
                                "does not meet security requirements"),
                            {'name': security_group_name,
                             'instance': instance.uuid,
                             'port_id': port['id']})
                raise exception.SecurityGroupCannotBeApplied()
            if 'security_groups' not in port:
                port['security_groups'] = []
            port['security_groups'].append(security_group_id)
            updated_port = {'security_groups': port['security_groups']}
            try:
                LOG.info(_LI("Adding security group %(security_group_id)s to "
                             "port %(port_id)s"),
                         {'security_group_id': security_group_id,
                          'port_id': port['id']})
                neutron.update_port(port['id'], {'port': updated_port})
            except Exception:
                with excutils.save_and_reraise_exception():
                    LOG.exception(_LE("Neutron Error:"))
Example #10
0
 def get_rule(self, context, id):
     neutron = neutronapi.get_client(context)
     try:
         rule = neutron.show_security_group_rule(
             id).get('security_group_rule')
     except n_exc.NeutronClientException as e:
         exc_info = sys.exc_info()
         if e.status_code == 404:
             LOG.debug("Neutron security group rule %s not found", id)
             self.raise_not_found(six.text_type(e))
         else:
             LOG.error(_LE("Neutron Error: %s"), e)
             raise exc_info[0], exc_info[1], exc_info[2]
     return self._convert_to_patron_security_group_rule_format(rule)
Example #11
0
 def get_rule(self, context, id):
     neutron = neutronapi.get_client(context)
     try:
         rule = neutron.show_security_group_rule(id).get(
             'security_group_rule')
     except n_exc.NeutronClientException as e:
         exc_info = sys.exc_info()
         if e.status_code == 404:
             LOG.debug("Neutron security group rule %s not found", id)
             self.raise_not_found(six.text_type(e))
         else:
             LOG.error(_LE("Neutron Error: %s"), e)
             raise exc_info[0], exc_info[1], exc_info[2]
     return self._convert_to_patron_security_group_rule_format(rule)
Example #12
0
 def remove_rules(self, context, security_group, rule_ids):
     neutron = neutronapi.get_client(context)
     rule_ids = set(rule_ids)
     try:
         # The ec2 api allows one to delete multiple security group rules
         # at once. Since there is no bulk delete for neutron the best
         # thing we can do is delete the rules one by one and hope this
         # works.... :/
         for rule_id in range(0, len(rule_ids)):
             neutron.delete_security_group_rule(rule_ids.pop())
     except n_exc.NeutronClientException:
         with excutils.save_and_reraise_exception():
             LOG.exception(_LE("Neutron Error unable to delete %s"),
                           rule_ids)
Example #13
0
 def remove_rules(self, context, security_group, rule_ids):
     neutron = neutronapi.get_client(context)
     rule_ids = set(rule_ids)
     try:
         # The ec2 api allows one to delete multiple security group rules
         # at once. Since there is no bulk delete for neutron the best
         # thing we can do is delete the rules one by one and hope this
         # works.... :/
         for rule_id in range(0, len(rule_ids)):
             neutron.delete_security_group_rule(rule_ids.pop())
     except n_exc.NeutronClientException:
         with excutils.save_and_reraise_exception():
             LOG.exception(_LE("Neutron Error unable to delete %s"),
                           rule_ids)
Example #14
0
    def destroy(self, context, security_group):
        """This function deletes a security group."""

        neutron = neutronapi.get_client(context)
        try:
            neutron.delete_security_group(security_group['id'])
        except n_exc.NeutronClientException as e:
            exc_info = sys.exc_info()
            if e.status_code == 404:
                self.raise_not_found(six.text_type(e))
            elif e.status_code == 409:
                self.raise_invalid_property(six.text_type(e))
            else:
                LOG.error(_LE("Neutron Error: %s"), e)
                raise exc_info[0], exc_info[1], exc_info[2]
Example #15
0
    def destroy(self, context, security_group):
        """This function deletes a security group."""

        neutron = neutronapi.get_client(context)
        try:
            neutron.delete_security_group(security_group['id'])
        except n_exc.NeutronClientException as e:
            exc_info = sys.exc_info()
            if e.status_code == 404:
                self.raise_not_found(six.text_type(e))
            elif e.status_code == 409:
                self.raise_invalid_property(six.text_type(e))
            else:
                LOG.error(_LE("Neutron Error: %s"), e)
                raise exc_info[0], exc_info[1], exc_info[2]
Example #16
0
 def update_security_group(self, context, security_group, name,
                           description):
     neutron = neutronapi.get_client(context)
     body = self._make_neutron_security_group_dict(name, description)
     try:
         security_group = neutron.update_security_group(
             security_group['id'], body).get('security_group')
     except n_exc.NeutronClientException as e:
         exc_info = sys.exc_info()
         LOG.exception(_LE("Neutron Error updating security group %s"),
                       name)
         if e.status_code == 401:
             # TODO(arosen) Cannot raise generic response from neutron here
             # as this error code could be related to bad input or over
             # quota
             raise exc.HTTPBadRequest()
         raise exc_info[0], exc_info[1], exc_info[2]
     return self._convert_to_patron_security_group_format(security_group)
Example #17
0
 def update_security_group(self, context, security_group,
                           name, description):
     neutron = neutronapi.get_client(context)
     body = self._make_neutron_security_group_dict(name, description)
     try:
         security_group = neutron.update_security_group(
             security_group['id'], body).get('security_group')
     except n_exc.NeutronClientException as e:
         exc_info = sys.exc_info()
         LOG.exception(_LE("Neutron Error updating security group %s"),
                       name)
         if e.status_code == 401:
             # TODO(arosen) Cannot raise generic response from neutron here
             # as this error code could be related to bad input or over
             # quota
             raise exc.HTTPBadRequest()
         raise exc_info[0], exc_info[1], exc_info[2]
     return self._convert_to_patron_security_group_format(security_group)
Example #18
0
 def list(self, context, names=None, ids=None, project=None,
          search_opts=None):
     """Returns list of security group rules owned by tenant."""
     neutron = neutronapi.get_client(context)
     search_opts = {}
     if names:
         search_opts['name'] = names
     if ids:
         search_opts['id'] = ids
     if project:
         search_opts['tenant_id'] = project
     try:
         security_groups = neutron.list_security_groups(**search_opts).get(
             'security_groups')
     except n_exc.NeutronClientException:
         with excutils.save_and_reraise_exception():
             LOG.exception(_LE("Neutron Error getting security groups"))
     converted_rules = []
     for security_group in security_groups:
         converted_rules.append(
             self._convert_to_patron_security_group_format(security_group))
     return converted_rules
Example #19
0
    def get_instances_security_groups_bindings(self,
                                               context,
                                               servers,
                                               detailed=False):
        """Returns a dict(instance_id, [security_groups]) to allow obtaining
        all of the instances and their security groups in one shot.
        """

        neutron = neutronapi.get_client(context)

        ports = self._get_ports_from_server_list(servers, neutron)

        security_groups = self._get_secgroups_from_port_list(ports, neutron)

        instances_security_group_bindings = {}
        for port in ports:
            for port_sg_id in port.get('security_groups', []):

                # Note:  have to check we found port_sg as its possible
                # the port has an SG that this user doesn't have access to
                port_sg = security_groups.get(port_sg_id)
                if port_sg:
                    if detailed:
                        sg_entry = self._convert_to_patron_security_group_format(
                            port_sg)
                        instances_security_group_bindings.setdefault(
                            port['device_id'], []).append(sg_entry)
                    else:
                        # name is optional in neutron so if not specified
                        # return id
                        name = port_sg.get('name')
                        if not name:
                            name = port_sg.get('id')
                        sg_entry = {'name': name}
                        instances_security_group_bindings.setdefault(
                            port['device_id'], []).append(sg_entry)

        return instances_security_group_bindings
Example #20
0
    def get_instances_security_groups_bindings(self, context, servers,
                                               detailed=False):
        """Returns a dict(instance_id, [security_groups]) to allow obtaining
        all of the instances and their security groups in one shot.
        """

        neutron = neutronapi.get_client(context)

        ports = self._get_ports_from_server_list(servers, neutron)

        security_groups = self._get_secgroups_from_port_list(ports, neutron)

        instances_security_group_bindings = {}
        for port in ports:
            for port_sg_id in port.get('security_groups', []):

                # Note:  have to check we found port_sg as its possible
                # the port has an SG that this user doesn't have access to
                port_sg = security_groups.get(port_sg_id)
                if port_sg:
                    if detailed:
                        sg_entry = self._convert_to_patron_security_group_format(
                                 port_sg)
                        instances_security_group_bindings.setdefault(
                            port['device_id'], []).append(sg_entry)
                    else:
                        # name is optional in neutron so if not specified
                        # return id
                        name = port_sg.get('name')
                        if not name:
                            name = port_sg.get('id')
                        sg_entry = {'name': name}
                        instances_security_group_bindings.setdefault(
                            port['device_id'], []).append(sg_entry)

        return instances_security_group_bindings
Example #21
0
    def add_rules(self, context, id, name, vals):
        """Add security group rule(s) to security group.

        Note: the Nova security group API doesn't support adding multiple
        security group rules at once but the EC2 one does. Therefore,
        this function is written to support both. Multiple rules are
        installed to a security group in neutron using bulk support.
        """

        neutron = neutronapi.get_client(context)
        body = self._make_neutron_security_group_rules_list(vals)
        try:
            rules = neutron.create_security_group_rule(body).get(
                'security_group_rules')
        except n_exc.NeutronClientException as e:
            exc_info = sys.exc_info()
            if e.status_code == 404:
                LOG.exception(_LE("Neutron Error getting security group %s"),
                              name)
                self.raise_not_found(six.text_type(e))
            elif e.status_code == 409:
                LOG.exception(
                    _LE("Neutron Error adding rules to security "
                        "group %s"), name)
                self.raise_over_quota(six.text_type(e))
            elif e.status_code == 400:
                LOG.exception(_LE("Neutron Error: %s"), six.text_type(e))
                self.raise_invalid_property(six.text_type(e))
            else:
                LOG.exception(_LE("Neutron Error:"))
                raise exc_info[0], exc_info[1], exc_info[2]
        converted_rules = []
        for rule in rules:
            converted_rules.append(
                self._convert_to_patron_security_group_rule_format(rule))
        return converted_rules
Example #22
0
    def remove_from_instance(self, context, instance, security_group_name):
        """Remove the security group associated with the instance."""
        neutron = neutronapi.get_client(context)
        try:
            security_group_id = neutronv20.find_resourceid_by_name_or_id(
                neutron, 'security_group', security_group_name,
                context.project_id)
        except n_exc.NeutronClientException as e:
            exc_info = sys.exc_info()
            if e.status_code == 404:
                msg = (_("Security group %(name)s is not found for "
                         "project %(project)s") % {
                             'name': security_group_name,
                             'project': context.project_id
                         })
                self.raise_not_found(msg)
            else:
                LOG.exception(_LE("Neutron Error:"))
                raise exc_info[0], exc_info[1], exc_info[2]
        params = {'device_id': instance.uuid}
        try:
            ports = neutron.list_ports(**params).get('ports')
        except n_exc.NeutronClientException:
            with excutils.save_and_reraise_exception():
                LOG.exception(_LE("Neutron Error:"))

        if not ports:
            msg = (_("instance_id %s could not be found as device id on"
                     " any ports") % instance.uuid)
            self.raise_not_found(msg)

        found_security_group = False
        for port in ports:
            try:
                port.get('security_groups', []).remove(security_group_id)
            except ValueError:
                # When removing a security group from an instance the security
                # group should be on both ports since it was added this way if
                # done through the patron api. In case it is not a 404 is only
                # raised if the security group is not found on any of the
                # ports on the instance.
                continue

            updated_port = {'security_groups': port['security_groups']}
            try:
                LOG.info(
                    _LI("Adding security group %(security_group_id)s to "
                        "port %(port_id)s"), {
                            'security_group_id': security_group_id,
                            'port_id': port['id']
                        })
                neutron.update_port(port['id'], {'port': updated_port})
                found_security_group = True
            except Exception:
                with excutils.save_and_reraise_exception():
                    LOG.exception(_LE("Neutron Error:"))
        if not found_security_group:
            msg = (_("Security group %(security_group_name)s not associated "
                     "with the instance %(instance)s") % {
                         'security_group_name': security_group_name,
                         'instance': instance.uuid
                     })
            self.raise_not_found(msg)