예제 #1
0
파일: rules.py 프로젝트: Frank889/neutron
    def _prepare_subports(self, context):
        """Utility method to parse subports in the request

        The objective of this method is two-fold:

            * Update subports segmentation details if INHERIT is requested;
            * Return the MTU for each of the subport in the request.

        This method does two things rather than one to allow us to hit the DB
        once, and thus minimize the number of lookups required to learn about
        the segmentation type and the MTU of the networks on which subports
        are plugged.
        """
        InheritIndex = (collections.namedtuple("InheritIndex",
                                               "index has_inherit"))
        port_ids = {}
        any_has_inherit = False
        for i, s in enumerate(self.subports):
            has_inherit = (s.get('segmentation_type') ==
                           constants.SEGMENTATION_TYPE_INHERIT)
            any_has_inherit |= has_inherit
            port_ids[s['port_id']] = (InheritIndex(index=i,
                                                   has_inherit=has_inherit))

        core_plugin = directory.get_plugin()
        if (any_has_inherit and not extensions.is_extension_supported(
                core_plugin, provider.ALIAS)):
            msg = (_("Cannot accept segmentation type %s") %
                   constants.SEGMENTATION_TYPE_INHERIT)
            raise n_exc.InvalidInput(error_message=msg)

        ports = core_plugin.get_ports(context, filters={'id': port_ids})
        network_port_map = collections.defaultdict(list)
        for p in ports:
            network_port_map[p['network_id']].append({'port_id': p['id']})
        networks = core_plugin.get_networks(
            common_utils.get_elevated_context(context),
            filters={'id': network_port_map})

        subport_mtus = {}
        for net in networks:
            for port in network_port_map[net['id']]:
                if port_ids[port['port_id']].has_inherit:
                    port.update({
                        'segmentation_id':
                        net[provider.SEGMENTATION_ID],
                        'segmentation_type':
                        net[provider.NETWORK_TYPE]
                    })
                    self.subports[port_ids[port['port_id']].index] = port
                # To speed up the request, record the network MTU for each
                # subport to avoid hitting the DB more than necessary. Do
                # that only if the extension is available.
                if extensions.is_extension_supported(core_plugin, 'net-mtu'):
                    subport_mtus[port['port_id']] = net[api.MTU]
        return subport_mtus
예제 #2
0
파일: rules.py 프로젝트: openstack/neutron
    def _prepare_subports(self, context):
        """Utility method to parse subports in the request

        The objective of this method is two-fold:

            * Update subports segmentation details if INHERIT is requested;
            * Return the MTU for each of the subport in the request.

        This method does two things rather than one to allow us to hit the DB
        once, and thus minimize the number of lookups required to learn about
        the segmentation type and the MTU of the networks on which subports
        are plugged.
        """
        InheritIndex = (
            collections.namedtuple("InheritIndex", "index has_inherit"))
        port_ids = {}
        any_has_inherit = False
        for i, s in enumerate(self.subports):
            has_inherit = (s.get('segmentation_type') ==
                           constants.SEGMENTATION_TYPE_INHERIT)
            any_has_inherit |= has_inherit
            port_ids[s['port_id']] = (
                InheritIndex(index=i, has_inherit=has_inherit))

        core_plugin = directory.get_plugin()
        if (any_has_inherit and
                not extensions.is_extension_supported(
                    core_plugin, provider.ALIAS)):
            msg = (_("Cannot accept segmentation type %s") %
                   constants.SEGMENTATION_TYPE_INHERIT)
            raise n_exc.InvalidInput(error_message=msg)

        ports = core_plugin.get_ports(context, filters={'id': port_ids})
        network_port_map = collections.defaultdict(list)
        for p in ports:
            network_port_map[p['network_id']].append({'port_id': p['id']})
        networks = core_plugin.get_networks(
            context.elevated(), filters={'id': network_port_map})

        subport_mtus = {}
        for net in networks:
            for port in network_port_map[net['id']]:
                if port_ids[port['port_id']].has_inherit:
                    port.update(
                        {'segmentation_id': net[provider.SEGMENTATION_ID],
                         'segmentation_type': net[provider.NETWORK_TYPE]})
                    self.subports[port_ids[port['port_id']].index] = port
                # To speed up the request, record the network MTU for each
                # subport to avoid hitting the DB more than necessary. Do
                # that only if the extension is available.
                if extensions.is_extension_supported(core_plugin, 'net-mtu'):
                    subport_mtus[port['port_id']] = net[api.MTU]
        return subport_mtus
예제 #3
0
    def update_all_ha_network_port_statuses(self, context, host):
        """Set HA network port to DOWN for HA routers hosted on <host>

        This will update HA network port status to down for all HA routers
        hosted on <host>. This is needed to avoid l3 agent spawning keepalived
        when l2 agent not yet wired the port. This can happen after a system
        reboot that has wiped out flows, etc and the L2 agent hasn't started up
        yet. The port will still be ACTIVE in the data model and the L3 agent
        will use that info to mistakenly think that L2 network is ready.
        By forcing into DOWN, we will require the L2 agent to essentially ack
        that the port is indeed ACTIVE by reacting to the port update and
        calling update_device_up.
        """
        if not extensions.is_extension_supported(
            self.plugin, constants.PORT_BINDING_EXT_ALIAS):
            return
        device_filter = {
            'device_owner': [constants.DEVICE_OWNER_ROUTER_HA_INTF],
            'status': [constants.PORT_STATUS_ACTIVE]}
        ports = self.plugin.get_ports(context, filters=device_filter)
        ha_ports = [p['id'] for p in ports
                    if p.get(portbindings.HOST_ID) == host]
        if not ha_ports:
            return
        LOG.debug("L3 agent on host %(host)s requested for fullsync, so "
                  "setting HA network ports %(ha_ports)s status to DOWN.",
                  {"host": host, "ha_ports": ha_ports})
        for p in ha_ports:
            self.plugin.update_port(
                context, p, {'port': {'status': constants.PORT_STATUS_DOWN}})
