예제 #1
0
    def refresh_nvgre_records(self, **kwargs):
        self._refresh_tunneling_agents()
        ports = self._n_client.get_network_ports(**kwargs)

        # process ports that were not processed yet.
        # process ports that are bound to tunneling_agents.
        ports = [p for p in ports if p['id'] not in self._nvgre_ports and
                 p['binding:host_id'] in self._tunneling_agents and
                 p['network_id'] in six.iterkeys(self._network_vsids)]

        for port in ports:
            tunneling_ip = self._tunneling_agents[port['binding:host_id']]
            customer_addr = port['fixed_ips'][0]['ip_address']
            mac_addr = port['mac_address'].replace(':', '')
            segmentation_id = self._network_vsids[port['network_id']]
            try:
                self._register_lookup_record(
                    tunneling_ip, customer_addr, mac_addr, segmentation_id)

                self._nvgre_ports.append(port['id'])
            except Exception as ex:
                LOG.error(_LE("Exception while adding lookup_record: %(ex)s. "
                              "VSID: %(vsid)s MAC: %(mac_address)s Customer "
                              "IP:%(cust_addr)s Provider IP: %(prov_addr)s"),
                          dict(ex=ex,
                               vsid=segmentation_id,
                               mac_address=mac_addr,
                               cust_addr=customer_addr,
                               prov_addr=tunneling_ip))
예제 #2
0
    def create_customer_routes(self, vsid, network_name, dest_prefix, gateway):
        cust_route_string = network_name + dest_prefix + str(vsid)
        rdid_uuid = uuid.uuid5(uuid.NAMESPACE_X500, cust_route_string)
        rdid_uuid = str(rdid_uuid)

        routes = self._scimv2.MSFT_NetVirtualizationCustomerRouteSettingData(
            VirtualSubnetID=vsid)

        for route in routes:
            route.Delete_()

        # TODO(claudiub): the logic should be moved to nvgre_ops. This should
        # create only one router per call.

        self._create_cust_route(vsid, dest_prefix, constants.IPV4_DEFAULT,
                                rdid_uuid)

        if not gateway:
            LOG.info(_LI('Subnet does not have gateway configured. Skipping.'))
            return

        if gateway.split('.')[-1] == '1':
            LOG.error(
                _LE('Subnet has unsupported gateway IP ending in 1: %s. '
                    'Any other gateway IP is supported.'), gateway)
            return

        # TODO(claudiub): what if there is no gateway?
        self._create_cust_route(vsid, '%s/0' % constants.IPV4_DEFAULT, gateway,
                                rdid_uuid)

        # customer route for metadata is also necessary.
        self._create_cust_route(vsid,
                                '%s/32' % CONF.AGENT.neutron_metadata_address,
                                gateway, rdid_uuid)
예제 #3
0
    def _create_customer_routes(self, segmentation_id, cidr, gw, rdid_uuid):
        self._nvgre_utils.clear_customer_routes(segmentation_id)

        # create cidr -> 0.0.0.0/0 customer route
        self._nvgre_utils.create_customer_route(segmentation_id, cidr,
                                                constants.IPV4_DEFAULT,
                                                rdid_uuid)

        if not gw:
            LOG.info(
                _LI('Subnet does not have gateway configured. '
                    'Skipping.'))
        elif gw.split('.')[-1] == '1':
            LOG.error(
                _LE('Subnet has unsupported gateway IP ending in 1: '
                    '%s. Any other gateway IP is supported.'), gw)
        else:
            # create 0.0.0.0/0 -> gateway customer route
            self._nvgre_utils.create_customer_route(
                segmentation_id, '%s/0' % constants.IPV4_DEFAULT, gw,
                rdid_uuid)

            # create metadata address -> gateway customer route
            metadata_addr = '%s/32' % CONF.AGENT.neutron_metadata_address
            self._nvgre_utils.create_customer_route(segmentation_id,
                                                    metadata_addr, gw,
                                                    rdid_uuid)
예제 #4
0
 def _report_state(self):
     try:
         self.state_rpc.report_state(self.context,
                                     self.agent_state)
         self.agent_state.pop('start_flag', None)
     except Exception:
         LOG.exception(_LE("Failed reporting state!"))
