Example #1
0
    def check_global_dhcp_opts(self):
        # This periodic task is included in DBInconsistenciesPeriodics since
        # it uses the lock to ensure only one worker is executing
        if not self.has_lock:
            return
        if (not ovn_conf.get_global_dhcpv4_opts() and
                not ovn_conf.get_global_dhcpv6_opts()):
            # No need to scan the subnets if the settings are unset.
            raise periodics.NeverAgain()
        LOG.debug('Maintenance task: Checking DHCP options on subnets')
        self._sync_timer.restart()
        fix_subnets = self._check_subnet_global_dhcp_opts()
        if fix_subnets:
            admin_context = n_context.get_admin_context()
            LOG.debug('Triggering update for %s subnets', len(fix_subnets))
            for subnet in fix_subnets:
                neutron_net = self._ovn_client._plugin.get_network(
                    admin_context, subnet['network_id'])
                try:
                    self._ovn_client.update_subnet(admin_context, subnet,
                                                   neutron_net)
                except Exception:
                    LOG.exception('Failed to update subnet %s',
                                  subnet['id'])

        self._sync_timer.stop()
        LOG.info('Maintenance task: DHCP options check finished '
                 '(took %.2f seconds)', self._sync_timer.elapsed())

        raise periodics.NeverAgain()
Example #2
0
    def check_for_ha_chassis_group(self):
        # If external ports is not supported stop running
        # this periodic task
        if not self._ovn_client.is_external_ports_supported():
            raise periodics.NeverAgain()

        if not self.has_lock:
            return

        external_ports = self._nb_idl.db_find_rows(
            'Logical_Switch_Port', ('type', '=', ovn_const.LSP_TYPE_EXTERNAL)
        ).execute(check_error=True)

        context = n_context.get_admin_context()
        with self._nb_idl.transaction(check_error=True) as txn:
            for port in external_ports:
                network_id = port.external_ids[
                    ovn_const.OVN_NETWORK_NAME_EXT_ID_KEY].replace(
                        ovn_const.OVN_NAME_PREFIX, '')
                ha_ch_grp = self._ovn_client.sync_ha_chassis_group(
                    context, network_id, txn)
                try:
                    port_ha_ch_uuid = port.ha_chassis_group[0].uuid
                except IndexError:
                    port_ha_ch_uuid = None
                if port_ha_ch_uuid != ha_ch_grp:
                    txn.add(self._nb_idl.set_lswitch_port(
                        port.name, ha_chassis_group=ha_ch_grp))

            self._delete_default_ha_chassis_group(txn)

        raise periodics.NeverAgain()
Example #3
0
    def check_for_ha_chassis_group_address(self):
        # If external ports is not supported stop running
        # this periodic task
        if not self._ovn_client.is_external_ports_supported():
            raise periodics.NeverAgain()

        if not self.has_lock:
            return

        default_ch_grp = self._nb_idl.ha_chassis_group_add(
            ovn_const.HA_CHASSIS_GROUP_DEFAULT_NAME,
            may_exist=True).execute(check_error=True)

        # NOTE(lucasagomes): Find the existing chassis with the highest
        # priority and keep it as being the highest to avoid moving
        # things around
        high_prio_ch = max(default_ch_grp.ha_chassis,
                           key=lambda x: x.priority,
                           default=None)

        all_ch = self._sb_idl.get_all_chassis()
        gw_ch = self._sb_idl.get_gateway_chassis_from_cms_options()
        ch_to_del = set(all_ch) - set(gw_ch)

        with self._nb_idl.transaction(check_error=True) as txn:
            for ch in ch_to_del:
                txn.add(
                    self._nb_idl.ha_chassis_group_del_chassis(
                        ovn_const.HA_CHASSIS_GROUP_DEFAULT_NAME,
                        ch,
                        if_exists=True))

            # NOTE(lucasagomes): If the high priority chassis is in
            # the list of chassis to be added/updated. Add it first with
            # the highest priority number possible and then add the rest
            # (the priority of the rest of the chassis does not matter
            # since only the highest one is active)
            priority = ovn_const.HA_CHASSIS_GROUP_HIGHEST_PRIORITY
            if high_prio_ch and high_prio_ch.chassis_name in gw_ch:
                txn.add(
                    self._nb_idl.ha_chassis_group_add_chassis(
                        ovn_const.HA_CHASSIS_GROUP_DEFAULT_NAME,
                        high_prio_ch.chassis_name,
                        priority=priority))
                gw_ch.remove(high_prio_ch.chassis_name)
                priority -= 1

            for ch in gw_ch:
                txn.add(
                    self._nb_idl.ha_chassis_group_add_chassis(
                        ovn_const.HA_CHASSIS_GROUP_DEFAULT_NAME,
                        ch,
                        priority=priority))
                priority -= 1

        raise periodics.NeverAgain()