예제 #4
0
    def _create_shadow_agent(self, context, port_body):
        """Create shadow agent before creating shadow port

        Called inside self.create_port function. Shadow port is created by xjob
        daemon. Xjob daemon will insert agent information(agent type, tunnel
        ip and host) in the binding profile of the request body. This function
        checks if the necessary information is in the request body, if so, it
        invokes real core plugin to create or update shadow agent. For other
        kinds of port creation requests, this function is called but does not
        take effect.

        :param context: neutron context
        :param port_body: port update body
        :return: None
        """
        if not extensions.is_extension_supported(self.core_plugin, 'agent'):
            return
        profile_dict = port_body.get(portbindings.PROFILE, {})
        if not validators.is_attr_set(profile_dict):
            return
        if t_constants.PROFILE_TUNNEL_IP not in profile_dict:
            return
        agent_type = profile_dict[t_constants.PROFILE_AGENT_TYPE]
        tunnel_ip = profile_dict[t_constants.PROFILE_TUNNEL_IP]
        agent_host = port_body[portbindings.HOST_ID]
        agent_state = helper.NetworkHelper.construct_agent_data(
            agent_type, agent_host, tunnel_ip)
        self.core_plugin.create_or_update_agent(context, agent_state)
        driver = self.core_plugin.type_manager.drivers.get('vxlan')
        if driver:
            driver.obj.add_endpoint(tunnel_ip, agent_host)
예제 #5
0
 def _add_az_to_response(router_res, router_db):
     l3_plugin = directory.get_plugin(constants.L3)
     if not extensions.is_extension_supported(l3_plugin,
                                              'router_availability_zone'):
         return
     router_res['availability_zones'] = (
         l3_plugin.get_router_availability_zones(router_db))
예제 #6
0
    def _create_shadow_agent(self, context, port_body):
        """Create shadow agent before creating shadow port

        Called inside self.create_port function. Shadow port is created by xjob
        daemon. Xjob daemon will insert agent information(agent type, tunnel
        ip and host) in the binding profile of the request body. This function
        checks if the necessary information is in the request body, if so, it
        invokes real core plugin to create or update shadow agent. For other
        kinds of port creation requests, this function is called but does not
        take effect.

        :param context: neutron context
        :param port_body: port update body
        :return: None
        """
        if not extensions.is_extension_supported(self.core_plugin, 'agent'):
            return
        profile_dict = port_body.get(portbindings.PROFILE, {})
        if not validators.is_attr_set(profile_dict):
            return
        if t_constants.PROFILE_TUNNEL_IP not in profile_dict:
            return
        agent_type = profile_dict[t_constants.PROFILE_AGENT_TYPE]
        tunnel_ip = profile_dict[t_constants.PROFILE_TUNNEL_IP]
        agent_host = port_body[portbindings.HOST_ID]
        agent_state = helper.NetworkHelper.construct_agent_data(
            agent_type, agent_host, tunnel_ip)
        self.core_plugin.create_or_update_agent(context, agent_state)
        driver = self.core_plugin.type_manager.drivers.get('vxlan')
        if driver:
            driver.obj.add_endpoint(tunnel_ip, agent_host)
예제 #7
0
    def get_sync_data_metering(self, context, **kwargs):
        l3_plugin = directory.get_plugin(plugin_constants.L3)
        if not l3_plugin:
            return

        metering_data = self.meter_plugin.get_sync_data_metering(context)
        host = kwargs.get('host')
        if not extensions.is_extension_supported(
                l3_plugin, consts.L3_AGENT_SCHEDULER_EXT_ALIAS) or not host:
            return metering_data
        else:
            agents = l3_plugin.get_l3_agents(context, filters={'host': [host]})
            if not agents:
                LOG.error('Unable to find agent on host %s.', host)
                return

            router_ids = []
            for agent in agents:
                routers = l3_plugin.list_routers_on_l3_agent(context, agent.id)
                router_ids += [router['id'] for router in routers['routers']]
            if not router_ids:
                return
            else:
                return [
                    router for router in metering_data
                    if router['id'] in router_ids
                ]
예제 #8
0
 def _notification(self,
                   context,
                   method,
                   router_ids,
                   operation,
                   shuffle_agents,
                   schedule_routers=True):
     """Notify all the agents that are hosting the routers."""
     plugin = directory.get_plugin(plugin_constants.L3)
     if not plugin:
         LOG.error(
             'No plugin for L3 routing registered. Cannot notify '
             'agents with the message %s', method)
         return
     if extensions.is_extension_supported(
             plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS):
         adminContext = (context.is_admin and context
                         or common_utils.get_elevated_context(context))
         if schedule_routers:
             plugin.schedule_routers(adminContext, router_ids)
         self._agent_notification(context, method, router_ids, operation,
                                  shuffle_agents)
     else:
         cctxt = self.client.prepare(fanout=True)
         cctxt.cast(context, method, routers=router_ids)
