Exemple #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")
Exemple #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')
    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("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
 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("Neutron Error: %s", e)
             six.reraise(*exc_info)
     except TypeError as e:
         LOG.error("Neutron Error: %s", e)
         msg = _("Invalid security group name: %(name)s.") % {"name": name}
         raise exception.SecurityGroupNotFound(six.text_type(msg))
    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 nova 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)
 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)
             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))
    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
    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_nova_security_group_rule_format(rule))
        return converted_rules
    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 nova 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)
Exemple #10
0
 def test_list_ports_with_resource_request_admin_client(self):
     ctxt = context.get_admin_context()
     client = neutron_api.get_client(ctxt)
     ports = client.list_ports(ctxt)['ports']
     port_id = self.neutron.port_with_resource_request['id']
     ports = [port for port in ports if port_id == port['id']]
     self.assertIsNotNone(ports[0]['resource_request'])
    def get_vifs_for_instance(self, context, **kwargs):
        """Return the list of VIF for an instance."""
        instance_id = kwargs['instance_id']
        LOG.debug('get_vifs_for_instance %s' % instance_id)
        instance = objects.Instance.get_by_uuid(
            nova_context.get_admin_context(), instance_id)
        hyper_net_info = compute_utils.get_nw_info_for_instance(instance)

        neutron = neutronapi.get_client(context, admin=True)
        check_host_exist(neutron, instance_id)
        tenant_ids = []
        LOG.debug('hyper_net_info: %s' % hyper_net_info)
        for vif in hyper_net_info:
            tenant_ids.append(vif['network']['meta']['tenant_id'])
            neutron.update_port(vif['id'],
                                {'port': {'binding:host_id': instance_id}})
        # get all the tenant router
        LOG.debug('tenant_ids: %s' % tenant_ids)
        for tenant_id in tenant_ids:
            routers = neutron.list_routers({'tenant_id': tenant_id})['routers']
            LOG.debug('routers: %s' % routers)
            for router in routers:
                neutron.update_router(router['id'],
                                      {'router': {'admin_state_up': 'False'}})
                neutron.update_router(router['id'],
                                      {'router': {'admin_state_up': 'True'}})

        return hyper_net_info
 def get_vif_for_provider_ip(self, context, **kwargs):
     """Return the VIF for a VM."""
     provider_ip = kwargs['provider_ip']
     LOG.debug("provider ip = % s" % provider_ip)
     # retrieve the instance id from the provider ip
     # from the nova metadata
     filters = {
         'filter': [{'name': 'tag:provider_ip', 'value': provider_ip}]
     }
     instances = objects.InstanceList.get_by_filters(
         context, filters=filters)
     # should return only one and check it
     if len(instances) == 1:
         instance = instances[0]
         vif_id = instance.metadata['ip_%s' % provider_ip]
         hyper_net_info = compute_utils.get_nw_info_for_instance(instance)
         hyper_vif = None
         for vif in hyper_net_info:
             if vif.get('id') == vif_id:
                 hyper_vif = vif
                 break
         neutron = neutronapi.get_client(context, admin=True)
         check_host_exist(neutron, instance.uuid)
         neutron.update_port(hyper_vif,
                             {'port': {'binding:host_id': instance.uuid}})
         return {'instance_id': instance.uuid, 'hyper_vif': hyper_vif}
     else:
         return None
Exemple #13
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_nova_security_group_format(security_group))
     return converted_rules
Exemple #14
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:"))
    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("Neutron Error getting security group %s", name)
                self.raise_not_found(six.text_type(e))
            elif e.status_code == 409:
                LOG.exception("Neutron Error adding rules to security "
                              "group %s", name)
                self.raise_over_quota(six.text_type(e))
            elif e.status_code == 400:
                LOG.exception("Neutron Error: %s", e)
                self.raise_invalid_property(six.text_type(e))
            else:
                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
Exemple #16
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 memorycache 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
 def destroy(self, context, instance, network_info, block_device_info=None,
             destroy_disks=True, migrate_data=None):
     LOG.debug("destroy")
     neutron = neutronapi.get_client(context, admin=True)
     agt_list = neutron.list_agents(host=instance.uuid)
     LOG.debug("for host %s: %s" % (instance.uuid, agt_list))
     for agent in agt_list['agents']:
         neutron.delete_agent(agent=agent['id'])