예제 #5
0
    def refresh_nvgre_records(self, **kwargs):
        self._refresh_tunneling_agents()
        ports = self._n_client.get_network_ports(**kwargs)

        # process ports that were not processed yet.
        # process ports that are bound to tunneling_agents.
        ports = [
            p for p in ports if p['id'] not in self._nvgre_ports
            and p['binding:host_id'] in self._tunneling_agents
            and p['network_id'] in six.iterkeys(self._network_vsids)
        ]

        for port in ports:
            tunneling_ip = self._tunneling_agents[port['binding:host_id']]
            customer_addr = port['fixed_ips'][0]['ip_address']
            mac_addr = port['mac_address'].replace(':', '')
            segmentation_id = self._network_vsids[port['network_id']]
            try:
                self._register_lookup_record(tunneling_ip, customer_addr,
                                             mac_addr, segmentation_id)

                self._nvgre_ports.append(port['id'])
            except Exception as ex:
                LOG.error(
                    _LE("Exception while adding lookup_record: %(ex)s. "
                        "VSID: %(vsid)s MAC: %(mac_address)s Customer "
                        "IP:%(cust_addr)s Provider IP: %(prov_addr)s"),
                    dict(ex=ex,
                         vsid=segmentation_id,
                         mac_address=mac_addr,
                         cust_addr=customer_addr,
                         prov_addr=tunneling_ip))
    def daemon_loop(self):
        sync = True
        ports = set()

        while True:
            try:
                start = time.time()
                if sync:
                    LOG.info(_LI("Agent out of sync with plugin!"))
                    ports.clear()
                    sync = False

                port_info = self._update_ports(ports)

                # notify plugin about port deltas
                if port_info:
                    LOG.debug("Agent loop has new devices!")
                    # If treat devices fails - must resync with plugin
                    sync = self._process_network_ports(port_info)
                    ports = port_info['current']

                self._port_enable_control_metrics()
            except Exception:
                LOG.exception(_LE("Error in agent event loop"))
                sync = True

            # sleep till end of polling interval
            elapsed = (time.time() - start)
            if (elapsed < self._polling_interval):
                time.sleep(self._polling_interval - elapsed)
            else:
                LOG.debug("Loop iteration exceeded interval "
                          "(%(polling_interval)s vs. %(elapsed)s)",
                          {'polling_interval': self._polling_interval,
                           'elapsed': elapsed})
예제 #7
0
    def _port_bound(self, port_id, net_uuid, network_type, physical_network,
                    segmentation_id):
        LOG.debug("Binding port %s", port_id)

        if net_uuid not in self._network_vswitch_map:
            self._provision_network(port_id, net_uuid, network_type,
                                    physical_network, segmentation_id)

        map = self._network_vswitch_map[net_uuid]
        map['ports'].append(port_id)

        self._utils.connect_vnic_to_vswitch(map['vswitch_name'], port_id)

        if network_type == constants.TYPE_VLAN:
            LOG.info(
                _LI('Binding VLAN ID %(segmentation_id)s '
                    'to switch port %(port_id)s'),
                dict(segmentation_id=segmentation_id, port_id=port_id))
            self._utils.set_vswitch_port_vlan_id(segmentation_id, port_id)
        elif network_type == constants.TYPE_NVGRE and self._nvgre_enabled:
            self._nvgre_ops.bind_nvgre_port(segmentation_id,
                                            map['vswitch_name'], port_id)
        elif network_type == constants.TYPE_FLAT:
            # Nothing to do
            pass
        elif network_type == constants.TYPE_LOCAL:
            # Nothing to do
            pass
        else:
            LOG.error(_LE('Unsupported network type %s'), network_type)

        if self.enable_metrics_collection:
            self._utils.add_metrics_collection_acls(port_id)
            self._port_metric_retries[port_id] = self._metrics_max_retries