예제 #9
0
파일: l3_rpc.py 프로젝트: openstack/neutron
    def update_all_ha_network_port_statuses(self, context, host):
        """Set HA network port to DOWN for HA routers hosted on <host>

        This will update HA network port status to down for all HA routers
        hosted on <host>. This is needed to avoid l3 agent spawning keepalived
        when l2 agent not yet wired the port. This can happen after a system
        reboot that has wiped out flows, etc and the L2 agent hasn't started up
        yet. The port will still be ACTIVE in the data model and the L3 agent
        will use that info to mistakenly think that L2 network is ready.
        By forcing into DOWN, we will require the L2 agent to essentially ack
        that the port is indeed ACTIVE by reacting to the port update and
        calling update_device_up.
        """
        if not extensions.is_extension_supported(
            self.plugin, constants.PORT_BINDING_EXT_ALIAS):
            return
        device_filter = {
            'device_owner': [constants.DEVICE_OWNER_ROUTER_HA_INTF],
            'status': [constants.PORT_STATUS_ACTIVE]}
        ports = self.plugin.get_ports(context, filters=device_filter)
        ha_ports = [p['id'] for p in ports
                    if p.get(portbindings.HOST_ID) == host]
        if not ha_ports:
            return
        LOG.debug("L3 agent on host %(host)s requested for fullsync, so "
                  "setting HA network ports %(ha_ports)s status to DOWN.",
                  {"host": host, "ha_ports": ha_ports})
        for p in ha_ports:
            self.plugin.update_port(
                context, p, {'port': {'status': constants.PORT_STATUS_DOWN}})
예제 #10
0
파일: router.py 프로젝트: cubeek/neutron
 def _add_az_to_response(router_res, router_db):
     l3_plugin = directory.get_plugin(constants.L3)
     if not extensions.is_extension_supported(
             l3_plugin, 'router_availability_zone'):
         return
     router_res['availability_zones'] = (
         l3_plugin.get_router_availability_zones(router_db))
예제 #11
0
파일: dhcp_rpc.py 프로젝트: zhhuabj/neutron
    def _get_active_networks(self, context, **kwargs):
        """Retrieve and return a list of the active networks."""
        host = kwargs.get('host')
        plugin = directory.get_plugin()
        if extensions.is_extension_supported(
                plugin, constants.DHCP_AGENT_SCHEDULER_EXT_ALIAS):
            if cfg.CONF.network_auto_schedule:
                plugin.auto_schedule_networks(context, host)
            nets = plugin.list_active_networks_on_active_dhcp_agent(
                context, host)
        else:
            # If no active DHCP agent or agent admin state is DOWN,
            # return empty network list for RPC to avoid unexpected
            # resource creation on remote host when the DHCP agent
            # scheduler extension is not supported.
            try:
                agent = plugin._get_agent_by_type_and_host(
                    context, constants.AGENT_TYPE_DHCP, host)
            except agent_exc.AgentNotFoundByTypeHost:
                LOG.debug("DHCP Agent not found on host %s", host)
                return []
            if not agent.admin_state_up:
                LOG.debug("DHCP Agent admin state is down on host %s", host)
                return []

            filters = dict(admin_state_up=[True])
            nets = plugin.get_networks(context, filters=filters)
        return nets
예제 #12
0
파일: l3_rpc.py 프로젝트: stackhpc/neutron
    def sync_routers(self, context, **kwargs):
        """Sync routers according to filters to a specific agent.

        @param context: contain user information
        @param kwargs: host, router_ids
        @return: a list of routers
                 with their interfaces and floating_ips
        """
        router_ids = kwargs.get('router_ids')
        host = kwargs.get('host')
        context = neutron_context.get_admin_context()
        LOG.debug('Sync routers for ids %(router_ids)s in %(host)s', {
            'router_ids': router_ids,
            'host': host
        })
        routers = self._routers_to_sync(context, router_ids, host)
        if extensions.is_extension_supported(self.plugin,
                                             constants.PORT_BINDING_EXT_ALIAS):
            self._ensure_host_set_on_ports(context, host, routers)
            # refresh the data structure after ports are bound
            routers = self._routers_to_sync(context, router_ids, host)
        pf_plugin = directory.get_plugin(plugin_constants.PORTFORWARDING)
        if pf_plugin:
            pf_plugin.sync_port_forwarding_fip(context, routers)
        LOG.debug(
            'The sync data for ids %(router_ids)s in %(host)s is: '
            '%(routers)s', {
                'router_ids': router_ids,
                'host': host,
                'routers': routers
            })
        return routers
예제 #13
0
 def _routers_to_sync(self, context, router_ids, host=None):
     if extensions.is_extension_supported(
             self.l3plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS):
         routers = (
             self.l3plugin.list_active_sync_routers_on_active_l3_agent(
                 context, host, router_ids))
     else:
         routers = self.l3plugin.get_sync_data(context, router_ids)
     return routers
예제 #14
0
 def _notification(self, context, method, routers):
     """Notify all the agents that are hosting the routers."""
     plugin = directory.get_plugin(plugin_constants.L3)
     if extensions.is_extension_supported(
             plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS):
         self._agent_notification(context, method, routers)
     else:
         cctxt = self.client.prepare(fanout=True)
         cctxt.cast(context, method, routers=routers)
예제 #15
0
파일: utils.py 프로젝트: zhhuabj/neutron
def get_agent_types_by_host(context, host):
    """Return the agent types registered on the host."""
    agent_types = []
    core_plugin = directory.get_plugin()
    if extensions.is_extension_supported(core_plugin, 'agent'):
        agents = core_plugin.get_agents(
            context.elevated(), filters={'host': [host]})
        agent_types = [a['agent_type'] for a in agents]
    return agent_types