Example #4
0
    def check_metadata_ports(self):
        # If OVN metadata is disabled do not run this task again
        if not ovn_conf.is_ovn_metadata_enabled():
            raise periodics.NeverAgain()

        # Make sure that only one worker is executing this
        if not self.has_lock:
            return

        admin_context = n_context.get_admin_context()
        for n in self._ovn_client._plugin.get_networks(admin_context):
            self._ovn_client.create_metadata_port(admin_context, n)

        raise periodics.NeverAgain()
Example #5
0
    def check_baremetal_ports_dhcp_options(self):
        """Update baremetal ports DHCP options

        Update baremetal ports DHCP options based on the
        "disable_ovn_dhcp_for_baremetal_ports" configuration option.
        """
        # If external ports is not supported stop running
        # this periodic task
        if not self._ovn_client.is_external_ports_supported():
            raise periodics.NeverAgain()

        if not self.has_lock:
            return

        context = n_context.get_admin_context()
        ports = self._ovn_client._plugin.get_ports(
            context,
            filters={portbindings.VNIC_TYPE: portbindings.VNIC_BAREMETAL})
        if not ports:
            raise periodics.NeverAgain()

        with self._nb_idl.transaction(check_error=True) as txn:
            for port in ports:
                lsp = self._nb_idl.lsp_get(port['id']).execute(
                    check_error=True)
                if not lsp:
                    continue

                update_dhcp = False
                if ovn_conf.is_ovn_dhcp_disabled_for_baremetal():
                    if lsp.dhcpv4_options or lsp.dhcpv6_options:
                        update_dhcp = True
                else:
                    if not lsp.dhcpv4_options and not lsp.dhcpv6_options:
                        update_dhcp = True

                if update_dhcp:
                    port_info = self._ovn_client._get_port_options(port)
                    dhcpv4_options, dhcpv6_options = (
                        self._ovn_client.update_port_dhcp_options(
                            port_info, txn))
                    txn.add(self._nb_idl.set_lswitch_port(
                                lport_name=port['id'],
                                dhcpv4_options=dhcpv4_options,
                                dhcpv6_options=dhcpv6_options,
                                if_exists=False))

        raise periodics.NeverAgain()
Example #6
0
    def migrate_to_stateless_fips(self):
        """Perform the migration from stateful to stateless Floating IPs. """
        if not self._ovn_client.is_stateless_nat_supported():
            raise periodics.NeverAgain()

        # Only the worker holding a valid lock within OVSDB will perform the
        # migration.
        if not self.has_lock:
            return

        admin_context = n_context.get_admin_context()
        nb_sync = ovn_db_sync.OvnNbSynchronizer(
            self._ovn_client._plugin, self._nb_idl, self._ovn_client._sb_idl,
            None, None)
        nb_sync.migrate_to_stateless_fips(admin_context)
        raise periodics.NeverAgain()
