Example #1
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_nova_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)
             six.reraise(*exc_info)
     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 #2
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)
        params = {}
        search_opts = search_opts if search_opts else {}
        if names:
            params['name'] = names
        if ids:
            params['id'] = ids

        # NOTE(jeffrey4l): list all the security groups when following
        # conditions are met
        #   * names and ids don't exist.
        #   * it is admin context and all_tenants exist in search_opts.
        #   * project is not specified.
        list_all_tenants = (context.is_admin
                            and 'all_tenants' in search_opts
                            and not any([names, ids]))
        # NOTE(jeffrey4l): The neutron doesn't have `all-tenants` concept.
        # All the security group will be returned if the project/tenant
        # id is not passed.
        if project and not list_all_tenants:
            params['tenant_id'] = project
        try:
            security_groups = neutron.list_security_groups(**params).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_nova_security_group_format(security_group))
        return converted_rules
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:"))
                six.reraise(*exc_info)
        converted_rules = []
        for rule in rules:
            converted_rules.append(
                self._convert_to_nova_security_group_rule_format(rule))
        return converted_rules
Example #4
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:"))
                six.reraise(*exc_info)
        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 compute 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 #5
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:"))
                six.reraise(*exc_info)
        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 #6
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_nova_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)
             six.reraise(*exc_info)
     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 #7
0
    def _get_instance_id_from_lb(self, provider_id, instance_address):
        # We use admin context, admin=True to lookup the
        # inter-Edge network port
        context = nova_context.get_admin_context()
        neutron = neutronapi.get_client(context, admin=True)

        # Tenant, instance ids are found in the following method:
        #  X-Metadata-Provider contains id of the metadata provider, and since
        #  overlapping networks cannot be connected to the same metadata
        #  provider, the combo of tenant's instance IP and the metadata
        #  provider has to be unique.
        #
        #  The networks which are connected to the metadata provider are
        #  retrieved in the 1st call to neutron.list_subnets()
        #  In the 2nd call we read the ports which belong to any of the
        #  networks retrieved above, and have the X-Forwarded-For IP address.
        #  This combination has to be unique as explained above, and we can
        #  read the instance_id, tenant_id from that port entry.

        # Retrieve networks which are connected to metadata provider
        md_subnets = neutron.list_subnets(
            context,
            advanced_service_providers=[provider_id],
            fields=['network_id'])

        md_networks = [
            subnet['network_id'] for subnet in md_subnets['subnets']
        ]

        try:
            # Retrieve the instance data from the instance's port
            instance_data = neutron.list_ports(
                context,
                fixed_ips='ip_address=' + instance_address,
                network_id=md_networks,
                fields=['device_id', 'tenant_id'])['ports'][0]
        except Exception as e:
            LOG.error(
                _LE('Failed to get instance id for metadata '
                    'request, provider %(provider)s '
                    'networks %(networks)s '
                    'requester %(requester)s. Error: %(error)s'), {
                        'provider': provider_id,
                        'networks': md_networks,
                        'requester': instance_address,
                        'error': e
                    })
            msg = _('An unknown error has occurred. '
                    'Please try your request again.')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        instance_id = instance_data['device_id']
        tenant_id = instance_data['tenant_id']

        # instance_data is unicode-encoded, while cache_utils doesn't like
        # that. Therefore we convert to str
        if isinstance(instance_id, six.text_type):
            instance_id = instance_id.encode('utf-8')
        return instance_id, tenant_id
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:"))
                six.reraise(*exc_info)
        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 _get_instance_id_from_lb(self, provider_id, instance_address):
        # We use admin context, admin=True to lookup the
        # inter-Edge network port
        context = nova_context.get_admin_context()
        neutron = neutronapi.get_client(context, admin=True)

        # Tenant, instance ids are found in the following method:
        #  X-Metadata-Provider contains id of the metadata provider, and since
        #  overlapping networks cannot be connected to the same metadata
        #  provider, the combo of tenant's instance IP and the metadata
        #  provider has to be unique.
        #
        #  The networks which are connected to the metadata provider are
        #  retrieved in the 1st call to neutron.list_subnets()
        #  In the 2nd call we read the ports which belong to any of the
        #  networks retrieved above, and have the X-Forwarded-For IP address.
        #  This combination has to be unique as explained above, and we can
        #  read the instance_id, tenant_id from that port entry.

        # Retrieve networks which are connected to metadata provider
        md_subnets = neutron.list_subnets(
            context,
            advanced_service_providers=[provider_id],
            fields=['network_id'])

        md_networks = [subnet['network_id']
                       for subnet in md_subnets['subnets']]

        try:
            # Retrieve the instance data from the instance's port
            instance_data = neutron.list_ports(
                context,
                fixed_ips='ip_address=' + instance_address,
                network_id=md_networks,
                fields=['device_id', 'tenant_id'])['ports'][0]
        except Exception as e:
            LOG.error(_LE('Failed to get instance id for metadata '
                          'request, provider %(provider)s '
                          'networks %(networks)s '
                          'requester %(requester)s. Error: %(error)s'),
                      {'provider': provider_id,
                       'networks': md_networks,
                       'requester': instance_address,
                       'error': e})
            msg = _('An unknown error has occurred. '
                    'Please try your request again.')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        instance_id = instance_data['device_id']
        tenant_id = instance_data['tenant_id']

        # instance_data is unicode-encoded, while cache_utils doesn't like
        # that. Therefore we convert to str
        if isinstance(instance_id, six.text_type):
            instance_id = instance_id.encode('utf-8')
        return instance_id, tenant_id
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)
             six.reraise(*exc_info)
     return self._convert_to_nova_security_group_rule_format(rule)
Example #11
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 #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 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)
             six.reraise(*exc_info)
     return self._convert_to_nova_security_group_rule_format(rule)
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)
                six.reraise(*exc_info)
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)
                six.reraise(*exc_info)
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()
         six.reraise(*exc_info)
     return self._convert_to_nova_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()
         six.reraise(*exc_info)
     return self._convert_to_nova_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)
        params = {}
        search_opts = search_opts if search_opts else {}
        if names:
            params['name'] = names
        if ids:
            params['id'] = ids

        # NOTE(jeffrey4l): list all the security groups when following
        # conditions are met
        #   * names and ids don't exist.
        #   * it is admin context and all_tenants exist in search_opts.
        #   * project is not specified.
        list_all_tenants = (context.is_admin and 'all_tenants' in search_opts
                            and not any([names, ids]))
        # NOTE(jeffrey4l): The neutron doesn't have `all-tenants` concept.
        # All the security group will be returned if the project/tenant
        # id is not passed.
        if project and not list_all_tenants:
            params['tenant_id'] = project
        try:
            security_groups = neutron.list_security_groups(
                **params).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_nova_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_nova_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_nova_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:"))
                six.reraise(*exc_info)
        converted_rules = []
        for rule in rules:
            converted_rules.append(
                self._convert_to_nova_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:"))
                six.reraise(*exc_info)
        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 compute 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)