예제 #8
0
    def create_customer_routes(self, vsid, network_name, dest_prefix, gateway):
        cust_route_string = network_name + dest_prefix + str(vsid)
        rdid_uuid = uuid.uuid5(uuid.NAMESPACE_X500, cust_route_string)
        rdid_uuid = str(rdid_uuid)

        routes = self._scimv2.MSFT_NetVirtualizationCustomerRouteSettingData(
            VirtualSubnetID=vsid)

        for route in routes:
            route.Delete_()

        # TODO(claudiub): the logic should be moved to nvgre_ops. This should
        # create only one router per call.

        self._create_cust_route(
            vsid, dest_prefix, constants.IPV4_DEFAULT, rdid_uuid)

        if not gateway:
            LOG.info(_LI('Subnet does not have gateway configured. Skipping.'))
            return

        if gateway.split('.')[-1] == '1':
            LOG.error(_LE('Subnet has unsupported gateway IP ending in 1: %s. '
                          'Any other gateway IP is supported.'), gateway)
            return

        # TODO(claudiub): what if there is no gateway?
        self._create_cust_route(
            vsid, '%s/0' % constants.IPV4_DEFAULT, gateway, rdid_uuid)

        # customer route for metadata is also necessary.
        self._create_cust_route(
            vsid, '%s/32' % CONF.AGENT.neutron_metadata_address, gateway,
            rdid_uuid)
    def daemon_loop(self):
        sync = True
        ports = set()

        while True:
            try:
                start = time.time()
                if sync:
                    LOG.info(_LI("Agent out of sync with plugin!"))
                    ports.clear()
                    sync = False

                port_info = self._update_ports(ports)

                # notify plugin about port deltas
                if port_info:
                    LOG.debug("Agent loop has new devices!")
                    # If treat devices fails - must resync with plugin
                    sync = self._process_network_ports(port_info)
                    ports = port_info['current']

                self._port_enable_control_metrics()
            except Exception:
                LOG.exception(_LE("Error in agent event loop"))
                sync = True

            # sleep till end of polling interval
            elapsed = (time.time() - start)
            if (elapsed < self._polling_interval):
                time.sleep(self._polling_interval - elapsed)
            else:
                LOG.debug("Loop iteration exceeded interval "
                          "(%(polling_interval)s vs. %(elapsed)s)",
                          {'polling_interval': self._polling_interval,
                           'elapsed': elapsed})
    def _port_bound(self, port_id, net_uuid, network_type, physical_network, segmentation_id):
        LOG.debug("Binding port %s", port_id)

        if net_uuid not in self._network_vswitch_map:
            self._provision_network(port_id, net_uuid, network_type, physical_network, segmentation_id)

        map = self._network_vswitch_map[net_uuid]
        map["ports"].append(port_id)

        self._utils.connect_vnic_to_vswitch(map["vswitch_name"], port_id)

        if network_type == constants.TYPE_VLAN:
            LOG.info(
                _LI("Binding VLAN ID %(segmentation_id)s " "to switch port %(port_id)s"),
                dict(segmentation_id=segmentation_id, port_id=port_id),
            )
            self._utils.set_vswitch_port_vlan_id(segmentation_id, port_id)
        elif network_type == constants.TYPE_NVGRE and self._nvgre_enabled:
            self._nvgre_ops.bind_nvgre_port(segmentation_id, map["vswitch_name"], port_id)
        elif network_type == constants.TYPE_FLAT:
            # Nothing to do
            pass
        elif network_type == constants.TYPE_LOCAL:
            # Nothing to do
            pass
        else:
            LOG.error(_LE("Unsupported network type %s"), network_type)

        if self.enable_metrics_collection:
            self._utils.enable_port_metrics_collection(port_id)
            self._port_metric_retries[port_id] = self._metrics_max_retries
 def _remove_port_rules(self, port_id, rules):
     for rule in rules:
         param_map = self._create_param_map(rule)
         try:
             self._utils.remove_security_rule(port_id, **param_map)
         except Exception as ex:
             LOG.error(_LE('Hyper-V Exception: %(hyperv_exeption)s while '
                           'removing rule: %(rule)s'),
                       dict(hyperv_exeption=ex, rule=rule))
예제 #12
0
    def get_network_subnets(self, network_id):
        try:
            net = self._client.show_network(network_id)
            return net['network']['subnets']
        except Exception as ex:
            LOG.error(_LE("Could not retrieve network %(network_id)s . Error: "
                          "%(ex)s"), {'network_id': network_id, 'ex': ex})

        return []
예제 #13
0
    def get_network_subnet_cidr_and_gateway(self, subnet_id):
        try:
            subnet = self._client.show_subnet(subnet_id)['subnet']
            return (str(subnet['cidr']), str(subnet['gateway_ip']))
        except Exception as ex:
            LOG.error(_LE("Could not retrieve subnet %(subnet_id)s . Error: "
                          "%(ex)s: "), {'subnet_id': subnet_id, 'ex': ex})

        return None, None
예제 #14
0
    def get_network_iface_ip(self, network_name):
        networks = [n for n in self._get_network_ifaces_by_name(network_name)
                    if n.DriverDescription == self._HYPERV_VIRT_ADAPTER]

        if networks:
            ip_addr = self._scimv2.MSFT_NetIPAddress(
                InterfaceIndex=networks[0].InterfaceIndex,
                AddressFamily=self._IPV4_ADDRESS_FAMILY)

            if ip_addr:
                return (ip_addr[0].IPAddress, ip_addr[0].PrefixLength)
            else:
                LOG.error(_LE('No IP Address could be found for network: %s'),
                          network_name)
        else:
            LOG.error(_LE('No vswitch was found with name: %s'), network_name)

        return (None, None)
예제 #15
0
    def get_port_ip_address(self, port_id):
        try:
            port = self._client.show_port(port_id)
            fixed_ips = port['port']['fixed_ips'][0]
            return fixed_ips['ip_address']
        except Exception as ex:
            LOG.error(_LE("Could not retrieve port %(port_id)s . Error: "
                          "%(ex)s"), {'port_id': port_id, 'ex': ex})

        return None
 def _remove_port_rules(self, port_id, rules):
     for rule in rules:
         param_map = self._create_param_map(rule)
         try:
             self._utils.remove_security_rule(port_id, **param_map)
         except Exception as ex:
             LOG.error(
                 _LE('Hyper-V Exception: %(hyperv_exeption)s while '
                     'removing rule: %(rule)s'),
                 dict(hyperv_exeption=ex, rule=rule))