Example #7
0
 def periodic_sync_task():
     try:
         self.sync(ironic)
     except InvalidFilterDriverState as e:
         LOG.warning('Filter driver %s disabling periodic sync '
                     'task because of an invalid state.', self)
         raise periodics.NeverAgain(e)
Example #8
0
    def check_for_port_security_unknown_address(self):

        if not self.has_lock:
            return

        for port in self._nb_idl.lsp_list().execute(check_error=True):

            if port.type == ovn_const.LSP_TYPE_LOCALNET:
                continue

            addresses = port.addresses
            type_ = port.type.strip()
            if not port.port_security:
                if not type_ and ovn_const.UNKNOWN_ADDR not in addresses:
                    addresses.append(ovn_const.UNKNOWN_ADDR)
                elif type_ and ovn_const.UNKNOWN_ADDR in addresses:
                    addresses.remove(ovn_const.UNKNOWN_ADDR)
            else:
                if type_ and ovn_const.UNKNOWN_ADDR in addresses:
                    addresses.remove(ovn_const.UNKNOWN_ADDR)
                elif not type_ and ovn_const.UNKNOWN_ADDR in addresses:
                    addresses.remove(ovn_const.UNKNOWN_ADDR)

            if addresses:
                self._nb_idl.lsp_set_addresses(
                    port.name, addresses=addresses).execute(check_error=True)
            else:
                self._nb_idl.db_clear('Logical_Switch_Port', port.name,
                                      'addresses').execute(check_error=True)

        raise periodics.NeverAgain()
Example #9
0
    def update_logical_router_with_gateway_network_id(self):
        """Update all OVN logical router registers with the GW network ID"""
        if not self.has_lock:
            return

        cmds = []
        context = n_context.get_admin_context()
        for lr in self._nb_idl.lr_list().execute(check_error=True):
            gw_port = lr.external_ids.get(ovn_const.OVN_GW_PORT_EXT_ID_KEY)
            gw_net = lr.external_ids.get(ovn_const.OVN_GW_NETWORK_EXT_ID_KEY)
            if not gw_port or (gw_port and gw_net):
                # This router does not have a gateway network assigned yet or
                # it has a gateway port and its corresponding network.
                continue

            port = self._ovn_client._plugin.get_port(context, gw_port)
            external_ids = {
                ovn_const.OVN_GW_NETWORK_EXT_ID_KEY: port['network_id']}
            cmds.append(self._nb_idl.db_set(
                'Logical_Router', lr.uuid, ('external_ids', external_ids)))

        if cmds:
            with self._nb_idl.transaction(check_error=True) as txn:
                for cmd in cmds:
                    txn.add(cmd)
        raise periodics.NeverAgain()
Example #10
0
 def check_vlan_distributed_ports(self):
     """Check VLAN distributed ports
     Check for the option "reside-on-redirect-chassis" value for
     distributed VLAN ports.
     """
     if not self.has_lock:
         return
     context = n_context.get_admin_context()
     cmds = []
     # Get router ports belonging to VLAN networks
     vlan_nets = self._ovn_client._plugin.get_networks(
         context, {pnet.NETWORK_TYPE: [n_const.TYPE_VLAN]})
     vlan_net_ids = [vn['id'] for vn in vlan_nets]
     router_ports = self._ovn_client._plugin.get_ports(
         context, {'network_id': vlan_net_ids,
                   'device_owner': n_const.ROUTER_PORT_OWNERS})
     expected_value = ('false' if ovn_conf.is_ovn_distributed_floating_ip()
                       else 'true')
     for rp in router_ports:
         lrp_name = utils.ovn_lrouter_port_name(rp['id'])
         lrp = self._nb_idl.get_lrouter_port(lrp_name)
         if lrp.options.get(
                 ovn_const.LRP_OPTIONS_RESIDE_REDIR_CH) != expected_value:
             opt = {ovn_const.LRP_OPTIONS_RESIDE_REDIR_CH: expected_value}
             cmds.append(self._nb_idl.db_set(
                 'Logical_Router_Port', lrp_name, ('options', opt)))
     if cmds:
         with self._nb_idl.transaction(check_error=True) as txn:
             for cmd in cmds:
                 txn.add(cmd)
     raise periodics.NeverAgain()