예제 #16
0
 def _get_active_l3_agent_routers_sync_data(self, context, host, agent,
                                            router_ids):
     if extensions.is_extension_supported(
             self, n_const.L3_HA_MODE_EXT_ALIAS):
         return self.get_ha_sync_data_for_host(context, host, agent,
                                               router_ids=router_ids,
                                               active=True)
     return self._get_dvr_sync_data(context, host, agent,
                                    router_ids=router_ids, active=True)
예제 #17
0
파일: l3_rpc.py 프로젝트: openstack/neutron
 def _routers_to_sync(self, context, router_ids, host=None):
     if extensions.is_extension_supported(
         self.l3plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS):
         routers = (
             self.l3plugin.list_active_sync_routers_on_active_l3_agent(
                 context, host, router_ids))
     else:
         routers = self.l3plugin.get_sync_data(context, router_ids)
     return routers
예제 #18
0
 def _notification(self, context, method, routers):
     """Notify all the agents that are hosting the routers."""
     plugin = directory.get_plugin(plugin_constants.L3)
     if extensions.is_extension_supported(
         plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS):
         self._agent_notification(context, method, routers)
     else:
         cctxt = self.client.prepare(fanout=True)
         cctxt.cast(context, method, routers=routers)
예제 #19
0
 def _get_active_l3_agent_routers_sync_data(self, context, host, agent,
                                            router_ids):
     if extensions.is_extension_supported(
             self, n_const.L3_HA_MODE_EXT_ALIAS):
         return self.get_ha_sync_data_for_host(context, host, agent,
                                               router_ids=router_ids,
                                               active=True)
     return self._get_dvr_sync_data(context, host, agent,
                                    router_ids=router_ids, active=True)
예제 #20
0
    def _fill_agent_info_in_profile(self, context, port_id, host,
                                    profile_dict):
        """Fill agent information in the binding profile

        Called inside self.update_port function. When local plugin handles
        port update request, it checks if host is in the body, if so, local
        plugin will send a port update request to central Neutron to tell
        central plugin that the port has been bound to a host. The information
        of the agent in the host is inserted in the update body by calling this
        function. So after central Neutron receives the request, it can save
        the agent information in the Tricircle shadow agent table.

        :param context: neutron object
        :param port_id: port uuid
        :param host: host the port is bound to
        :param profile_dict: binding profile dict in the port update body
        :return: None
        """
        if not extensions.is_extension_supported(self.core_plugin, 'agent'):
            return
        if cfg.CONF.client.cross_pod_vxlan_mode == t_constants.NM_NOOP:
            return

        port = self.core_plugin.get_port(context, port_id)
        net = self.core_plugin.get_network(context, port['network_id'])
        if net[provider_net.NETWORK_TYPE] != t_constants.NT_VxLAN:
            return

        vif_type = port[portbindings.VIF_TYPE]
        agent_type = helper.NetworkHelper.get_agent_type_by_vif(vif_type)
        if not agent_type:
            return
        agents = self.core_plugin.get_agents(context,
                                             filters={
                                                 'agent_type': [agent_type],
                                                 'host': [host]
                                             })
        if not agents:
            return

        if cfg.CONF.client.cross_pod_vxlan_mode == t_constants.NM_P2P:
            helper.NetworkHelper.fill_agent_data(agent_type, host, agents[0],
                                                 profile_dict)
        elif cfg.CONF.client.cross_pod_vxlan_mode == t_constants.NM_L2GW:
            if not cfg.CONF.tricircle.l2gw_tunnel_ip:
                LOG.error('Cross-pod VxLAN networking mode is set to l2gw '
                          'but L2 gateway tunnel ip is not configured')
                return
            l2gw_tunnel_ip = cfg.CONF.tricircle.l2gw_tunnel_ip
            helper.NetworkHelper.fill_agent_data(agent_type,
                                                 host,
                                                 agents[0],
                                                 profile_dict,
                                                 tunnel_ip=l2gw_tunnel_ip)
예제 #21
0
    def is_az_filter_supported(self):
        supported = self._is_az_filter_supported
        if supported is None:
            supported = False
            for plugin in directory.get_plugins().values():
                if extensions.is_extension_supported(plugin, azfil_ext.ALIAS):
                    supported = True
                    break
        self._is_az_filter_supported = supported

        return self._is_az_filter_supported
예제 #22
0
 def _process_dns_floatingip_delete(self, context, floatingip_data):
     if not extensions.is_extension_supported(self._core_plugin,
                                              dns_apidef.ALIAS):
         return
     dns_data_db = fip_obj.FloatingIPDNS.get_object(
         context, floatingip_id=floatingip_data['id'])
     if dns_data_db:
         self._delete_floatingip_from_external_dns_service(
             context, dns_data_db['published_dns_domain'],
             dns_data_db['published_dns_name'],
             [floatingip_data['floating_ip_address']])
예제 #23
0
파일: l3_rpc.py 프로젝트: openstack/neutron
    def get_router_ids(self, context, host):
        """Returns IDs of routers scheduled to l3 agent on <host>

        This will autoschedule unhosted routers to l3 agent on <host> and then
        return all ids of routers scheduled to it.
        """
        if extensions.is_extension_supported(
                self.l3plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS):
            if cfg.CONF.router_auto_schedule:
                self.l3plugin.auto_schedule_routers(context, host)
        return self.l3plugin.list_router_ids_on_host(context, host)