예제 #17
0
    def get_network_iface_ip(self, network_name):
        networks = [
            n for n in self._get_network_ifaces_by_name(network_name)
            if n.DriverDescription == self._HYPERV_VIRT_ADAPTER
        ]

        if networks:
            ip_addr = self._scimv2.MSFT_NetIPAddress(
                InterfaceIndex=networks[0].InterfaceIndex,
                AddressFamily=self._IPV4_ADDRESS_FAMILY)

            if ip_addr:
                return (ip_addr[0].IPAddress, ip_addr[0].PrefixLength)
            else:
                LOG.error(_LE('No IP Address could be found for network: %s'),
                          network_name)
        else:
            LOG.error(_LE('No vswitch was found with name: %s'), network_name)

        return (None, None)
 def _remove_sg_port_rules(self, port_id, sg_rules):
     if not sg_rules:
         return
     old_sg_rules = self._sec_group_rules[port_id]
     try:
         self._utils.remove_security_rules(port_id, sg_rules)
         for rule in sg_rules:
             old_sg_rules.remove(rule)
     except Exception:
         LOG.exception(_LE('Exception encountered while removing rules for '
                           'port: %s'), port_id)
         raise
 def _remove_sg_port_rules(self, port_id, sg_rules):
     if not sg_rules:
         return
     old_sg_rules = self._sec_group_rules[port_id]
     try:
         self._utils.remove_security_rules(port_id, sg_rules)
         for rule in sg_rules:
             old_sg_rules.remove(rule)
     except Exception as ex:
         LOG.error(_LE('Hyper-V Exception: %(hyperv_exeption)s while '
                       'removing rules for port: %(port_id)s'),
                   dict(hyperv_exeption=ex, port_id=port_id))
 def _add_sg_port_rules(self, port_id, sg_rules):
     if not sg_rules:
         return
     old_sg_rules = self._sec_group_rules[port_id]
     # yielding to other threads that must run (like state reporting)
     greenthread.sleep()
     try:
         self._utils.create_security_rules(port_id, sg_rules)
         old_sg_rules.extend(sg_rules)
     except Exception:
         LOG.exception(_LE('Exception encountered while adding rules for '
                           'port: %s'), port_id)
         raise
 def _add_sg_port_rules(self, port_id, sg_rules):
     if not sg_rules:
         return
     old_sg_rules = self._sec_group_rules[port_id]
     # yielding to other threads that must run (like state reporting)
     greenthread.sleep()
     try:
         self._utils.create_security_rules(port_id, sg_rules)
         old_sg_rules.extend(sg_rules)
     except Exception as ex:
         LOG.error(_LE('Hyper-V Exception: %(hyperv_exeption)s while '
                       'adding rules for port: %(port_id)s'),
                   dict(hyperv_exeption=ex, port_id=port_id))
예제 #22
0
 def _remove_sg_port_rules(self, port_id, sg_rules):
     if not sg_rules:
         return
     old_sg_rules = self._sec_group_rules[port_id]
     try:
         self._utils.remove_security_rules(port_id, sg_rules)
         for rule in sg_rules:
             old_sg_rules.remove(rule)
     except Exception as ex:
         LOG.error(
             _LE('Hyper-V Exception: %(hyperv_exeption)s while '
                 'removing rules for port: %(port_id)s'),
             dict(hyperv_exeption=ex, port_id=port_id))
예제 #23
0
 def _add_sg_port_rules(self, port_id, sg_rules):
     if not sg_rules:
         return
     old_sg_rules = self._sec_group_rules[port_id]
     # yielding to other threads that must run (like state reporting)
     greenthread.sleep()
     try:
         self._utils.create_security_rules(port_id, sg_rules)
         old_sg_rules.extend(sg_rules)
     except Exception as ex:
         LOG.error(
             _LE('Hyper-V Exception: %(hyperv_exeption)s while '
                 'adding rules for port: %(port_id)s'),
             dict(hyperv_exeption=ex, port_id=port_id))
 def _add_sg_port_rules(self, port_id, sg_rules):
     if not sg_rules:
         return
     old_sg_rules = self._sec_group_rules[port_id]
     try:
         self._utils.create_security_rules(port_id, sg_rules)
         old_sg_rules.extend(sg_rules)
     except exceptions.NotFound:
         # port no longer exists.
         self._sec_group_rules.pop(port_id, None)
         raise
     except Exception:
         LOG.exception(_LE('Exception encountered while adding rules for '
                           'port: %s'), port_id)
         raise
 def _add_sg_port_rules(self, port_id, sg_rules):
     if not sg_rules:
         return
     old_sg_rules = self._sec_group_rules[port_id]
     try:
         self._utils.create_security_rules(port_id, sg_rules)
         old_sg_rules.extend(sg_rules)
     except exceptions.NotFound:
         # port no longer exists.
         self._sec_group_rules.pop(port_id, None)
         raise
     except Exception:
         LOG.exception(_LE('Exception encountered while adding rules for '
                           'port: %s'), port_id)
         raise
    def _port_enable_control_metrics(self):
        if not self.enable_metrics_collection:
            return

        for port_id in self._port_metric_retries.keys():
            if self._utils.can_enable_control_metrics(port_id):
                self._utils.enable_control_metrics(port_id)
                LOG.info(_LI("Port metrics enabled for port: %s"), port_id)
                del self._port_metric_retries[port_id]
            elif self._port_metric_retries[port_id] < 1:
                self._utils.enable_control_metrics(port_id)
                LOG.error(_LE("Port metrics raw enabling for port: %s"), port_id)
                del self._port_metric_retries[port_id]
            else:
                self._port_metric_retries[port_id] -= 1
    def _port_enable_control_metrics(self):
        if not self.enable_metrics_collection:
            return

        for port_id in list(self._port_metric_retries.keys()):
            if self._utils.is_metrics_collection_allowed(port_id):
                self._metricsutils.enable_port_metrics_collection(port_id)
                LOG.info(_LI('Port metrics enabled for port: %s'), port_id)
                del self._port_metric_retries[port_id]
            elif self._port_metric_retries[port_id] < 1:
                self._metricsutils.enable_port_metrics_collection(port_id)
                LOG.error(_LE('Port metrics raw enabling for port: %s'),
                          port_id)
                del self._port_metric_retries[port_id]
            else:
                self._port_metric_retries[port_id] -= 1