Example #11
0
    def check_for_localnet_legacy_port_name(self):
        if not self.has_lock:
            return

        admin_context = n_context.get_admin_context()
        cmds = []
        for ls in self._nb_idl.ls_list().execute(check_error=True):
            network_id = ls.name.replace('neutron-', '')
            legacy_name = utils.ovn_provnet_port_name(network_id)
            legacy_port = None
            segment_id = None
            for lsp in ls.ports:
                if legacy_name == lsp.name:
                    legacy_port = lsp
                    break
            else:
                continue
            for segment in segments_db.get_network_segments(
                    admin_context, network_id):
                if (segment.get(segment_def.PHYSICAL_NETWORK) ==
                        legacy_port.options['network_name']):
                    segment_id = segment['id']
                    break
            if not segment_id:
                continue
            new_p_name = utils.ovn_provnet_port_name(segment_id)
            cmds.append(
                self._nb_idl.db_set('Logical_Switch_Port', legacy_port.uuid,
                                    ('name', new_p_name)))
        if cmds:
            with self._nb_idl.transaction(check_error=True) as txn:
                for cmd in cmds:
                    txn.add(cmd)
        raise periodics.NeverAgain()
Example #12
0
    def check_for_mcast_flood_reports(self):
        if not self.has_lock:
            return

        cmds = []
        for port in self._nb_idl.lsp_list().execute(check_error=True):
            port_type = port.type.strip()
            if port_type in ("vtep", ovn_const.LSP_TYPE_LOCALPORT, "router"):
                continue

            options = port.options
            if port_type == ovn_const.LSP_TYPE_LOCALNET:
                mcast_flood_value = options.get(
                    ovn_const.LSP_OPTIONS_MCAST_FLOOD_REPORTS)
                if mcast_flood_value == 'false':
                    continue
                options.update({ovn_const.LSP_OPTIONS_MCAST_FLOOD: 'false'})
            elif ovn_const.LSP_OPTIONS_MCAST_FLOOD_REPORTS in options:
                continue

            options.update({ovn_const.LSP_OPTIONS_MCAST_FLOOD_REPORTS: 'true'})
            cmds.append(self._nb_idl.lsp_set_options(port.name, **options))

        if cmds:
            with self._nb_idl.transaction(check_error=True) as txn:
                for cmd in cmds:
                    txn.add(cmd)

        raise periodics.NeverAgain()
Example #13
0
    def update_port_qos_with_external_ids_reference(self):
        """Update all OVN QoS registers with the port ID

        This method will only update the OVN QoS registers related to port QoS,
        not FIP QoS. FIP QoS have the corresponding "external_ids" reference.
        """
        if not self.has_lock:
            return

        regex = re.compile(
            r'(inport|outport) == \"(?P<port_id>[a-z0-9\-]{36})\"')
        cmds = []
        for ls in self._nb_idl.ls_list().execute(check_error=True):
            for qos in self._nb_idl.qos_list(ls.name).execute(
                    check_error=True):
                if qos.external_ids:
                    continue
                match = re.match(regex, qos.match)
                if not match:
                    continue
                port_id = match.group('port_id')
                external_ids = {ovn_const.OVN_PORT_EXT_ID_KEY: port_id}
                cmds.append(self._nb_idl.db_set(
                    'QoS', qos.uuid, ('external_ids', external_ids)))

        if cmds:
            with self._nb_idl.transaction(check_error=True) as txn:
                for cmd in cmds:
                    txn.add(cmd)
        raise periodics.NeverAgain()