예제 #24
0
파일: dns_db.py 프로젝트: igordcard/neutron
 def _process_dns_floatingip_delete(self, context, floatingip_data):
     if not extensions.is_extension_supported(
             self._core_plugin, dns_apidef.ALIAS):
         return
     dns_data_db = fip_obj.FloatingIPDNS.get_object(
         context, floatingip_id=floatingip_data['id'])
     if dns_data_db:
         self._delete_floatingip_from_external_dns_service(
             context, dns_data_db['published_dns_domain'],
             dns_data_db['published_dns_name'],
             [floatingip_data['floating_ip_address']])
예제 #25
0
    def get_router_ids(self, context, host):
        """Returns IDs of routers scheduled to l3 agent on <host>

        This will autoschedule unhosted routers to l3 agent on <host> and then
        return all ids of routers scheduled to it.
        """
        if extensions.is_extension_supported(
                self.l3plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS):
            if cfg.CONF.router_auto_schedule:
                self.l3plugin.auto_schedule_routers(context, host)
        return self.l3plugin.list_router_ids_on_host(context, host)
예제 #26
0
    def is_az_filter_supported(self):
        supported = self._is_az_filter_supported
        if supported is None:
            supported = False
            for plugin in directory.get_plugins().values():
                if extensions.is_extension_supported(plugin, azfil_ext.ALIAS):
                    supported = True
                    break
        self._is_az_filter_supported = supported

        return self._is_az_filter_supported
예제 #27
0
    def _notify_agents(
            self, context, method, payload, network_id, network=None):
        """Notify all the agents that are hosting the network."""
        payload['priority'] = METHOD_PRIORITY_MAP.get(method)
        # fanout is required as we do not know who is "listening"
        no_agents = not extensions.is_extension_supported(
            self.plugin, constants.DHCP_AGENT_SCHEDULER_EXT_ALIAS)
        fanout_required = method == 'network_delete_end' or no_agents

        # we do nothing on network creation because we want to give the
        # admin the chance to associate an agent to the network manually
        cast_required = method != 'network_create_end'

        if fanout_required:
            self._fanout_message(context, method, payload)
        elif cast_required:
            candidate_hosts = None
            if 'subnet' in payload and payload['subnet'].get('segment_id'):
                # if segment_id exists then the segment service plugin
                # must be loaded
                segment_plugin = directory.get_plugin('segments')
                segment = segment_plugin.get_segment(
                    context, payload['subnet']['segment_id'])
                candidate_hosts = segment['hosts']

            agents = self.plugin.get_dhcp_agents_hosting_networks(
                context, [network_id], hosts=candidate_hosts)
            # schedule the network first, if needed
            schedule_required = (
                method == 'subnet_create_end' or
                method == 'port_create_end' and
                not self._is_reserved_dhcp_port(payload['port']))
            if schedule_required:
                admin_ctx = context if context.is_admin else context.elevated()
                network = network or self.plugin.get_network(
                    admin_ctx, network_id)
                if candidate_hosts:
                    network['candidate_hosts'] = candidate_hosts
                agents = self._schedule_network(admin_ctx, network, agents)
            if not agents:
                LOG.debug("Network %s is not hosted by any dhcp agent",
                          network_id)
                return
            enabled_agents = self._get_enabled_agents(
                context, network_id, network, agents, method, payload)

            if method == 'port_create_end' and enabled_agents:
                high_agent = enabled_agents.pop(
                    random.randint(0, len(enabled_agents) - 1))
                self._notify_high_priority_agent(
                    context, copy.deepcopy(payload), high_agent)
            for agent in enabled_agents:
                self._cast_message(
                    context, method, payload, agent.host, agent.topic)
예제 #28
0
    def _get_hosts_to_notify(self, context, router_ids):
        """Returns all hosts to send notification about firewall update"""
        l3_plugin = directory.get_plugin(plugin_constants.L3)
        no_broadcast = (extensions.is_extension_supported(
            l3_plugin, nl_constants.L3_AGENT_SCHEDULER_EXT_ALIAS) and getattr(
                l3_plugin, 'get_l3_agents_hosting_routers', False))
        if no_broadcast:
            agents = l3_plugin.get_l3_agents_hosting_routers(
                context, router_ids, admin_state_up=True, active=True)
            return [a.host for a in agents]

        # NOTE(blallau): default: FirewallAgentAPI performs RPC broadcast
        return [None]
예제 #29
0
파일: l3_rpc.py 프로젝트: yinyalan/neutron
    def sync_routers(self, context, **kwargs):
        """Sync routers according to filters to a specific agent.

        @param context: contain user information
        @param kwargs: host, router_ids
        @return: a list of routers
                 with their interfaces and floating_ips
        """
        router_ids = kwargs.get('router_ids')
        host = kwargs.get('host')
        context = neutron_context.get_admin_context()
        if extensions.is_extension_supported(
                self.l3plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS):
            routers = (
                self.l3plugin.list_active_sync_routers_on_active_l3_agent(
                    context, host, router_ids))
        else:
            routers = self.l3plugin.get_sync_data(context, router_ids)
        if extensions.is_extension_supported(self.plugin,
                                             constants.PORT_BINDING_EXT_ALIAS):
            self._ensure_host_set_on_ports(context, host, routers)
        return routers