예제 #28
0
    def _port_enable_control_metrics(self):
        if not self.enable_metrics_collection:
            return

        for port_id in list(self._port_metric_retries.keys()):
            if self._utils.can_enable_control_metrics(port_id):
                self._utils.enable_control_metrics(port_id)
                LOG.info(_LI('Port metrics enabled for port: %s'), port_id)
                del self._port_metric_retries[port_id]
            elif self._port_metric_retries[port_id] < 1:
                self._utils.enable_control_metrics(port_id)
                LOG.error(_LE('Port metrics raw enabling for port: %s'),
                          port_id)
                del self._port_metric_retries[port_id]
            else:
                self._port_metric_retries[port_id] -= 1
 def _remove_sg_port_rules(self, port_id, sg_rules):
     if not sg_rules:
         return
     old_sg_rules = self._sec_group_rules[port_id]
     try:
         self._utils.remove_security_rules(port_id, sg_rules)
         for rule in sg_rules:
             if rule in old_sg_rules:
                 old_sg_rules.remove(rule)
     except exceptions.NotFound:
         # port no longer exists.
         self._sec_group_rules.pop(port_id, None)
         raise
     except Exception:
         LOG.exception(_LE('Exception encountered while removing rules for '
                           'port: %s'), port_id)
         raise
예제 #30
0
    def daemon_loop(self):
        # init NVGRE after the RPC connection and context is created.
        self._init_nvgre()

        sync = True
        ports = set()

        while True:
            try:
                start = time.time()
                if sync:
                    LOG.info(_LI("Agent out of sync with plugin!"))
                    ports.clear()
                    sync = False

                port_info = self._update_ports(ports)

                # notify plugin about port deltas
                if port_info:
                    LOG.debug("Agent loop has new devices!")
                    # If treat devices fails - must resync with plugin
                    sync = self._process_network_ports(port_info)
                    ports = port_info['current']

                if self._nvgre_enabled:
                    self._nvgre_ops.refresh_nvgre_records()
                self._port_enable_control_metrics()
            except Exception:
                LOG.exception(_LE("Error in agent event loop"))

                # inconsistent cache might cause exceptions. for example, if a
                # port has been removed, it will be known in the next loop.
                # using the old switch port can cause exceptions.
                self._utils.update_cache()

            # sleep till end of polling interval
            elapsed = (time.time() - start)
            if (elapsed < self._polling_interval):
                time.sleep(self._polling_interval - elapsed)
            else:
                LOG.debug(
                    "Loop iteration exceeded interval "
                    "(%(polling_interval)s vs. %(elapsed)s)", {
                        'polling_interval': self._polling_interval,
                        'elapsed': elapsed
                    })
    def daemon_loop(self):
        # The following sets contain ports that are to be processed.
        self._added_ports = self._utils.get_vnic_ids()
        self._removed_ports = set()
        # The following sets contain ports that have been processed.
        self._bound_ports = set()
        self._unbound_ports = set()

        self._create_event_listeners()

        while True:
            try:
                start = time.time()

                eventlet.spawn_n(self._notify_plugin_on_port_updates)

                # notify plugin about port deltas
                if self._added_ports:
                    LOG.debug("Agent loop has new devices!")
                    self._treat_devices_added()

                if self._removed_ports:
                    LOG.debug("Agent loop has lost devices...")
                    self._treat_devices_removed()

                if self._nvgre_enabled:
                    self._nvgre_ops.refresh_nvgre_records()
                self._port_enable_control_metrics()
            except Exception:
                LOG.exception(_LE("Error in agent event loop"))

                # inconsistent cache might cause exceptions. for example, if a
                # port has been removed, it will be known in the next loop.
                # using the old switch port can cause exceptions.
                self._utils.update_cache()

            # sleep till end of polling interval
            elapsed = (time.time() - start)
            if (elapsed < self._polling_interval):
                time.sleep(self._polling_interval - elapsed)
            else:
                LOG.debug("Loop iteration exceeded interval "
                          "(%(polling_interval)s vs. %(elapsed)s)",
                          {'polling_interval': self._polling_interval,
                           'elapsed': elapsed})