Example #14
0
    def check_for_fragmentation_support(self):
        if not self.has_lock:
            return

        context = n_context.get_admin_context()
        for net in self._ovn_client._plugin.get_networks(
                context, {external_net.EXTERNAL: [True]}):
            self._ovn_client.set_gateway_mtu(context, net)

        raise periodics.NeverAgain()
Example #15
0
 def periodic_sync_task():
     nonlocal _cached_client
     if _cached_client is None:
         _cached_client = ir_utils.get_client()
     try:
         self.sync(_cached_client)
     except InvalidFilterDriverState as e:
         LOG.warning(
             'Filter driver %s disabling periodic sync '
             'task because of an invalid state.', self)
         raise periodics.NeverAgain(e)
Example #16
0
    def migrate_to_port_groups(self):
        """Perform the migration from Address Sets to Port Groups. """
        # TODO(dalvarez): Remove this in U cycle when we're sure that all
        # versions are running using Port Groups (and OVS >= 2.10).

        # If Port Groups are not supported or we've already migrated, we don't
        # need to attempt to migrate again.
        if not self._nb_idl.get_address_sets():
            raise periodics.NeverAgain()

        # Only the worker holding a valid lock within OVSDB will perform the
        # migration.
        if not self.has_lock:
            return

        admin_context = n_context.get_admin_context()
        nb_sync = ovn_db_sync.OvnNbSynchronizer(
            self._ovn_client._plugin, self._nb_idl, self._ovn_client._sb_idl,
            None, None)
        nb_sync.migrate_to_port_groups(admin_context)
        raise periodics.NeverAgain()
Example #17
0
    def check_for_igmp_snoop_support(self):
        if not self.has_lock:
            return

        with self._nb_idl.transaction(check_error=True) as txn:
            value = ('true' if ovn_conf.is_igmp_snooping_enabled()
                     else 'false')
            for ls in self._nb_idl.ls_list().execute(check_error=True):
                if ls.other_config.get(ovn_const.MCAST_SNOOP, None) == value:
                    continue
                txn.add(self._nb_idl.db_set(
                    'Logical_Switch', ls.name,
                    ('other_config', {
                        ovn_const.MCAST_SNOOP: value,
                        ovn_const.MCAST_FLOOD_UNREGISTERED: value})))

        raise periodics.NeverAgain()
Example #18
0
    def check_for_port_security_unknown_address(self):

        if not self.has_lock:
            return

        for port in self._nb_idl.lsp_list().execute(check_error=True):
            addresses = port.addresses
            if not port.port_security and 'unknown' not in addresses:
                addresses.append('unknown')
            elif port.port_security and 'unknown' in addresses:
                addresses.remove('unknown')
            else:
                continue

            self._nb_idl.lsp_set_addresses(
                port.name, addresses=addresses).execute(check_error=True)

        raise periodics.NeverAgain()
Example #19
0
    def check_router_mac_binding_options(self):
        if not self.has_lock:
            return

        cmds = []
        for router in self._nb_idl.lr_list().execute(check_error=True):
            if (router.options.get('always_learn_from_arp_request') and
                    router.options.get('dynamic_neigh_routers')):
                continue

            opts = copy.deepcopy(router.options)
            opts.update({'always_learn_from_arp_request': 'false',
                         'dynamic_neigh_routers': 'true'})
            cmds.append(self._nb_idl.update_lrouter(router.name, options=opts))

        if cmds:
            with self._nb_idl.transaction(check_error=True) as txn:
                for cmd in cmds:
                    txn.add(cmd)
        raise periodics.NeverAgain()
Example #20
0
 def run_only_once():
     raise periodics.NeverAgain("No need to run again !!")
Example #21
0
def run_only_once(started_at):
    print("1: %s" % (time.time() - started_at))
    raise periodics.NeverAgain("No need to run again after first run !!")
def run_for_some_time(started_at):
    print("2: %s" % (time.time() - started_at))
    if (time.time() - started_at) > 5:
        raise periodics.NeverAgain("No need to run again !!")