Beispiel #1
0
    def on_datamodel_in_sync(self):
        if not self._data_model_in_sync:
            _log.info("%s: First time we've been in-sync with the datamodel,"
                      "sending snapshot to DispatchChains and FIPManager.",
                      self)
            self._data_model_in_sync = True

            # Tell the dispatch chains about the local endpoints in advance so
            # that we don't flap the dispatch chain at start-of-day.  Note:
            # the snapshot may contain information that is ahead of the
            # state that our individual LocalEndpoint actors are sending to the
            # DispatchChains actor.  That is OK!  The worst that can happen is
            # that a LocalEndpoint undoes part of our update and then goes on
            # to re-apply the update when it catches up to the snapshot.
            local_ifaces = frozenset(self.endpoint_id_by_iface_name.keys())
            self.dispatch_chains.apply_snapshot(local_ifaces, async=True)
            self._update_dirty_policy()

            nat_maps = {}
            for ep_id, ep in self.endpoints_by_id.iteritems():
                if ep_id in self.local_endpoint_ids:
                    nat_map = ep.get(nat_key(self.ip_type), None)
                    if nat_map:
                        nat_maps[ep_id] = nat_map
            self.fip_manager.apply_snapshot(nat_maps, async=True)
Beispiel #2
0
    def on_datamodel_in_sync(self):
        if not self._data_model_in_sync:
            _log.info(
                "%s: First time we've been in-sync with the datamodel,"
                "sending snapshot to DispatchChains and FIPManager.", self)
            self._data_model_in_sync = True

            # Tell the dispatch chains about the local endpoints in advance so
            # that we don't flap the dispatch chain at start-of-day.  Note:
            # the snapshot may contain information that is ahead of the
            # state that our individual LocalEndpoint actors are sending to the
            # DispatchChains actor.  That is OK!  The worst that can happen is
            # that a LocalEndpoint undoes part of our update and then goes on
            # to re-apply the update when it catches up to the snapshot.
            workload_ifaces = set()
            host_eps = set()
            for if_name, ep_id in self.endpoint_id_by_iface_name.iteritems():
                if isinstance(ep_id, WloadEndpointId):
                    workload_ifaces.add(if_name)
                else:
                    host_eps.add(if_name)
            self.workload_disp_chains.apply_snapshot(
                frozenset(workload_ifaces), async=True)
            self.host_disp_chains.apply_snapshot(frozenset(host_eps),
                                                 async=True)
            self._update_dirty_policy()

            nat_maps = {}
            for ep_id, ep in self.endpoints_by_id.iteritems():
                if ep_id in self.local_endpoint_ids:
                    nat_map = ep.get(nat_key(self.ip_type), None)
                    if nat_map:
                        nat_maps[ep_id] = nat_map
            self.fip_manager.apply_snapshot(nat_maps, async=True)
Beispiel #3
0
 def _update_chains(self):
     updates, deps = self.iptables_generator.endpoint_updates(
         IP_TYPE_TO_VERSION[self.ip_type], self.combined_id.endpoint,
         self._suffix, self._mac, self.endpoint["profile_ids"])
     try:
         self.iptables_updater.rewrite_chains(updates, deps, async=False)
         self.fip_manager.update_endpoint(self.combined_id,
                                          self.endpoint.get(
                                              nat_key(self.ip_type), None),
                                          async=True)
     except FailedSystemCall:
         _log.exception("Failed to program chains for %s. Removing.", self)
         try:
             self.iptables_updater.delete_chains(
                 self.iptables_generator.endpoint_chain_names(self._suffix),
                 async=False)
             self.fip_manager.update_endpoint(self.combined_id,
                                              None,
                                              async=True)
         except FailedSystemCall:
             _log.exception("Failed to remove chains after original "
                            "failure")
     else:
         self._iptables_in_sync = True
         self._chains_programmed = True