예제 #32
0
    def daemon_loop(self):
        # The following sets contain ports that are to be processed.
        self._added_ports = self._utils.get_vnic_ids()
        self._removed_ports = set()
        # The following sets contain ports that have been processed.
        self._bound_ports = set()
        self._unbound_ports = set()

        self._create_event_listeners()

        while True:
            try:
                start = time.time()

                eventlet.spawn_n(self._notify_plugin_on_port_updates)

                # notify plugin about port deltas
                if self._added_ports:
                    LOG.debug("Agent loop has new devices!")
                    self._treat_devices_added()

                if self._removed_ports:
                    LOG.debug("Agent loop has lost devices...")
                    self._treat_devices_removed()

                if self._nvgre_enabled:
                    self._nvgre_ops.refresh_nvgre_records()
                self._port_enable_control_metrics()
            except Exception:
                LOG.exception(_LE("Error in agent event loop"))

                # inconsistent cache might cause exceptions. for example, if a
                # port has been removed, it will be known in the next loop.
                # using the old switch port can cause exceptions.
                self._utils.update_cache()

            # sleep till end of polling interval
            elapsed = (time.time() - start)
            if (elapsed < self._polling_interval):
                time.sleep(self._polling_interval - elapsed)
            else:
                LOG.debug("Loop iteration exceeded interval "
                          "(%(polling_interval)s vs. %(elapsed)s)",
                          {'polling_interval': self._polling_interval,
                           'elapsed': elapsed})
예제 #33
0
    def bind_nvgre_network(self, segmentation_id, net_uuid, vswitch_name):
        subnets = self._n_client.get_network_subnets(net_uuid)
        if len(subnets) > 1:
            LOG.warning(_LW("Multiple subnets in the same network is not "
                            "supported."))
        subnet = subnets[0]
        try:
            cidr, gw = self._n_client.get_network_subnet_cidr_and_gateway(
                subnet)
            self._nvgre_utils.create_customer_routes(
                segmentation_id, vswitch_name, cidr, gw)
        except Exception as ex:
            LOG.error(_LE("Exception caught: %s"), ex)

        self._network_vsids[net_uuid] = segmentation_id
        self.refresh_nvgre_records(network_id=net_uuid)
        self._notifier.tunnel_update(
            self.context, CONF.NVGRE.provider_tunnel_ip, segmentation_id)
    def daemon_loop(self):
        # init NVGRE after the RPC connection and context is created.
        self._init_nvgre()

        sync = True
        ports = set()

        while True:
            try:
                start = time.time()
                if sync:
                    LOG.info(_LI("Agent out of sync with plugin!"))
                    ports.clear()
                    sync = False

                port_info = self._update_ports(ports)

                # notify plugin about port deltas
                if port_info:
                    LOG.debug("Agent loop has new devices!")
                    # If treat devices fails - must resync with plugin
                    sync = self._process_network_ports(port_info)
                    ports = port_info['current']

                if self._nvgre_enabled:
                    self._nvgre_ops.refresh_nvgre_records()
                self._port_enable_control_metrics()
            except Exception:
                LOG.exception(_LE("Error in agent event loop"))

                # inconsistent cache might cause exceptions. for example, if a
                # port has been removed, it will be known in the next loop.
                # using the old switch port can cause exceptions.
                self._utils.update_cache()

            # sleep till end of polling interval
            elapsed = (time.time() - start)
            if (elapsed < self._polling_interval):
                time.sleep(self._polling_interval - elapsed)
            else:
                LOG.debug("Loop iteration exceeded interval "
                          "(%(polling_interval)s vs. %(elapsed)s)",
                          {'polling_interval': self._polling_interval,
                           'elapsed': elapsed})
    def _setup_trunk(self, trunk, vlan_id=None):
        """Sets up VLAN trunk and updates the trunk status."""

        LOG.info(_LI('Binding trunk port: %s.'), trunk)
        try:
            # bind sub_ports to host.
            self._trunk_rpc.update_subport_bindings(self._context,
                                                    trunk.sub_ports)

            vlan_trunk = [s.segmentation_id for s in trunk.sub_ports]
            self._set_port_vlan(trunk.port_id, vlan_id, vlan_trunk)

            self._trunk_rpc.update_trunk_status(self._context, trunk.id,
                                                t_const.ACTIVE_STATUS)
        except Exception:
            # something broke
            LOG.exception(_LE("Failure setting up subports for %s"),
                          trunk.port_id)
            self._trunk_rpc.update_trunk_status(self._context, trunk.id,
                                                t_const.DEGRADED_STATUS)
    def bind_nvgre_network(self, segmentation_id, net_uuid, vswitch_name):
        subnets = self._n_client.get_network_subnets(net_uuid)
        if len(subnets) > 1:
            LOG.warning(
                _LW("Multiple subnets in the same network is not "
                    "supported."))
        subnet = subnets[0]
        try:
            cidr, gw = self._n_client.get_network_subnet_cidr_and_gateway(
                subnet)
            self._nvgre_utils.create_customer_routes(segmentation_id,
                                                     vswitch_name, cidr, gw)
        except Exception as ex:
            LOG.error(_LE("Exception caught: %s"), ex)

        self._network_vsids[net_uuid] = segmentation_id
        self.refresh_nvgre_records(network_id=net_uuid)
        self._notifier.tunnel_update(self.context,
                                     CONF.NVGRE.provider_tunnel_ip,
                                     segmentation_id)
