Exemple #1
0
 def _validate_ignored_port(self, port, original_port):
     if utils.is_lsp_ignored(port):
         if not utils.is_lsp_ignored(original_port):
             # From not ignored port to ignored port
             msg = (_('Updating device_owner to %(device_owner)s for port '
                      '%(port_id)s is not supported') % {
                          'device_owner': port['device_owner'],
                          'port_id': port['id']
                      })
             raise OVNPortUpdateError(resource='port', msg=msg)
     elif utils.is_lsp_ignored(original_port):
         # From ignored port to not ignored port
         msg = (_('Updating device_owner for port %(port_id)s owned by '
                  '%(device_owner)s is not supported') % {
                      'port_id': port['id'],
                      'device_owner': original_port['device_owner']
                  })
         raise OVNPortUpdateError(resource='port', msg=msg)
    def sync_networks_ports_and_dhcp_opts(self, ctx):
        LOG.debug('OVN-NB Sync networks, ports and DHCP options started')
        db_networks = {}
        for net in self.core_plugin.get_networks(ctx):
            db_networks[utils.ovn_name(net['id'])] = net

        # Ignore the floating ip ports with device_owner set to
        # constants.DEVICE_OWNER_FLOATINGIP
        db_ports = {
            port['id']: port
            for port in self.core_plugin.get_ports(ctx)
            if not utils.is_lsp_ignored(port)
        }

        ovn_all_dhcp_options = self.ovn_api.get_all_dhcp_options()
        db_network_cache = dict(db_networks)

        ports_need_sync_dhcp_opts = []
        lswitches = self.ovn_api.get_all_logical_switches_with_ports()
        del_lswitchs_list = []
        del_lports_list = []
        add_provnet_ports_list = []
        for lswitch in lswitches:
            if lswitch['name'] in db_networks:
                for lport in lswitch['ports']:
                    if lport in db_ports:
                        port = db_ports.pop(lport)
                        if not utils.is_network_device_port(port):
                            ports_need_sync_dhcp_opts.append(port)
                    else:
                        del_lports_list.append({
                            'port': lport,
                            'lswitch': lswitch['name']
                        })
                db_network = db_networks[lswitch['name']]
                physnet = db_network.get(pnet.PHYSICAL_NETWORK)
                # Updating provider attributes is forbidden by neutron, thus
                # we only need to consider missing provnet-ports in OVN DB.
                if physnet and not lswitch['provnet_port']:
                    add_provnet_ports_list.append({
                        'network': db_network,
                        'lswitch': lswitch['name']
                    })

                del db_networks[lswitch['name']]
            else:
                del_lswitchs_list.append(lswitch)

        for net_id, network in db_networks.items():
            LOG.warning(
                "Network found in Neutron but not in "
                "OVN DB, network_id=%s", network['id'])
            if self.mode == SYNC_MODE_REPAIR:
                try:
                    LOG.debug('Creating the network %s in OVN NB DB',
                              network['id'])
                    self._ovn_client.create_network(network)
                except RuntimeError:
                    LOG.warning(
                        "Create network in OVN NB failed for "
                        "network %s", network['id'])

        self._sync_metadata_ports(ctx, db_ports)

        self._sync_subnet_dhcp_options(ctx, db_network_cache,
                                       ovn_all_dhcp_options['subnets'])

        for port_id, port in db_ports.items():
            LOG.warning(
                "Port found in Neutron but not in OVN "
                "DB, port_id=%s", port['id'])
            if self.mode == SYNC_MODE_REPAIR:
                try:
                    LOG.debug('Creating the port %s in OVN NB DB', port['id'])
                    self._create_port_in_ovn(ctx, port)
                    if port_id in ovn_all_dhcp_options['ports_v4']:
                        _, lsp_opts = utils.get_lsp_dhcp_opts(
                            port, constants.IP_VERSION_4)
                        if lsp_opts:
                            ovn_all_dhcp_options['ports_v4'].pop(port_id)
                    if port_id in ovn_all_dhcp_options['ports_v6']:
                        _, lsp_opts = utils.get_lsp_dhcp_opts(
                            port, constants.IP_VERSION_6)
                        if lsp_opts:
                            ovn_all_dhcp_options['ports_v6'].pop(port_id)
                except RuntimeError:
                    LOG.warning("Create port in OVN NB failed for"
                                " port %s", port['id'])

        with self.ovn_api.transaction(check_error=True) as txn:
            for lswitch in del_lswitchs_list:
                LOG.warning(
                    "Network found in OVN but not in "
                    "Neutron, network_id=%s", lswitch['name'])
                if self.mode == SYNC_MODE_REPAIR:
                    LOG.debug('Deleting the network %s from OVN NB DB',
                              lswitch['name'])
                    txn.add(self.ovn_api.ls_del(lswitch['name']))

            for provnet_port_info in add_provnet_ports_list:
                network = provnet_port_info['network']
                LOG.warning(
                    "Provider network found in Neutron but "
                    "provider network port not found in OVN DB, "
                    "network_id=%s", provnet_port_info['lswitch'])
                if self.mode == SYNC_MODE_REPAIR:
                    LOG.debug('Creating the provnet port %s in OVN NB DB',
                              utils.ovn_provnet_port_name(network['id']))
                    self._ovn_client._create_provnet_port(
                        txn, network, network.get(pnet.PHYSICAL_NETWORK),
                        network.get(pnet.SEGMENTATION_ID))

            for lport_info in del_lports_list:
                LOG.warning(
                    "Port found in OVN but not in "
                    "Neutron, port_id=%s", lport_info['port'])
                if self.mode == SYNC_MODE_REPAIR:
                    LOG.debug('Deleting the port %s from OVN NB DB',
                              lport_info['port'])
                    txn.add(
                        self.ovn_api.delete_lswitch_port(
                            lport_name=lport_info['port'],
                            lswitch_name=lport_info['lswitch']))
                    if lport_info['port'] in ovn_all_dhcp_options['ports_v4']:
                        LOG.debug('Deleting port DHCPv4 options for (port %s)',
                                  lport_info['port'])
                        txn.add(
                            self.ovn_api.delete_dhcp_options(
                                ovn_all_dhcp_options['ports_v4'].pop(
                                    lport_info['port'])['uuid']))
                    if lport_info['port'] in ovn_all_dhcp_options['ports_v6']:
                        LOG.debug('Deleting port DHCPv6 options for (port %s)',
                                  lport_info['port'])
                        txn.add(
                            self.ovn_api.delete_dhcp_options(
                                ovn_all_dhcp_options['ports_v6'].pop(
                                    lport_info['port'])['uuid']))

        self._sync_port_dhcp_options(ctx, ports_need_sync_dhcp_opts,
                                     ovn_all_dhcp_options['ports_v4'],
                                     ovn_all_dhcp_options['ports_v6'])
        LOG.debug('OVN-NB Sync networks, ports and DHCP options finished')