예제 #30
0
 def _get_active_networks(self, context, **kwargs):
     """Retrieve and return a list of the active networks."""
     host = kwargs.get('host')
     plugin = directory.get_plugin()
     if extensions.is_extension_supported(
         plugin, constants.DHCP_AGENT_SCHEDULER_EXT_ALIAS):
         if cfg.CONF.network_auto_schedule:
             plugin.auto_schedule_networks(context, host)
         nets = plugin.list_active_networks_on_active_dhcp_agent(
             context, host)
     else:
         filters = dict(admin_state_up=[True])
         nets = plugin.get_networks(context, filters=filters)
     return nets
예제 #31
0
 def _get_active_networks(self, context, **kwargs):
     """Retrieve and return a list of the active networks."""
     host = kwargs.get('host')
     plugin = directory.get_plugin()
     if extensions.is_extension_supported(
             plugin, constants.DHCP_AGENT_SCHEDULER_EXT_ALIAS):
         if cfg.CONF.network_auto_schedule:
             plugin.auto_schedule_networks(context, host)
         nets = plugin.list_active_networks_on_active_dhcp_agent(
             context, host)
     else:
         filters = dict(admin_state_up=[True])
         nets = plugin.get_networks(context, filters=filters)
     return nets
예제 #32
0
    def _fill_agent_info_in_profile(self, context, port_id, host,
                                    profile_dict):
        """Fill agent information in the binding profile

        Called inside self.update_port function. When local plugin handles
        port update request, it checks if host is in the body, if so, local
        plugin will send a port update request to central Neutron to tell
        central plugin that the port has been bound to a host. The information
        of the agent in the host is inserted in the update body by calling this
        function. So after central Neutron receives the request, it can save
        the agent information in the Tricircle shadow agent table.

        :param context: neutron object
        :param port_id: port uuid
        :param host: host the port is bound to
        :param profile_dict: binding profile dict in the port update body
        :return: None
        """
        if not extensions.is_extension_supported(self.core_plugin, 'agent'):
            return
        if cfg.CONF.client.cross_pod_vxlan_mode == t_constants.NM_NOOP:
            return

        port = self.core_plugin.get_port(context, port_id)
        net = self.core_plugin.get_network(context, port['network_id'])
        if net[provider_net.NETWORK_TYPE] != t_constants.NT_VxLAN:
            return

        vif_type = port[portbindings.VIF_TYPE]
        agent_type = helper.NetworkHelper.get_agent_type_by_vif(vif_type)
        if not agent_type:
            return
        agents = self.core_plugin.get_agents(
            context, filters={'agent_type': [agent_type], 'host': [host]})
        if not agents:
            return

        if cfg.CONF.client.cross_pod_vxlan_mode == t_constants.NM_P2P:
            helper.NetworkHelper.fill_agent_data(agent_type, host, agents[0],
                                                 profile_dict)
        elif cfg.CONF.client.cross_pod_vxlan_mode == t_constants.NM_L2GW:
            if not cfg.CONF.tricircle.l2gw_tunnel_ip:
                LOG.error('Cross-pod VxLAN networking mode is set to l2gw '
                          'but L2 gateway tunnel ip is not configured')
                return
            l2gw_tunnel_ip = cfg.CONF.tricircle.l2gw_tunnel_ip
            helper.NetworkHelper.fill_agent_data(agent_type, host, agents[0],
                                                 profile_dict,
                                                 tunnel_ip=l2gw_tunnel_ip)
예제 #33
0
    def _notify_agents(self, context, method, payload, network_id):
        """Notify all the agents that are hosting the network."""
        payload['priority'] = METHOD_PRIORITY_MAP.get(method)
        # fanout is required as we do not know who is "listening"
        no_agents = not extensions.is_extension_supported(
            self.plugin, constants.DHCP_AGENT_SCHEDULER_EXT_ALIAS)
        fanout_required = method == 'network_delete_end' or no_agents

        # we do nothing on network creation because we want to give the
        # admin the chance to associate an agent to the network manually
        cast_required = method != 'network_create_end'

        if fanout_required:
            self._fanout_message(context, method, payload)
        elif cast_required:
            admin_ctx = (context if context.is_admin else context.elevated())
            network = self.plugin.get_network(admin_ctx, network_id)
            if 'subnet' in payload and payload['subnet'].get('segment_id'):
                # if segment_id exists then the segment service plugin
                # must be loaded
                segment_plugin = directory.get_plugin('segments')
                segment = segment_plugin.get_segment(
                    context, payload['subnet']['segment_id'])
                network['candidate_hosts'] = segment['hosts']

            agents = self.plugin.get_dhcp_agents_hosting_networks(
                context, [network_id], hosts=network.get('candidate_hosts'))
            # schedule the network first, if needed
            schedule_required = (
                method == 'subnet_create_end' or
                method == 'port_create_end' and
                not self._is_reserved_dhcp_port(payload['port']))
            if schedule_required:
                agents = self._schedule_network(admin_ctx, network, agents)
            if not agents:
                LOG.debug("Network %s is not hosted by any dhcp agent",
                          network_id)
                return
            enabled_agents = self._get_enabled_agents(
                context, network, agents, method, payload)

            if method == 'port_create_end':
                high_agent = enabled_agents.pop(
                    random.randint(0, len(enabled_agents) - 1))
                self._notify_high_priority_agent(
                    context, copy.deepcopy(payload), high_agent)
            for agent in enabled_agents:
                self._cast_message(
                    context, method, payload, agent.host, agent.topic)