예제 #37
0
    def get_tunneling_agents(self):
        try:
            agents = self._client.list_agents()
            tunneling_agents = [
                a for a in agents['agents'] if constants.TYPE_NVGRE in
                a.get('configurations', {}).get('tunnel_types', [])]

            tunneling_ip_agents = [
                a for a in tunneling_agents if
                a.get('configurations', {}).get('tunneling_ip')]

            if len(tunneling_ip_agents) < len(tunneling_agents):
                LOG.warning(_LW('Some agents have NVGRE tunneling enabled, but'
                                ' do not provide tunneling_ip. Ignoring those '
                                'agents.'))

            return dict([(a['host'], a['configurations']['tunneling_ip'])
                         for a in tunneling_ip_agents])
        except Exception as ex:
            LOG.error(_LE("Could not get tunneling agents. Error: %s"), ex)
            return {}
    def _process_added_port(self, device_details):
        device = device_details['device']
        port_id = device_details['port_id']

        try:
            self._treat_vif_port(port_id,
                                 device_details['network_id'],
                                 device_details['network_type'],
                                 device_details['physical_network'],
                                 device_details['segmentation_id'],
                                 device_details['admin_state_up'])

            LOG.debug("Updating cached port %s status as UP.", port_id)
            self._update_port_status_cache(device, device_bound=True)
            LOG.info("Port %s processed.", port_id)
        except Exception:
            LOG.exception(_LE("Exception encountered while processing port "
                              "%s."), port_id)

            # readd the port as "added", so it can be reprocessed.
            self._added_ports.add(device)
예제 #39
0
    def set_switch_external_port_trunk_vlan(self, vswitch_name, vlan_id,
                                            desired_endpoint_mode):
        vswitch_external_port = self._get_vswitch_external_port(vswitch_name)
        if vswitch_external_port:
            vlan_endpoint = vswitch_external_port.associators(
                wmi_association_class=self._BINDS_TO)[0]
            vlan_endpoint_settings = vlan_endpoint.associators(
                wmi_result_class=self._VLAN_ENDPOINT_SET_DATA)[0]
            if vlan_id not in vlan_endpoint_settings.TrunkedVLANList:
                vlan_endpoint_settings.TrunkedVLANList += (vlan_id,)
                vlan_endpoint_settings.put()

            if (desired_endpoint_mode not in
                    vlan_endpoint.SupportedEndpointModes):
                LOG.error(_LE("'Trunk' VLAN endpoint mode is not supported by "
                              "the switch / physycal network adapter. Correct "
                              "this issue or use flat networks instead."))
                return
            if vlan_endpoint.DesiredEndpointMode != desired_endpoint_mode:
                vlan_endpoint.DesiredEndpointMode = desired_endpoint_mode
                vlan_endpoint.put()
예제 #40
0
    def _process_added_port(self, device_details):
        device = device_details['device']
        port_id = device_details['port_id']

        try:
            self._treat_vif_port(port_id, device_details['network_id'],
                                 device_details['network_type'],
                                 device_details['physical_network'],
                                 device_details['segmentation_id'],
                                 device_details['admin_state_up'])

            LOG.debug("Updating port %s status as UP.", port_id)
            self.plugin_rpc.update_device_up(self.context, device,
                                             self.agent_id, self._host)
            LOG.info("Port %s processed.", port_id)
        except Exception:
            LOG.exception(
                _LE("Exception encountered while processing port "
                    "%s."), port_id)

            # readd the port as "added", so it can be reprocessed.
            self._added_ports.add(device)
    def daemon_loop(self):
        # init NVGRE after the RPC connection and context is created.
        self._init_nvgre()

        sync = True
        ports = set()

        while True:
            try:
                start = time.time()
                if sync:
                    LOG.info(_LI("Agent out of sync with plugin!"))
                    ports.clear()
                    sync = False

                port_info = self._update_ports(ports)

                # notify plugin about port deltas
                if port_info:
                    LOG.debug("Agent loop has new devices!")
                    # If treat devices fails - must resync with plugin
                    sync = self._process_network_ports(port_info)
                    ports = port_info["current"]

                if self._nvgre_enabled:
                    self._nvgre_ops.refresh_nvgre_records()
                self._port_enable_control_metrics()
            except Exception:
                LOG.exception(_LE("Error in agent event loop"))

            # sleep till end of polling interval
            elapsed = time.time() - start
            if elapsed < self._polling_interval:
                time.sleep(self._polling_interval - elapsed)
            else:
                LOG.debug(
                    "Loop iteration exceeded interval " "(%(polling_interval)s vs. %(elapsed)s)",
                    {"polling_interval": self._polling_interval, "elapsed": elapsed},
                )