Exemple #18
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:"))
Exemple #19
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
Exemple #20
0
 def get_subnet_by_id(self, context, subnet_id):
     search_pots = {'id': subnet_id}
     data = neutron_api.get_client(context).list_subnets(**search_pots)
     ipam_subnets = data.get('subnets', [])
     result = None
     for subnet in ipam_subnets:
         if subnet_id == subnet['id']:
             result = subnet
             break
     return result
Exemple #21
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("Neutron Error unable to delete %s", rule_ids)
 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("Neutron Error unable to delete %s", rule_ids)
Exemple #23
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_nova_security_group_rule_format(rule)
Exemple #24
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_nova_security_group_rule_format(rule)
Exemple #25
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]
Exemple #26
0
    def _get_network_from_neutron(self, context, network_info):
        """send message to neutron server to get network information

        :param context:
        :param network_info:
        :return:
        """
        client = neutron_api.get_client(context)
        try:
            network = client.show_network(
                network_info['id']).get('network') or {}
        except neutron_client_exc.NetworkNotFoundClient:
            raise exception.NetworkNotFound(network_id=network_info['id'])
        network['label'] = network['name']
        return network
Exemple #27
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]
 def _plug_vifs(self, node, instance, network_info):
     LOG.debug('Plug VIFs called for instance', instance=instance)
     node_uuid = instance.get('node')
     client = neutron.get_client(None, admin=True)
     for vif in network_info:
         network = client.show_network(vif['network']['id'])
         net_info = {
             'vlan': network['network']['provider:segmentation_id'],
             'mac': vif['address'],
             'uuid': vif['id'],
             'pxe': False
         }
         self.ironicclient.call("node.vendor_passthru", node_uuid,
                                "add_vnic", args=net_info)
     LOG.debug('Plug VIFs successful for instance', instance=instance)