예제 #34
0
 def get_ha_sync_data_for_host(self, context, host, agent,
                               router_ids=None, active=None):
     agent_mode = self._get_agent_mode(agent)
     dvr_agent_mode = (
         agent_mode in [constants.L3_AGENT_MODE_DVR_SNAT,
                        constants.L3_AGENT_MODE_DVR,
                        constants.L3_AGENT_MODE_DVR_NO_EXTERNAL])
     if (dvr_agent_mode and extensions.is_extension_supported(
             self, constants.L3_DISTRIBUTED_EXT_ALIAS)):
         # DVR has to be handled differently
         sync_data = self._get_dvr_sync_data(context, host, agent,
                                             router_ids, active)
     else:
         sync_data = super(L3_HA_NAT_db_mixin, self).get_sync_data(context,
                                                         router_ids, active)
     return self._process_sync_ha_data(
         context, sync_data, host, dvr_agent_mode)
예제 #35
0
 def get_ha_sync_data_for_host(self, context, host, agent,
                               router_ids=None, active=None):
     agent_mode = self._get_agent_mode(agent)
     dvr_agent_mode = (
         agent_mode in [constants.L3_AGENT_MODE_DVR_SNAT,
                        constants.L3_AGENT_MODE_DVR,
                        constants.L3_AGENT_MODE_DVR_NO_EXTERNAL])
     if (dvr_agent_mode and extensions.is_extension_supported(
             self, constants.L3_DISTRIBUTED_EXT_ALIAS)):
         # DVR has to be handled differently
         sync_data = self._get_dvr_sync_data(context, host, agent,
                                             router_ids, active)
     else:
         sync_data = super(L3_HA_NAT_db_mixin, self).get_sync_data(context,
                                                         router_ids, active)
     return self._process_sync_ha_data(
         context, sync_data, host, dvr_agent_mode)
예제 #36
0
    def sync_routers(self, context, **kwargs):
        """Sync routers according to filters to a specific agent.

        @param context: contain user information
        @param kwargs: host, router_ids
        @return: a list of routers
                 with their interfaces and floating_ips
        """
        router_ids = kwargs.get('router_ids')
        host = kwargs.get('host')
        context = neutron_context.get_admin_context()
        routers = self._routers_to_sync(context, router_ids, host)
        if extensions.is_extension_supported(
            self.plugin, constants.PORT_BINDING_EXT_ALIAS):
            self._ensure_host_set_on_ports(context, host, routers)
            # refresh the data structure after ports are bound
            routers = self._routers_to_sync(context, router_ids, host)
        return routers
예제 #37
0
    def sync_routers(self, context, **kwargs):
        """Sync routers according to filters to a specific agent.

        @param context: contain user information
        @param kwargs: host, router_ids
        @return: a list of routers
                 with their interfaces and floating_ips
        """
        router_ids = kwargs.get('router_ids')
        host = kwargs.get('host')
        context = neutron_context.get_admin_context()
        routers = self._routers_to_sync(context, router_ids, host)
        if extensions.is_extension_supported(self.plugin,
                                             constants.PORT_BINDING_EXT_ALIAS):
            self._ensure_host_set_on_ports(context, host, routers)
            # refresh the data structure after ports are bound
            routers = self._routers_to_sync(context, router_ids, host)
        return routers
예제 #38
0
 def _notification(self, context, method, router_ids, operation,
                   shuffle_agents, schedule_routers=True):
     """Notify all the agents that are hosting the routers."""
     plugin = directory.get_plugin(plugin_constants.L3)
     if not plugin:
         LOG.error('No plugin for L3 routing registered. Cannot notify '
                   'agents with the message %s', method)
         return
     if extensions.is_extension_supported(
             plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS):
         adminContext = (context.is_admin and
                         context or context.elevated())
         if schedule_routers:
             plugin.schedule_routers(adminContext, router_ids)
         self._agent_notification(
             context, method, router_ids, operation, shuffle_agents)
     else:
         cctxt = self.client.prepare(fanout=True)
         cctxt.cast(context, method, routers=router_ids)
예제 #39
0
파일: dns_db.py 프로젝트: openstack/neutron
 def _process_dns_floatingip_update_precommit(self, context,
                                              floatingip_data):
     # expects to be called within a plugin's session
     if not extensions.is_extension_supported(
             self._core_plugin, dns_apidef.ALIAS):
         return
     if not self.dns_driver:
         return
     dns_data_db = fip_obj.FloatingIPDNS.get_object(
         context, floatingip_id=floatingip_data['id'])
     if dns_data_db and dns_data_db['dns_name']:
         # dns_name and dns_domain assigned for floating ip. It doesn't
         # matter whether they are defined for internal port
         return
     current_dns_name, current_dns_domain = (
         self._get_requested_state_for_external_dns_service_update(
             context, floatingip_data))
     if dns_data_db:
         if (dns_data_db['published_dns_name'] != current_dns_name or
                 dns_data_db['published_dns_domain'] != current_dns_domain):
             dns_actions_data = DNSActionsData(
                 previous_dns_name=dns_data_db['published_dns_name'],
                 previous_dns_domain=dns_data_db['published_dns_domain'])
             if current_dns_name and current_dns_domain:
                 dns_data_db['published_dns_name'] = current_dns_name
                 dns_data_db['published_dns_domain'] = current_dns_domain
                 dns_actions_data.current_dns_name = current_dns_name
                 dns_actions_data.current_dns_domain = current_dns_domain
             else:
                 dns_data_db.delete()
             return dns_actions_data
         else:
             return
     if current_dns_name and current_dns_domain:
         fip_obj.FloatingIPDNS(
             context,
             floatingip_id=floatingip_data['id'],
             dns_name='',
             dns_domain='',
             published_dns_name=current_dns_name,
             published_dns_domain=current_dns_domain).create()
         return DNSActionsData(current_dns_name=current_dns_name,
                               current_dns_domain=current_dns_domain)