Beispiel #4
0
    def _configure_interface(self):
        """
        Applies sysctls and routes to the interface.
        """
        if not self._device_is_up:
            _log.debug("Device is known to be down, skipping attempt to "
                       "configure it.")
            return
        try:
            if self.ip_type == IPV4:
                devices.configure_interface_ipv4(self._iface_name)
                reset_arp = self._mac_changed
            else:
                ipv6_gw = self.endpoint.get("ipv6_gateway", None)
                devices.configure_interface_ipv6(self._iface_name, ipv6_gw)
                reset_arp = False

            ips = set()
            for ip in self.endpoint.get(self.nets_key, []):
                ips.add(futils.net_to_ip(ip))
            for nat_map in self.endpoint.get(nat_key(self.ip_type), []):
                ips.add(nat_map['ext_ip'])
            devices.set_routes(self.ip_type,
                               ips,
                               self._iface_name,
                               self.endpoint.get("mac"),
                               reset_arp=reset_arp)

        except (IOError, FailedSystemCall) as e:
            if not devices.interface_exists(self._iface_name):
                _log.info("Interface %s for %s does not exist yet",
                          self._iface_name, self.combined_id)
            elif not devices.interface_up(self._iface_name):
                _log.info("Interface %s for %s is not up yet",
                          self._iface_name, self.combined_id)
            else:
                # Either the interface flapped back up after the failure (in
                # which case we'll retry when the event reaches us) or there
                # was a genuine failure due to bad data or some other factor.
                #
                # Since the former is fairly common, we log at warning level
                # rather than error, which avoids false positives.
                _log.warning(
                    "Failed to configure interface %s for %s: %r.  "
                    "Either the interface is flapping or it is "
                    "misconfigured.", self._iface_name, self.combined_id, e)
        else:
            _log.info("Interface %s configured", self._iface_name)
            super(WorkloadEndpoint, self)._configure_interface()
Beispiel #5
0
    def _configure_interface(self):
        """
        Applies sysctls and routes to the interface.
        """
        if not self._device_is_up:
            _log.debug("Device is known to be down, skipping attempt to "
                       "configure it.")
            return
        try:
            if self.ip_type == IPV4:
                devices.configure_interface_ipv4(self._iface_name)
                reset_arp = self._mac_changed
            else:
                ipv6_gw = self.endpoint.get("ipv6_gateway", None)
                devices.configure_interface_ipv6(self._iface_name, ipv6_gw)
                reset_arp = False

            ips = set()
            for ip in self.endpoint.get(self.nets_key, []):
                ips.add(futils.net_to_ip(ip))
            for nat_map in self.endpoint.get(nat_key(self.ip_type), []):
                ips.add(nat_map['ext_ip'])
            devices.set_routes(self.ip_type, ips,
                               self._iface_name,
                               self.endpoint["mac"],
                               reset_arp=reset_arp)

        except (IOError, FailedSystemCall) as e:
            if not devices.interface_exists(self._iface_name):
                _log.info("Interface %s for %s does not exist yet",
                          self._iface_name, self.combined_id)
            elif not devices.interface_up(self._iface_name):
                _log.info("Interface %s for %s is not up yet",
                          self._iface_name, self.combined_id)
            else:
                # Either the interface flapped back up after the failure (in
                # which case we'll retry when the event reaches us) or there
                # was a genuine failure due to bad data or some other factor.
                #
                # Since the former is fairly common, we log at warning level
                # rather than error, which avoids false positives.
                _log.warning("Failed to configure interface %s for %s: %r.  "
                             "Either the interface is flapping or it is "
                             "misconfigured.", self._iface_name,
                             self.combined_id, e)
        else:
            _log.info("Interface %s configured", self._iface_name)
            self._device_in_sync = True
Beispiel #6
0
 def nat_key(self):
     return nat_key(self.ip_type)
Beispiel #7
0
 def nat_key(self):
     return nat_key(self.ip_type)