예제 #42
0
    def set_switch_external_port_trunk_vlan(self, vswitch_name, vlan_id,
                                            desired_endpoint_mode):
        vswitch_external_port = self._get_vswitch_external_port(vswitch_name)
        if vswitch_external_port:
            vlan_endpoint = vswitch_external_port.associators(
                wmi_association_class=self._BINDS_TO)[0]
            vlan_endpoint_settings = vlan_endpoint.associators(
                wmi_result_class=self._VLAN_ENDPOINT_SET_DATA)[0]
            if vlan_id not in vlan_endpoint_settings.TrunkedVLANList:
                vlan_endpoint_settings.TrunkedVLANList += (vlan_id, )
                vlan_endpoint_settings.put()

            if (desired_endpoint_mode
                    not in vlan_endpoint.SupportedEndpointModes):
                LOG.error(
                    _LE("'Trunk' VLAN endpoint mode is not supported by "
                        "the switch / physycal network adapter. Correct "
                        "this issue or use flat networks instead."))
                return
            if vlan_endpoint.DesiredEndpointMode != desired_endpoint_mode:
                vlan_endpoint.DesiredEndpointMode = desired_endpoint_mode
                vlan_endpoint.put()
    def _port_enable_control_metrics(self):
        if not self.enable_metrics_collection:
            return

        for port_id in list(self._port_metric_retries.keys()):
            try:
                if self._utils.is_metrics_collection_allowed(port_id):
                    self._metricsutils.enable_port_metrics_collection(port_id)
                    LOG.info(_LI('Port metrics enabled for port: %s'), port_id)
                    del self._port_metric_retries[port_id]
                elif self._port_metric_retries[port_id] < 1:
                    self._metricsutils.enable_port_metrics_collection(port_id)
                    LOG.error(_LE('Port metrics raw enabling for port: %s'),
                              port_id)
                    del self._port_metric_retries[port_id]
                else:
                    self._port_metric_retries[port_id] -= 1
            except exceptions.NotFound:
                # the vNIC no longer exists. it might have been removed or
                # the VM it was attached to was destroyed.
                LOG.warning(_LW("Port %s no longer exists. Cannot enable "
                                "metrics."), port_id)
                del self._port_metric_retries[port_id]
예제 #44
0
    def _process_added_port(self, device_details):
        device = device_details['device']
        port_id = device_details['port_id']

        try:
            self._treat_vif_port(port_id,
                                 device_details['network_id'],
                                 device_details['network_type'],
                                 device_details['physical_network'],
                                 device_details['segmentation_id'],
                                 device_details['admin_state_up'])
            if CONF.AGENT.enable_qos_extension:
                self._qos_ext.handle_port(self.context, device_details)

            LOG.debug("Updating cached port %s status as UP.", port_id)
            self._update_port_status_cache(device, device_bound=True)
            LOG.info("Port %s processed.", port_id)
        except Exception:
            LOG.exception(_LE("Exception encountered while processing port "
                              "%s."), port_id)

            # readd the port as "added", so it can be reprocessed.
            self._added_ports.add(device)
예제 #45
0
    def _port_enable_control_metrics(self):
        if not self.enable_metrics_collection:
            return

        for port_id in list(self._port_metric_retries.keys()):
            try:
                if self._utils.is_metrics_collection_allowed(port_id):
                    self._metricsutils.enable_port_metrics_collection(port_id)
                    LOG.info(_LI('Port metrics enabled for port: %s'), port_id)
                    del self._port_metric_retries[port_id]
                elif self._port_metric_retries[port_id] < 1:
                    self._metricsutils.enable_port_metrics_collection(port_id)
                    LOG.error(_LE('Port metrics raw enabling for port: %s'),
                              port_id)
                    del self._port_metric_retries[port_id]
                else:
                    self._port_metric_retries[port_id] -= 1
            except exceptions.NotFound:
                # the vNIC no longer exists. it might have been removed or
                # the VM it was attached to was destroyed.
                LOG.warning(_LW("Port %s no longer exists. Cannot enable "
                                "metrics."), port_id)
                del self._port_metric_retries[port_id]
    def _process_added_port(self, device_details):
        device = device_details['device']
        port_id = device_details['port_id']

        try:
            self._treat_vif_port(port_id,
                                 device_details['network_id'],
                                 device_details['network_type'],
                                 device_details['physical_network'],
                                 device_details['segmentation_id'],
                                 device_details['admin_state_up'])

            self.plugin_rpc.update_device_up(self.context,
                                             device,
                                             self.agent_id,
                                             self._host)
            LOG.info("Port %s processed.", port_id)
        except Exception:
            LOG.exception(_LE("Exception encountered while processing port "
                              "%s."), port_id)

            # readd the port as "added", so it can be reprocessed.
            self._added_ports.add(device)
예제 #47
0
 def _report_state(self):
     try:
         self.state_rpc.report_state(self.context, self.agent_state)
         self.agent_state.pop('start_flag', None)
     except Exception:
         LOG.exception(_LE("Failed reporting state!"))
예제 #48
0
 def get_network_ports(self, **kwargs):
     try:
         return self._client.list_ports(**kwargs)['ports']
     except Exception as ex:
         LOG.error(_LE("Exception caught: %s"), ex)
     return []