예제 #40
0
 def _process_dns_floatingip_update_precommit(self, context,
                                              floatingip_data):
     # expects to be called within a plugin's session
     if not extensions.is_extension_supported(self._core_plugin,
                                              dns_apidef.ALIAS):
         return
     if not self.dns_driver:
         return
     dns_data_db = fip_obj.FloatingIPDNS.get_object(
         context, floatingip_id=floatingip_data['id'])
     if dns_data_db and dns_data_db['dns_name']:
         # dns_name and dns_domain assigned for floating ip. It doesn't
         # matter whether they are defined for internal port
         return
     current_dns_name, current_dns_domain = (
         self._get_requested_state_for_external_dns_service_update(
             context, floatingip_data))
     if dns_data_db:
         if (dns_data_db['published_dns_name'] != current_dns_name or
                 dns_data_db['published_dns_domain'] != current_dns_domain):
             dns_actions_data = DNSActionsData(
                 previous_dns_name=dns_data_db['published_dns_name'],
                 previous_dns_domain=dns_data_db['published_dns_domain'])
             if current_dns_name and current_dns_domain:
                 dns_data_db['published_dns_name'] = current_dns_name
                 dns_data_db['published_dns_domain'] = current_dns_domain
                 dns_actions_data.current_dns_name = current_dns_name
                 dns_actions_data.current_dns_domain = current_dns_domain
             else:
                 dns_data_db.delete()
             return dns_actions_data
         else:
             return
     if current_dns_name and current_dns_domain:
         fip_obj.FloatingIPDNS(
             context,
             floatingip_id=floatingip_data['id'],
             dns_name='',
             dns_domain='',
             published_dns_name=current_dns_name,
             published_dns_domain=current_dns_domain).create()
         return DNSActionsData(current_dns_name=current_dns_name,
                               current_dns_domain=current_dns_domain)
예제 #41
0
파일: rules.py 프로젝트: zhh1989/neutron
    def _get_port_mtu(self, context, port_id):
        """
        Return MTU for the network where the given port belongs to.
        If the network or port cannot be obtained, or if MTU is not defined,
        returns None.
        """
        core_plugin = directory.get_plugin()

        if not extensions.is_extension_supported(core_plugin, 'net-mtu'):
            return

        try:
            port = core_plugin.get_port(context, port_id)
            return core_plugin.get_network(context,
                                           port['network_id'])[api.MTU]
        except (n_exc.PortNotFound, n_exc.NetworkNotFound):
            # A concurrent request might have made the port or network
            # disappear; though during DB insertion, the subport request
            # will fail on integrity constraint, it is safer to return
            # a None MTU here.
            return
예제 #42
0
파일: rules.py 프로젝트: igordcard/neutron
    def _get_port_mtu(self, context, port_id):
        """Get port MTU

        Return MTU for the network where the given port belongs to.
        If the network or port cannot be obtained, or if MTU is not defined,
        returns None.
        """
        core_plugin = directory.get_plugin()

        if not extensions.is_extension_supported(core_plugin, 'net-mtu'):
            return

        try:
            port = core_plugin.get_port(context, port_id)
            return core_plugin.get_network(
                context, port['network_id'])[api.MTU]
        except (n_exc.PortNotFound, n_exc.NetworkNotFound):
            # A concurrent request might have made the port or network
            # disappear; though during DB insertion, the subport request
            # will fail on integrity constraint, it is safer to return
            # a None MTU here.
            return
예제 #43
0
    def _ensure_default_security_group(self, context, tenant_id):
        """Create a default security group if one doesn't exist.

        :returns: the default security group id for given tenant.
        """
        if not extensions.is_extension_supported(self, 'security-group'):
            return
        default_group_id = self._get_default_sg_id(context, tenant_id)
        if default_group_id:
            return default_group_id

        security_group = {
            'security_group':
                {'name': 'default',
                 'tenant_id': tenant_id,
                 'description': DEFAULT_SG_DESCRIPTION}
        }
        try:
            return self.create_security_group(context, security_group,
                                              default_sg=True)['id']
        except obj_exc.NeutronDbObjectDuplicateEntry:
            return self._get_default_sg_id(context, tenant_id)
예제 #44
0
 def disable_dns_extension_by_extension_drivers(aliases):
     core_plugin = directory.get_plugin()
     if not api_extensions.is_extension_supported(
             core_plugin, dns_apidef.ALIAS):
         aliases.remove(dns_apidef.ALIAS)
예제 #45
0
 def test_extension_exists(self):
     self.assertTrue(extensions.is_extension_supported(self._plugin,
                                                       "flash"))
예제 #46
0
 def test_extension_does_not_exist(self):
     self.assertFalse(extensions.is_extension_supported(self._plugin,
                                                        "gordon"))
예제 #47
0
 def _is_gw_ip_qos_supported(self):
     if self._gw_ip_qos is None:
         # Check L3 service plugin
         self._gw_ip_qos = extensions.is_extension_supported(
             self, qos_gateway_ip.ALIAS)
     return self._gw_ip_qos
예제 #48
0
 def _is_gw_ip_qos_supported(self):
     if self._gw_ip_qos is None:
         # Check L3 service plugin
         self._gw_ip_qos = extensions.is_extension_supported(
             self, qos_gateway_ip.ALIAS)
     return self._gw_ip_qos