Exemple #29
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.
        If detailed is False only the security group name is returned.
        """

        neutron = neutronapi.get_client(context)

        ports = self._get_ports_from_server_list(servers, neutron)

        # If detailed is True, we want all fields from the security groups
        # including the potentially slow-to-join security_group_rules field.
        # But if detailed is False, only get the id and name fields since
        # that's all we'll use below.
        fields = None if detailed else ['id', 'name']
        security_groups = self._get_secgroups_from_port_list(ports,
                                                             neutron,
                                                             fields=fields)

        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
 def plug_vifs(self,
               context,
               instance,
               network_info,
               provider_mgnt_ip,
               provider_data_ip):
     LOG.debug("plug_vifs")
     neutron = neutronapi.get_client(context, admin=True)
     for vif in network_info:
         neutron.update_port(vif['id'],
                             {'port': {
                                 'binding:host_id': instance.uuid,
                                 'binding:profile': {
                                     'provider_mgnt_ip': provider_mgnt_ip,
                                     'provider_data_ip': provider_data_ip,
                                 }
                             }})
 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("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)
Exemple #32
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("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)
Exemple #33
0
    def show(self, req, id):
        context = req.environ['nova.context']
        context.can(wrs_providernet_policies.BASE_POLICY_NAME)

        neutron = neutronapi.get_client(context)
        try:
            providernet = neutron.show_providernet(id).get('providernet', {})
        except n_exc.NeutronClientException:
            LOG.exception("Neutron Error getting provider network %s", id)
            msg = _("Error getting provider network")
            raise exc.HTTPNotFound(explanation=msg)

        physnet = providernet.get('name')
        pci_pfs_configured = 0
        pci_pfs_count = 0
        pci_vfs_configured = 0
        pci_vfs_count = 0
        nodes = objects.ComputeNodeList.get_all(context)
        for node in nodes:
            if node.pci_device_pools and node.pci_device_pools.objects:
                for pool in node.pci_device_pools.objects:
                    tags = pool.tags
                    if physnet in tags.get('physical_network', {}):
                        dev_type = tags.get('dev_type', {})
                        configured = int(tags.get('configured', '0'))

                        if 'type-PF' in dev_type:
                            pci_pfs_configured += configured
                            pci_pfs_count += pool.count

                        if 'type-VF' in dev_type:
                            pci_vfs_configured += configured
                            pci_vfs_count += pool.count

        return {
            'providernet': {
                'id': id,
                'name': physnet,
                'pci_pfs_configured': pci_pfs_configured,
                'pci_pfs_used': pci_pfs_configured - pci_pfs_count,
                'pci_vfs_configured': pci_vfs_configured,
                'pci_vfs_used': pci_vfs_configured - pci_vfs_count
            }
        }
Exemple #34
0
 def create_security_group(self, context, name, description):
     neutron = neutronapi.get_client(context)
     body = self._make_neutron_security_group_dict(name, description)
     try:
         security_group = neutron.create_security_group(body).get(
             'security_group')
     except n_exc.NeutronClientException as e:
         exc_info = sys.exc_info()
         LOG.exception(_LE("Neutron Error creating 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()
         elif e.status_code == 409:
             self.raise_over_quota(six.text_type(e))
         raise exc_info[0], exc_info[1], exc_info[2]
     return self._convert_to_nova_security_group_format(security_group)
Exemple #35
0
 def create_security_group(self, context, name, description):
     neutron = neutronapi.get_client(context)
     body = self._make_neutron_security_group_dict(name, description)
     try:
         security_group = neutron.create_security_group(
             body).get('security_group')
     except n_exc.NeutronClientException as e:
         exc_info = sys.exc_info()
         LOG.exception(_LE("Neutron Error creating 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()
         elif e.status_code == 409:
             self.raise_over_quota(six.text_type(e))
         raise exc_info[0], exc_info[1], exc_info[2]
     return self._convert_to_nova_security_group_format(security_group)
Exemple #36
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_nova_security_group_format(security_group))
     return converted_rules
Exemple #37
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
Exemple #38
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
Exemple #39
0
    def buildup_nova_neutron_connection(self):

        self.context = get_admin_context()
        self.neutron = neutronapi.API()
        self.client = neutronapi.get_client(self.context)
Exemple #40
0
    def create(self, req, server_id, body):
        """Attach an interface to an instance."""
        context = req.environ['nova.context']
        context.can(ai_policies.BASE_POLICY_NAME)
        context.can(ai_policies.POLICY_ROOT % 'create')

        network_id = None
        port_id = None
        req_ip = None
        tag = None
        vif_model = None
        if body:
            attachment = body['interfaceAttachment']
            network_id = attachment.get('net_id', None)
            port_id = attachment.get('port_id', None)
            tag = attachment.get('tag', None)
            vif_model = attachment.get('wrs-if:vif_model')
            try:
                req_ip = attachment['fixed_ips'][0]['ip_address']
            except Exception:
                pass

        if network_id and port_id:
            msg = _("Must not input both network_id and port_id")
            raise exc.HTTPBadRequest(explanation=msg)
        if req_ip and not network_id:
            msg = _("Must input network_id when request IP address")
            raise exc.HTTPBadRequest(explanation=msg)

        instance = common.get_instance(self.compute_api, context, server_id)

        try:
            if hasattr(instance, 'info_cache'):
                instance_nic_count = len(instance.info_cache.network_info)
                if instance_nic_count >= wrs_server_if.MAXIMUM_VNICS:
                    msg = _("Already at %(max)d configured NICs, "
                            "which is the maximum amount supported") % {
                                "max": wrs_server_if.MAXIMUM_VNICS,
                           }
                    raise exc.HTTPBadRequest(explanation=msg)
            if hasattr(instance, 'host'):
                physkey = 'provider:physical_network'
                aggr_list = objects.AggregateList.get_by_metadata_key(
                    context, physkey, hosts=set([instance.host])
                )
                providernet_list = []
                for aggr_entry in aggr_list:
                    providernet_list.append(aggr_entry.metadata[physkey])

                neutron = neutronapi.get_client(context, admin=True)
                temp_network_id = None
                if port_id:
                    port = neutron.show_port(port_id)['port']
                    temp_network_id = port.get('network_id')
                    if not vif_model:
                        vif_model = port.get('wrs-binding:vif_model')
                else:
                    temp_network_id = network_id
                network = neutron.show_network(temp_network_id)['network']
                providernet = network[physkey]
                providernet_on_host = (providernet in providernet_list)
                if not providernet_on_host:
                    msg = _("Providernet %(pnet)s not on instance's "
                            "host %(host)s") % {
                                "pnet": providernet,
                                "host": instance.host,
                            }
                    raise exc.HTTPBadRequest(explanation=msg)
            if not vif_model:
                vif_model = network_model.VIF_MODEL_VIRTIO
            elif vif_model not in network_model.VIF_MODEL_HOTPLUGGABLE:
                msg = _("Interface attach not supported for vif_model "
                        "%(vif_model)s. Must be one of %(valid_vifs)s.") % {
                            'vif_model': vif_model,
                            'valid_vifs': network_model.VIF_MODEL_HOTPLUGGABLE,
                        }
                raise exception.InvalidInput(msg)
            vif = self.compute_api.attach_interface(context,
                instance, network_id, port_id, req_ip, vif_model, tag=tag)
        except (exception.InterfaceAttachFailedNoNetwork,
                exception.NetworkAmbiguous,
                exception.NoMoreFixedIps,
                exception.PortNotUsable,
                exception.AttachInterfaceNotSupported,
                exception.SecurityGroupCannotBeApplied,
                exception.InvalidInput,
                exception.TaggedAttachmentNotSupported) as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
        except (exception.InstanceIsLocked,
                exception.FixedIpAlreadyInUse,
                exception.PortInUse) as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except (exception.PortNotFound,
                exception.NetworkNotFound) as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InterfaceAttachFailed as e:
            raise webob.exc.HTTPInternalServerError(
                explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'attach_interface', server_id)

        return self.show(req, server_id, vif['id'])
    def _generate_configdrive(self, instance, node, network_info,
                              extra_md=None, files=None):
        if not extra_md:
            extra_md = {}

        client = neutron.get_client(None, admin=True)

        # Get vlan to port map
        net_vlan_map = {}
        port_vlan_map = {}
        for vif in network_info:
            if vif['network']['id'] not in net_vlan_map:
                network = client.show_network(vif['network']['id'])
                net_vlan_map[vif['network']['id']] = (
                    network['network']['provider:segmentation_id'])
            port_vlan_map[vif['id']] = net_vlan_map[vif['network']['id']]

        network_metadata = netutils.get_network_metadata(network_info)

        ports = self.ironicclient.call("node.list_ports",
                                       node.uuid, detail=True)
        portgroups = self.ironicclient.call("node.list_portgroups", node.uuid)
        all_ports = ports + portgroups

        for link in network_metadata['links']:
            link['type'] = 'vlan'
            link['vlan_mac_address'] = link['ethernet_mac_address']
            link['neutron_port_id'] = link['vif_id']
            link['vlan_id'] = port_vlan_map[link['vif_id']]
            link['vlan_link'] = self._get_port_for_vif(
                all_ports, link['vif_id']).uuid
            del link['ethernet_mac_address']
            del link['vif_id']

        for port in ports:
            if port.extra.get('vif_port_ids', []):
                link = {'id': port.uuid, 'type': 'phy', 'mtu': 9000,
                        'ethernet_mac_address': port.address}
                network_metadata['links'].append(link)

        for pg in portgroups:
            ps = [port for port in ports if port.portgroup_id is pg.id]
            link = {'id': pg.uuid, 'type': 'bond',
                    'ethernet_mac_address': ports[0].address,
                    'bond_mode': '802.1ad',
                    'bond_xmit_hash_policy': 'layer3+4',
                    'bond_miimon': 100, 'bond_links': []}
            for port in ps:
                link['bond_links'].append(port.uuid)

        files.append(('ironicnetworking', 'yes'.encode()))

        i_meta = instance_metadata.InstanceMetadata(
            instance, content=files, extra_md=extra_md,
            network_metadata=network_metadata)

        with tempfile.NamedTemporaryFile() as uncompressed:
            try:
                with configdrive.ConfigDriveBuilder(instance_md=i_meta) as cdb:
                    cdb.make_drive(uncompressed.name)
            except Exception as e:
                with excutils.save_and_reraise_exception():
                    LOG.error(_LE("Creating config drive failed with "
                                  "error: %s"), e, instance=instance)

            with tempfile.NamedTemporaryFile() as compressed:
                # compress config drive
                with gzip.GzipFile(fileobj=compressed, mode='wb') as gzipped:
                    uncompressed.seek(0)
                    shutil.copyfileobj(uncompressed, gzipped)

                # base64 encode config drive
                compressed.seek(0)
                return base64.b64encode(compressed.read())